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