blob: 5d6559fb2b435d1a20690f2049dc4e8c63630f94 [file] [log] [blame]
Eric Liu826b7832017-10-26 10:38:14 +00001//===- lib/Tooling/Execution.cpp - Implements tool execution framework. ---===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "clang/Tooling/Execution.h"
11#include "clang/Tooling/ToolExecutorPluginRegistry.h"
12#include "clang/Tooling/Tooling.h"
13
14LLVM_INSTANTIATE_REGISTRY(clang::tooling::ToolExecutorPluginRegistry)
15
16namespace clang {
17namespace tooling {
18
19static llvm::cl::opt<std::string>
20 ExecutorName("executor", llvm::cl::desc("The name of the executor to use."),
21 llvm::cl::init("standalone"));
22
23void InMemoryToolResults::addResult(StringRef Key, StringRef Value) {
Haojian Wu9f36c7e2018-04-11 08:13:07 +000024 auto Intern = [&](StringRef &V) {
25 auto R = Strings.insert(V);
26 if (R.second) { // A new entry, create a new string copy.
27 *R.first = StringsPool.save(V);
28 }
29 V = *R.first;
30 };
31 Intern(Key);
32 Intern(Value);
33 KVResults.push_back({Key, Value});
Eric Liu826b7832017-10-26 10:38:14 +000034}
35
Haojian Wu9f36c7e2018-04-11 08:13:07 +000036std::vector<std::pair<llvm::StringRef, llvm::StringRef>>
Eric Liu826b7832017-10-26 10:38:14 +000037InMemoryToolResults::AllKVResults() {
38 return KVResults;
39}
40
41void InMemoryToolResults::forEachResult(
42 llvm::function_ref<void(StringRef Key, StringRef Value)> Callback) {
43 for (const auto &KV : KVResults) {
44 Callback(KV.first, KV.second);
45 }
46}
47
48void ExecutionContext::reportResult(StringRef Key, StringRef Value) {
49 Results->addResult(Key, Value);
50}
51
52llvm::Error
53ToolExecutor::execute(std::unique_ptr<FrontendActionFactory> Action) {
54 return execute(std::move(Action), ArgumentsAdjuster());
55}
56
57llvm::Error ToolExecutor::execute(std::unique_ptr<FrontendActionFactory> Action,
58 ArgumentsAdjuster Adjuster) {
59 std::vector<
60 std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
61 Actions;
62 Actions.emplace_back(std::move(Action), std::move(Adjuster));
63 return execute(Actions);
64}
65
Eric Liu6e622842017-11-03 15:20:57 +000066namespace internal {
Eric Liu826b7832017-10-26 10:38:14 +000067llvm::Expected<std::unique_ptr<ToolExecutor>>
Eric Liu6e622842017-11-03 15:20:57 +000068createExecutorFromCommandLineArgsImpl(int &argc, const char **argv,
69 llvm::cl::OptionCategory &Category,
70 const char *Overview) {
Eric Liu826b7832017-10-26 10:38:14 +000071 auto OptionsParser =
72 CommonOptionsParser::create(argc, argv, Category, llvm::cl::ZeroOrMore,
Eric Liu152ad052017-11-03 15:57:27 +000073 /*Overview=*/Overview);
Eric Liu826b7832017-10-26 10:38:14 +000074 if (!OptionsParser)
75 return OptionsParser.takeError();
76 for (auto I = ToolExecutorPluginRegistry::begin(),
77 E = ToolExecutorPluginRegistry::end();
78 I != E; ++I) {
79 if (I->getName() != ExecutorName) {
80 continue;
81 }
82 std::unique_ptr<ToolExecutorPlugin> Plugin(I->instantiate());
83 llvm::Expected<std::unique_ptr<ToolExecutor>> Executor =
84 Plugin->create(*OptionsParser);
85 if (!Executor) {
86 return llvm::make_error<llvm::StringError>(
87 llvm::Twine("Failed to create '") + I->getName() +
88 "': " + llvm::toString(Executor.takeError()) + "\n",
89 llvm::inconvertibleErrorCode());
90 }
91 return std::move(*Executor);
92 }
93 return llvm::make_error<llvm::StringError>(
94 llvm::Twine("Executor \"") + ExecutorName + "\" is not registered.",
95 llvm::inconvertibleErrorCode());
96}
Eric Liu6e622842017-11-03 15:20:57 +000097} // end namespace internal
98
99llvm::Expected<std::unique_ptr<ToolExecutor>>
100createExecutorFromCommandLineArgs(int &argc, const char **argv,
101 llvm::cl::OptionCategory &Category,
102 const char *Overview) {
103 return internal::createExecutorFromCommandLineArgsImpl(argc, argv, Category,
104 Overview);
105}
Eric Liu826b7832017-10-26 10:38:14 +0000106
Eric Liu152ad052017-11-03 15:57:27 +0000107// This anchor is used to force the linker to link in the generated object file
Eric Liue25f3672018-01-05 10:32:16 +0000108// and thus register the StandaloneToolExecutorPlugin etc.
Eric Liu152ad052017-11-03 15:57:27 +0000109extern volatile int StandaloneToolExecutorAnchorSource;
Eric Liue25f3672018-01-05 10:32:16 +0000110extern volatile int AllTUsToolExecutorAnchorSource;
Eric Liu152ad052017-11-03 15:57:27 +0000111static int LLVM_ATTRIBUTE_UNUSED StandaloneToolExecutorAnchorDest =
112 StandaloneToolExecutorAnchorSource;
Eric Liue25f3672018-01-05 10:32:16 +0000113static int LLVM_ATTRIBUTE_UNUSED AllTUsToolExecutorAnchorDest =
114 AllTUsToolExecutorAnchorSource;
Eric Liu152ad052017-11-03 15:57:27 +0000115
Eric Liu826b7832017-10-26 10:38:14 +0000116} // end namespace tooling
117} // end namespace clang