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 12 namespace clang { 13 namespace tooling { 14 15 static llvm::Error make_string_error(const llvm::Twine &Message) { 16 return llvm::make_error<llvm::StringError>(Message, 17 llvm::inconvertibleErrorCode()); 18 } 19 20 const char *StandaloneToolExecutor::ExecutorName = "StandaloneToolExecutor"; 21 22 static ArgumentsAdjuster getDefaultArgumentsAdjusters() { 23 return combineAdjusters( 24 getClangStripOutputAdjuster(), 25 combineAdjusters(getClangSyntaxOnlyAdjuster(), 26 getClangStripDependencyFileAdjuster())); 27 } 28 29 StandaloneToolExecutor::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 42 StandaloneToolExecutor::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 52 llvm::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 72 class StandaloneToolExecutorPlugin : public ToolExecutorPlugin { 73 public: 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 83 static 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. 89 volatile int StandaloneToolExecutorAnchorSource = 0; 90 91 } // end namespace tooling 92 } // end namespace clang 93