1 //===- lib/Tooling/Execution.cpp - Implements tool execution framework. ---===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "clang/Tooling/Execution.h"
10 #include "clang/Tooling/ToolExecutorPluginRegistry.h"
11 #include "clang/Tooling/Tooling.h"
12 
13 LLVM_INSTANTIATE_REGISTRY(clang::tooling::ToolExecutorPluginRegistry)
14 
15 namespace clang {
16 namespace tooling {
17 
18 llvm::cl::opt<std::string>
19     ExecutorName("executor", llvm::cl::desc("The name of the executor to use."),
20                  llvm::cl::init("standalone"));
21 
22 void InMemoryToolResults::addResult(StringRef Key, StringRef Value) {
23   KVResults.push_back({Strings.save(Key), Strings.save(Value)});
24 }
25 
26 std::vector<std::pair<llvm::StringRef, llvm::StringRef>>
27 InMemoryToolResults::AllKVResults() {
28   return KVResults;
29 }
30 
31 void 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 
38 void ExecutionContext::reportResult(StringRef Key, StringRef Value) {
39   Results->addResult(Key, Value);
40 }
41 
42 llvm::Error
43 ToolExecutor::execute(std::unique_ptr<FrontendActionFactory> Action) {
44   return execute(std::move(Action), ArgumentsAdjuster());
45 }
46 
47 llvm::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 
56 namespace internal {
57 llvm::Expected<std::unique_ptr<ToolExecutor>>
58 createExecutorFromCommandLineArgsImpl(int &argc, const char **argv,
59                                       llvm::cl::OptionCategory &Category,
60                                       const char *Overview) {
61   auto OptionsParser =
62       CommonOptionsParser::create(argc, argv, Category, llvm::cl::ZeroOrMore,
63                                   /*Overview=*/Overview);
64   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 }
87 } // end namespace internal
88 
89 llvm::Expected<std::unique_ptr<ToolExecutor>>
90 createExecutorFromCommandLineArgs(int &argc, const char **argv,
91                                   llvm::cl::OptionCategory &Category,
92                                   const char *Overview) {
93   return internal::createExecutorFromCommandLineArgsImpl(argc, argv, Category,
94                                                          Overview);
95 }
96 
97 // This anchor is used to force the linker to link in the generated object file
98 // and thus register the StandaloneToolExecutorPlugin etc.
99 extern volatile int StandaloneToolExecutorAnchorSource;
100 extern volatile int AllTUsToolExecutorAnchorSource;
101 static int LLVM_ATTRIBUTE_UNUSED StandaloneToolExecutorAnchorDest =
102     StandaloneToolExecutorAnchorSource;
103 static int LLVM_ATTRIBUTE_UNUSED AllTUsToolExecutorAnchorDest =
104     AllTUsToolExecutorAnchorSource;
105 
106 } // end namespace tooling
107 } // end namespace clang
108