summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Index/IndexingAction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Index/IndexingAction.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Index/IndexingAction.cpp176
1 files changed, 176 insertions, 0 deletions
diff --git a/contrib/llvm/tools/clang/lib/Index/IndexingAction.cpp b/contrib/llvm/tools/clang/lib/Index/IndexingAction.cpp
new file mode 100644
index 0000000..d744293
--- /dev/null
+++ b/contrib/llvm/tools/clang/lib/Index/IndexingAction.cpp
@@ -0,0 +1,176 @@
+//===- IndexingAction.cpp - Frontend index action -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/IndexingAction.h"
+#include "clang/Index/IndexDataConsumer.h"
+#include "IndexingContext.h"
+#include "clang/Frontend/FrontendAction.h"
+#include "clang/Frontend/MultiplexConsumer.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang;
+using namespace clang::index;
+
+void IndexDataConsumer::_anchor() {}
+
+bool IndexDataConsumer::handleDeclOccurence(const Decl *D, SymbolRoleSet Roles,
+ ArrayRef<SymbolRelation> Relations,
+ FileID FID, unsigned Offset,
+ ASTNodeInfo ASTNode) {
+ return true;
+}
+
+bool IndexDataConsumer::handleMacroOccurence(const IdentifierInfo *Name,
+ const MacroInfo *MI, SymbolRoleSet Roles,
+ FileID FID, unsigned Offset) {
+ return true;
+}
+
+bool IndexDataConsumer::handleModuleOccurence(const ImportDecl *ImportD,
+ SymbolRoleSet Roles,
+ FileID FID, unsigned Offset) {
+ return true;
+}
+
+namespace {
+
+class IndexASTConsumer : public ASTConsumer {
+ IndexingContext &IndexCtx;
+
+public:
+ IndexASTConsumer(IndexingContext &IndexCtx)
+ : IndexCtx(IndexCtx) {}
+
+protected:
+ void Initialize(ASTContext &Context) override {
+ IndexCtx.setASTContext(Context);
+ IndexCtx.getDataConsumer().initialize(Context);
+ }
+
+ bool HandleTopLevelDecl(DeclGroupRef DG) override {
+ return IndexCtx.indexDeclGroupRef(DG);
+ }
+
+ void HandleInterestingDecl(DeclGroupRef DG) override {
+ // Ignore deserialized decls.
+ }
+
+ void HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) override {
+ IndexCtx.indexDeclGroupRef(DG);
+ }
+
+ void HandleTranslationUnit(ASTContext &Ctx) override {
+ }
+};
+
+class IndexActionBase {
+protected:
+ std::shared_ptr<IndexDataConsumer> DataConsumer;
+ IndexingContext IndexCtx;
+
+ IndexActionBase(std::shared_ptr<IndexDataConsumer> dataConsumer,
+ IndexingOptions Opts)
+ : DataConsumer(std::move(dataConsumer)),
+ IndexCtx(Opts, *DataConsumer) {}
+
+ std::unique_ptr<IndexASTConsumer> createIndexASTConsumer() {
+ return llvm::make_unique<IndexASTConsumer>(IndexCtx);
+ }
+
+ void finish() {
+ DataConsumer->finish();
+ }
+};
+
+class IndexAction : public ASTFrontendAction, IndexActionBase {
+public:
+ IndexAction(std::shared_ptr<IndexDataConsumer> DataConsumer,
+ IndexingOptions Opts)
+ : IndexActionBase(std::move(DataConsumer), Opts) {}
+
+protected:
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override {
+ return createIndexASTConsumer();
+ }
+
+ void EndSourceFileAction() override {
+ FrontendAction::EndSourceFileAction();
+ finish();
+ }
+};
+
+class WrappingIndexAction : public WrapperFrontendAction, IndexActionBase {
+ bool IndexActionFailed = false;
+
+public:
+ WrappingIndexAction(std::unique_ptr<FrontendAction> WrappedAction,
+ std::shared_ptr<IndexDataConsumer> DataConsumer,
+ IndexingOptions Opts)
+ : WrapperFrontendAction(std::move(WrappedAction)),
+ IndexActionBase(std::move(DataConsumer), Opts) {}
+
+protected:
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
+ void EndSourceFileAction() override;
+};
+
+} // anonymous namespace
+
+void WrappingIndexAction::EndSourceFileAction() {
+ // Invoke wrapped action's method.
+ WrapperFrontendAction::EndSourceFileAction();
+ if (!IndexActionFailed)
+ finish();
+}
+
+std::unique_ptr<ASTConsumer>
+WrappingIndexAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
+ auto OtherConsumer = WrapperFrontendAction::CreateASTConsumer(CI, InFile);
+ if (!OtherConsumer) {
+ IndexActionFailed = true;
+ return nullptr;
+ }
+
+ std::vector<std::unique_ptr<ASTConsumer>> Consumers;
+ Consumers.push_back(std::move(OtherConsumer));
+ Consumers.push_back(createIndexASTConsumer());
+ return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
+}
+
+std::unique_ptr<FrontendAction>
+index::createIndexingAction(std::shared_ptr<IndexDataConsumer> DataConsumer,
+ IndexingOptions Opts,
+ std::unique_ptr<FrontendAction> WrappedAction) {
+ if (WrappedAction)
+ return llvm::make_unique<WrappingIndexAction>(std::move(WrappedAction),
+ std::move(DataConsumer),
+ Opts);
+ return llvm::make_unique<IndexAction>(std::move(DataConsumer), Opts);
+}
+
+
+static bool topLevelDeclVisitor(void *context, const Decl *D) {
+ IndexingContext &IndexCtx = *static_cast<IndexingContext*>(context);
+ return IndexCtx.indexTopLevelDecl(D);
+}
+
+static void indexTranslationUnit(ASTUnit &Unit, IndexingContext &IndexCtx) {
+ Unit.visitLocalTopLevelDecls(&IndexCtx, topLevelDeclVisitor);
+}
+
+void index::indexASTUnit(ASTUnit &Unit,
+ std::shared_ptr<IndexDataConsumer> DataConsumer,
+ IndexingOptions Opts) {
+ IndexingContext IndexCtx(Opts, *DataConsumer);
+ IndexCtx.setASTContext(Unit.getASTContext());
+ DataConsumer->initialize(Unit.getASTContext());
+ indexTranslationUnit(Unit, IndexCtx);
+}
OpenPOWER on IntegriCloud