1 //===- lib/Tooling/Execution.cpp - Standalone clang action execution. -----===//
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 "clang/Tooling/StandaloneExecution.h"
10 #include "clang/Tooling/ToolExecutorPluginRegistry.h"
11
12 namespace clang {
13 namespace tooling {
14
make_string_error(const llvm::Twine & Message)15 static llvm::Error make_string_error(const llvm::Twine &Message) {
16 return llvm::make_error<llvm::StringError>(Message,
17 llvm::inconvertibleErrorCode());
18 }
19
20 const char *StandaloneToolExecutor::ExecutorName = "StandaloneToolExecutor";
21
getDefaultArgumentsAdjusters()22 static ArgumentsAdjuster getDefaultArgumentsAdjusters() {
23 return combineAdjusters(
24 getClangStripOutputAdjuster(),
25 combineAdjusters(getClangSyntaxOnlyAdjuster(),
26 getClangStripDependencyFileAdjuster()));
27 }
28
StandaloneToolExecutor(const CompilationDatabase & Compilations,llvm::ArrayRef<std::string> SourcePaths,IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,std::shared_ptr<PCHContainerOperations> PCHContainerOps)29 StandaloneToolExecutor::StandaloneToolExecutor(
30 const CompilationDatabase &Compilations,
31 llvm::ArrayRef<std::string> SourcePaths,
32 IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
33 std::shared_ptr<PCHContainerOperations> PCHContainerOps)
34 : Tool(Compilations, SourcePaths, std::move(PCHContainerOps),
35 std::move(BaseFS)),
36 Context(&Results), ArgsAdjuster(getDefaultArgumentsAdjusters()) {
37 // Use self-defined default argument adjusters instead of the default
38 // adjusters that come with the old `ClangTool`.
39 Tool.clearArgumentsAdjusters();
40 }
41
StandaloneToolExecutor(CommonOptionsParser Options,std::shared_ptr<PCHContainerOperations> PCHContainerOps)42 StandaloneToolExecutor::StandaloneToolExecutor(
43 CommonOptionsParser Options,
44 std::shared_ptr<PCHContainerOperations> PCHContainerOps)
45 : OptionsParser(std::move(Options)),
46 Tool(OptionsParser->getCompilations(), OptionsParser->getSourcePathList(),
47 std::move(PCHContainerOps)),
48 Context(&Results), ArgsAdjuster(getDefaultArgumentsAdjusters()) {
49 Tool.clearArgumentsAdjusters();
50 }
51
execute(llvm::ArrayRef<std::pair<std::unique_ptr<FrontendActionFactory>,ArgumentsAdjuster>> Actions)52 llvm::Error StandaloneToolExecutor::execute(
53 llvm::ArrayRef<
54 std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
55 Actions) {
56 if (Actions.empty())
57 return make_string_error("No action to execute.");
58
59 if (Actions.size() != 1)
60 return make_string_error(
61 "Only support executing exactly 1 action at this point.");
62
63 auto &Action = Actions.front();
64 Tool.appendArgumentsAdjuster(Action.second);
65 Tool.appendArgumentsAdjuster(ArgsAdjuster);
66 if (Tool.run(Action.first.get()))
67 return make_string_error("Failed to run action.");
68
69 return llvm::Error::success();
70 }
71
72 class StandaloneToolExecutorPlugin : public ToolExecutorPlugin {
73 public:
74 llvm::Expected<std::unique_ptr<ToolExecutor>>
create(CommonOptionsParser & OptionsParser)75 create(CommonOptionsParser &OptionsParser) override {
76 if (OptionsParser.getSourcePathList().empty())
77 return make_string_error(
78 "[StandaloneToolExecutorPlugin] No positional argument found.");
79 return std::make_unique<StandaloneToolExecutor>(std::move(OptionsParser));
80 }
81 };
82
83 static ToolExecutorPluginRegistry::Add<StandaloneToolExecutorPlugin>
84 X("standalone", "Runs FrontendActions on a set of files provided "
85 "via positional arguments.");
86
87 // This anchor is used to force the linker to link in the generated object file
88 // and thus register the plugin.
89 volatile int StandaloneToolExecutorAnchorSource = 0;
90
91 } // end namespace tooling
92 } // end namespace clang
93