1 //===- 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 
14 LLVM_INSTANTIATE_REGISTRY(clang::tooling::ToolExecutorPluginRegistry)
15 
16 namespace clang {
17 namespace tooling {
18 
19 static llvm::cl::opt<std::string>
20     ExecutorName("executor", llvm::cl::desc("The name of the executor to use."),
21                  llvm::cl::init("standalone"));
22 
23 void InMemoryToolResults::addResult(StringRef Key, StringRef Value) {
24   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});
34 }
35 
36 std::vector<std::pair<llvm::StringRef, llvm::StringRef>>
37 InMemoryToolResults::AllKVResults() {
38   return KVResults;
39 }
40 
41 void 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 
48 void ExecutionContext::reportResult(StringRef Key, StringRef Value) {
49   Results->addResult(Key, Value);
50 }
51 
52 llvm::Error
53 ToolExecutor::execute(std::unique_ptr<FrontendActionFactory> Action) {
54   return execute(std::move(Action), ArgumentsAdjuster());
55 }
56 
57 llvm::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 
66 namespace internal {
67 llvm::Expected<std::unique_ptr<ToolExecutor>>
68 createExecutorFromCommandLineArgsImpl(int &argc, const char **argv,
69                                       llvm::cl::OptionCategory &Category,
70                                       const char *Overview) {
71   auto OptionsParser =
72       CommonOptionsParser::create(argc, argv, Category, llvm::cl::ZeroOrMore,
73                                   /*Overview=*/Overview);
74   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 }
97 } // end namespace internal
98 
99 llvm::Expected<std::unique_ptr<ToolExecutor>>
100 createExecutorFromCommandLineArgs(int &argc, const char **argv,
101                                   llvm::cl::OptionCategory &Category,
102                                   const char *Overview) {
103   return internal::createExecutorFromCommandLineArgsImpl(argc, argv, Category,
104                                                          Overview);
105 }
106 
107 // This anchor is used to force the linker to link in the generated object file
108 // and thus register the StandaloneToolExecutorPlugin etc.
109 extern volatile int StandaloneToolExecutorAnchorSource;
110 extern volatile int AllTUsToolExecutorAnchorSource;
111 static int LLVM_ATTRIBUTE_UNUSED StandaloneToolExecutorAnchorDest =
112     StandaloneToolExecutorAnchorSource;
113 static int LLVM_ATTRIBUTE_UNUSED AllTUsToolExecutorAnchorDest =
114     AllTUsToolExecutorAnchorSource;
115 
116 } // end namespace tooling
117 } // end namespace clang
118