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 @@ -35,6 +35,7 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" +#include namespace clang { namespace clangd { @@ -167,6 +168,7 @@ llvm::StringRef FallbackDir; llvm::DenseMap CacheFEToURI; llvm::StringMap CachePathToURI; + std::list StorageForSystemHeaders; llvm::DenseMap CacheFIDToInclude; public: @@ -250,6 +252,18 @@ // Conservatively refuse to insert #includes to files without guards. return ""; } + // 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) { + StorageForSystemHeaders.push_back("<" + ShorterInclude + ">"); + return StorageForSystemHeaders.back(); + } // Standard case: just insert the file itself. return toURI(FE); } 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;