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