This is an archive of the discontinued LLVM Phabricator instance.

[AST][clangd] Expose documentation of Attrs on hover.
ClosedPublic

Authored by sammccall on Aug 7 2021, 3:42 PM.

Details

Summary

This adds a method to Attr to get at the documentation programmatically.

Diff Detail

Event Timeline

sammccall created this revision.Aug 7 2021, 3:42 PM
sammccall requested review of this revision.Aug 7 2021, 3:42 PM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptAug 7 2021, 3:42 PM
aaron.ballman added inline comments.Aug 9 2021, 7:05 AM
clang/utils/TableGen/ClangAttrEmitter.cpp
4220

FWIW, this will miss omp::sequence and omp::directive, but that's not the end of the world. May be worth a fixme comment in case we want to solve it someday.

4242

Hmmmm, I am not 100% certain this assertion is correct -- the user may have plugin attributes, which I believe are given a "kind" that's larger than the last-known builtin attribute kind.

sammccall updated this revision to Diff 365461.Aug 10 2021, 6:41 AM
sammccall marked an inline comment as done.

Change assertion to defensive check

clang/utils/TableGen/ClangAttrEmitter.cpp
4220

Well, those

  • don't themselves have Attr nodes or AttrKinds, so the API couldn't query for them
  • don't actually have any documentation as far as I can tell

So I'm not sure there's much to fix.


The ParsedAttr-kind vs Attr-kind distinction, and the fact that many attributes don't leave any AST nodes at all, mean this method doesn't seem "universal". But the goal is to show docs in clangd when hovering on an attribute (which we only support for those with AST nodes).

If we want to do something different (like show documenation while code-completing) we'll probably have to add a second ParsedAttrKind-based API.

4242

Thanks, changed it to an if() instead.
(I don't think it's particularly pressing to allow them to be documented)

aaron.ballman accepted this revision.Aug 10 2021, 8:37 AM

This generally LGTM but the only other thing I'm wondering is whether there should be any clang-specific testing for this functionality. Right now, it relies on running the clangd unit tests to notice failures and that's not ideal because not everyone builds clang-tools-extra as part of their usual Clang development. However, given that this functionality isn't really *used* by Clang, I'm not certain there's much to test and there's not a whole lot of failure mode beyond "the file didn't get generated".

So giving this my LGTM, but if you think of a way to introduce clang-specific tests for this, I'm happy to do further review.

clang/utils/TableGen/ClangAttrEmitter.cpp
4220

So I'm not sure there's much to fix.

The big reason they're not documented is because I've not thought of a good way to expose the documentation via AttrDocs.td. Currently, that documentation needs the attributes to live in Attr.td, and we don't expose the attributes there because we have no way to express their arguments.

At some point in the future, I expect we'll make these two attributes "more normal" by getting them into Attr.td and AttrDocs.td, and at that point this probably fixes itself? So I think you're right, maybe not much to fix *here*.

4242

Agreed that we can figure out how to let plugin attributes add documentation at a later date.

This revision is now accepted and ready to land.Aug 10 2021, 8:37 AM
sammccall updated this revision to Diff 365499.Aug 10 2021, 9:04 AM

add unit test for getDocumentation

This generally LGTM but the only other thing I'm wondering is whether there should be any clang-specific testing

Makes sense. Here the "clang feature" is just the API, so I've added a very basic unittest for that.

aaron.ballman added inline comments.Aug 10 2021, 11:49 AM
clang/unittests/AST/CMakeLists.txt
18

I don't think this new file got attached to the patch.

Oops, forgot test file

sammccall updated this revision to Diff 365601.Aug 10 2021, 1:24 PM

Oops, I'm just bad at git. Here's the test file!

aaron.ballman accepted this revision.Aug 11 2021, 9:36 AM

LGTM, thanks!

kadircet accepted this revision.Aug 12 2021, 12:10 AM

thanks, LG from my side as well, just a couple of clarification questions regarding tablegen.

clang-tools-extra/clangd/unittests/HoverTests.cpp
2389

nit: maybe ASSERT_FALSE(HI.Documentation.empty()) ? (I actually think the test in AST/AttrTest is enough and we can drop this assertion).

clang/utils/TableGen/ClangAttrEmitter.cpp
4231

not sure if this comment will stay useful.

4237

i am not well-versed in tablegen, so sorry if i am being dense here, butt what happens to the attributes we skipped above (e.g. the ones without a ASTNode flag)?

Maybe we should be emitting a ... AttrDoc_X[] = ""; for all attributes, no matter what?

aaron.ballman added inline comments.Aug 12 2021, 4:04 AM
clang/unittests/AST/AttrTest.cpp
20

It seems this is failing the premerge CI -- I think you need a call to .str() in here to convert the StringRef to a std::string?

clang/utils/TableGen/ClangAttrEmitter.cpp
4237

The ones without an AST node don't get an attr::Kind enumeration generated for them, so I believe this interface is safe.

sammccall marked 9 inline comments as done.Aug 12 2021, 12:09 PM
sammccall added inline comments.
clang/unittests/AST/AttrTest.cpp
20

Thanks - no idea why this only breaks MSVC, but gmock is a subtle beast...

clang/utils/TableGen/ClangAttrEmitter.cpp
4231

I want a comment to avoid a chesterton's fence:

  • the motivation for doing something lazy is that this is really rare
  • it's sensible to revisit this if it stops being rare

Reworded it to make this more explicit.

4237

Right, all those extra strings would just tickle -Wunused :-(

I'd love to have an API that can also be used for attrs with ASTNode=0 (many are documented!). However:

  • for the motivating use case (hover), we can only trigger when we find an AST node anyway (sadly)
  • the obvious alternative is AttributeCommonInfo::Kind, (i.e. ParsedAttr kind), which isn't actually better, just differently bad. e.g. there's one ParsedAttr kind for interrupt, but three target-specific Attr kinds, each of which is documented separately. For hover you want to get the right one, and ParsedAttr kind can't choose it.
This revision was landed with ongoing or failed builds.Aug 12 2021, 12:16 PM
This revision was automatically updated to reflect the committed changes.
sammccall marked 3 inline comments as done.
thakis added a subscriber: thakis.Aug 12 2021, 6:15 PM

The docs are in rST format. Is that the format LSP wants?

Also, I tweaked the tablegen bits a bit to be more like all the other tablegen bits in 189911203779e793cb7767ad233d9994a88c7ea3. Hope that's ok :)

sammccall added a comment.EditedAug 13 2021, 1:53 AM

The docs are in rST format. Is that the format LSP wants?

Not really :-) LSP's favorite would be markdown.
But we're used to ingesting comments in unknown formats and trying to make sense of them, and our users are used to us failing. (Those heuristics could use some love).
So the rst will be thrown into that meatgrinder as if they're comments, and at the very least the text will survive, which is the main thing.

Hopefully one day we can do real conversion.

Edit: and thanks for fixing up the tablegen!

RKSimon added inline comments.
clang/utils/TableGen/ClangAttrEmitter.cpp
4231

coverity is complaining that the for loop will never execute more than once, would it be worth refactoring?

if (!Docs.empty) {
  const auto *D = Docs[0];
  ...
}
sammccall added inline comments.Aug 19 2021, 11:51 PM
clang/utils/TableGen/ClangAttrEmitter.cpp
4231