clang  3.9.0
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"
16 
17 using namespace clang;
18 using namespace clang::index;
19 
20 void IndexDataConsumer::_anchor() {}
21 
23  ArrayRef<SymbolRelation> Relations,
24  FileID FID, unsigned Offset,
25  ASTNodeInfo ASTNode) {
26  return true;
27 }
28 
30  const MacroInfo *MI, SymbolRoleSet Roles,
31  FileID FID, unsigned Offset) {
32  return true;
33 }
34 
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 {
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.
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) {
167 }
168 
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 }
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs...
Definition: ASTConsumer.h:36
virtual bool handleDeclOccurence(const Decl *D, SymbolRoleSet Roles, ArrayRef< SymbolRelation > Relations, FileID FID, unsigned Offset, ASTNodeInfo ASTNode)
bool indexTopLevelDecl(const Decl *D)
Definition: IndexDecl.cpp:439
void setASTContext(ASTContext &ctx)
One of these records is kept for each identifier that is lexed.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
Definition: Type.h:4549
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:92
Utility class for loading a ASTContext from an AST file.
Definition: ASTUnit.h:68
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:44
ASTContext * Context
Defines the clang::Preprocessor interface.
virtual bool handleModuleOccurence(const ImportDecl *ImportD, SymbolRoleSet Roles, FileID FID, unsigned Offset)
virtual void EndSourceFileAction()
Callback at the end of processing a single input.
void EndSourceFileAction() override
Callback at the end of processing a single input.
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:2778
const ASTContext & getASTContext() const
Definition: ASTUnit.h:508
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Definition: Decl.h:3728
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
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)
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...