usaxena95 created this revision. usaxena95 added a reviewer: hokein. usaxena95 added a project: clang.
This patch adds the cross references for Macros in the MainFile. We add references for the main file to the ParsedAST. We query the references from it using the SymbolID. Xref outside main file will be added to the index in a separate patch. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D70008 Files: clang-tools-extra/clangd/AST.cpp clang-tools-extra/clangd/AST.h clang-tools-extra/clangd/CodeComplete.cpp clang-tools-extra/clangd/CollectMacros.h clang-tools-extra/clangd/XRefs.cpp clang-tools-extra/clangd/index/SymbolCollector.cpp clang-tools-extra/clangd/unittests/XRefsTests.cpp
Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -2050,6 +2050,23 @@ } // namespace ns int main() { [[^ns]]::Foo foo; } )cpp", + + R"cpp(// Macros + #define [[FOO]](x,y) (x + y) + // FIXME: No references for nested macros. + #define BAR(x,y,z) (FOO(x, y) * FOO(y, z)) + int main() { + int x = [[FOO]](1, 2); + int y = [[FOO]]([[FO^O]](x, 1), [[FOO]](1, 1)); + int z = BAR(1, 2, 3); + } + #define FOO(x) (x + 1) + )cpp", + + R"cpp(// Macros: Cursor on definition. + #define [[F^OO]](x,y) (x + y) + int main() { int x = [[FOO]](1, 2); } + )cpp", }; for (const char *Test : Tests) { Annotations T(Test); Index: clang-tools-extra/clangd/index/SymbolCollector.cpp =================================================================== --- clang-tools-extra/clangd/index/SymbolCollector.cpp +++ clang-tools-extra/clangd/index/SymbolCollector.cpp @@ -377,7 +377,7 @@ Roles & static_cast<unsigned>(index::SymbolRole::Definition))) return true; - auto ID = getSymbolID(*Name, MI, SM); + auto ID = getSymbolID(Name->getName(), MI, SM); if (!ID) return true; @@ -473,14 +473,14 @@ // First, drop header guards. We can't identify these until EOF. for (const IdentifierInfo *II : IndexedMacros) { if (const auto *MI = PP->getMacroDefinition(II).getMacroInfo()) - if (auto ID = getSymbolID(*II, MI, PP->getSourceManager())) + if (auto ID = getSymbolID(II->getName(), MI, PP->getSourceManager())) if (MI->isUsedForHeaderGuard()) Symbols.erase(*ID); } // Now increment refcounts. for (const IdentifierInfo *II : ReferencedMacros) { if (const auto *MI = PP->getMacroDefinition(II).getMacroInfo()) - if (auto ID = getSymbolID(*II, MI, PP->getSourceManager())) + if (auto ID = getSymbolID(II->getName(), MI, PP->getSourceManager())) IncRef(*ID); } } Index: clang-tools-extra/clangd/XRefs.cpp =================================================================== --- clang-tools-extra/clangd/XRefs.cpp +++ clang-tools-extra/clangd/XRefs.cpp @@ -21,6 +21,7 @@ #include "index/Merge.h" #include "index/Relation.h" #include "index/SymbolCollector.h" +#include "index/SymbolID.h" #include "index/SymbolLocation.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" @@ -47,6 +48,7 @@ #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" +#include <set> namespace clang { namespace clangd { @@ -891,7 +893,20 @@ } auto Loc = SM.getMacroArgExpandedLocation( getBeginningOfIdentifier(Pos, SM, AST.getASTContext().getLangOpts())); - // TODO: should we handle macros, too? + + // Handle macros. + if (auto Macro = locateMacroAt(Loc, AST.getPreprocessor())) { + if (auto MacroSID = getSymbolID(Macro->Name, Macro->Info, SM)) { + const auto &IDToRefs = AST.getMacros().MacroRefs; + auto Refs = IDToRefs.find(*MacroSID); + if (Refs != IDToRefs.end()) + Results.insert(Results.end(), Refs->second.begin(), Refs->second.end()); + } + if (Results.size() > Limit) + Results.resize(Limit); + return Results; + } + // We also show references to the targets of using-decls, so we include // DeclRelation::Underlying. DeclRelationSet Relations = DeclRelation::TemplatePattern | @@ -911,8 +926,7 @@ MainFileRefs.end()); for (const auto &Ref : MainFileRefs) { if (auto Range = - getTokenRange(AST.getASTContext().getSourceManager(), - AST.getASTContext().getLangOpts(), Ref.Loc)) { + getTokenRange(SM, AST.getASTContext().getLangOpts(), Ref.Loc)) { Location Result; Result.range = *Range; Result.uri = URIForFile::canonicalize(*MainFilePath, *MainFilePath); Index: clang-tools-extra/clangd/CollectMacros.h =================================================================== --- clang-tools-extra/clangd/CollectMacros.h +++ clang-tools-extra/clangd/CollectMacros.h @@ -9,10 +9,13 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_COLLECTEDMACROS_H #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_COLLECTEDMACROS_H +#include "AST.h" #include "Protocol.h" #include "SourceCode.h" +#include "index/SymbolID.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Lex/PPCallbacks.h" +#include "llvm/ADT/DenseMap.h" #include <string> namespace clang { @@ -23,6 +26,7 @@ // Instead of storing SourceLocation, we have to store the token range because // SourceManager from preamble is not available when we build the AST. std::vector<Range> Ranges; + llvm::DenseMap<SymbolID, std::set<Location>> MacroRefs; }; /// Collects macro references (e.g. definitions, expansions) in the main file. @@ -39,6 +43,12 @@ void FileChanged(SourceLocation Loc, FileChangeReason, SrcMgr::CharacteristicKind, FileID) override { InMainFile = isInsideMainFile(Loc, SM); + if (InMainFile) { + auto MainFilePath = + getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM); + if (MainFilePath) + MainFileURI = URIForFile::canonicalize(*MainFilePath, *MainFilePath); + } } void MacroDefined(const Token &MacroName, const MacroDirective *MD) override { @@ -82,9 +92,17 @@ if (auto Range = getTokenRange(SM, LangOpts, Loc)) { Out.Names.insert(MacroNameTok.getIdentifierInfo()->getName()); Out.Ranges.push_back(*Range); + if (auto SID = getSymbolID(MacroNameTok.getIdentifierInfo()->getName(), + MI, SM)) { + Location Loc; + Loc.uri = MainFileURI; + Loc.range = *Range; + Out.MacroRefs[*SID].insert(Loc); + } } } const SourceManager &SM; + URIForFile MainFileURI; const LangOptions &LangOpts; bool InMainFile = true; MainFileMacros &Out; Index: clang-tools-extra/clangd/CodeComplete.cpp =================================================================== --- clang-tools-extra/clangd/CodeComplete.cpp +++ clang-tools-extra/clangd/CodeComplete.cpp @@ -492,7 +492,7 @@ return clang::clangd::getSymbolID(R.Declaration); } case CodeCompletionResult::RK_Macro: - return clang::clangd::getSymbolID(*R.Macro, R.MacroDefInfo, SM); + return clang::clangd::getSymbolID(R.Macro->getName(), R.MacroDefInfo, SM); case CodeCompletionResult::RK_Keyword: return None; } @@ -1765,8 +1765,7 @@ Options.IncludeBriefComments = false; IncludeStructure PreambleInclusions; // Unused for signatureHelp semaCodeComplete( - std::make_unique<SignatureHelpCollector>(Options, Index, Result), - Options, + std::make_unique<SignatureHelpCollector>(Options, Index, Result), Options, {FileName, Command, Preamble, Contents, *Offset, std::move(VFS)}); return Result; } Index: clang-tools-extra/clangd/AST.h =================================================================== --- clang-tools-extra/clangd/AST.h +++ clang-tools-extra/clangd/AST.h @@ -17,6 +17,7 @@ #include "clang/AST/Decl.h" #include "clang/Basic/SourceLocation.h" #include "clang/Lex/MacroInfo.h" +#include "llvm/ADT/StringRef.h" namespace clang { class SourceManager; @@ -69,7 +70,7 @@ /// macro (e.g. a change in definition offset can result in a different USR). We /// could change these semantics in the future by reimplementing this funcure /// (e.g. avoid USR for macros). -llvm::Optional<SymbolID> getSymbolID(const IdentifierInfo &II, +llvm::Optional<SymbolID> getSymbolID(const llvm::StringRef MacroName, const MacroInfo *MI, const SourceManager &SM); Index: clang-tools-extra/clangd/AST.cpp =================================================================== --- clang-tools-extra/clangd/AST.cpp +++ clang-tools-extra/clangd/AST.cpp @@ -203,13 +203,13 @@ return SymbolID(USR); } -llvm::Optional<SymbolID> getSymbolID(const IdentifierInfo &II, +llvm::Optional<SymbolID> getSymbolID(const llvm::StringRef MacroName, const MacroInfo *MI, const SourceManager &SM) { if (MI == nullptr) return None; llvm::SmallString<128> USR; - if (index::generateUSRForMacro(II.getName(), MI->getDefinitionLoc(), SM, USR)) + if (index::generateUSRForMacro(MacroName, MI->getDefinitionLoc(), SM, USR)) return None; return SymbolID(USR); } @@ -225,7 +225,7 @@ unsigned DifferentAt = 0; while (DifferentAt < MinLength && - CurrentParts[DifferentAt] == OriginalParts[DifferentAt]) { + CurrentParts[DifferentAt] == OriginalParts[DifferentAt]) { DifferentAt++; } @@ -235,15 +235,12 @@ return join(Result, "::"); } -std::string printType(const QualType QT, const DeclContext & Context){ +std::string printType(const QualType QT, const DeclContext &Context) { PrintingPolicy PP(Context.getParentASTContext().getPrintingPolicy()); PP.SuppressUnwrittenScope = 1; PP.SuppressTagKeyword = 1; - return shortenNamespace( - QT.getAsString(PP), - printNamespaceScope(Context) ); + return shortenNamespace(QT.getAsString(PP), printNamespaceScope(Context)); } - } // namespace clangd } // namespace clang
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits