clang  6.0.0svn
IndexingAction.cpp
Go to the documentation of this file.
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 
11 #include "IndexingContext.h"
16 #include "clang/Lex/Preprocessor.h"
18 
19 using namespace clang;
20 using namespace clang::index;
21 
22 void IndexDataConsumer::_anchor() {}
23 
25  ArrayRef<SymbolRelation> Relations,
26  FileID FID, unsigned Offset,
27  ASTNodeInfo ASTNode) {
28  return true;
29 }
30 
32  const MacroInfo *MI, SymbolRoleSet Roles,
33  FileID FID, unsigned Offset) {
34  return true;
35 }
36 
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 {
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.
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) {
173 }
174 
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 
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 
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 }
virtual void setPreprocessor(std::shared_ptr< Preprocessor > PP)
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs...
Definition: ASTConsumer.h:34
virtual bool handleDeclOccurence(const Decl *D, SymbolRoleSet Roles, ArrayRef< SymbolRelation > Relations, FileID FID, unsigned Offset, ASTNodeInfo ASTNode)
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
bool indexTopLevelDecl(const Decl *D)
Definition: IndexDecl.cpp:748
void setASTContext(ASTContext &ctx)
One of these records is kept for each identifier that is lexed.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:149
Utility class for loading a ASTContext from an AST file.
Definition: ASTUnit.h:71
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
std::shared_ptr< Preprocessor > getPreprocessorPtr()
uint32_t Offset
Definition: CacheTokens.cpp:43
llvm::iterator_range< ModuleDeclIterator > getModuleFileLevelDecls(ModuleFile &Mod)
Definition: ASTReader.cpp:5383
ASTContext & getContext()
Retrieve the AST context that this AST reader supplements.
Definition: ASTReader.h:2268
unsigned SymbolRoleSet
Definition: IndexSymbol.h:116
Defines the clang::Preprocessor interface.
virtual bool handleModuleOccurence(const ImportDecl *ImportD, SymbolRoleSet Roles, FileID FID, unsigned Offset)
bool indexDeclGroupRef(DeclGroupRef DG)
Definition: IndexDecl.cpp:758
virtual void EndSourceFileAction()
Callback at the end of processing a single input.
Information about a module that has been loaded by the ASTReader.
Definition: Module.h:100
void indexTopLevelDecls(ASTContext &Ctx, ArrayRef< const Decl *> Decls, std::shared_ptr< IndexDataConsumer > DataConsumer, IndexingOptions Opts)
void EndSourceFileAction() override
Callback at the end of processing a single input.
virtual void initialize(ASTContext &Ctx)
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
Abstract base class to use for AST consumer-based frontend actions.
bool visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn)
Iterate over local declarations (locally parsed if this is a parsed source file or the loaded declara...
Definition: ASTUnit.cpp:2521
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Definition: Decl.h:3965
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Dataflow Directional Tag Classes.
Reads an AST files chain containing the contents of a translation unit.
Definition: ASTReader.h:358
A frontend action which simply wraps some other runtime-specified frontend action.
Encapsulates the data about a macro definition (e.g.
Definition: MacroInfo.h:40
void indexASTUnit(ASTUnit &Unit, std::shared_ptr< IndexDataConsumer > DataConsumer, IndexingOptions Opts)
std::shared_ptr< Preprocessor > getPreprocessorPtr() const
Definition: ASTUnit.h:415
const ASTContext & getASTContext() const
Definition: ASTUnit.h:417
IndexDataConsumer & getDataConsumer()
static void indexTranslationUnit(ASTUnit &Unit, IndexingContext &IndexCtx)
virtual bool handleMacroOccurence(const IdentifierInfo *Name, const MacroInfo *MI, SymbolRoleSet Roles, FileID FID, unsigned Offset)
std::unique_ptr< FrontendAction > createIndexingAction(std::shared_ptr< IndexDataConsumer > DataConsumer, IndexingOptions Opts, std::unique_ptr< FrontendAction > WrappedAction)
static bool topLevelDeclVisitor(void *context, const Decl *D)
Defines the clang::FrontendAction interface and various convenience abstract classes (clang::ASTFront...
void indexModuleFile(serialization::ModuleFile &Mod, ASTReader &Reader, std::shared_ptr< IndexDataConsumer > DataConsumer, IndexingOptions Opts)