Skip to content
This repository has been archived by the owner on Apr 23, 2020. It is now read-only.

Commit

Permalink
[index] Enhance indexing for module references
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
akyrtzi committed Sep 18, 2018
1 parent f02ab3c commit 16f27fb
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 10 deletions.
5 changes: 5 additions & 0 deletions include/clang/Index/IndexDataConsumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,12 @@ class IndexDataConsumer {
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() {}
Expand Down
17 changes: 17 additions & 0 deletions include/clang/Index/USRGeneration.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
namespace clang {
class Decl;
class MacroDefinitionRecord;
class Module;
class SourceLocation;
class SourceManager;

Expand Down Expand Up @@ -70,6 +71,22 @@ bool generateUSRForMacro(const MacroDefinitionRecord *MD,
bool generateUSRForMacro(StringRef MacroName, SourceLocation Loc,
const SourceManager &SM, SmallVectorImpl<char> &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

Expand Down
1 change: 1 addition & 0 deletions lib/Index/IndexingAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
26 changes: 24 additions & 2 deletions lib/Index/IndexingContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,27 @@ bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
RefE, RefD, DC);
}

static void reportModuleReferences(const Module *Mod,
ArrayRef<SourceLocation> 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();

Expand All @@ -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) {
Expand Down
26 changes: 26 additions & 0 deletions lib/Index/USRGeneration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
2 changes: 2 additions & 0 deletions test/Index/Core/Inputs/module/SubModA.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

void SubModA_func(void);
2 changes: 2 additions & 0 deletions test/Index/Core/Inputs/module/SubSubModA.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

void SubSubModA_func(void);
12 changes: 11 additions & 1 deletion test/Index/Core/Inputs/module/module.modulemap
Original file line number Diff line number Diff line change
@@ -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"
}
}
}
10 changes: 8 additions & 2 deletions test/Index/Core/index-with-module.m
Original file line number Diff line number Diff line change
@@ -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();
Expand Down
15 changes: 12 additions & 3 deletions tools/c-index-test/core_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ static cl::opt<std::string>
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 {

Expand Down Expand Up @@ -132,8 +133,9 @@ class PrintIndexDataConsumer : public IndexDataConsumer {
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();

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

OS << ImportD->getImportedModule()->getFullModuleName() << " | ";
printSymbolNameAndUSR(Mod, OS);
OS << " | ";

printSymbolRoles(Roles, OS);
OS << " |\n";
Expand Down Expand Up @@ -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.
//===----------------------------------------------------------------------===//
Expand Down
4 changes: 3 additions & 1 deletion tools/libclang/CXIndexDataConsumer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down
2 changes: 1 addition & 1 deletion tools/libclang/CXIndexDataConsumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ class CXIndexDataConsumer : public index::IndexDataConsumer {
ArrayRef<index::SymbolRelation> 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;

Expand Down

0 comments on commit 16f27fb

Please sign in to comment.