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 
12 #include "IndexingContext.h"
15 #include "clang/Lex/Preprocessor.h"
17 
18 using namespace clang;
19 using namespace clang::index;
20 
21 void IndexDataConsumer::_anchor() {}
22 
24  ArrayRef<SymbolRelation> Relations,
25  FileID FID, unsigned Offset,
26  ASTNodeInfo ASTNode) {
27  return true;
28 }
29 
31  const MacroInfo *MI, SymbolRoleSet Roles,
32  FileID FID, unsigned Offset) {
33  return true;
34 }
35 
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 {
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.
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) {
168 }
169 
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 
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 
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();
205 }
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:81
bool indexTopLevelDecl(const Decl *D)
Definition: IndexDecl.cpp:750
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:128
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.
uint32_t Offset
Definition: CacheTokens.cpp:43
llvm::iterator_range< ModuleDeclIterator > getModuleFileLevelDecls(ModuleFile &Mod)
Definition: ASTReader.cpp:5334
ASTContext & getContext()
Retrieve the AST context that this AST reader supplements.
Definition: ASTReader.h:2222
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:760
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:2535
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Definition: Decl.h:3859
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:328
A frontend action which simply wraps some other runtime-specified frontend action.
Encapsulates the data about a macro definition (e.g.
Definition: MacroInfo.h:34
void indexASTUnit(ASTUnit &Unit, std::shared_ptr< IndexDataConsumer > DataConsumer, IndexingOptions Opts)
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)