diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2016-08-16 21:17:51 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2016-08-16 21:17:51 +0000 | 
| commit | e7145dcb9f6563389ebbfa0572ef7589bdd94b1b (patch) | |
| tree | b1b30c4998f6e9769784be87d402e4f8db13e34d /contrib/llvm/tools/clang/lib/Index/IndexingAction.cpp | |
| parent | 3ca95b020283db6244cab92ede73c969253b6a31 (diff) | |
| parent | 7fd6ba58d980ec2bf312a80444948501dd27d020 (diff) | |
Notes
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Index/IndexingAction.cpp')
| -rw-r--r-- | contrib/llvm/tools/clang/lib/Index/IndexingAction.cpp | 176 | 
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 000000000000..d7442931523f --- /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); +}  | 
