xref: /openbsd-src/gnu/llvm/clang/lib/Tooling/Execution.cpp (revision ec727ea710c91afd8ce4f788c5aaa8482b7b69b2)
1e5dd7070Spatrick //===- lib/Tooling/Execution.cpp - Implements tool execution framework. ---===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick 
9e5dd7070Spatrick #include "clang/Tooling/Execution.h"
10e5dd7070Spatrick #include "clang/Tooling/ToolExecutorPluginRegistry.h"
11e5dd7070Spatrick #include "clang/Tooling/Tooling.h"
12e5dd7070Spatrick 
13e5dd7070Spatrick LLVM_INSTANTIATE_REGISTRY(clang::tooling::ToolExecutorPluginRegistry)
14e5dd7070Spatrick 
15e5dd7070Spatrick namespace clang {
16e5dd7070Spatrick namespace tooling {
17e5dd7070Spatrick 
18e5dd7070Spatrick llvm::cl::opt<std::string>
19e5dd7070Spatrick     ExecutorName("executor", llvm::cl::desc("The name of the executor to use."),
20e5dd7070Spatrick                  llvm::cl::init("standalone"));
21e5dd7070Spatrick 
addResult(StringRef Key,StringRef Value)22e5dd7070Spatrick void InMemoryToolResults::addResult(StringRef Key, StringRef Value) {
23e5dd7070Spatrick   KVResults.push_back({Strings.save(Key), Strings.save(Value)});
24e5dd7070Spatrick }
25e5dd7070Spatrick 
26e5dd7070Spatrick std::vector<std::pair<llvm::StringRef, llvm::StringRef>>
AllKVResults()27e5dd7070Spatrick InMemoryToolResults::AllKVResults() {
28e5dd7070Spatrick   return KVResults;
29e5dd7070Spatrick }
30e5dd7070Spatrick 
forEachResult(llvm::function_ref<void (StringRef Key,StringRef Value)> Callback)31e5dd7070Spatrick void InMemoryToolResults::forEachResult(
32e5dd7070Spatrick     llvm::function_ref<void(StringRef Key, StringRef Value)> Callback) {
33e5dd7070Spatrick   for (const auto &KV : KVResults) {
34e5dd7070Spatrick     Callback(KV.first, KV.second);
35e5dd7070Spatrick   }
36e5dd7070Spatrick }
37e5dd7070Spatrick 
reportResult(StringRef Key,StringRef Value)38e5dd7070Spatrick void ExecutionContext::reportResult(StringRef Key, StringRef Value) {
39e5dd7070Spatrick   Results->addResult(Key, Value);
40e5dd7070Spatrick }
41e5dd7070Spatrick 
42e5dd7070Spatrick llvm::Error
execute(std::unique_ptr<FrontendActionFactory> Action)43e5dd7070Spatrick ToolExecutor::execute(std::unique_ptr<FrontendActionFactory> Action) {
44e5dd7070Spatrick   return execute(std::move(Action), ArgumentsAdjuster());
45e5dd7070Spatrick }
46e5dd7070Spatrick 
execute(std::unique_ptr<FrontendActionFactory> Action,ArgumentsAdjuster Adjuster)47e5dd7070Spatrick llvm::Error ToolExecutor::execute(std::unique_ptr<FrontendActionFactory> Action,
48e5dd7070Spatrick                                   ArgumentsAdjuster Adjuster) {
49e5dd7070Spatrick   std::vector<
50e5dd7070Spatrick       std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
51e5dd7070Spatrick       Actions;
52e5dd7070Spatrick   Actions.emplace_back(std::move(Action), std::move(Adjuster));
53e5dd7070Spatrick   return execute(Actions);
54e5dd7070Spatrick }
55e5dd7070Spatrick 
56e5dd7070Spatrick namespace internal {
57e5dd7070Spatrick llvm::Expected<std::unique_ptr<ToolExecutor>>
createExecutorFromCommandLineArgsImpl(int & argc,const char ** argv,llvm::cl::OptionCategory & Category,const char * Overview)58e5dd7070Spatrick createExecutorFromCommandLineArgsImpl(int &argc, const char **argv,
59e5dd7070Spatrick                                       llvm::cl::OptionCategory &Category,
60e5dd7070Spatrick                                       const char *Overview) {
61e5dd7070Spatrick   auto OptionsParser =
62e5dd7070Spatrick       CommonOptionsParser::create(argc, argv, Category, llvm::cl::ZeroOrMore,
63e5dd7070Spatrick                                   /*Overview=*/Overview);
64e5dd7070Spatrick   if (!OptionsParser)
65e5dd7070Spatrick     return OptionsParser.takeError();
66*ec727ea7Spatrick   for (const auto &TEPlugin : ToolExecutorPluginRegistry::entries()) {
67*ec727ea7Spatrick     if (TEPlugin.getName() != ExecutorName) {
68e5dd7070Spatrick       continue;
69e5dd7070Spatrick     }
70*ec727ea7Spatrick     std::unique_ptr<ToolExecutorPlugin> Plugin(TEPlugin.instantiate());
71e5dd7070Spatrick     llvm::Expected<std::unique_ptr<ToolExecutor>> Executor =
72e5dd7070Spatrick         Plugin->create(*OptionsParser);
73e5dd7070Spatrick     if (!Executor) {
74e5dd7070Spatrick       return llvm::make_error<llvm::StringError>(
75*ec727ea7Spatrick           llvm::Twine("Failed to create '") + TEPlugin.getName() +
76e5dd7070Spatrick               "': " + llvm::toString(Executor.takeError()) + "\n",
77e5dd7070Spatrick           llvm::inconvertibleErrorCode());
78e5dd7070Spatrick     }
79e5dd7070Spatrick     return std::move(*Executor);
80e5dd7070Spatrick   }
81e5dd7070Spatrick   return llvm::make_error<llvm::StringError>(
82e5dd7070Spatrick       llvm::Twine("Executor \"") + ExecutorName + "\" is not registered.",
83e5dd7070Spatrick       llvm::inconvertibleErrorCode());
84e5dd7070Spatrick }
85e5dd7070Spatrick } // end namespace internal
86e5dd7070Spatrick 
87e5dd7070Spatrick llvm::Expected<std::unique_ptr<ToolExecutor>>
createExecutorFromCommandLineArgs(int & argc,const char ** argv,llvm::cl::OptionCategory & Category,const char * Overview)88e5dd7070Spatrick createExecutorFromCommandLineArgs(int &argc, const char **argv,
89e5dd7070Spatrick                                   llvm::cl::OptionCategory &Category,
90e5dd7070Spatrick                                   const char *Overview) {
91e5dd7070Spatrick   return internal::createExecutorFromCommandLineArgsImpl(argc, argv, Category,
92e5dd7070Spatrick                                                          Overview);
93e5dd7070Spatrick }
94e5dd7070Spatrick 
95e5dd7070Spatrick // This anchor is used to force the linker to link in the generated object file
96e5dd7070Spatrick // and thus register the StandaloneToolExecutorPlugin etc.
97e5dd7070Spatrick extern volatile int StandaloneToolExecutorAnchorSource;
98e5dd7070Spatrick extern volatile int AllTUsToolExecutorAnchorSource;
99e5dd7070Spatrick static int LLVM_ATTRIBUTE_UNUSED StandaloneToolExecutorAnchorDest =
100e5dd7070Spatrick     StandaloneToolExecutorAnchorSource;
101e5dd7070Spatrick static int LLVM_ATTRIBUTE_UNUSED AllTUsToolExecutorAnchorDest =
102e5dd7070Spatrick     AllTUsToolExecutorAnchorSource;
103e5dd7070Spatrick 
104e5dd7070Spatrick } // end namespace tooling
105e5dd7070Spatrick } // end namespace clang
106