clang-tools  14.0.0git
IncludeFixerPlugin.cpp
Go to the documentation of this file.
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-exception
6 //
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 
17 namespace clang {
18 namespace include_fixer {
19 
20 /// The core include fixer plugin action. This just provides the AST consumer
21 /// and command line flag parsing for using include fixer as a clang plugin.
23  /// ASTConsumer to keep the symbol index alive. We don't really need an
24  /// ASTConsumer for this plugin (everything is funneled on the side through
25  /// 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 
32 public:
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.startswith("-db="))
58  DB = Arg.substr(strlen("-db="));
59  else if (Arg.startswith("-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()) {
71  } else {
72  // If we don't have any input file, look in the directory of the first
73  // file and its parents.
74  SmallString<128> AbsolutePath(tooling::getAbsolutePath(InputFile));
75  StringRef Directory = llvm::sys::path::parent_path(AbsolutePath);
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 
87 private:
88  std::shared_ptr<SymbolIndexManager> SymbolIndexMgr;
89  IntrusiveRefCntPtr<IncludeFixerSemaSource> SemaSource;
90 };
91 } // namespace include_fixer
92 } // namespace clang
93 
94 // This anchor is used to force the linker to link in the generated object file
95 // and thus register the include fixer plugin.
97 
98 static clang::FrontendPluginRegistry::Add<
100  X("clang-include-fixer", "clang-include-fixer");
clang::include_fixer::IncludeFixerSemaSource
Handles callbacks from sema, does the include lookup and turns it into an IncludeFixerContext.
Definition: clang-include-fixer/IncludeFixer.h:85
CI
std::unique_ptr< CompilerInvocation > CI
Definition: TUScheduler.cpp:450
clang::include_fixer::ClangIncludeFixerPluginAction::ParseArgs
bool ParseArgs(const CompilerInstance &CI, const std::vector< std::string > &Args) override
Definition: IncludeFixerPlugin.cpp:49
clang::include_fixer::ClangIncludeFixerPluginAction
The core include fixer plugin action.
Definition: IncludeFixerPlugin.cpp:22
Args
llvm::json::Object Args
Definition: Trace.cpp:139
Directory
llvm::StringRef Directory
Definition: Serialization.cpp:419
PluginASTAction
clang::include_fixer::ClangIncludeFixerPluginAction::CreateASTConsumer
std::unique_ptr< clang::ASTConsumer > CreateASTConsumer(clang::CompilerInstance &CI, StringRef InFile) override
Definition: IncludeFixerPlugin.cpp:40
clang::include_fixer::ClangIncludeFixerPluginAction::ExecuteAction
void ExecuteAction() override
Definition: IncludeFixerPlugin.cpp:47
clang::include_fixer::SymbolIndexManager
This class provides an interface for finding the header files corresponding to an identifier in the s...
Definition: SymbolIndexManager.h:33
ASTConsumer
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
ClangIncludeFixerPluginAnchorSource
volatile int ClangIncludeFixerPluginAnchorSource
Definition: IncludeFixerPlugin.cpp:96
X
static clang::FrontendPluginRegistry::Add< clang::include_fixer::ClangIncludeFixerPluginAction > X("clang-include-fixer", "clang-include-fixer")
clang::include_fixer::YamlSymbolIndex::createFromDirectory
static llvm::ErrorOr< std::unique_ptr< YamlSymbolIndex > > createFromDirectory(llvm::StringRef Directory, llvm::StringRef Name)
Look for a file called Name in Directory and all parent directories.
Definition: YamlSymbolIndex.cpp:35
clang::include_fixer::YamlSymbolIndex::createFromFile
static llvm::ErrorOr< std::unique_ptr< YamlSymbolIndex > > createFromFile(llvm::StringRef FilePath)
Create a new Yaml db from a file.
Definition: YamlSymbolIndex.cpp:25
clang::include_fixer::ClangIncludeFixerPluginAction::ClangIncludeFixerPluginAction
ClangIncludeFixerPluginAction()
Definition: IncludeFixerPlugin.cpp:33