brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.9 KiB · ce431d4 Raw
101 lines · cpp
1//===- IncludeFixerPlugin.cpp - clang-include-fixer as a clang plugin -----===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "../IncludeFixer.h"10#include "../YamlSymbolIndex.h"11#include "clang/Frontend/CompilerInstance.h"12#include "clang/Frontend/FrontendPluginRegistry.h"13#include "clang/Parse/ParseAST.h"14#include "clang/Sema/Sema.h"15#include "llvm/Support/Path.h"16 17namespace clang {18namespace include_fixer {19 20/// The core include fixer plugin action. This just provides the AST consumer21/// and command line flag parsing for using include fixer as a clang plugin.22class ClangIncludeFixerPluginAction : public PluginASTAction {23  /// ASTConsumer to keep the symbol index alive. We don't really need an24  /// ASTConsumer for this plugin (everything is funneled on the side through25  /// Sema) but we have to keep the symbol index alive until sema is done.26  struct ASTConsumerManagerWrapper : public ASTConsumer {27    ASTConsumerManagerWrapper(std::shared_ptr<SymbolIndexManager> SIM)28        : SymbolIndexMgr(std::move(SIM)) {}29    std::shared_ptr<SymbolIndexManager> SymbolIndexMgr;30  };31 32public:33  explicit ClangIncludeFixerPluginAction()34      : SymbolIndexMgr(std::make_shared<SymbolIndexManager>()),35        SemaSource(new IncludeFixerSemaSource(*SymbolIndexMgr,36                                              /*MinimizeIncludePaths=*/true,37                                              /*GenerateDiagnostics=*/true)) {}38 39  std::unique_ptr<clang::ASTConsumer>40  CreateASTConsumer(clang::CompilerInstance &CI, StringRef InFile) override {41    CI.setExternalSemaSource(SemaSource);42    SemaSource->setFilePath(InFile);43    SemaSource->setCompilerInstance(&CI);44    return std::make_unique<ASTConsumerManagerWrapper>(SymbolIndexMgr);45  }46 47  void ExecuteAction() override {} // Do nothing.48 49  bool ParseArgs(const CompilerInstance &CI,50                 const std::vector<std::string> &Args) override {51    StringRef DB = "yaml";52    StringRef Input;53 54    // Parse the extra command line args.55    // FIXME: This is very limited at the moment.56    for (StringRef Arg : Args) {57      if (Arg.starts_with("-db="))58        DB = Arg.substr(strlen("-db="));59      else if (Arg.starts_with("-input="))60        Input = Arg.substr(strlen("-input="));61    }62 63    std::string InputFile =64        std::string(CI.getFrontendOpts().Inputs[0].getFile());65    auto CreateYamlIdx = [=]() -> std::unique_ptr<include_fixer::SymbolIndex> {66      llvm::ErrorOr<std::unique_ptr<include_fixer::YamlSymbolIndex>> SymbolIdx(67          nullptr);68      if (DB == "yaml") {69        if (!Input.empty()) {70          SymbolIdx = include_fixer::YamlSymbolIndex::createFromFile(Input);71        } else {72          // If we don't have any input file, look in the directory of the first73          // file and its parents.74          SmallString<128> AbsolutePath(tooling::getAbsolutePath(InputFile));75          StringRef Directory = llvm::sys::path::parent_path(AbsolutePath);76          SymbolIdx = include_fixer::YamlSymbolIndex::createFromDirectory(77              Directory, "find_all_symbols_db.yaml");78        }79      }80      return std::move(*SymbolIdx);81    };82 83    SymbolIndexMgr->addSymbolIndex(std::move(CreateYamlIdx));84    return true;85  }86 87private:88  std::shared_ptr<SymbolIndexManager> SymbolIndexMgr;89  IntrusiveRefCntPtr<IncludeFixerSemaSource> SemaSource;90};91} // namespace include_fixer92} // namespace clang93 94// This anchor is used to force the linker to link in the generated object file95// and thus register the include fixer plugin.96volatile int ClangIncludeFixerPluginAnchorSource = 0;97 98static clang::FrontendPluginRegistry::Add<99    clang::include_fixer::ClangIncludeFixerPluginAction>100    X("clang-include-fixer", "clang-include-fixer");101