clang-tools 19.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
17namespace clang {
18namespace 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
32public:
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()) {
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
87private:
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
98static clang::FrontendPluginRegistry::Add<
100 X("clang-include-fixer", "clang-include-fixer");
volatile int ClangIncludeFixerPluginAnchorSource
int X
llvm::StringRef Directory
std::unique_ptr< CompilerInvocation > CI
llvm::json::Object Args
Definition: Trace.cpp:138
bool ParseArgs(const CompilerInstance &CI, const std::vector< std::string > &Args) override
std::unique_ptr< clang::ASTConsumer > CreateASTConsumer(clang::CompilerInstance &CI, StringRef InFile) override
Handles callbacks from sema, does the include lookup and turns it into an IncludeFixerContext.
This class provides an interface for finding the header files corresponding to an identifier in the s...
static llvm::ErrorOr< std::unique_ptr< YamlSymbolIndex > > createFromFile(llvm::StringRef FilePath)
Create a new Yaml db from a file.
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.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//