diff --git a/clang-tools-extra/clangd/index/Ref.h b/clang-tools-extra/clangd/index/Ref.h --- a/clang-tools-extra/clangd/index/Ref.h +++ b/clang-tools-extra/clangd/index/Ref.h @@ -88,13 +88,16 @@ /// The source location where the symbol is named. SymbolLocation Location; RefKind Kind = RefKind::Unknown; + SymbolID Container; }; inline bool operator<(const Ref &L, const Ref &R) { - return std::tie(L.Location, L.Kind) < std::tie(R.Location, R.Kind); + return std::tie(L.Location, L.Kind, L.Container) < + std::tie(R.Location, R.Kind, R.Container); } inline bool operator==(const Ref &L, const Ref &R) { - return std::tie(L.Location, L.Kind) == std::tie(R.Location, R.Kind); + return std::tie(L.Location, L.Kind, L.Container) == + std::tie(R.Location, R.Kind, R.Container); } llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Ref &); diff --git a/clang-tools-extra/clangd/index/Serialization.cpp b/clang-tools-extra/clangd/index/Serialization.cpp --- a/clang-tools-extra/clangd/index/Serialization.cpp +++ b/clang-tools-extra/clangd/index/Serialization.cpp @@ -345,6 +345,7 @@ for (const auto &Ref : Refs) { OS.write(static_cast(Ref.Kind)); writeLocation(Ref.Location, Strings, OS); + OS << Ref.Container.raw(); } } @@ -356,6 +357,7 @@ for (auto &Ref : Result.second) { Ref.Kind = static_cast(Data.consume8()); Ref.Location = readLocation(Data, Strings); + Ref.Container = Data.consumeID(); } return Result; } diff --git a/clang-tools-extra/clangd/index/SymbolCollector.h b/clang-tools-extra/clangd/index/SymbolCollector.h --- a/clang-tools-extra/clangd/index/SymbolCollector.h +++ b/clang-tools-extra/clangd/index/SymbolCollector.h @@ -156,7 +156,11 @@ std::shared_ptr CompletionAllocator; std::unique_ptr CompletionTUInfo; Options Opts; - using SymbolRef = std::pair; + struct SymbolRef { + SourceLocation Loc; + index::SymbolRoleSet Roles; + const NamedDecl *Container; + }; // Symbols referenced from the current TU, flushed on finish(). llvm::DenseSet ReferencedDecls; llvm::DenseSet ReferencedMacros; 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 @@ -344,7 +344,9 @@ !isa(ND) && (Opts.RefsInHeaders || SM.getFileID(SM.getFileLoc(Loc)) == SM.getMainFileID())) - DeclRefs[ND].emplace_back(SM.getFileLoc(Loc), Roles); + DeclRefs[ND].push_back( + SymbolRef{SM.getFileLoc(Loc), Roles, + dyn_cast_or_null(ASTNode.Parent)}); // Don't continue indexing if this is a mere reference. if (IsOnlyRef) return true; @@ -422,7 +424,8 @@ // Do not store references to main-file macros. if ((static_cast(Opts.RefFilter) & Roles) && !IsMainFileOnly && (Opts.RefsInHeaders || SM.getFileID(SpellingLoc) == SM.getMainFileID())) - MacroRefs[*ID].push_back({Loc, Roles}); + // FIXME: Populate container information for macro references. + MacroRefs[*ID].push_back({Loc, Roles, /*Container=*/nullptr}); // Collect symbols. if (!Opts.CollectMacro) @@ -579,24 +582,23 @@ } return Found->second; }; - auto CollectRef = - [&](SymbolID ID, - const std::pair &LocAndRole, - bool Spelled = false) { - auto FileID = SM.getFileID(LocAndRole.first); - // FIXME: use the result to filter out references. - shouldIndexFile(FileID); - if (auto FileURI = GetURI(FileID)) { - auto Range = - getTokenRange(LocAndRole.first, SM, ASTCtx->getLangOpts()); - Ref R; - R.Location.Start = Range.first; - R.Location.End = Range.second; - R.Location.FileURI = FileURI->c_str(); - R.Kind = toRefKind(LocAndRole.second, Spelled); - Refs.insert(ID, R); - } - }; + auto CollectRef = [&](SymbolID ID, const SymbolRef &LocAndRole, + bool Spelled = false) { + auto FileID = SM.getFileID(LocAndRole.Loc); + // FIXME: use the result to filter out references. + shouldIndexFile(FileID); + if (auto FileURI = GetURI(FileID)) { + auto Range = getTokenRange(LocAndRole.Loc, SM, ASTCtx->getLangOpts()); + Ref R; + R.Location.Start = Range.first; + R.Location.End = Range.second; + R.Location.FileURI = FileURI->c_str(); + R.Kind = toRefKind(LocAndRole.Roles, Spelled); + if (auto RefID = getSymbolID(LocAndRole.Container)) + R.Container = *RefID; + Refs.insert(ID, R); + } + }; // Populate Refs slab from MacroRefs. // FIXME: All MacroRefs are marked as Spelled now, but this should be checked. for (const auto &IDAndRefs : MacroRefs) @@ -607,7 +609,7 @@ for (auto &DeclAndRef : DeclRefs) { if (auto ID = getSymbolID(DeclAndRef.first)) { for (auto &LocAndRole : DeclAndRef.second) { - const auto FileID = SM.getFileID(LocAndRole.first); + const auto FileID = SM.getFileID(LocAndRole.Loc); // FIXME: It's better to use TokenBuffer by passing spelled tokens from // the caller of SymbolCollector. if (!FilesToTokensCache.count(FileID)) @@ -617,7 +619,7 @@ // Check if the referenced symbol is spelled exactly the same way the // corresponding NamedDecl is. If it is, mark this reference as spelled. const auto *IdentifierToken = - spelledIdentifierTouching(LocAndRole.first, Tokens); + spelledIdentifierTouching(LocAndRole.Loc, Tokens); DeclarationName Name = DeclAndRef.first->getDeclName(); const auto NameKind = Name.getNameKind(); bool IsTargetKind = NameKind == DeclarationName::Identifier ||