blob: 84d31200bab4351fd9887c57c9dc1beb64be6417 [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"
Argyrios Kyrtzidisa38cb202017-01-30 06:05:58 +000016#include "clang/Serialization/ASTReader.h"
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000017
18using namespace clang;
19using namespace clang::index;
20
21void IndexDataConsumer::_anchor() {}
22
23bool IndexDataConsumer::handleDeclOccurence(const Decl *D, SymbolRoleSet Roles,
24 ArrayRef<SymbolRelation> Relations,
25 FileID FID, unsigned Offset,
26 ASTNodeInfo ASTNode) {
27 return true;
28}
29
30bool IndexDataConsumer::handleMacroOccurence(const IdentifierInfo *Name,
31 const MacroInfo *MI, SymbolRoleSet Roles,
32 FileID FID, unsigned Offset) {
33 return true;
34}
35
36bool IndexDataConsumer::handleModuleOccurence(const ImportDecl *ImportD,
37 SymbolRoleSet Roles,
38 FileID FID, unsigned Offset) {
39 return true;
40}
41
42namespace {
43
44class IndexASTConsumer : public ASTConsumer {
45 IndexingContext &IndexCtx;
46
47public:
48 IndexASTConsumer(IndexingContext &IndexCtx)
49 : IndexCtx(IndexCtx) {}
50
51protected:
52 void Initialize(ASTContext &Context) override {
53 IndexCtx.setASTContext(Context);
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +000054 IndexCtx.getDataConsumer().initialize(Context);
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000055 }
56
57 bool HandleTopLevelDecl(DeclGroupRef DG) override {
58 return IndexCtx.indexDeclGroupRef(DG);
59 }
60
61 void HandleInterestingDecl(DeclGroupRef DG) override {
62 // Ignore deserialized decls.
63 }
64
65 void HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) override {
66 IndexCtx.indexDeclGroupRef(DG);
67 }
68
69 void HandleTranslationUnit(ASTContext &Ctx) override {
70 }
71};
72
Argyrios Kyrtzidis469c1362016-02-14 06:39:03 +000073class IndexActionBase {
74protected:
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000075 std::shared_ptr<IndexDataConsumer> DataConsumer;
Argyrios Kyrtzidis469c1362016-02-14 06:39:03 +000076 IndexingContext IndexCtx;
77
78 IndexActionBase(std::shared_ptr<IndexDataConsumer> dataConsumer,
79 IndexingOptions Opts)
80 : DataConsumer(std::move(dataConsumer)),
81 IndexCtx(Opts, *DataConsumer) {}
82
83 std::unique_ptr<IndexASTConsumer> createIndexASTConsumer() {
84 return llvm::make_unique<IndexASTConsumer>(IndexCtx);
85 }
86
87 void finish() {
88 DataConsumer->finish();
89 }
90};
91
92class IndexAction : public ASTFrontendAction, IndexActionBase {
93public:
94 IndexAction(std::shared_ptr<IndexDataConsumer> DataConsumer,
95 IndexingOptions Opts)
96 : IndexActionBase(std::move(DataConsumer), Opts) {}
97
98protected:
99 std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
100 StringRef InFile) override {
101 return createIndexASTConsumer();
102 }
103
104 void EndSourceFileAction() override {
105 FrontendAction::EndSourceFileAction();
106 finish();
107 }
108};
109
110class WrappingIndexAction : public WrapperFrontendAction, IndexActionBase {
111 bool IndexActionFailed = false;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000112
113public:
Argyrios Kyrtzidis469c1362016-02-14 06:39:03 +0000114 WrappingIndexAction(std::unique_ptr<FrontendAction> WrappedAction,
115 std::shared_ptr<IndexDataConsumer> DataConsumer,
116 IndexingOptions Opts)
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000117 : WrapperFrontendAction(std::move(WrappedAction)),
Argyrios Kyrtzidis469c1362016-02-14 06:39:03 +0000118 IndexActionBase(std::move(DataConsumer), Opts) {}
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000119
120protected:
121 std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
122 StringRef InFile) override;
123 void EndSourceFileAction() override;
124};
125
126} // anonymous namespace
127
Argyrios Kyrtzidis469c1362016-02-14 06:39:03 +0000128void WrappingIndexAction::EndSourceFileAction() {
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000129 // Invoke wrapped action's method.
130 WrapperFrontendAction::EndSourceFileAction();
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000131 if (!IndexActionFailed)
Argyrios Kyrtzidis469c1362016-02-14 06:39:03 +0000132 finish();
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000133}
134
135std::unique_ptr<ASTConsumer>
Argyrios Kyrtzidis469c1362016-02-14 06:39:03 +0000136WrappingIndexAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000137 auto OtherConsumer = WrapperFrontendAction::CreateASTConsumer(CI, InFile);
Argyrios Kyrtzidis469c1362016-02-14 06:39:03 +0000138 if (!OtherConsumer) {
139 IndexActionFailed = true;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000140 return nullptr;
Argyrios Kyrtzidis469c1362016-02-14 06:39:03 +0000141 }
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000142
143 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
144 Consumers.push_back(std::move(OtherConsumer));
Argyrios Kyrtzidis469c1362016-02-14 06:39:03 +0000145 Consumers.push_back(createIndexASTConsumer());
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000146 return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
147}
148
149std::unique_ptr<FrontendAction>
Argyrios Kyrtzidis469c1362016-02-14 06:39:03 +0000150index::createIndexingAction(std::shared_ptr<IndexDataConsumer> DataConsumer,
151 IndexingOptions Opts,
152 std::unique_ptr<FrontendAction> WrappedAction) {
153 if (WrappedAction)
154 return llvm::make_unique<WrappingIndexAction>(std::move(WrappedAction),
155 std::move(DataConsumer),
156 Opts);
157 return llvm::make_unique<IndexAction>(std::move(DataConsumer), Opts);
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000158}
159
160
161static bool topLevelDeclVisitor(void *context, const Decl *D) {
162 IndexingContext &IndexCtx = *static_cast<IndexingContext*>(context);
163 return IndexCtx.indexTopLevelDecl(D);
164}
165
166static void indexTranslationUnit(ASTUnit &Unit, IndexingContext &IndexCtx) {
167 Unit.visitLocalTopLevelDecls(&IndexCtx, topLevelDeclVisitor);
168}
169
170void index::indexASTUnit(ASTUnit &Unit,
171 std::shared_ptr<IndexDataConsumer> DataConsumer,
172 IndexingOptions Opts) {
173 IndexingContext IndexCtx(Opts, *DataConsumer);
174 IndexCtx.setASTContext(Unit.getASTContext());
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +0000175 DataConsumer->initialize(Unit.getASTContext());
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000176 indexTranslationUnit(Unit, IndexCtx);
Argyrios Kyrtzidisa38cb202017-01-30 06:05:58 +0000177 DataConsumer->finish();
178}
179
Ilya Biryukov00f5f292017-07-14 10:47:45 +0000180void index::indexTopLevelDecls(ASTContext &Ctx, ArrayRef<const Decl *> Decls,
181 std::shared_ptr<IndexDataConsumer> DataConsumer,
182 IndexingOptions Opts) {
183 IndexingContext IndexCtx(Opts, *DataConsumer);
184 IndexCtx.setASTContext(Ctx);
185
186 DataConsumer->initialize(Ctx);
187 for (const Decl *D : Decls)
188 IndexCtx.indexTopLevelDecl(D);
189 DataConsumer->finish();
190}
191
Argyrios Kyrtzidisa38cb202017-01-30 06:05:58 +0000192void index::indexModuleFile(serialization::ModuleFile &Mod,
193 ASTReader &Reader,
194 std::shared_ptr<IndexDataConsumer> DataConsumer,
195 IndexingOptions Opts) {
196 ASTContext &Ctx = Reader.getContext();
197 IndexingContext IndexCtx(Opts, *DataConsumer);
198 IndexCtx.setASTContext(Ctx);
199 DataConsumer->initialize(Ctx);
200
201 for (const Decl *D :Reader.getModuleFileLevelDecls(Mod)) {
202 IndexCtx.indexTopLevelDecl(D);
203 }
204 DataConsumer->finish();
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000205}