1826b7832SEric Liu //===- lib/Tooling/Execution.cpp - Implements tool execution framework. ---===//
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/Execution.h"
10826b7832SEric Liu #include "clang/Tooling/ToolExecutorPluginRegistry.h"
11826b7832SEric Liu #include "clang/Tooling/Tooling.h"
12826b7832SEric Liu
13826b7832SEric Liu LLVM_INSTANTIATE_REGISTRY(clang::tooling::ToolExecutorPluginRegistry)
14826b7832SEric Liu
15826b7832SEric Liu namespace clang {
16826b7832SEric Liu namespace tooling {
17826b7832SEric Liu
18f5617dceSEric Liu llvm::cl::opt<std::string>
19826b7832SEric Liu ExecutorName("executor", llvm::cl::desc("The name of the executor to use."),
20826b7832SEric Liu llvm::cl::init("standalone"));
21826b7832SEric Liu
addResult(StringRef Key,StringRef Value)22826b7832SEric Liu void InMemoryToolResults::addResult(StringRef Key, StringRef Value) {
23fae3f890SSam McCall KVResults.push_back({Strings.save(Key), Strings.save(Value)});
24826b7832SEric Liu }
25826b7832SEric Liu
269f36c7e7SHaojian Wu std::vector<std::pair<llvm::StringRef, llvm::StringRef>>
AllKVResults()27826b7832SEric Liu InMemoryToolResults::AllKVResults() {
28826b7832SEric Liu return KVResults;
29826b7832SEric Liu }
30826b7832SEric Liu
forEachResult(llvm::function_ref<void (StringRef Key,StringRef Value)> Callback)31826b7832SEric Liu void InMemoryToolResults::forEachResult(
32826b7832SEric Liu llvm::function_ref<void(StringRef Key, StringRef Value)> Callback) {
33826b7832SEric Liu for (const auto &KV : KVResults) {
34826b7832SEric Liu Callback(KV.first, KV.second);
35826b7832SEric Liu }
36826b7832SEric Liu }
37826b7832SEric Liu
reportResult(StringRef Key,StringRef Value)38826b7832SEric Liu void ExecutionContext::reportResult(StringRef Key, StringRef Value) {
39826b7832SEric Liu Results->addResult(Key, Value);
40826b7832SEric Liu }
41826b7832SEric Liu
42826b7832SEric Liu llvm::Error
execute(std::unique_ptr<FrontendActionFactory> Action)43826b7832SEric Liu ToolExecutor::execute(std::unique_ptr<FrontendActionFactory> Action) {
44826b7832SEric Liu return execute(std::move(Action), ArgumentsAdjuster());
45826b7832SEric Liu }
46826b7832SEric Liu
execute(std::unique_ptr<FrontendActionFactory> Action,ArgumentsAdjuster Adjuster)47826b7832SEric Liu llvm::Error ToolExecutor::execute(std::unique_ptr<FrontendActionFactory> Action,
48826b7832SEric Liu ArgumentsAdjuster Adjuster) {
49826b7832SEric Liu std::vector<
50826b7832SEric Liu std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
51826b7832SEric Liu Actions;
52826b7832SEric Liu Actions.emplace_back(std::move(Action), std::move(Adjuster));
53826b7832SEric Liu return execute(Actions);
54826b7832SEric Liu }
55826b7832SEric Liu
566e622847SEric Liu namespace internal {
57826b7832SEric Liu llvm::Expected<std::unique_ptr<ToolExecutor>>
createExecutorFromCommandLineArgsImpl(int & argc,const char ** argv,llvm::cl::OptionCategory & Category,const char * Overview)586e622847SEric Liu createExecutorFromCommandLineArgsImpl(int &argc, const char **argv,
59826b7832SEric Liu llvm::cl::OptionCategory &Category,
60826b7832SEric Liu const char *Overview) {
61826b7832SEric Liu auto OptionsParser =
62826b7832SEric Liu CommonOptionsParser::create(argc, argv, Category, llvm::cl::ZeroOrMore,
63152ad050SEric Liu /*Overview=*/Overview);
64826b7832SEric Liu if (!OptionsParser)
65826b7832SEric Liu return OptionsParser.takeError();
66*8b0df1c1SNathan James for (const auto &TEPlugin : ToolExecutorPluginRegistry::entries()) {
67*8b0df1c1SNathan James if (TEPlugin.getName() != ExecutorName) {
68826b7832SEric Liu continue;
69826b7832SEric Liu }
70*8b0df1c1SNathan James std::unique_ptr<ToolExecutorPlugin> Plugin(TEPlugin.instantiate());
71826b7832SEric Liu llvm::Expected<std::unique_ptr<ToolExecutor>> Executor =
72826b7832SEric Liu Plugin->create(*OptionsParser);
73826b7832SEric Liu if (!Executor) {
74826b7832SEric Liu return llvm::make_error<llvm::StringError>(
75*8b0df1c1SNathan James llvm::Twine("Failed to create '") + TEPlugin.getName() +
76826b7832SEric Liu "': " + llvm::toString(Executor.takeError()) + "\n",
77826b7832SEric Liu llvm::inconvertibleErrorCode());
78826b7832SEric Liu }
79826b7832SEric Liu return std::move(*Executor);
80826b7832SEric Liu }
81826b7832SEric Liu return llvm::make_error<llvm::StringError>(
82826b7832SEric Liu llvm::Twine("Executor \"") + ExecutorName + "\" is not registered.",
83826b7832SEric Liu llvm::inconvertibleErrorCode());
84826b7832SEric Liu }
856e622847SEric Liu } // end namespace internal
866e622847SEric Liu
876e622847SEric Liu llvm::Expected<std::unique_ptr<ToolExecutor>>
createExecutorFromCommandLineArgs(int & argc,const char ** argv,llvm::cl::OptionCategory & Category,const char * Overview)886e622847SEric Liu createExecutorFromCommandLineArgs(int &argc, const char **argv,
896e622847SEric Liu llvm::cl::OptionCategory &Category,
906e622847SEric Liu const char *Overview) {
916e622847SEric Liu return internal::createExecutorFromCommandLineArgsImpl(argc, argv, Category,
926e622847SEric Liu Overview);
936e622847SEric Liu }
94826b7832SEric Liu
95152ad050SEric Liu // This anchor is used to force the linker to link in the generated object file
96e25f3676SEric Liu // and thus register the StandaloneToolExecutorPlugin etc.
97152ad050SEric Liu extern volatile int StandaloneToolExecutorAnchorSource;
98e25f3676SEric Liu extern volatile int AllTUsToolExecutorAnchorSource;
99152ad050SEric Liu static int LLVM_ATTRIBUTE_UNUSED StandaloneToolExecutorAnchorDest =
100152ad050SEric Liu StandaloneToolExecutorAnchorSource;
101e25f3676SEric Liu static int LLVM_ATTRIBUTE_UNUSED AllTUsToolExecutorAnchorDest =
102e25f3676SEric Liu AllTUsToolExecutorAnchorSource;
103152ad050SEric Liu
104826b7832SEric Liu } // end namespace tooling
105826b7832SEric Liu } // end namespace clang
106