blob: c39a4fcdac829e863198fc6e167915f9f16d1c1c [file] [log] [blame]
Eric Liu826b7832017-10-26 10:38:14 +00001//===- lib/Tooling/Execution.cpp - Implements tool execution framework. ---===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Eric Liu826b7832017-10-26 10:38:14 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "clang/Tooling/Execution.h"
10#include "clang/Tooling/ToolExecutorPluginRegistry.h"
11#include "clang/Tooling/Tooling.h"
12
13LLVM_INSTANTIATE_REGISTRY(clang::tooling::ToolExecutorPluginRegistry)
14
15namespace clang {
16namespace tooling {
17
Eric Liuf5617dc2018-10-12 11:47:36 +000018llvm::cl::opt<std::string>
Eric Liu826b7832017-10-26 10:38:14 +000019 ExecutorName("executor", llvm::cl::desc("The name of the executor to use."),
20 llvm::cl::init("standalone"));
21
22void InMemoryToolResults::addResult(StringRef Key, StringRef Value) {
Sam McCallfae3f892018-07-23 11:25:25 +000023 KVResults.push_back({Strings.save(Key), Strings.save(Value)});
Eric Liu826b7832017-10-26 10:38:14 +000024}
25
Haojian Wu9f36c7e2018-04-11 08:13:07 +000026std::vector<std::pair<llvm::StringRef, llvm::StringRef>>
Eric Liu826b7832017-10-26 10:38:14 +000027InMemoryToolResults::AllKVResults() {
28 return KVResults;
29}
30
31void InMemoryToolResults::forEachResult(
32 llvm::function_ref<void(StringRef Key, StringRef Value)> Callback) {
33 for (const auto &KV : KVResults) {
34 Callback(KV.first, KV.second);
35 }
36}
37
38void ExecutionContext::reportResult(StringRef Key, StringRef Value) {
39 Results->addResult(Key, Value);
40}
41
42llvm::Error
43ToolExecutor::execute(std::unique_ptr<FrontendActionFactory> Action) {
44 return execute(std::move(Action), ArgumentsAdjuster());
45}
46
47llvm::Error ToolExecutor::execute(std::unique_ptr<FrontendActionFactory> Action,
48 ArgumentsAdjuster Adjuster) {
49 std::vector<
50 std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
51 Actions;
52 Actions.emplace_back(std::move(Action), std::move(Adjuster));
53 return execute(Actions);
54}
55
Eric Liu6e622842017-11-03 15:20:57 +000056namespace internal {
Eric Liu826b7832017-10-26 10:38:14 +000057llvm::Expected<std::unique_ptr<ToolExecutor>>
Eric Liu6e622842017-11-03 15:20:57 +000058createExecutorFromCommandLineArgsImpl(int &argc, const char **argv,
59 llvm::cl::OptionCategory &Category,
60 const char *Overview) {
Eric Liu826b7832017-10-26 10:38:14 +000061 auto OptionsParser =
62 CommonOptionsParser::create(argc, argv, Category, llvm::cl::ZeroOrMore,
Eric Liu152ad052017-11-03 15:57:27 +000063 /*Overview=*/Overview);
Eric Liu826b7832017-10-26 10:38:14 +000064 if (!OptionsParser)
65 return OptionsParser.takeError();
66 for (auto I = ToolExecutorPluginRegistry::begin(),
67 E = ToolExecutorPluginRegistry::end();
68 I != E; ++I) {
69 if (I->getName() != ExecutorName) {
70 continue;
71 }
72 std::unique_ptr<ToolExecutorPlugin> Plugin(I->instantiate());
73 llvm::Expected<std::unique_ptr<ToolExecutor>> Executor =
74 Plugin->create(*OptionsParser);
75 if (!Executor) {
76 return llvm::make_error<llvm::StringError>(
77 llvm::Twine("Failed to create '") + I->getName() +
78 "': " + llvm::toString(Executor.takeError()) + "\n",
79 llvm::inconvertibleErrorCode());
80 }
81 return std::move(*Executor);
82 }
83 return llvm::make_error<llvm::StringError>(
84 llvm::Twine("Executor \"") + ExecutorName + "\" is not registered.",
85 llvm::inconvertibleErrorCode());
86}
Eric Liu6e622842017-11-03 15:20:57 +000087} // end namespace internal
88
89llvm::Expected<std::unique_ptr<ToolExecutor>>
90createExecutorFromCommandLineArgs(int &argc, const char **argv,
91 llvm::cl::OptionCategory &Category,
92 const char *Overview) {
93 return internal::createExecutorFromCommandLineArgsImpl(argc, argv, Category,
94 Overview);
95}
Eric Liu826b7832017-10-26 10:38:14 +000096
Eric Liu152ad052017-11-03 15:57:27 +000097// This anchor is used to force the linker to link in the generated object file
Eric Liue25f3672018-01-05 10:32:16 +000098// and thus register the StandaloneToolExecutorPlugin etc.
Eric Liu152ad052017-11-03 15:57:27 +000099extern volatile int StandaloneToolExecutorAnchorSource;
Eric Liue25f3672018-01-05 10:32:16 +0000100extern volatile int AllTUsToolExecutorAnchorSource;
Eric Liu152ad052017-11-03 15:57:27 +0000101static int LLVM_ATTRIBUTE_UNUSED StandaloneToolExecutorAnchorDest =
102 StandaloneToolExecutorAnchorSource;
Eric Liue25f3672018-01-05 10:32:16 +0000103static int LLVM_ATTRIBUTE_UNUSED AllTUsToolExecutorAnchorDest =
104 AllTUsToolExecutorAnchorSource;
Eric Liu152ad052017-11-03 15:57:27 +0000105
Eric Liu826b7832017-10-26 10:38:14 +0000106} // end namespace tooling
107} // end namespace clang