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)

268

return Optional<FrameworkInfo> instead of sentinel values

271

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)

293

Short doc comment here. In particular what Framework contains

293

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

299

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

301

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?

303

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

311

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.

316

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

397

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

402

nit: inline, this var doesn't improve readability

404

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

406

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?

993

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
303

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)

311

Fixed

316

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
301

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)

317

nit: this is a no-op

334

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

342

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
334

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.

342

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
316

nit: move next to first use

321

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