From: Argyrios Kyrtzidis Date: Tue, 18 Sep 2018 15:02:56 +0000 (+0000) Subject: [index] Enhance indexing for module references X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=16f27fb3e9a4d061864859279b62392d602d2698;p=clang [index] Enhance indexing for module references * Create a USR for the occurrences of the 'module' symbol kind * Record module references for each identifier in an import declaration git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@342484 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Index/IndexDataConsumer.h b/include/clang/Index/IndexDataConsumer.h index 6e11455661..c79f6be3e1 100644 --- a/include/clang/Index/IndexDataConsumer.h +++ b/include/clang/Index/IndexDataConsumer.h @@ -50,7 +50,12 @@ public: SourceLocation Loc); /// \returns true to continue indexing, or false to abort. + /// + /// This will be called for each module reference in an import decl. + /// For "@import MyMod.SubMod", there will be a call for 'MyMod' with the + /// 'reference' role, and a call for 'SubMod' with the 'declaration' role. virtual bool handleModuleOccurence(const ImportDecl *ImportD, + const Module *Mod, SymbolRoleSet Roles, SourceLocation Loc); virtual void finish() {} diff --git a/include/clang/Index/USRGeneration.h b/include/clang/Index/USRGeneration.h index 1ece321746..4987cd6c5e 100644 --- a/include/clang/Index/USRGeneration.h +++ b/include/clang/Index/USRGeneration.h @@ -16,6 +16,7 @@ namespace clang { class Decl; class MacroDefinitionRecord; +class Module; class SourceLocation; class SourceManager; @@ -70,6 +71,22 @@ bool generateUSRForMacro(const MacroDefinitionRecord *MD, bool generateUSRForMacro(StringRef MacroName, SourceLocation Loc, const SourceManager &SM, SmallVectorImpl &Buf); +/// Generate a USR for a module, including the USR prefix. +/// \returns true on error, false on success. +bool generateFullUSRForModule(const Module *Mod, raw_ostream &OS); + +/// Generate a USR for a top-level module name, including the USR prefix. +/// \returns true on error, false on success. +bool generateFullUSRForTopLevelModuleName(StringRef ModName, raw_ostream &OS); + +/// Generate a USR fragment for a module. +/// \returns true on error, false on success. +bool generateUSRFragmentForModule(const Module *Mod, raw_ostream &OS); + +/// Generate a USR fragment for a module name. +/// \returns true on error, false on success. +bool generateUSRFragmentForModuleName(StringRef ModName, raw_ostream &OS); + } // namespace index } // namespace clang diff --git a/lib/Index/IndexingAction.cpp b/lib/Index/IndexingAction.cpp index cb5c951f38..5cdec4b452 100644 --- a/lib/Index/IndexingAction.cpp +++ b/lib/Index/IndexingAction.cpp @@ -37,6 +37,7 @@ bool IndexDataConsumer::handleMacroOccurence(const IdentifierInfo *Name, } bool IndexDataConsumer::handleModuleOccurence(const ImportDecl *ImportD, + const Module *Mod, SymbolRoleSet Roles, SourceLocation Loc) { return true; diff --git a/lib/Index/IndexingContext.cpp b/lib/Index/IndexingContext.cpp index 333f9dc309..bba6c8390b 100644 --- a/lib/Index/IndexingContext.cpp +++ b/lib/Index/IndexingContext.cpp @@ -80,11 +80,27 @@ bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc, RefE, RefD, DC); } +static void reportModuleReferences(const Module *Mod, + ArrayRef IdLocs, + const ImportDecl *ImportD, + IndexDataConsumer &DataConsumer) { + if (!Mod) + return; + reportModuleReferences(Mod->Parent, IdLocs.drop_back(), ImportD, + DataConsumer); + DataConsumer.handleModuleOccurence(ImportD, Mod, + (SymbolRoleSet)SymbolRole::Reference, + IdLocs.back()); +} + bool IndexingContext::importedModule(const ImportDecl *ImportD) { + if (ImportD->isInvalidDecl()) + return true; + SourceLocation Loc; auto IdLocs = ImportD->getIdentifierLocs(); if (!IdLocs.empty()) - Loc = IdLocs.front(); + Loc = IdLocs.back(); else Loc = ImportD->getLocation(); @@ -108,11 +124,17 @@ bool IndexingContext::importedModule(const ImportDecl *ImportD) { } } + const Module *Mod = ImportD->getImportedModule(); + if (!ImportD->isImplicit() && Mod->Parent && !IdLocs.empty()) { + reportModuleReferences(Mod->Parent, IdLocs.drop_back(), ImportD, + DataConsumer); + } + SymbolRoleSet Roles = (unsigned)SymbolRole::Declaration; if (ImportD->isImplicit()) Roles |= (unsigned)SymbolRole::Implicit; - return DataConsumer.handleModuleOccurence(ImportD, Roles, Loc); + return DataConsumer.handleModuleOccurence(ImportD, Mod, Roles, Loc); } bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) { diff --git a/lib/Index/USRGeneration.cpp b/lib/Index/USRGeneration.cpp index 62ae7108fc..8194c9508f 100644 --- a/lib/Index/USRGeneration.cpp +++ b/lib/Index/USRGeneration.cpp @@ -1094,3 +1094,29 @@ bool clang::index::generateUSRForMacro(StringRef MacroName, SourceLocation Loc, Out << MacroName; return false; } + +bool clang::index::generateFullUSRForModule(const Module *Mod, + raw_ostream &OS) { + if (!Mod->Parent) + return generateFullUSRForTopLevelModuleName(Mod->Name, OS); + if (generateFullUSRForModule(Mod->Parent, OS)) + return true; + return generateUSRFragmentForModule(Mod, OS); +} + +bool clang::index::generateFullUSRForTopLevelModuleName(StringRef ModName, + raw_ostream &OS) { + OS << getUSRSpacePrefix(); + return generateUSRFragmentForModuleName(ModName, OS); +} + +bool clang::index::generateUSRFragmentForModule(const Module *Mod, + raw_ostream &OS) { + return generateUSRFragmentForModuleName(Mod->Name, OS); +} + +bool clang::index::generateUSRFragmentForModuleName(StringRef ModName, + raw_ostream &OS) { + OS << "@M@" << ModName; + return false; +} diff --git a/test/Index/Core/Inputs/module/SubModA.h b/test/Index/Core/Inputs/module/SubModA.h new file mode 100644 index 0000000000..59d243ecfa --- /dev/null +++ b/test/Index/Core/Inputs/module/SubModA.h @@ -0,0 +1,2 @@ + +void SubModA_func(void); diff --git a/test/Index/Core/Inputs/module/SubSubModA.h b/test/Index/Core/Inputs/module/SubSubModA.h new file mode 100644 index 0000000000..51ffa910f7 --- /dev/null +++ b/test/Index/Core/Inputs/module/SubSubModA.h @@ -0,0 +1,2 @@ + +void SubSubModA_func(void); diff --git a/test/Index/Core/Inputs/module/module.modulemap b/test/Index/Core/Inputs/module/module.modulemap index a132562eaf..180a4aad36 100644 --- a/test/Index/Core/Inputs/module/module.modulemap +++ b/test/Index/Core/Inputs/module/module.modulemap @@ -1 +1,11 @@ -module ModA { header "ModA.h" export * } +module ModA { + header "ModA.h" export * + + module SubModA { + header "SubModA.h" + + module SubSubModA { + header "SubSubModA.h" + } + } +} diff --git a/test/Index/Core/index-with-module.m b/test/Index/Core/index-with-module.m index c83de63701..ca89c2e1de 100644 --- a/test/Index/Core/index-with-module.m +++ b/test/Index/Core/index-with-module.m @@ -1,11 +1,17 @@ // RUN: rm -rf %t.mcp // RUN: c-index-test core -print-source-symbols -dump-imported-module-files -- %s -I %S/Inputs/module -fmodules -fmodules-cache-path=%t.mcp | FileCheck %s -// CHECK: [[@LINE+1]]:9 | module/C | ModA | Decl | +// CHECK: [[@LINE+1]]:9 | module/C | ModA | [[ModA_USR:c:@M@ModA]] | Decl | @import ModA; -// CHECK: [[@LINE+1]]:1 | module/C | ModA | Decl,Impl | +// CHECK: [[@LINE+1]]:1 | module/C | ModA | [[ModA_USR]] | Decl,Impl | #include "ModA.h" +@import ModA.SubModA.SubSubModA; +// CHECK: [[@LINE-1]]:9 | module/C | ModA | [[ModA_USR]] | Ref | +// CHECK: [[@LINE-2]]:14 | module/C | ModA.SubModA | c:@M@ModA@M@SubModA | Ref | +// CHECK: [[@LINE-3]]:22 | module/C | ModA.SubModA.SubSubModA | [[SubSubModA_USR:c:@M@ModA@M@SubModA@M@SubSubModA]] | Decl | +#include "SubSubModA.h" // CHECK: [[@LINE]]:1 | module/C | ModA.SubModA.SubSubModA | [[SubSubModA_USR]] | Decl,Impl | + void foo() { // CHECK: [[@LINE+1]]:3 | function/C | ModA_func | c:@F@ModA_func | {{.*}} | Ref,Call,RelCall,RelCont | rel: 1 ModA_func(); diff --git a/tools/c-index-test/core_main.cpp b/tools/c-index-test/core_main.cpp index 9921a403a4..b9c0f19a7f 100644 --- a/tools/c-index-test/core_main.cpp +++ b/tools/c-index-test/core_main.cpp @@ -74,6 +74,7 @@ static cl::opt static void printSymbolInfo(SymbolInfo SymInfo, raw_ostream &OS); static void printSymbolNameAndUSR(const Decl *D, ASTContext &Ctx, raw_ostream &OS); +static void printSymbolNameAndUSR(const clang::Module *Mod, raw_ostream &OS); namespace { @@ -132,8 +133,9 @@ public: return true; } - bool handleModuleOccurence(const ImportDecl *ImportD, SymbolRoleSet Roles, - SourceLocation Loc) override { + bool handleModuleOccurence(const ImportDecl *ImportD, + const clang::Module *Mod, + SymbolRoleSet Roles, SourceLocation Loc) override { ASTContext &Ctx = ImportD->getASTContext(); SourceManager &SM = Ctx.getSourceManager(); @@ -146,7 +148,8 @@ public: printSymbolInfo(getSymbolInfo(ImportD), OS); OS << " | "; - OS << ImportD->getImportedModule()->getFullModuleName() << " | "; + printSymbolNameAndUSR(Mod, OS); + OS << " | "; printSymbolRoles(Roles, OS); OS << " |\n"; @@ -308,6 +311,12 @@ static void printSymbolNameAndUSR(const Decl *D, ASTContext &Ctx, } } +static void printSymbolNameAndUSR(const clang::Module *Mod, raw_ostream &OS) { + assert(Mod); + OS << Mod->getFullModuleName() << " | "; + generateFullUSRForModule(Mod, OS); +} + //===----------------------------------------------------------------------===// // Command line processing. //===----------------------------------------------------------------------===// diff --git a/tools/libclang/CXIndexDataConsumer.cpp b/tools/libclang/CXIndexDataConsumer.cpp index 00ade2ee8f..3dec36a5da 100644 --- a/tools/libclang/CXIndexDataConsumer.cpp +++ b/tools/libclang/CXIndexDataConsumer.cpp @@ -222,9 +222,11 @@ bool CXIndexDataConsumer::handleDeclOccurence( } bool CXIndexDataConsumer::handleModuleOccurence(const ImportDecl *ImportD, + const Module *Mod, SymbolRoleSet Roles, SourceLocation Loc) { - IndexingDeclVisitor(*this, SourceLocation(), nullptr).Visit(ImportD); + if (Roles & (SymbolRoleSet)SymbolRole::Declaration) + IndexingDeclVisitor(*this, SourceLocation(), nullptr).Visit(ImportD); return !shouldAbort(); } diff --git a/tools/libclang/CXIndexDataConsumer.h b/tools/libclang/CXIndexDataConsumer.h index 19e39b281a..5c1ce80b2f 100644 --- a/tools/libclang/CXIndexDataConsumer.h +++ b/tools/libclang/CXIndexDataConsumer.h @@ -467,7 +467,7 @@ private: ArrayRef Relations, SourceLocation Loc, ASTNodeInfo ASTNode) override; - bool handleModuleOccurence(const ImportDecl *ImportD, + bool handleModuleOccurence(const ImportDecl *ImportD, const Module *Mod, index::SymbolRoleSet Roles, SourceLocation Loc) override;