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 IntrusiveRefCntPtr<vfs::FileSystem> BaseFS, 34 std::shared_ptr<PCHContainerOperations> PCHContainerOps) 35 : Tool(Compilations, SourcePaths, std::move(PCHContainerOps), 36 std::move(BaseFS)), 37 Context(&Results), ArgsAdjuster(getDefaultArgumentsAdjusters()) { 38 // Use self-defined default argument adjusters instead of the default 39 // adjusters that come with the old `ClangTool`. 40 Tool.clearArgumentsAdjusters(); 41 } 42 43 StandaloneToolExecutor::StandaloneToolExecutor( 44 CommonOptionsParser Options, 45 std::shared_ptr<PCHContainerOperations> PCHContainerOps) 46 : OptionsParser(std::move(Options)), 47 Tool(OptionsParser->getCompilations(), OptionsParser->getSourcePathList(), 48 std::move(PCHContainerOps)), 49 Context(&Results), ArgsAdjuster(getDefaultArgumentsAdjusters()) { 50 Tool.clearArgumentsAdjusters(); 51 } 52 53 llvm::Error StandaloneToolExecutor::execute( 54 llvm::ArrayRef< 55 std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>> 56 Actions) { 57 if (Actions.empty()) 58 return make_string_error("No action to execute."); 59 60 if (Actions.size() != 1) 61 return make_string_error( 62 "Only support executing exactly 1 action at this point."); 63 64 auto &Action = Actions.front(); 65 Tool.appendArgumentsAdjuster(Action.second); 66 Tool.appendArgumentsAdjuster(ArgsAdjuster); 67 if (Tool.run(Action.first.get())) 68 return make_string_error("Failed to run action."); 69 70 return llvm::Error::success(); 71 } 72 73 class StandaloneToolExecutorPlugin : public ToolExecutorPlugin { 74 public: 75 llvm::Expected<std::unique_ptr<ToolExecutor>> 76 create(CommonOptionsParser &OptionsParser) override { 77 if (OptionsParser.getSourcePathList().empty()) 78 return make_string_error( 79 "[StandaloneToolExecutorPlugin] No positional argument found."); 80 return llvm::make_unique<StandaloneToolExecutor>(std::move(OptionsParser)); 81 } 82 }; 83 84 static ToolExecutorPluginRegistry::Add<StandaloneToolExecutorPlugin> 85 X("standalone", "Runs FrontendActions on a set of files provided " 86 "via positional arguments."); 87 88 // This anchor is used to force the linker to link in the generated object file 89 // and thus register the plugin. 90 volatile int StandaloneToolExecutorAnchorSource = 0; 91 92 } // end namespace tooling 93 } // end namespace clang 94