]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/Index/IndexingAction.cpp
Merge clang trunk r321017 to contrib/llvm/tools/clang.
[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 "IndexingContext.h"
12 #include "clang/Frontend/CompilerInstance.h"
13 #include "clang/Frontend/FrontendAction.h"
14 #include "clang/Frontend/MultiplexConsumer.h"
15 #include "clang/Index/IndexDataConsumer.h"
16 #include "clang/Lex/Preprocessor.h"
17 #include "clang/Serialization/ASTReader.h"
18
19 using namespace clang;
20 using namespace clang::index;
21
22 void IndexDataConsumer::_anchor() {}
23
24 bool IndexDataConsumer::handleDeclOccurence(const Decl *D, SymbolRoleSet Roles,
25                                             ArrayRef<SymbolRelation> Relations,
26                                             FileID FID, unsigned Offset,
27                                             ASTNodeInfo ASTNode) {
28   return true;
29 }
30
31 bool IndexDataConsumer::handleMacroOccurence(const IdentifierInfo *Name,
32                                              const MacroInfo *MI, SymbolRoleSet Roles,
33                                              FileID FID, unsigned Offset) {
34   return true;
35 }
36
37 bool IndexDataConsumer::handleModuleOccurence(const ImportDecl *ImportD,
38                                               SymbolRoleSet Roles,
39                                               FileID FID, unsigned Offset) {
40   return true;
41 }
42
43 namespace {
44
45 class IndexASTConsumer : public ASTConsumer {
46   std::shared_ptr<Preprocessor> PP;
47   IndexingContext &IndexCtx;
48
49 public:
50   IndexASTConsumer(std::shared_ptr<Preprocessor> PP, IndexingContext &IndexCtx)
51       : PP(std::move(PP)), IndexCtx(IndexCtx) {}
52
53 protected:
54   void Initialize(ASTContext &Context) override {
55     IndexCtx.setASTContext(Context);
56     IndexCtx.getDataConsumer().initialize(Context);
57     IndexCtx.getDataConsumer().setPreprocessor(PP);
58   }
59
60   bool HandleTopLevelDecl(DeclGroupRef DG) override {
61     return IndexCtx.indexDeclGroupRef(DG);
62   }
63
64   void HandleInterestingDecl(DeclGroupRef DG) override {
65     // Ignore deserialized decls.
66   }
67
68   void HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) override {
69     IndexCtx.indexDeclGroupRef(DG);
70   }
71
72   void HandleTranslationUnit(ASTContext &Ctx) override {
73   }
74 };
75
76 class IndexActionBase {
77 protected:
78   std::shared_ptr<IndexDataConsumer> DataConsumer;
79   IndexingContext IndexCtx;
80
81   IndexActionBase(std::shared_ptr<IndexDataConsumer> dataConsumer,
82                   IndexingOptions Opts)
83     : DataConsumer(std::move(dataConsumer)),
84       IndexCtx(Opts, *DataConsumer) {}
85
86   std::unique_ptr<IndexASTConsumer>
87   createIndexASTConsumer(CompilerInstance &CI) {
88     return llvm::make_unique<IndexASTConsumer>(CI.getPreprocessorPtr(),
89                                                IndexCtx);
90   }
91
92   void finish() {
93     DataConsumer->finish();
94   }
95 };
96
97 class IndexAction : public ASTFrontendAction, IndexActionBase {
98 public:
99   IndexAction(std::shared_ptr<IndexDataConsumer> DataConsumer,
100               IndexingOptions Opts)
101     : IndexActionBase(std::move(DataConsumer), Opts) {}
102
103 protected:
104   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
105                                                  StringRef InFile) override {
106     return createIndexASTConsumer(CI);
107   }
108
109   void EndSourceFileAction() override {
110     FrontendAction::EndSourceFileAction();
111     finish();
112   }
113 };
114
115 class WrappingIndexAction : public WrapperFrontendAction, IndexActionBase {
116   bool IndexActionFailed = false;
117
118 public:
119   WrappingIndexAction(std::unique_ptr<FrontendAction> WrappedAction,
120                       std::shared_ptr<IndexDataConsumer> DataConsumer,
121                       IndexingOptions Opts)
122     : WrapperFrontendAction(std::move(WrappedAction)),
123       IndexActionBase(std::move(DataConsumer), Opts) {}
124
125 protected:
126   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
127                                                  StringRef InFile) override;
128   void EndSourceFileAction() override;
129 };
130
131 } // anonymous namespace
132
133 void WrappingIndexAction::EndSourceFileAction() {
134   // Invoke wrapped action's method.
135   WrapperFrontendAction::EndSourceFileAction();
136   if (!IndexActionFailed)
137     finish();
138 }
139
140 std::unique_ptr<ASTConsumer>
141 WrappingIndexAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
142   auto OtherConsumer = WrapperFrontendAction::CreateASTConsumer(CI, InFile);
143   if (!OtherConsumer) {
144     IndexActionFailed = true;
145     return nullptr;
146   }
147
148   std::vector<std::unique_ptr<ASTConsumer>> Consumers;
149   Consumers.push_back(std::move(OtherConsumer));
150   Consumers.push_back(createIndexASTConsumer(CI));
151   return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
152 }
153
154 std::unique_ptr<FrontendAction>
155 index::createIndexingAction(std::shared_ptr<IndexDataConsumer> DataConsumer,
156                             IndexingOptions Opts,
157                             std::unique_ptr<FrontendAction> WrappedAction) {
158   if (WrappedAction)
159     return llvm::make_unique<WrappingIndexAction>(std::move(WrappedAction),
160                                                   std::move(DataConsumer),
161                                                   Opts);
162   return llvm::make_unique<IndexAction>(std::move(DataConsumer), Opts);
163 }
164
165
166 static bool topLevelDeclVisitor(void *context, const Decl *D) {
167   IndexingContext &IndexCtx = *static_cast<IndexingContext*>(context);
168   return IndexCtx.indexTopLevelDecl(D);
169 }
170
171 static void indexTranslationUnit(ASTUnit &Unit, IndexingContext &IndexCtx) {
172   Unit.visitLocalTopLevelDecls(&IndexCtx, topLevelDeclVisitor);
173 }
174
175 void index::indexASTUnit(ASTUnit &Unit,
176                          std::shared_ptr<IndexDataConsumer> DataConsumer,
177                          IndexingOptions Opts) {
178   IndexingContext IndexCtx(Opts, *DataConsumer);
179   IndexCtx.setASTContext(Unit.getASTContext());
180   DataConsumer->initialize(Unit.getASTContext());
181   DataConsumer->setPreprocessor(Unit.getPreprocessorPtr());
182   indexTranslationUnit(Unit, IndexCtx);
183   DataConsumer->finish();
184 }
185
186 void index::indexTopLevelDecls(ASTContext &Ctx, ArrayRef<const Decl *> Decls,
187                                std::shared_ptr<IndexDataConsumer> DataConsumer,
188                                IndexingOptions Opts) {
189   IndexingContext IndexCtx(Opts, *DataConsumer);
190   IndexCtx.setASTContext(Ctx);
191
192   DataConsumer->initialize(Ctx);
193   for (const Decl *D : Decls)
194     IndexCtx.indexTopLevelDecl(D);
195   DataConsumer->finish();
196 }
197
198 void index::indexModuleFile(serialization::ModuleFile &Mod,
199                             ASTReader &Reader,
200                             std::shared_ptr<IndexDataConsumer> DataConsumer,
201                             IndexingOptions Opts) {
202   ASTContext &Ctx = Reader.getContext();
203   IndexingContext IndexCtx(Opts, *DataConsumer);
204   IndexCtx.setASTContext(Ctx);
205   DataConsumer->initialize(Ctx);
206
207   for (const Decl *D : Reader.getModuleFileLevelDecls(Mod)) {
208     IndexCtx.indexTopLevelDecl(D);
209   }
210   DataConsumer->finish();
211 }