xref: /freebsd-src/contrib/llvm-project/clang/lib/Tooling/Execution.cpp (revision e25152834cdf3b353892835a4f3b157e066a8ed4)
10b57cec5SDimitry Andric //===- lib/Tooling/Execution.cpp - Implements tool execution framework. ---===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "clang/Tooling/Execution.h"
100b57cec5SDimitry Andric #include "clang/Tooling/ToolExecutorPluginRegistry.h"
110b57cec5SDimitry Andric #include "clang/Tooling/Tooling.h"
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric LLVM_INSTANTIATE_REGISTRY(clang::tooling::ToolExecutorPluginRegistry)
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric namespace clang {
160b57cec5SDimitry Andric namespace tooling {
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric llvm::cl::opt<std::string>
190b57cec5SDimitry Andric     ExecutorName("executor", llvm::cl::desc("The name of the executor to use."),
200b57cec5SDimitry Andric                  llvm::cl::init("standalone"));
210b57cec5SDimitry Andric 
addResult(StringRef Key,StringRef Value)220b57cec5SDimitry Andric void InMemoryToolResults::addResult(StringRef Key, StringRef Value) {
230b57cec5SDimitry Andric   KVResults.push_back({Strings.save(Key), Strings.save(Value)});
240b57cec5SDimitry Andric }
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric std::vector<std::pair<llvm::StringRef, llvm::StringRef>>
AllKVResults()270b57cec5SDimitry Andric InMemoryToolResults::AllKVResults() {
280b57cec5SDimitry Andric   return KVResults;
290b57cec5SDimitry Andric }
300b57cec5SDimitry Andric 
forEachResult(llvm::function_ref<void (StringRef Key,StringRef Value)> Callback)310b57cec5SDimitry Andric void InMemoryToolResults::forEachResult(
320b57cec5SDimitry Andric     llvm::function_ref<void(StringRef Key, StringRef Value)> Callback) {
330b57cec5SDimitry Andric   for (const auto &KV : KVResults) {
340b57cec5SDimitry Andric     Callback(KV.first, KV.second);
350b57cec5SDimitry Andric   }
360b57cec5SDimitry Andric }
370b57cec5SDimitry Andric 
reportResult(StringRef Key,StringRef Value)380b57cec5SDimitry Andric void ExecutionContext::reportResult(StringRef Key, StringRef Value) {
390b57cec5SDimitry Andric   Results->addResult(Key, Value);
400b57cec5SDimitry Andric }
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric llvm::Error
execute(std::unique_ptr<FrontendActionFactory> Action)430b57cec5SDimitry Andric ToolExecutor::execute(std::unique_ptr<FrontendActionFactory> Action) {
440b57cec5SDimitry Andric   return execute(std::move(Action), ArgumentsAdjuster());
450b57cec5SDimitry Andric }
460b57cec5SDimitry Andric 
execute(std::unique_ptr<FrontendActionFactory> Action,ArgumentsAdjuster Adjuster)470b57cec5SDimitry Andric llvm::Error ToolExecutor::execute(std::unique_ptr<FrontendActionFactory> Action,
480b57cec5SDimitry Andric                                   ArgumentsAdjuster Adjuster) {
490b57cec5SDimitry Andric   std::vector<
500b57cec5SDimitry Andric       std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
510b57cec5SDimitry Andric       Actions;
520b57cec5SDimitry Andric   Actions.emplace_back(std::move(Action), std::move(Adjuster));
530b57cec5SDimitry Andric   return execute(Actions);
540b57cec5SDimitry Andric }
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric namespace internal {
570b57cec5SDimitry Andric llvm::Expected<std::unique_ptr<ToolExecutor>>
createExecutorFromCommandLineArgsImpl(int & argc,const char ** argv,llvm::cl::OptionCategory & Category,const char * Overview)580b57cec5SDimitry Andric createExecutorFromCommandLineArgsImpl(int &argc, const char **argv,
590b57cec5SDimitry Andric                                       llvm::cl::OptionCategory &Category,
600b57cec5SDimitry Andric                                       const char *Overview) {
610b57cec5SDimitry Andric   auto OptionsParser =
620b57cec5SDimitry Andric       CommonOptionsParser::create(argc, argv, Category, llvm::cl::ZeroOrMore,
630b57cec5SDimitry Andric                                   /*Overview=*/Overview);
640b57cec5SDimitry Andric   if (!OptionsParser)
650b57cec5SDimitry Andric     return OptionsParser.takeError();
66*5ffd83dbSDimitry Andric   for (const auto &TEPlugin : ToolExecutorPluginRegistry::entries()) {
67*5ffd83dbSDimitry Andric     if (TEPlugin.getName() != ExecutorName) {
680b57cec5SDimitry Andric       continue;
690b57cec5SDimitry Andric     }
70*5ffd83dbSDimitry Andric     std::unique_ptr<ToolExecutorPlugin> Plugin(TEPlugin.instantiate());
710b57cec5SDimitry Andric     llvm::Expected<std::unique_ptr<ToolExecutor>> Executor =
720b57cec5SDimitry Andric         Plugin->create(*OptionsParser);
730b57cec5SDimitry Andric     if (!Executor) {
740b57cec5SDimitry Andric       return llvm::make_error<llvm::StringError>(
75*5ffd83dbSDimitry Andric           llvm::Twine("Failed to create '") + TEPlugin.getName() +
760b57cec5SDimitry Andric               "': " + llvm::toString(Executor.takeError()) + "\n",
770b57cec5SDimitry Andric           llvm::inconvertibleErrorCode());
780b57cec5SDimitry Andric     }
790b57cec5SDimitry Andric     return std::move(*Executor);
800b57cec5SDimitry Andric   }
810b57cec5SDimitry Andric   return llvm::make_error<llvm::StringError>(
820b57cec5SDimitry Andric       llvm::Twine("Executor \"") + ExecutorName + "\" is not registered.",
830b57cec5SDimitry Andric       llvm::inconvertibleErrorCode());
840b57cec5SDimitry Andric }
850b57cec5SDimitry Andric } // end namespace internal
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric llvm::Expected<std::unique_ptr<ToolExecutor>>
createExecutorFromCommandLineArgs(int & argc,const char ** argv,llvm::cl::OptionCategory & Category,const char * Overview)880b57cec5SDimitry Andric createExecutorFromCommandLineArgs(int &argc, const char **argv,
890b57cec5SDimitry Andric                                   llvm::cl::OptionCategory &Category,
900b57cec5SDimitry Andric                                   const char *Overview) {
910b57cec5SDimitry Andric   return internal::createExecutorFromCommandLineArgsImpl(argc, argv, Category,
920b57cec5SDimitry Andric                                                          Overview);
930b57cec5SDimitry Andric }
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric // This anchor is used to force the linker to link in the generated object file
960b57cec5SDimitry Andric // and thus register the StandaloneToolExecutorPlugin etc.
970b57cec5SDimitry Andric extern volatile int StandaloneToolExecutorAnchorSource;
980b57cec5SDimitry Andric extern volatile int AllTUsToolExecutorAnchorSource;
990b57cec5SDimitry Andric static int LLVM_ATTRIBUTE_UNUSED StandaloneToolExecutorAnchorDest =
1000b57cec5SDimitry Andric     StandaloneToolExecutorAnchorSource;
1010b57cec5SDimitry Andric static int LLVM_ATTRIBUTE_UNUSED AllTUsToolExecutorAnchorDest =
1020b57cec5SDimitry Andric     AllTUsToolExecutorAnchorSource;
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric } // end namespace tooling
1050b57cec5SDimitry Andric } // end namespace clang
106