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