This is an archive of the discontinued LLVM Phabricator instance.

[clangd] Properly compute framework-style include spelling
ClosedPublic

Authored by dgoldman on Jan 11 2022, 2:38 PM.

Details

Summary

With this change, clangd now computes framework-style includes
for framework headers at indexing time.

This also updates HeaderSearch to consistently set the Framework
HeaderFileInfo field for framework headers.

Diff Detail

Event Timeline

dgoldman created this revision.Jan 11 2022, 2:38 PM
dgoldman requested review of this revision.Jan 11 2022, 2:38 PM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptJan 11 2022, 2:38 PM
dgoldman updated this revision to Diff 399336.Jan 12 2022, 8:12 AM

Run clang-format

Nice!

clang-tools-extra/clangd/index/SymbolCollector.cpp
204

...ToUmbrellaHeaderSpelling?

(Unclear to me what values "umbrella include" would take)

267

return Optional<FrameworkInfo> instead of sentinel values

270

This name is very vague: splitFrameworkHeaderPath?
Similarly FrameworkInfo -> FrameworkHeaderPath.

(I was confused why this wasn't cached until I understood this *isn't* per-framework information, it's per-header information)

292

Short doc comment here. In particular what Framework contains

292

no need to pass Path, it's FE->getName()

298

there are 7 references to SpellingR.first->second in this function, give it a name?

300

Having multiple caches managed by this function makes it hard to understand.
Pull out a function to get the (cached) umbrella header for a framework?

302

Why? Seems like just looking up the umbrella first would be simpler and just as efficient.

310

if the header we happened to see first is PrivateHeaders, then you're caching the fact that this framework has no umbrella header.

There's a design decision here: is the path of any single header sufficient to decide whether a framework has an umbrella? If not, the cache needs to work differently.

315

comment here on what an umbrella header is and why we care

395

This comment is most useful to people not very familiar with frameworks, but isn't specific enough. maybe:
Framework headers are spelled as <Framework/Foo.h>, not "path/Framework.framework/Headers/Foo.h"

The bit about umbrella headers should go where we do that, and mostly say *why* rather than what

400

nit: inline, this var doesn't improve readability

402

return Optional<StringRef> and initialize this in the if, rather than using the empty string as a sentinel value

404

nit: no braces

clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
669

nit: inline these filenames used once

671

nit: no const on locals

695

Instead of copying the setup 3 times, can we:

  • run the test, expect "Foundation/NSObject.h"
  • add the umbrella file
  • run the test, expect "Foundation/Foundation.h"
  • run the test with -isysroot, expect <Foundation/Foundation.h>

?

762

OOC, is "withsysroot" needed here?

988

unrelated whitespace changes

clang/lib/Lex/HeaderSearch.cpp
1052 ↗(On Diff #399336)

This looks like a separate change, and should have a test in clang.

dgoldman updated this revision to Diff 401422.Jan 19 2022, 3:32 PM
dgoldman marked 18 inline comments as done.

Changes for review

clang-tools-extra/clangd/index/SymbolCollector.cpp
302

To give a proper spelling for private framework headers (although maybe the framework import would be more useful than a non-framework import? I dunno)

310

Fixed

315

Added a comment to the top of getFrameworkUmbrellaSpelling

clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
762

Changed, should have been iframework to add a system framework path

dgoldman added inline comments.Jan 19 2022, 3:55 PM
clang/lib/Lex/HeaderSearch.cpp
1052 ↗(On Diff #399336)

Will try to split out + add a test tomorrow

This looks good now, only blocker is dropping the change to LookupFile somehow.

Is it valuable to land this before the imminent 14 branch cut? I think it's OK but as an indexing change a crash has the possibility to be really disruptive, and most of the rest of us aren't regularly dogfooding this on Mac.
I'd suggest we only land it before the branch if you feel like you can test this on a reasonable variety of code in the next few weeks. WDYT?

clang-tools-extra/clangd/index/SymbolCollector.cpp
300

I'd suggest only passing the CharacteristicKind HeadersDir here rather than the whole FileEntry + HeaderPath.
Or failing that, being very explicit that these are just for an *example* header.

(The confusing part/trap here is that we're computing something based on one input, and then caching it so that it will be used for other inputs, without verifying that they would produce the same answer)

316

nit: this is a no-op

333

any reason not to also try_emplace here and reuse the iterator below?

341

We're (deliberately?) bypassing the umbrella cache here, say why private headers shouldn't be replaced by the umbrella header?
Presumably because they're not exported by it...

clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
712

Add a test that private headers are not replaced by the umbrella?

dgoldman updated this revision to Diff 401671.Jan 20 2022, 9:37 AM
dgoldman marked 4 inline comments as done.

Support private headers + private umbrellas

clang-tools-extra/clangd/index/SymbolCollector.cpp
333

In case the splitFrameworkHeaderPath fails we shouldn't cache the failure. But it's unexpected and shouldn't happen in practice now that I've added the private headers support, so flipped it to remove the entry if it happens.

341

Just went ahead and added proper support for privateheaders since it wasn't too much more work. They should have a separate umbrella header (or none), see https://clang.llvm.org/docs/Modules.html#private-module-map-files

This looks good now, only blocker is dropping the change to LookupFile somehow.

Is it valuable to land this before the imminent 14 branch cut? I think it's OK but as an indexing change a crash has the possibility to be really disruptive, and most of the rest of us aren't regularly dogfooding this on Mac.
I'd suggest we only land it before the branch if you feel like you can test this on a reasonable variety of code in the next few weeks. WDYT?

SGTM to wait until after, the cut is in 2 weeks right? That should be fine

dgoldman updated this revision to Diff 401746.Jan 20 2022, 12:31 PM

Split up HeaderSearch change

sammccall accepted this revision.Jan 26 2022, 12:55 AM

Thanks! LG with a couple of optional nits.
Cut should be on 2022-02-01 or thereabouts, best to land after that if it's not a problem.

clang-tools-extra/clangd/index/SymbolCollector.cpp
315

nit: move next to first use

320

now that we're filling in a couple of fields for a whole cache entry, probably worth pulling out a function just for that. That will also naturally eliminate the duplicate returns here.

This revision is now accepted and ready to land.Jan 26 2022, 12:55 AM
dgoldman updated this revision to Diff 403361.Jan 26 2022, 11:50 AM
dgoldman marked an inline comment as done.

Formatting fixes