diff --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp b/clang-tools-extra/clangd/index/SymbolCollector.cpp --- a/clang-tools-extra/clangd/index/SymbolCollector.cpp +++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp @@ -789,6 +789,16 @@ // Conservatively refuse to insert #includes to files without guards. return llvm::None; } + // Store system includes as verbatim. This enables making use of the same + // index in different environments, e.g. a system header like + // might resolve to different absolute paths, but the path relative to sysroot + // will be the same. + bool IsSystem = false; + auto ShorterInclude = + PP->getHeaderSearchInfo().suggestPathToFileForDiagnostics(FE, "", + &IsSystem); + if (IsSystem) + return "<" + ShorterInclude + ">"; // Standard case: just insert the file itself. return toURI(SM, Filename, Opts); } diff --git a/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp b/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp --- a/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp +++ b/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp @@ -1446,6 +1446,20 @@ UnorderedElementsAre(IncludeHeaderWithRef(TestHeaderURI, 1u))); } +TEST_F(SymbolCollectorTest, IncludeHeaderFromSystemIsVerbatim) { + llvm::StringRef HeaderName = "header.h"; + TestHeaderName = testPath(HeaderName); + TestHeaderURI = URI::create(TestHeaderName).toString(); + CollectorOpts.CollectIncludePath = true; + runSymbolCollector("#pragma once\nclass Foo {};", /*Main=*/"", + {"-isystem", testRoot()}); + EXPECT_THAT(Symbols, UnorderedElementsAre( + AllOf(QName("Foo"), DeclURI(TestHeaderURI)))); + EXPECT_THAT(Symbols.begin()->IncludeHeaders, + UnorderedElementsAre( + IncludeHeaderWithRef("<" + HeaderName.str() + ">", 1u))); +} + TEST_F(SymbolCollectorTest, CanonicalSTLHeader) { CollectorOpts.CollectIncludePath = true; CanonicalIncludes Includes;