reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
//===- lib/Tooling/Execution.cpp - Implements tool execution framework. ---===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "clang/Tooling/Execution.h"
#include "clang/Tooling/ToolExecutorPluginRegistry.h"
#include "clang/Tooling/Tooling.h"

LLVM_INSTANTIATE_REGISTRY(clang::tooling::ToolExecutorPluginRegistry)

namespace clang {
namespace tooling {

llvm::cl::opt<std::string>
    ExecutorName("executor", llvm::cl::desc("The name of the executor to use."),
                 llvm::cl::init("standalone"));

void InMemoryToolResults::addResult(StringRef Key, StringRef Value) {
  KVResults.push_back({Strings.save(Key), Strings.save(Value)});
}

std::vector<std::pair<llvm::StringRef, llvm::StringRef>>
InMemoryToolResults::AllKVResults() {
  return KVResults;
}

void InMemoryToolResults::forEachResult(
    llvm::function_ref<void(StringRef Key, StringRef Value)> Callback) {
  for (const auto &KV : KVResults) {
    Callback(KV.first, KV.second);
  }
}

void ExecutionContext::reportResult(StringRef Key, StringRef Value) {
  Results->addResult(Key, Value);
}

llvm::Error
ToolExecutor::execute(std::unique_ptr<FrontendActionFactory> Action) {
  return execute(std::move(Action), ArgumentsAdjuster());
}

llvm::Error ToolExecutor::execute(std::unique_ptr<FrontendActionFactory> Action,
                                  ArgumentsAdjuster Adjuster) {
  std::vector<
      std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
      Actions;
  Actions.emplace_back(std::move(Action), std::move(Adjuster));
  return execute(Actions);
}

namespace internal {
llvm::Expected<std::unique_ptr<ToolExecutor>>
createExecutorFromCommandLineArgsImpl(int &argc, const char **argv,
                                      llvm::cl::OptionCategory &Category,
                                      const char *Overview) {
  auto OptionsParser =
      CommonOptionsParser::create(argc, argv, Category, llvm::cl::ZeroOrMore,
                                  /*Overview=*/Overview);
  if (!OptionsParser)
    return OptionsParser.takeError();
  for (auto I = ToolExecutorPluginRegistry::begin(),
            E = ToolExecutorPluginRegistry::end();
       I != E; ++I) {
    if (I->getName() != ExecutorName) {
      continue;
    }
    std::unique_ptr<ToolExecutorPlugin> Plugin(I->instantiate());
    llvm::Expected<std::unique_ptr<ToolExecutor>> Executor =
        Plugin->create(*OptionsParser);
    if (!Executor) {
      return llvm::make_error<llvm::StringError>(
          llvm::Twine("Failed to create '") + I->getName() +
              "': " + llvm::toString(Executor.takeError()) + "\n",
          llvm::inconvertibleErrorCode());
    }
    return std::move(*Executor);
  }
  return llvm::make_error<llvm::StringError>(
      llvm::Twine("Executor \"") + ExecutorName + "\" is not registered.",
      llvm::inconvertibleErrorCode());
}
} // end namespace internal

llvm::Expected<std::unique_ptr<ToolExecutor>>
createExecutorFromCommandLineArgs(int &argc, const char **argv,
                                  llvm::cl::OptionCategory &Category,
                                  const char *Overview) {
  return internal::createExecutorFromCommandLineArgsImpl(argc, argv, Category,
                                                         Overview);
}

// This anchor is used to force the linker to link in the generated object file
// and thus register the StandaloneToolExecutorPlugin etc.
extern volatile int StandaloneToolExecutorAnchorSource;
extern volatile int AllTUsToolExecutorAnchorSource;
static int LLVM_ATTRIBUTE_UNUSED StandaloneToolExecutorAnchorDest =
    StandaloneToolExecutorAnchorSource;
static int LLVM_ATTRIBUTE_UNUSED AllTUsToolExecutorAnchorDest =
    AllTUsToolExecutorAnchorSource;

} // end namespace tooling
} // end namespace clang