1*e5dd7070Spatrick //===--- Execution.h - Executing clang frontend actions -*- C++ ---------*-===// 2*e5dd7070Spatrick // 3*e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information. 5*e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*e5dd7070Spatrick // 7*e5dd7070Spatrick //===----------------------------------------------------------------------===// 8*e5dd7070Spatrick // 9*e5dd7070Spatrick // This file defines framework for executing clang frontend actions. 10*e5dd7070Spatrick // 11*e5dd7070Spatrick // The framework can be extended to support different execution plans including 12*e5dd7070Spatrick // standalone execution on the given TUs or parallel execution on all TUs in 13*e5dd7070Spatrick // the codebase. 14*e5dd7070Spatrick // 15*e5dd7070Spatrick // In order to enable multiprocessing execution, tool actions are expected to 16*e5dd7070Spatrick // output result into the ToolResults provided by the executor. The 17*e5dd7070Spatrick // `ToolResults` is an interface that abstracts how results are stored e.g. 18*e5dd7070Spatrick // in-memory for standalone execution or on-disk for large-scale execution. 19*e5dd7070Spatrick // 20*e5dd7070Spatrick // New executors can be registered as ToolExecutorPlugins via the 21*e5dd7070Spatrick // `ToolExecutorPluginRegistry`. CLI tools can use 22*e5dd7070Spatrick // `createExecutorFromCommandLineArgs` to create a specific registered executor 23*e5dd7070Spatrick // according to the command-line arguments. 24*e5dd7070Spatrick // 25*e5dd7070Spatrick //===----------------------------------------------------------------------===// 26*e5dd7070Spatrick 27*e5dd7070Spatrick #ifndef LLVM_CLANG_TOOLING_EXECUTION_H 28*e5dd7070Spatrick #define LLVM_CLANG_TOOLING_EXECUTION_H 29*e5dd7070Spatrick 30*e5dd7070Spatrick #include "clang/Tooling/CommonOptionsParser.h" 31*e5dd7070Spatrick #include "clang/Tooling/Tooling.h" 32*e5dd7070Spatrick #include "llvm/Support/Error.h" 33*e5dd7070Spatrick #include "llvm/Support/Registry.h" 34*e5dd7070Spatrick #include "llvm/Support/StringSaver.h" 35*e5dd7070Spatrick 36*e5dd7070Spatrick namespace clang { 37*e5dd7070Spatrick namespace tooling { 38*e5dd7070Spatrick 39*e5dd7070Spatrick extern llvm::cl::opt<std::string> ExecutorName; 40*e5dd7070Spatrick 41*e5dd7070Spatrick /// An abstraction for the result of a tool execution. For example, the 42*e5dd7070Spatrick /// underlying result can be in-memory or on-disk. 43*e5dd7070Spatrick /// 44*e5dd7070Spatrick /// Results should be string key-value pairs. For example, a refactoring tool 45*e5dd7070Spatrick /// can use source location as key and a replacement in YAML format as value. 46*e5dd7070Spatrick class ToolResults { 47*e5dd7070Spatrick public: 48*e5dd7070Spatrick virtual ~ToolResults() = default; 49*e5dd7070Spatrick virtual void addResult(StringRef Key, StringRef Value) = 0; 50*e5dd7070Spatrick virtual std::vector<std::pair<llvm::StringRef, llvm::StringRef>> 51*e5dd7070Spatrick AllKVResults() = 0; 52*e5dd7070Spatrick virtual void forEachResult( 53*e5dd7070Spatrick llvm::function_ref<void(StringRef Key, StringRef Value)> Callback) = 0; 54*e5dd7070Spatrick }; 55*e5dd7070Spatrick 56*e5dd7070Spatrick /// Stores the key-value results in memory. It maintains the lifetime of 57*e5dd7070Spatrick /// the result. Clang tools using this class are expected to generate a small 58*e5dd7070Spatrick /// set of different results, or a large set of duplicated results. 59*e5dd7070Spatrick class InMemoryToolResults : public ToolResults { 60*e5dd7070Spatrick public: InMemoryToolResults()61*e5dd7070Spatrick InMemoryToolResults() : Strings(Arena) {} 62*e5dd7070Spatrick void addResult(StringRef Key, StringRef Value) override; 63*e5dd7070Spatrick std::vector<std::pair<llvm::StringRef, llvm::StringRef>> 64*e5dd7070Spatrick AllKVResults() override; 65*e5dd7070Spatrick void forEachResult(llvm::function_ref<void(StringRef Key, StringRef Value)> 66*e5dd7070Spatrick Callback) override; 67*e5dd7070Spatrick 68*e5dd7070Spatrick private: 69*e5dd7070Spatrick llvm::BumpPtrAllocator Arena; 70*e5dd7070Spatrick llvm::UniqueStringSaver Strings; 71*e5dd7070Spatrick 72*e5dd7070Spatrick std::vector<std::pair<llvm::StringRef, llvm::StringRef>> KVResults; 73*e5dd7070Spatrick }; 74*e5dd7070Spatrick 75*e5dd7070Spatrick /// The context of an execution, including the information about 76*e5dd7070Spatrick /// compilation and results. 77*e5dd7070Spatrick class ExecutionContext { 78*e5dd7070Spatrick public: ~ExecutionContext()79*e5dd7070Spatrick virtual ~ExecutionContext() {} 80*e5dd7070Spatrick 81*e5dd7070Spatrick /// Initializes a context. This does not take ownership of `Results`. ExecutionContext(ToolResults * Results)82*e5dd7070Spatrick explicit ExecutionContext(ToolResults *Results) : Results(Results) {} 83*e5dd7070Spatrick 84*e5dd7070Spatrick /// Adds a KV pair to the result container of this execution. 85*e5dd7070Spatrick void reportResult(StringRef Key, StringRef Value); 86*e5dd7070Spatrick 87*e5dd7070Spatrick // Returns the source control system's revision number if applicable. 88*e5dd7070Spatrick // Otherwise returns an empty string. getRevision()89*e5dd7070Spatrick virtual std::string getRevision() { return ""; } 90*e5dd7070Spatrick 91*e5dd7070Spatrick // Returns the corpus being analyzed, e.g. "llvm" for the LLVM codebase, if 92*e5dd7070Spatrick // applicable. getCorpus()93*e5dd7070Spatrick virtual std::string getCorpus() { return ""; } 94*e5dd7070Spatrick 95*e5dd7070Spatrick // Returns the currently processed compilation unit if available. getCurrentCompilationUnit()96*e5dd7070Spatrick virtual std::string getCurrentCompilationUnit() { return ""; } 97*e5dd7070Spatrick 98*e5dd7070Spatrick private: 99*e5dd7070Spatrick ToolResults *Results; 100*e5dd7070Spatrick }; 101*e5dd7070Spatrick 102*e5dd7070Spatrick /// Interface for executing clang frontend actions. 103*e5dd7070Spatrick /// 104*e5dd7070Spatrick /// This can be extended to support running tool actions in different 105*e5dd7070Spatrick /// execution mode, e.g. on a specific set of TUs or many TUs in parallel. 106*e5dd7070Spatrick /// 107*e5dd7070Spatrick /// New executors can be registered as ToolExecutorPlugins via the 108*e5dd7070Spatrick /// `ToolExecutorPluginRegistry`. CLI tools can use 109*e5dd7070Spatrick /// `createExecutorFromCommandLineArgs` to create a specific registered 110*e5dd7070Spatrick /// executor according to the command-line arguments. 111*e5dd7070Spatrick class ToolExecutor { 112*e5dd7070Spatrick public: ~ToolExecutor()113*e5dd7070Spatrick virtual ~ToolExecutor() {} 114*e5dd7070Spatrick 115*e5dd7070Spatrick /// Returns the name of a specific executor. 116*e5dd7070Spatrick virtual StringRef getExecutorName() const = 0; 117*e5dd7070Spatrick 118*e5dd7070Spatrick /// Executes each action with a corresponding arguments adjuster. 119*e5dd7070Spatrick virtual llvm::Error 120*e5dd7070Spatrick execute(llvm::ArrayRef< 121*e5dd7070Spatrick std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>> 122*e5dd7070Spatrick Actions) = 0; 123*e5dd7070Spatrick 124*e5dd7070Spatrick /// Convenient functions for the above `execute`. 125*e5dd7070Spatrick llvm::Error execute(std::unique_ptr<FrontendActionFactory> Action); 126*e5dd7070Spatrick /// Executes an action with an argument adjuster. 127*e5dd7070Spatrick llvm::Error execute(std::unique_ptr<FrontendActionFactory> Action, 128*e5dd7070Spatrick ArgumentsAdjuster Adjuster); 129*e5dd7070Spatrick 130*e5dd7070Spatrick /// Returns a reference to the execution context. 131*e5dd7070Spatrick /// 132*e5dd7070Spatrick /// This should be passed to tool callbacks, and tool callbacks should report 133*e5dd7070Spatrick /// results via the returned context. 134*e5dd7070Spatrick virtual ExecutionContext *getExecutionContext() = 0; 135*e5dd7070Spatrick 136*e5dd7070Spatrick /// Returns a reference to the result container. 137*e5dd7070Spatrick /// 138*e5dd7070Spatrick /// NOTE: This should only be used after the execution finishes. Tool 139*e5dd7070Spatrick /// callbacks should report results via `ExecutionContext` instead. 140*e5dd7070Spatrick virtual ToolResults *getToolResults() = 0; 141*e5dd7070Spatrick 142*e5dd7070Spatrick /// Map a virtual file to be used while running the tool. 143*e5dd7070Spatrick /// 144*e5dd7070Spatrick /// \param FilePath The path at which the content will be mapped. 145*e5dd7070Spatrick /// \param Content A buffer of the file's content. 146*e5dd7070Spatrick virtual void mapVirtualFile(StringRef FilePath, StringRef Content) = 0; 147*e5dd7070Spatrick }; 148*e5dd7070Spatrick 149*e5dd7070Spatrick /// Interface for factories that create specific executors. This is also 150*e5dd7070Spatrick /// used as a plugin to be registered into ToolExecutorPluginRegistry. 151*e5dd7070Spatrick class ToolExecutorPlugin { 152*e5dd7070Spatrick public: ~ToolExecutorPlugin()153*e5dd7070Spatrick virtual ~ToolExecutorPlugin() {} 154*e5dd7070Spatrick 155*e5dd7070Spatrick /// Create an `ToolExecutor`. 156*e5dd7070Spatrick /// 157*e5dd7070Spatrick /// `OptionsParser` can be consumed (e.g. moved) if the creation succeeds. 158*e5dd7070Spatrick virtual llvm::Expected<std::unique_ptr<ToolExecutor>> 159*e5dd7070Spatrick create(CommonOptionsParser &OptionsParser) = 0; 160*e5dd7070Spatrick }; 161*e5dd7070Spatrick 162*e5dd7070Spatrick /// This creates a ToolExecutor that is in the global registry based on 163*e5dd7070Spatrick /// commandline arguments. 164*e5dd7070Spatrick /// 165*e5dd7070Spatrick /// This picks the right executor based on the `--executor` option. This parses 166*e5dd7070Spatrick /// the commandline arguments with `CommonOptionsParser`, so caller does not 167*e5dd7070Spatrick /// need to parse again. 168*e5dd7070Spatrick /// 169*e5dd7070Spatrick /// By default, this creates a `StandaloneToolExecutor` ("standalone") if 170*e5dd7070Spatrick /// `--executor` is not provided. 171*e5dd7070Spatrick llvm::Expected<std::unique_ptr<ToolExecutor>> 172*e5dd7070Spatrick createExecutorFromCommandLineArgs(int &argc, const char **argv, 173*e5dd7070Spatrick llvm::cl::OptionCategory &Category, 174*e5dd7070Spatrick const char *Overview = nullptr); 175*e5dd7070Spatrick 176*e5dd7070Spatrick namespace internal { 177*e5dd7070Spatrick llvm::Expected<std::unique_ptr<ToolExecutor>> 178*e5dd7070Spatrick createExecutorFromCommandLineArgsImpl(int &argc, const char **argv, 179*e5dd7070Spatrick llvm::cl::OptionCategory &Category, 180*e5dd7070Spatrick const char *Overview = nullptr); 181*e5dd7070Spatrick } // end namespace internal 182*e5dd7070Spatrick 183*e5dd7070Spatrick } // end namespace tooling 184*e5dd7070Spatrick } // end namespace clang 185*e5dd7070Spatrick 186*e5dd7070Spatrick #endif // LLVM_CLANG_TOOLING_EXECUTION_H 187