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