This is an archive of the discontinued LLVM Phabricator instance.

[clangd] Patch PP directives to use stale preambles while building ASTs
ClosedPublic

Authored by kadircet on May 15 2020, 3:05 AM.

Details

Summary

Depends on D79930.

This enables more accurate parsing of the AST, by making changes in PP
directives in preamble section visible. This is handled by injecting conditional
directives and macro defines/undefs. Note that include insertions are handled
separately in D77644, to not duplicate existing include headers.

This patch doesn't handle any location mappings yet, so features like go-to-def,
go-to-refs and hover might not work as expected. These will be addressed in a
follow-up patch.

Diff Detail

Event Timeline

kadircet created this revision.May 15 2020, 3:05 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 15 2020, 3:05 AM
kadircet retitled this revision from [clangd] Patch PP directives to use stale preambles while building ASTs to [WIP][clangd] Patch PP directives to use stale preambles while building ASTs.May 15 2020, 3:15 AM
kadircet updated this revision to Diff 264567.May 18 2020, 2:30 AM
  • Only store defines
  • Make use of source text directly instead of printing tokens
kadircet updated this revision to Diff 264666.May 18 2020, 9:49 AM
  • MacroInfo's definition range is a token range, convert it to a char range.
sammccall added inline comments.May 19 2020, 4:29 AM
clang-tools-extra/clangd/Preamble.cpp
415

Hmm, with N macros in the file and O(1) changed, it seems like the inaccuracy of the conditional-scanning may outweigh defining that one in the wrong order in complex cases.

Especially since this only seems to come up if there are multiple definitions of the same macro, which seems easy enough to detect if that's an important case.

427

don't you need a #line directive too? Seems like you're not using the DirectiveLine anywhere.

clang-tools-extra/clangd/unittests/PreambleTests.cpp
205

do you think it makes sense to have a test that just asserts on the contents of the preamble patch? it seems like a more direct way to test some of these things.

These tests are nice, but debugging them seems like it might be a bit of work.

kadircet marked 3 inline comments as done.May 19 2020, 6:31 AM
kadircet added inline comments.
clang-tools-extra/clangd/Preamble.cpp
415

makes sense, will change it to only patch new defines. And actually most of the time any define directive below this one would also be considered new, because line information has changed for them, hence we need to patch. Unless user both inserts and deletes a line.

427

spoileers. that's in D80198, I didn't want to make this one any bigger.

clang-tools-extra/clangd/unittests/PreambleTests.cpp
205

I had 2 reasons for not doing that:

  • Not clobbering the API of PreamblePatch just for testing.
  • Making tests less fragile for changes in the patch format.

I suppose the first one is not that important, but I believe the latter is quite useful. We can always to something like hassubstr I suppose, but in the end we only care about its effect while creating an AST. We can do something like hassubstr, but we would still need these tests to ensure they interact as expected with the preprocessor.

kadircet retitled this revision from [WIP][clangd] Patch PP directives to use stale preambles while building ASTs to [clangd] Patch PP directives to use stale preambles while building ASTs.May 20 2020, 3:16 AM
sammccall accepted this revision.May 20 2020, 6:43 AM
sammccall added inline comments.
clang-tools-extra/clangd/Preamble.cpp
110–167

this is worth a comment saying what this is used for: directives *other* than includes where we need only basic structure.

clang-tools-extra/clangd/unittests/PreambleTests.cpp
205

Agree that having robust tests of the whole thing is important.

Maybe we could add an additional (sorry) single smoke test that asserts on the whole patch?
It'd be brittle indeed but those diffs would actually be really interesting to me as a reader of the code and reviewer of changes... gives a different perspective on what the code is doing.

I don't think having a text() or textForTests() accessor is too bad, especially if it's trivial.

This revision is now accepted and ready to land.May 20 2020, 6:43 AM
kadircet updated this revision to Diff 265995.May 25 2020, 3:42 AM
kadircet marked 5 inline comments as done.
  • Assert on patch contents, using regexes for main file match.
This revision was automatically updated to reflect the committed changes.