1*67e74705SXin Li //===- IndexingAction.cpp - Frontend index action -------------------------===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li
10*67e74705SXin Li #include "clang/Index/IndexingAction.h"
11*67e74705SXin Li #include "clang/Index/IndexDataConsumer.h"
12*67e74705SXin Li #include "IndexingContext.h"
13*67e74705SXin Li #include "clang/Frontend/FrontendAction.h"
14*67e74705SXin Li #include "clang/Frontend/MultiplexConsumer.h"
15*67e74705SXin Li #include "clang/Lex/Preprocessor.h"
16*67e74705SXin Li
17*67e74705SXin Li using namespace clang;
18*67e74705SXin Li using namespace clang::index;
19*67e74705SXin Li
_anchor()20*67e74705SXin Li void IndexDataConsumer::_anchor() {}
21*67e74705SXin Li
handleDeclOccurence(const Decl * D,SymbolRoleSet Roles,ArrayRef<SymbolRelation> Relations,FileID FID,unsigned Offset,ASTNodeInfo ASTNode)22*67e74705SXin Li bool IndexDataConsumer::handleDeclOccurence(const Decl *D, SymbolRoleSet Roles,
23*67e74705SXin Li ArrayRef<SymbolRelation> Relations,
24*67e74705SXin Li FileID FID, unsigned Offset,
25*67e74705SXin Li ASTNodeInfo ASTNode) {
26*67e74705SXin Li return true;
27*67e74705SXin Li }
28*67e74705SXin Li
handleMacroOccurence(const IdentifierInfo * Name,const MacroInfo * MI,SymbolRoleSet Roles,FileID FID,unsigned Offset)29*67e74705SXin Li bool IndexDataConsumer::handleMacroOccurence(const IdentifierInfo *Name,
30*67e74705SXin Li const MacroInfo *MI, SymbolRoleSet Roles,
31*67e74705SXin Li FileID FID, unsigned Offset) {
32*67e74705SXin Li return true;
33*67e74705SXin Li }
34*67e74705SXin Li
handleModuleOccurence(const ImportDecl * ImportD,SymbolRoleSet Roles,FileID FID,unsigned Offset)35*67e74705SXin Li bool IndexDataConsumer::handleModuleOccurence(const ImportDecl *ImportD,
36*67e74705SXin Li SymbolRoleSet Roles,
37*67e74705SXin Li FileID FID, unsigned Offset) {
38*67e74705SXin Li return true;
39*67e74705SXin Li }
40*67e74705SXin Li
41*67e74705SXin Li namespace {
42*67e74705SXin Li
43*67e74705SXin Li class IndexASTConsumer : public ASTConsumer {
44*67e74705SXin Li IndexingContext &IndexCtx;
45*67e74705SXin Li
46*67e74705SXin Li public:
IndexASTConsumer(IndexingContext & IndexCtx)47*67e74705SXin Li IndexASTConsumer(IndexingContext &IndexCtx)
48*67e74705SXin Li : IndexCtx(IndexCtx) {}
49*67e74705SXin Li
50*67e74705SXin Li protected:
Initialize(ASTContext & Context)51*67e74705SXin Li void Initialize(ASTContext &Context) override {
52*67e74705SXin Li IndexCtx.setASTContext(Context);
53*67e74705SXin Li IndexCtx.getDataConsumer().initialize(Context);
54*67e74705SXin Li }
55*67e74705SXin Li
HandleTopLevelDecl(DeclGroupRef DG)56*67e74705SXin Li bool HandleTopLevelDecl(DeclGroupRef DG) override {
57*67e74705SXin Li return IndexCtx.indexDeclGroupRef(DG);
58*67e74705SXin Li }
59*67e74705SXin Li
HandleInterestingDecl(DeclGroupRef DG)60*67e74705SXin Li void HandleInterestingDecl(DeclGroupRef DG) override {
61*67e74705SXin Li // Ignore deserialized decls.
62*67e74705SXin Li }
63*67e74705SXin Li
HandleTopLevelDeclInObjCContainer(DeclGroupRef DG)64*67e74705SXin Li void HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) override {
65*67e74705SXin Li IndexCtx.indexDeclGroupRef(DG);
66*67e74705SXin Li }
67*67e74705SXin Li
HandleTranslationUnit(ASTContext & Ctx)68*67e74705SXin Li void HandleTranslationUnit(ASTContext &Ctx) override {
69*67e74705SXin Li }
70*67e74705SXin Li };
71*67e74705SXin Li
72*67e74705SXin Li class IndexActionBase {
73*67e74705SXin Li protected:
74*67e74705SXin Li std::shared_ptr<IndexDataConsumer> DataConsumer;
75*67e74705SXin Li IndexingContext IndexCtx;
76*67e74705SXin Li
IndexActionBase(std::shared_ptr<IndexDataConsumer> dataConsumer,IndexingOptions Opts)77*67e74705SXin Li IndexActionBase(std::shared_ptr<IndexDataConsumer> dataConsumer,
78*67e74705SXin Li IndexingOptions Opts)
79*67e74705SXin Li : DataConsumer(std::move(dataConsumer)),
80*67e74705SXin Li IndexCtx(Opts, *DataConsumer) {}
81*67e74705SXin Li
createIndexASTConsumer()82*67e74705SXin Li std::unique_ptr<IndexASTConsumer> createIndexASTConsumer() {
83*67e74705SXin Li return llvm::make_unique<IndexASTConsumer>(IndexCtx);
84*67e74705SXin Li }
85*67e74705SXin Li
finish()86*67e74705SXin Li void finish() {
87*67e74705SXin Li DataConsumer->finish();
88*67e74705SXin Li }
89*67e74705SXin Li };
90*67e74705SXin Li
91*67e74705SXin Li class IndexAction : public ASTFrontendAction, IndexActionBase {
92*67e74705SXin Li public:
IndexAction(std::shared_ptr<IndexDataConsumer> DataConsumer,IndexingOptions Opts)93*67e74705SXin Li IndexAction(std::shared_ptr<IndexDataConsumer> DataConsumer,
94*67e74705SXin Li IndexingOptions Opts)
95*67e74705SXin Li : IndexActionBase(std::move(DataConsumer), Opts) {}
96*67e74705SXin Li
97*67e74705SXin Li protected:
CreateASTConsumer(CompilerInstance & CI,StringRef InFile)98*67e74705SXin Li std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
99*67e74705SXin Li StringRef InFile) override {
100*67e74705SXin Li return createIndexASTConsumer();
101*67e74705SXin Li }
102*67e74705SXin Li
EndSourceFileAction()103*67e74705SXin Li void EndSourceFileAction() override {
104*67e74705SXin Li FrontendAction::EndSourceFileAction();
105*67e74705SXin Li finish();
106*67e74705SXin Li }
107*67e74705SXin Li };
108*67e74705SXin Li
109*67e74705SXin Li class WrappingIndexAction : public WrapperFrontendAction, IndexActionBase {
110*67e74705SXin Li bool IndexActionFailed = false;
111*67e74705SXin Li
112*67e74705SXin Li public:
WrappingIndexAction(std::unique_ptr<FrontendAction> WrappedAction,std::shared_ptr<IndexDataConsumer> DataConsumer,IndexingOptions Opts)113*67e74705SXin Li WrappingIndexAction(std::unique_ptr<FrontendAction> WrappedAction,
114*67e74705SXin Li std::shared_ptr<IndexDataConsumer> DataConsumer,
115*67e74705SXin Li IndexingOptions Opts)
116*67e74705SXin Li : WrapperFrontendAction(std::move(WrappedAction)),
117*67e74705SXin Li IndexActionBase(std::move(DataConsumer), Opts) {}
118*67e74705SXin Li
119*67e74705SXin Li protected:
120*67e74705SXin Li std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
121*67e74705SXin Li StringRef InFile) override;
122*67e74705SXin Li void EndSourceFileAction() override;
123*67e74705SXin Li };
124*67e74705SXin Li
125*67e74705SXin Li } // anonymous namespace
126*67e74705SXin Li
EndSourceFileAction()127*67e74705SXin Li void WrappingIndexAction::EndSourceFileAction() {
128*67e74705SXin Li // Invoke wrapped action's method.
129*67e74705SXin Li WrapperFrontendAction::EndSourceFileAction();
130*67e74705SXin Li if (!IndexActionFailed)
131*67e74705SXin Li finish();
132*67e74705SXin Li }
133*67e74705SXin Li
134*67e74705SXin Li std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance & CI,StringRef InFile)135*67e74705SXin Li WrappingIndexAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
136*67e74705SXin Li auto OtherConsumer = WrapperFrontendAction::CreateASTConsumer(CI, InFile);
137*67e74705SXin Li if (!OtherConsumer) {
138*67e74705SXin Li IndexActionFailed = true;
139*67e74705SXin Li return nullptr;
140*67e74705SXin Li }
141*67e74705SXin Li
142*67e74705SXin Li std::vector<std::unique_ptr<ASTConsumer>> Consumers;
143*67e74705SXin Li Consumers.push_back(std::move(OtherConsumer));
144*67e74705SXin Li Consumers.push_back(createIndexASTConsumer());
145*67e74705SXin Li return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
146*67e74705SXin Li }
147*67e74705SXin Li
148*67e74705SXin Li std::unique_ptr<FrontendAction>
createIndexingAction(std::shared_ptr<IndexDataConsumer> DataConsumer,IndexingOptions Opts,std::unique_ptr<FrontendAction> WrappedAction)149*67e74705SXin Li index::createIndexingAction(std::shared_ptr<IndexDataConsumer> DataConsumer,
150*67e74705SXin Li IndexingOptions Opts,
151*67e74705SXin Li std::unique_ptr<FrontendAction> WrappedAction) {
152*67e74705SXin Li if (WrappedAction)
153*67e74705SXin Li return llvm::make_unique<WrappingIndexAction>(std::move(WrappedAction),
154*67e74705SXin Li std::move(DataConsumer),
155*67e74705SXin Li Opts);
156*67e74705SXin Li return llvm::make_unique<IndexAction>(std::move(DataConsumer), Opts);
157*67e74705SXin Li }
158*67e74705SXin Li
159*67e74705SXin Li
topLevelDeclVisitor(void * context,const Decl * D)160*67e74705SXin Li static bool topLevelDeclVisitor(void *context, const Decl *D) {
161*67e74705SXin Li IndexingContext &IndexCtx = *static_cast<IndexingContext*>(context);
162*67e74705SXin Li return IndexCtx.indexTopLevelDecl(D);
163*67e74705SXin Li }
164*67e74705SXin Li
indexTranslationUnit(ASTUnit & Unit,IndexingContext & IndexCtx)165*67e74705SXin Li static void indexTranslationUnit(ASTUnit &Unit, IndexingContext &IndexCtx) {
166*67e74705SXin Li Unit.visitLocalTopLevelDecls(&IndexCtx, topLevelDeclVisitor);
167*67e74705SXin Li }
168*67e74705SXin Li
indexASTUnit(ASTUnit & Unit,std::shared_ptr<IndexDataConsumer> DataConsumer,IndexingOptions Opts)169*67e74705SXin Li void index::indexASTUnit(ASTUnit &Unit,
170*67e74705SXin Li std::shared_ptr<IndexDataConsumer> DataConsumer,
171*67e74705SXin Li IndexingOptions Opts) {
172*67e74705SXin Li IndexingContext IndexCtx(Opts, *DataConsumer);
173*67e74705SXin Li IndexCtx.setASTContext(Unit.getASTContext());
174*67e74705SXin Li DataConsumer->initialize(Unit.getASTContext());
175*67e74705SXin Li indexTranslationUnit(Unit, IndexCtx);
176*67e74705SXin Li }
177