hokein created this revision. hokein added a reviewer: sammccall. Herald added subscribers: kadircet, arphaman, jkorous, MaskRay, ioeric, ilya-biryukov.
Add a flag to SymbolCollector to collect refs fdrom headers. Note that we collect refs from headers in static index, and we don't do it for dynamic index because of the preamble (we skip function body in preamble, collecting it will result incomplete results). Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D53322 Files: clangd/index/IndexAction.cpp clangd/index/IndexAction.h clangd/index/SymbolCollector.cpp clangd/index/SymbolCollector.h unittests/clangd/SymbolCollectorTests.cpp
Index: unittests/clangd/SymbolCollectorTests.cpp =================================================================== --- unittests/clangd/SymbolCollectorTests.cpp +++ unittests/clangd/SymbolCollectorTests.cpp @@ -479,6 +479,17 @@ EXPECT_THAT(Refs, Not(Contains(Pair(findSymbol(MainSymbols, "c").ID, _)))); } +TEST_F(SymbolCollectorTest, RefsInHeaders) { + CollectorOpts.RefFilter = RefKind::All; + CollectorOpts.RefMainFileOnly = false; + Annotations Header(R"( + class [[Foo]] {}; + )"); + runSymbolCollector(Header.code(), ""); + EXPECT_THAT(Refs, Contains(Pair(findSymbol(Symbols, "Foo").ID, + HaveRanges(Header.ranges())))); +} + TEST_F(SymbolCollectorTest, References) { const std::string Header = R"( class W; Index: clangd/index/SymbolCollector.h =================================================================== --- clangd/index/SymbolCollector.h +++ clangd/index/SymbolCollector.h @@ -57,6 +57,10 @@ /// The symbol ref kinds that will be collected. /// If not set, SymbolCollector will not collect refs. RefKind RefFilter = RefKind::Unknown; + /// If set to true, SymbolCollector will collect refs from main file only; + /// otherwise, refs from headers included by main file will be collected. + /// This flag is only available when RefFilter is set. + bool RefMainFileOnly = true; // Every symbol collected will be stamped with this origin. SymbolOrigin Origin = SymbolOrigin::Unknown; /// Collect macros. Index: clangd/index/SymbolCollector.cpp =================================================================== --- clangd/index/SymbolCollector.cpp +++ clangd/index/SymbolCollector.cpp @@ -354,7 +354,8 @@ return true; if (!shouldCollectSymbol(*ND, *ASTCtx, Opts)) return true; - if (CollectRef && SM.getFileID(SpellingLoc) == SM.getMainFileID()) + if (CollectRef && + (!Opts.RefMainFileOnly || SM.getFileID(SpellingLoc) == SM.getMainFileID())) DeclRefs[ND].emplace_back(SpellingLoc, Roles); // Don't continue indexing if this is a mere reference. if (IsOnlyRef) @@ -476,17 +477,35 @@ const auto &SM = ASTCtx->getSourceManager(); auto* MainFileEntry = SM.getFileEntryForID(SM.getMainFileID()); + llvm::DenseMap<clang::FileID, std::string> URICache; if (auto MainFileURI = toURI(SM, MainFileEntry->getName(), Opts)) { - std::string MainURI = *MainFileURI; + URICache.insert({SM.getMainFileID(), *MainFileURI}); for (const auto &It : DeclRefs) { if (auto ID = getSymbolID(It.first)) { for (const auto &LocAndRole : It.second) { - Ref R; + auto FileID = SM.getFileID(LocAndRole.first); + auto Found = URICache.find(FileID); + if (Found == URICache.end()) { + if (auto* FileEntry = SM.getFileEntryForID(FileID)) { + auto FileURI = toURI(SM, FileEntry->getName(), Opts); + if (!FileURI) { + log("Failed to create URI for file: {0}\n", FileEntry); + continue; + } + Found = URICache.insert({FileID, *FileURI}).first; + } else { + // Ignore cases where we can not find a corresponding file entry + // for the loc, thoses are not interesting, e.g. symbols formed + // via macro concatenation. + continue; + } + } auto Range = getTokenRange(LocAndRole.first, SM, ASTCtx->getLangOpts()); + Ref R; R.Location.Start = Range.first; R.Location.End = Range.second; - R.Location.FileURI = MainURI; + R.Location.FileURI = Found->second; R.Kind = toRefKind(LocAndRole.second); Refs.insert(*ID, R); } Index: clangd/index/IndexAction.h =================================================================== --- clangd/index/IndexAction.h +++ clangd/index/IndexAction.h @@ -21,9 +21,9 @@ // Only a subset of SymbolCollector::Options are respected: // - include paths are always collected, and canonicalized appropriately // - references are always counted -// - main-file refs are collected (if RefsCallback is non-null) +// - refs in main file and #included headers are collected (if RefsCallback +// is non-null) // - the symbol origin is always Static -// FIXME: refs from headers should also be collected. std::unique_ptr<FrontendAction> createStaticIndexingAction(SymbolCollector::Options Opts, std::function<void(SymbolSlab)> SymbolsCallback, Index: clangd/index/IndexAction.cpp =================================================================== --- clangd/index/IndexAction.cpp +++ clangd/index/IndexAction.cpp @@ -66,8 +66,10 @@ Opts.CollectIncludePath = true; Opts.CountReferences = true; Opts.Origin = SymbolOrigin::Static; - if (RefsCallback != nullptr) + if (RefsCallback != nullptr) { Opts.RefFilter = RefKind::All; + Opts.RefMainFileOnly = false; // collect refs for #included headers. + } auto Includes = llvm::make_unique<CanonicalIncludes>(); addSystemHeadersMapping(Includes.get()); Opts.Includes = Includes.get();
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits