ioeric added a comment.

Thank you for reviewing this!



================
Comment at: clangd/index/CanonicalIncludes.h:52
+  /// a canonical header name.
+  llvm::StringRef mapHeader(llvm::StringRef Header) const;
+
----------------
sammccall wrote:
> ioeric wrote:
> > sammccall wrote:
> > > So I'm a bit concerned this is too narrow an interface, and we really 
> > > want to deal with SourceLocation here which would give us the include 
> > > stack.
> > > 
> > > Evidence #1: .inc handling really is the same job, but because this class 
> > > has a single-file interface, we have to push it into the caller.
> > > Evidence #2: I was thinking about a more... principled way of determining 
> > > system headers. One option would be to have a whitelist of public 
> > > headers, and walk up the include stack to see if you hit one. (I'm not 
> > > 100% sure this would work, but still...) This isn't implementable with 
> > > the current interface.
> > > 
> > > One compromise would be to pass in a stack<StringRef> or something. 
> > > Efficiency doesn't really matter because the caller can cache based on 
> > > the top element.
> > > Evidence #1: .inc handling really is the same job, but because this class 
> > > has a single-file interface, we have to push it into the caller.
> > I think this would depend on how you define the scope of this class. `.inc` 
> > handling is a subtle case that I'm a bit hesitated to build into the 
> > interface here.
> > 
> > > Evidence #2: ....
> > This is actually very similar to how the hardcoded mapping was generated. I 
> > had a tool that examined include stacks for a library (e.g. STL) and 
> > applied a similar heuristic - treat the last header in the include stack 
> > within the library boundary as the "exporting" public header for a leaf 
> > include header, if there is no other public header that has shorter 
> > distance to that include. For example, if we see a stack like 
> > `stl/bits/internal.h -> stl/bits/another.h -> stl/public_1.h -> 
> > user_code.cc`, we say `public_1.h` exports `bits/internal.h` and add a 
> > mapping from `bits/internal.h$` to `public_1.h`. But if we see another 
> > (shorter) include stack like `stl/bits/internal.h -> stl/public_2.h -> 
> > user_code.cc`, we say `stl/public_2.h` exports `stl/bits/internal.h`. This 
> > heuristic works well for many cases. However, this may produce wrong 
> > mappings when an internal header is used by multiple public headers. For 
> > example, if we have two include stacks with the same length e.g. 
> > `bits/internal.h -> public_1.h -> user.cc` and `bits/inernal.h -> 
> > public_2.h -> user.cc`, the result mapping would depend on the order in 
> > which we see these two stacks; thus, we had to do some manual adjustment to 
> > make sure bits/internal.h is mapped to the correct header according to the 
> > standard.
> > 
> > I am happy to discuss better solution here. But within the scope of this 
> > patch, I'd prefer to stick to interfaces that work well for the current 
> > working solution instead of designing for potential future solutions. I 
> > should be easy to iterate on the interfaces as these interfaces aren't 
> > going to be widely used in clangd after all. WDYT?
> > I think this would depend on how you define the scope of this class. .inc 
> > handling is a subtle case that I'm a bit hesitated to build into the 
> > interface here.
> 
> Sure it's subtle, but it's clearly in the scope of determining what the 
> canonical header is for a symbol, which is the job of this class. We wouldn't 
> be building it into the interface - on the contrary, the *current* proposed 
> interface codifies *not* handling .inc files.
> 
> But you're right that we should check in something that handles most cases.
> 
> My preference would be to drop `.inc` from this patch until we can 
> incorporate it into the design, but I'm also OK with a FIXME to move it.
Okay, I removed `.inc` handling from this patch ;) 


================
Comment at: unittests/clangd/HeadersTests.cpp:29
+  // absolute path.
+  std::string addToSubdir(PathRef File, llvm::StringRef Code = "") {
+    assert(llvm::sys::path::is_relative(File) && "FileName should be 
relative");
----------------
sammccall wrote:
> sammccall wrote:
> > This test would be clearer to me if you removed this helper and just did
> > 
> > ```FS.Files["sub/bar.h"] = ...```
> > 
> > in the test.
> > 
> > Can we change `buildTestFS` in `TestFS.cpp` to call 
> > `getVirtualTestFilePath` on relative paths to allow this?
> > 
> > (I can do this as a followup if you like, but it seems like a trivial 
> > change)
> I thought better of that change to TestFS, but did some renames in r325326.
> 
> So this would be `FS.Files[testPath("sub/bar.h")) = ...` which still seems 
> more transparent - up to you.
Thanks a lot!


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D42640



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to