Skip to content

Commit 16f27fb

Browse files
committedSep 18, 2018
[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
1 parent f02ab3c commit 16f27fb

12 files changed

+112
-10
lines changed
 

‎include/clang/Index/IndexDataConsumer.h

+5
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,12 @@ class IndexDataConsumer {
5050
SourceLocation Loc);
5151

5252
/// \returns true to continue indexing, or false to abort.
53+
///
54+
/// This will be called for each module reference in an import decl.
55+
/// For "@import MyMod.SubMod", there will be a call for 'MyMod' with the
56+
/// 'reference' role, and a call for 'SubMod' with the 'declaration' role.
5357
virtual bool handleModuleOccurence(const ImportDecl *ImportD,
58+
const Module *Mod,
5459
SymbolRoleSet Roles, SourceLocation Loc);
5560

5661
virtual void finish() {}

‎include/clang/Index/USRGeneration.h

+17
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
namespace clang {
1717
class Decl;
1818
class MacroDefinitionRecord;
19+
class Module;
1920
class SourceLocation;
2021
class SourceManager;
2122

@@ -70,6 +71,22 @@ bool generateUSRForMacro(const MacroDefinitionRecord *MD,
7071
bool generateUSRForMacro(StringRef MacroName, SourceLocation Loc,
7172
const SourceManager &SM, SmallVectorImpl<char> &Buf);
7273

74+
/// Generate a USR for a module, including the USR prefix.
75+
/// \returns true on error, false on success.
76+
bool generateFullUSRForModule(const Module *Mod, raw_ostream &OS);
77+
78+
/// Generate a USR for a top-level module name, including the USR prefix.
79+
/// \returns true on error, false on success.
80+
bool generateFullUSRForTopLevelModuleName(StringRef ModName, raw_ostream &OS);
81+
82+
/// Generate a USR fragment for a module.
83+
/// \returns true on error, false on success.
84+
bool generateUSRFragmentForModule(const Module *Mod, raw_ostream &OS);
85+
86+
/// Generate a USR fragment for a module name.
87+
/// \returns true on error, false on success.
88+
bool generateUSRFragmentForModuleName(StringRef ModName, raw_ostream &OS);
89+
7390
} // namespace index
7491
} // namespace clang
7592

‎lib/Index/IndexingAction.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ bool IndexDataConsumer::handleMacroOccurence(const IdentifierInfo *Name,
3737
}
3838

3939
bool IndexDataConsumer::handleModuleOccurence(const ImportDecl *ImportD,
40+
const Module *Mod,
4041
SymbolRoleSet Roles,
4142
SourceLocation Loc) {
4243
return true;

‎lib/Index/IndexingContext.cpp

+24-2
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,27 @@ bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
8080
RefE, RefD, DC);
8181
}
8282

83+
static void reportModuleReferences(const Module *Mod,
84+
ArrayRef<SourceLocation> IdLocs,
85+
const ImportDecl *ImportD,
86+
IndexDataConsumer &DataConsumer) {
87+
if (!Mod)
88+
return;
89+
reportModuleReferences(Mod->Parent, IdLocs.drop_back(), ImportD,
90+
DataConsumer);
91+
DataConsumer.handleModuleOccurence(ImportD, Mod,
92+
(SymbolRoleSet)SymbolRole::Reference,
93+
IdLocs.back());
94+
}
95+
8396
bool IndexingContext::importedModule(const ImportDecl *ImportD) {
97+
if (ImportD->isInvalidDecl())
98+
return true;
99+
84100
SourceLocation Loc;
85101
auto IdLocs = ImportD->getIdentifierLocs();
86102
if (!IdLocs.empty())
87-
Loc = IdLocs.front();
103+
Loc = IdLocs.back();
88104
else
89105
Loc = ImportD->getLocation();
90106

@@ -108,11 +124,17 @@ bool IndexingContext::importedModule(const ImportDecl *ImportD) {
108124
}
109125
}
110126

127+
const Module *Mod = ImportD->getImportedModule();
128+
if (!ImportD->isImplicit() && Mod->Parent && !IdLocs.empty()) {
129+
reportModuleReferences(Mod->Parent, IdLocs.drop_back(), ImportD,
130+
DataConsumer);
131+
}
132+
111133
SymbolRoleSet Roles = (unsigned)SymbolRole::Declaration;
112134
if (ImportD->isImplicit())
113135
Roles |= (unsigned)SymbolRole::Implicit;
114136

115-
return DataConsumer.handleModuleOccurence(ImportD, Roles, Loc);
137+
return DataConsumer.handleModuleOccurence(ImportD, Mod, Roles, Loc);
116138
}
117139

118140
bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) {

‎lib/Index/USRGeneration.cpp

+26
Original file line numberDiff line numberDiff line change
@@ -1094,3 +1094,29 @@ bool clang::index::generateUSRForMacro(StringRef MacroName, SourceLocation Loc,
10941094
Out << MacroName;
10951095
return false;
10961096
}
1097+
1098+
bool clang::index::generateFullUSRForModule(const Module *Mod,
1099+
raw_ostream &OS) {
1100+
if (!Mod->Parent)
1101+
return generateFullUSRForTopLevelModuleName(Mod->Name, OS);
1102+
if (generateFullUSRForModule(Mod->Parent, OS))
1103+
return true;
1104+
return generateUSRFragmentForModule(Mod, OS);
1105+
}
1106+
1107+
bool clang::index::generateFullUSRForTopLevelModuleName(StringRef ModName,
1108+
raw_ostream &OS) {
1109+
OS << getUSRSpacePrefix();
1110+
return generateUSRFragmentForModuleName(ModName, OS);
1111+
}
1112+
1113+
bool clang::index::generateUSRFragmentForModule(const Module *Mod,
1114+
raw_ostream &OS) {
1115+
return generateUSRFragmentForModuleName(Mod->Name, OS);
1116+
}
1117+
1118+
bool clang::index::generateUSRFragmentForModuleName(StringRef ModName,
1119+
raw_ostream &OS) {
1120+
OS << "@M@" << ModName;
1121+
return false;
1122+
}
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
void SubModA_func(void);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
void SubSubModA_func(void);
Original file line numberDiff line numberDiff line change
@@ -1 +1,11 @@
1-
module ModA { header "ModA.h" export * }
1+
module ModA {
2+
header "ModA.h" export *
3+
4+
module SubModA {
5+
header "SubModA.h"
6+
7+
module SubSubModA {
8+
header "SubSubModA.h"
9+
}
10+
}
11+
}

‎test/Index/Core/index-with-module.m

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
// RUN: rm -rf %t.mcp
22
// 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
33

4-
// CHECK: [[@LINE+1]]:9 | module/C | ModA | Decl |
4+
// CHECK: [[@LINE+1]]:9 | module/C | ModA | [[ModA_USR:c:@M@ModA]] | Decl |
55
@import ModA;
6-
// CHECK: [[@LINE+1]]:1 | module/C | ModA | Decl,Impl |
6+
// CHECK: [[@LINE+1]]:1 | module/C | ModA | [[ModA_USR]] | Decl,Impl |
77
#include "ModA.h"
88

9+
@import ModA.SubModA.SubSubModA;
10+
// CHECK: [[@LINE-1]]:9 | module/C | ModA | [[ModA_USR]] | Ref |
11+
// CHECK: [[@LINE-2]]:14 | module/C | ModA.SubModA | c:@M@ModA@M@SubModA | Ref |
12+
// CHECK: [[@LINE-3]]:22 | module/C | ModA.SubModA.SubSubModA | [[SubSubModA_USR:c:@M@ModA@M@SubModA@M@SubSubModA]] | Decl |
13+
#include "SubSubModA.h" // CHECK: [[@LINE]]:1 | module/C | ModA.SubModA.SubSubModA | [[SubSubModA_USR]] | Decl,Impl |
14+
915
void foo() {
1016
// CHECK: [[@LINE+1]]:3 | function/C | ModA_func | c:@F@ModA_func | {{.*}} | Ref,Call,RelCall,RelCont | rel: 1
1117
ModA_func();

‎tools/c-index-test/core_main.cpp

+12-3
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ static cl::opt<std::string>
7474
static void printSymbolInfo(SymbolInfo SymInfo, raw_ostream &OS);
7575
static void printSymbolNameAndUSR(const Decl *D, ASTContext &Ctx,
7676
raw_ostream &OS);
77+
static void printSymbolNameAndUSR(const clang::Module *Mod, raw_ostream &OS);
7778

7879
namespace {
7980

@@ -132,8 +133,9 @@ class PrintIndexDataConsumer : public IndexDataConsumer {
132133
return true;
133134
}
134135

135-
bool handleModuleOccurence(const ImportDecl *ImportD, SymbolRoleSet Roles,
136-
SourceLocation Loc) override {
136+
bool handleModuleOccurence(const ImportDecl *ImportD,
137+
const clang::Module *Mod,
138+
SymbolRoleSet Roles, SourceLocation Loc) override {
137139
ASTContext &Ctx = ImportD->getASTContext();
138140
SourceManager &SM = Ctx.getSourceManager();
139141

@@ -146,7 +148,8 @@ class PrintIndexDataConsumer : public IndexDataConsumer {
146148
printSymbolInfo(getSymbolInfo(ImportD), OS);
147149
OS << " | ";
148150

149-
OS << ImportD->getImportedModule()->getFullModuleName() << " | ";
151+
printSymbolNameAndUSR(Mod, OS);
152+
OS << " | ";
150153

151154
printSymbolRoles(Roles, OS);
152155
OS << " |\n";
@@ -308,6 +311,12 @@ static void printSymbolNameAndUSR(const Decl *D, ASTContext &Ctx,
308311
}
309312
}
310313

314+
static void printSymbolNameAndUSR(const clang::Module *Mod, raw_ostream &OS) {
315+
assert(Mod);
316+
OS << Mod->getFullModuleName() << " | ";
317+
generateFullUSRForModule(Mod, OS);
318+
}
319+
311320
//===----------------------------------------------------------------------===//
312321
// Command line processing.
313322
//===----------------------------------------------------------------------===//

‎tools/libclang/CXIndexDataConsumer.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,11 @@ bool CXIndexDataConsumer::handleDeclOccurence(
222222
}
223223

224224
bool CXIndexDataConsumer::handleModuleOccurence(const ImportDecl *ImportD,
225+
const Module *Mod,
225226
SymbolRoleSet Roles,
226227
SourceLocation Loc) {
227-
IndexingDeclVisitor(*this, SourceLocation(), nullptr).Visit(ImportD);
228+
if (Roles & (SymbolRoleSet)SymbolRole::Declaration)
229+
IndexingDeclVisitor(*this, SourceLocation(), nullptr).Visit(ImportD);
228230
return !shouldAbort();
229231
}
230232

‎tools/libclang/CXIndexDataConsumer.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ class CXIndexDataConsumer : public index::IndexDataConsumer {
467467
ArrayRef<index::SymbolRelation> Relations,
468468
SourceLocation Loc, ASTNodeInfo ASTNode) override;
469469

470-
bool handleModuleOccurence(const ImportDecl *ImportD,
470+
bool handleModuleOccurence(const ImportDecl *ImportD, const Module *Mod,
471471
index::SymbolRoleSet Roles,
472472
SourceLocation Loc) override;
473473

0 commit comments

Comments
 (0)
Please sign in to comment.