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