93 lines · cpp
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-exception6//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 default38 // 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 file88// and thus register the plugin.89volatile int StandaloneToolExecutorAnchorSource = 0;90 91} // end namespace tooling92} // end namespace clang93