StandaloneExecution.cpp revision 360784
1//===- lib/Tooling/Execution.cpp - Standalone clang action execution. -----===//
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/StandaloneExecution.h"
10#include "clang/Tooling/ToolExecutorPluginRegistry.h"
11
12namespace clang {
13namespace tooling {
14
15static llvm::Error make_string_error(const llvm::Twine &Message) {
16  return llvm::make_error<llvm::StringError>(Message,
17                                             llvm::inconvertibleErrorCode());
18}
19
20const char *StandaloneToolExecutor::ExecutorName = "StandaloneToolExecutor";
21
22static ArgumentsAdjuster getDefaultArgumentsAdjusters() {
23  return combineAdjusters(
24      getClangStripOutputAdjuster(),
25      combineAdjusters(getClangSyntaxOnlyAdjuster(),
26                       getClangStripDependencyFileAdjuster()));
27}
28
29StandaloneToolExecutor::StandaloneToolExecutor(
30    const CompilationDatabase &Compilations,
31    llvm::ArrayRef<std::string> SourcePaths,
32    IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
33    std::shared_ptr<PCHContainerOperations> PCHContainerOps)
34    : Tool(Compilations, SourcePaths, std::move(PCHContainerOps),
35           std::move(BaseFS)),
36      Context(&Results), ArgsAdjuster(getDefaultArgumentsAdjusters()) {
37  // Use self-defined default argument adjusters instead of the default
38  // adjusters that come with the old `ClangTool`.
39  Tool.clearArgumentsAdjusters();
40}
41
42StandaloneToolExecutor::StandaloneToolExecutor(
43    CommonOptionsParser Options,
44    std::shared_ptr<PCHContainerOperations> PCHContainerOps)
45    : OptionsParser(std::move(Options)),
46      Tool(OptionsParser->getCompilations(), OptionsParser->getSourcePathList(),
47           std::move(PCHContainerOps)),
48      Context(&Results), ArgsAdjuster(getDefaultArgumentsAdjusters()) {
49  Tool.clearArgumentsAdjusters();
50}
51
52llvm::Error StandaloneToolExecutor::execute(
53    llvm::ArrayRef<
54        std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
55        Actions) {
56  if (Actions.empty())
57    return make_string_error("No action to execute.");
58
59  if (Actions.size() != 1)
60    return make_string_error(
61        "Only support executing exactly 1 action at this point.");
62
63  auto &Action = Actions.front();
64  Tool.appendArgumentsAdjuster(Action.second);
65  Tool.appendArgumentsAdjuster(ArgsAdjuster);
66  if (Tool.run(Action.first.get()))
67    return make_string_error("Failed to run action.");
68
69  return llvm::Error::success();
70}
71
72class StandaloneToolExecutorPlugin : public ToolExecutorPlugin {
73public:
74  llvm::Expected<std::unique_ptr<ToolExecutor>>
75  create(CommonOptionsParser &OptionsParser) override {
76    if (OptionsParser.getSourcePathList().empty())
77      return make_string_error(
78          "[StandaloneToolExecutorPlugin] No positional argument found.");
79    return std::make_unique<StandaloneToolExecutor>(std::move(OptionsParser));
80  }
81};
82
83static ToolExecutorPluginRegistry::Add<StandaloneToolExecutorPlugin>
84    X("standalone", "Runs FrontendActions on a set of files provided "
85                    "via positional arguments.");
86
87// This anchor is used to force the linker to link in the generated object file
88// and thus register the plugin.
89volatile int StandaloneToolExecutorAnchorSource = 0;
90
91} // end namespace tooling
92} // end namespace clang
93