]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/Index/IndexingAction.cpp
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r305145, and update
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / Index / IndexingAction.cpp
1 //===- 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 #include "clang/Serialization/ASTReader.h"
17
18 using namespace clang;
19 using namespace clang::index;
20
21 void IndexDataConsumer::_anchor() {}
22
23 bool IndexDataConsumer::handleDeclOccurence(const Decl *D, SymbolRoleSet Roles,
24                                             ArrayRef<SymbolRelation> Relations,
25                                             FileID FID, unsigned Offset,
26                                             ASTNodeInfo ASTNode) {
27   return true;
28 }
29
30 bool IndexDataConsumer::handleMacroOccurence(const IdentifierInfo *Name,
31                                              const MacroInfo *MI, SymbolRoleSet Roles,
32                                              FileID FID, unsigned Offset) {
33   return true;
34 }
35
36 bool IndexDataConsumer::handleModuleOccurence(const ImportDecl *ImportD,
37                                               SymbolRoleSet Roles,
38                                               FileID FID, unsigned Offset) {
39   return true;
40 }
41
42 namespace {
43
44 class IndexASTConsumer : public ASTConsumer {
45   IndexingContext &IndexCtx;
46
47 public:
48   IndexASTConsumer(IndexingContext &IndexCtx)
49     : IndexCtx(IndexCtx) {}
50
51 protected:
52   void Initialize(ASTContext &Context) override {
53     IndexCtx.setASTContext(Context);
54     IndexCtx.getDataConsumer().initialize(Context);
55   }
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
73 class IndexActionBase {
74 protected:
75   std::shared_ptr<IndexDataConsumer> DataConsumer;
76   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
92 class IndexAction : public ASTFrontendAction, IndexActionBase {
93 public:
94   IndexAction(std::shared_ptr<IndexDataConsumer> DataConsumer,
95               IndexingOptions Opts)
96     : IndexActionBase(std::move(DataConsumer), Opts) {}
97
98 protected:
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
110 class WrappingIndexAction : public WrapperFrontendAction, IndexActionBase {
111   bool IndexActionFailed = false;
112
113 public:
114   WrappingIndexAction(std::unique_ptr<FrontendAction> WrappedAction,
115                       std::shared_ptr<IndexDataConsumer> DataConsumer,
116                       IndexingOptions Opts)
117     : WrapperFrontendAction(std::move(WrappedAction)),
118       IndexActionBase(std::move(DataConsumer), Opts) {}
119
120 protected:
121   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
122                                                  StringRef InFile) override;
123   void EndSourceFileAction() override;
124 };
125
126 } // anonymous namespace
127
128 void WrappingIndexAction::EndSourceFileAction() {
129   // Invoke wrapped action's method.
130   WrapperFrontendAction::EndSourceFileAction();
131   if (!IndexActionFailed)
132     finish();
133 }
134
135 std::unique_ptr<ASTConsumer>
136 WrappingIndexAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
137   auto OtherConsumer = WrapperFrontendAction::CreateASTConsumer(CI, InFile);
138   if (!OtherConsumer) {
139     IndexActionFailed = true;
140     return nullptr;
141   }
142
143   std::vector<std::unique_ptr<ASTConsumer>> Consumers;
144   Consumers.push_back(std::move(OtherConsumer));
145   Consumers.push_back(createIndexASTConsumer());
146   return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
147 }
148
149 std::unique_ptr<FrontendAction>
150 index::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);
158 }
159
160
161 static bool topLevelDeclVisitor(void *context, const Decl *D) {
162   IndexingContext &IndexCtx = *static_cast<IndexingContext*>(context);
163   return IndexCtx.indexTopLevelDecl(D);
164 }
165
166 static void indexTranslationUnit(ASTUnit &Unit, IndexingContext &IndexCtx) {
167   Unit.visitLocalTopLevelDecls(&IndexCtx, topLevelDeclVisitor);
168 }
169
170 void index::indexASTUnit(ASTUnit &Unit,
171                          std::shared_ptr<IndexDataConsumer> DataConsumer,
172                          IndexingOptions Opts) {
173   IndexingContext IndexCtx(Opts, *DataConsumer);
174   IndexCtx.setASTContext(Unit.getASTContext());
175   DataConsumer->initialize(Unit.getASTContext());
176   indexTranslationUnit(Unit, IndexCtx);
177   DataConsumer->finish();
178 }
179
180 void index::indexModuleFile(serialization::ModuleFile &Mod,
181                             ASTReader &Reader,
182                             std::shared_ptr<IndexDataConsumer> DataConsumer,
183                             IndexingOptions Opts) {
184   ASTContext &Ctx = Reader.getContext();
185   IndexingContext IndexCtx(Opts, *DataConsumer);
186   IndexCtx.setASTContext(Ctx);
187   DataConsumer->initialize(Ctx);
188
189   for (const Decl *D :Reader.getModuleFileLevelDecls(Mod)) {
190     IndexCtx.indexTopLevelDecl(D);
191   }
192   DataConsumer->finish();
193 }