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