xref: /llvm-project/clang/lib/Tooling/StandaloneExecution.cpp (revision 2b3d49b610bd2a45884115edcb21110bfa325f51)
1826b7832SEric Liu //===- lib/Tooling/Execution.cpp - Standalone clang action execution. -----===//
2826b7832SEric Liu //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6826b7832SEric Liu //
7826b7832SEric Liu //===----------------------------------------------------------------------===//
8826b7832SEric Liu 
9826b7832SEric Liu #include "clang/Tooling/StandaloneExecution.h"
10826b7832SEric Liu #include "clang/Tooling/ToolExecutorPluginRegistry.h"
11826b7832SEric Liu 
12826b7832SEric Liu namespace clang {
13826b7832SEric Liu namespace tooling {
14826b7832SEric Liu 
make_string_error(const llvm::Twine & Message)15826b7832SEric Liu static llvm::Error make_string_error(const llvm::Twine &Message) {
16826b7832SEric Liu   return llvm::make_error<llvm::StringError>(Message,
17826b7832SEric Liu                                              llvm::inconvertibleErrorCode());
18826b7832SEric Liu }
19826b7832SEric Liu 
20826b7832SEric Liu const char *StandaloneToolExecutor::ExecutorName = "StandaloneToolExecutor";
21826b7832SEric Liu 
getDefaultArgumentsAdjusters()22826b7832SEric Liu static ArgumentsAdjuster getDefaultArgumentsAdjusters() {
23826b7832SEric Liu   return combineAdjusters(
24826b7832SEric Liu       getClangStripOutputAdjuster(),
25826b7832SEric Liu       combineAdjusters(getClangSyntaxOnlyAdjuster(),
26826b7832SEric Liu                        getClangStripDependencyFileAdjuster()));
27826b7832SEric Liu }
28826b7832SEric Liu 
StandaloneToolExecutor(const CompilationDatabase & Compilations,llvm::ArrayRef<std::string> SourcePaths,IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,std::shared_ptr<PCHContainerOperations> PCHContainerOps)29826b7832SEric Liu StandaloneToolExecutor::StandaloneToolExecutor(
30826b7832SEric Liu     const CompilationDatabase &Compilations,
31826b7832SEric Liu     llvm::ArrayRef<std::string> SourcePaths,
32fc51490bSJonas Devlieghere     IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
33826b7832SEric Liu     std::shared_ptr<PCHContainerOperations> PCHContainerOps)
34a2a25121SEric Liu     : Tool(Compilations, SourcePaths, std::move(PCHContainerOps),
35a2a25121SEric Liu            std::move(BaseFS)),
36a2a25121SEric Liu       Context(&Results), ArgsAdjuster(getDefaultArgumentsAdjusters()) {
37826b7832SEric Liu   // Use self-defined default argument adjusters instead of the default
38826b7832SEric Liu   // adjusters that come with the old `ClangTool`.
39826b7832SEric Liu   Tool.clearArgumentsAdjusters();
40826b7832SEric Liu }
41826b7832SEric Liu 
StandaloneToolExecutor(CommonOptionsParser Options,std::shared_ptr<PCHContainerOperations> PCHContainerOps)42826b7832SEric Liu StandaloneToolExecutor::StandaloneToolExecutor(
43826b7832SEric Liu     CommonOptionsParser Options,
44826b7832SEric Liu     std::shared_ptr<PCHContainerOperations> PCHContainerOps)
45826b7832SEric Liu     : OptionsParser(std::move(Options)),
46826b7832SEric Liu       Tool(OptionsParser->getCompilations(), OptionsParser->getSourcePathList(),
47a2a25121SEric Liu            std::move(PCHContainerOps)),
48826b7832SEric Liu       Context(&Results), ArgsAdjuster(getDefaultArgumentsAdjusters()) {
49826b7832SEric Liu   Tool.clearArgumentsAdjusters();
50826b7832SEric Liu }
51826b7832SEric Liu 
execute(llvm::ArrayRef<std::pair<std::unique_ptr<FrontendActionFactory>,ArgumentsAdjuster>> Actions)52826b7832SEric Liu llvm::Error StandaloneToolExecutor::execute(
53826b7832SEric Liu     llvm::ArrayRef<
54826b7832SEric Liu         std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
55826b7832SEric Liu         Actions) {
56826b7832SEric Liu   if (Actions.empty())
57826b7832SEric Liu     return make_string_error("No action to execute.");
58826b7832SEric Liu 
59826b7832SEric Liu   if (Actions.size() != 1)
60826b7832SEric Liu     return make_string_error(
61826b7832SEric Liu         "Only support executing exactly 1 action at this point.");
62826b7832SEric Liu 
63826b7832SEric Liu   auto &Action = Actions.front();
64826b7832SEric Liu   Tool.appendArgumentsAdjuster(Action.second);
65826b7832SEric Liu   Tool.appendArgumentsAdjuster(ArgsAdjuster);
6683454aaeSEric Liu   if (Tool.run(Action.first.get()))
67826b7832SEric Liu     return make_string_error("Failed to run action.");
68826b7832SEric Liu 
69826b7832SEric Liu   return llvm::Error::success();
70826b7832SEric Liu }
71826b7832SEric Liu 
72826b7832SEric Liu class StandaloneToolExecutorPlugin : public ToolExecutorPlugin {
73826b7832SEric Liu public:
74826b7832SEric Liu   llvm::Expected<std::unique_ptr<ToolExecutor>>
create(CommonOptionsParser & OptionsParser)75826b7832SEric Liu   create(CommonOptionsParser &OptionsParser) override {
76826b7832SEric Liu     if (OptionsParser.getSourcePathList().empty())
77826b7832SEric Liu       return make_string_error(
78826b7832SEric Liu           "[StandaloneToolExecutorPlugin] No positional argument found.");
79*2b3d49b6SJonas Devlieghere     return std::make_unique<StandaloneToolExecutor>(std::move(OptionsParser));
80826b7832SEric Liu   }
81826b7832SEric Liu };
82826b7832SEric Liu 
83826b7832SEric Liu static ToolExecutorPluginRegistry::Add<StandaloneToolExecutorPlugin>
84826b7832SEric Liu     X("standalone", "Runs FrontendActions on a set of files provided "
85826b7832SEric Liu                     "via positional arguments.");
86826b7832SEric Liu 
87152ad050SEric Liu // This anchor is used to force the linker to link in the generated object file
88152ad050SEric Liu // and thus register the plugin.
89152ad050SEric Liu volatile int StandaloneToolExecutorAnchorSource = 0;
90152ad050SEric Liu 
91826b7832SEric Liu } // end namespace tooling
92826b7832SEric Liu } // end namespace clang
93