Execution.h revision 344779
1262617Sdelphij//===--- Execution.h - Executing clang frontend actions -*- C++ ---------*-===// 2262685Sdelphij// 3262617Sdelphij// The LLVM Compiler Infrastructure 4262617Sdelphij// 5262617Sdelphij// This file is distributed under the University of Illinois Open Source 6262617Sdelphij// License. See LICENSE.TXT for details. 7262617Sdelphij// 8262617Sdelphij//===----------------------------------------------------------------------===// 9262617Sdelphij// 10262617Sdelphij// This file defines framework for executing clang frontend actions. 11262617Sdelphij// 12262617Sdelphij// The framework can be extended to support different execution plans including 13262617Sdelphij// standalone execution on the given TUs or parallel execution on all TUs in 14262617Sdelphij// the codebase. 15262617Sdelphij// 16262617Sdelphij// In order to enable multiprocessing execution, tool actions are expected to 17262617Sdelphij// output result into the ToolResults provided by the executor. The 18262617Sdelphij// `ToolResults` is an interface that abstracts how results are stored e.g. 19262617Sdelphij// in-memory for standalone execution or on-disk for large-scale execution. 20262617Sdelphij// 21262617Sdelphij// New executors can be registered as ToolExecutorPlugins via the 22262617Sdelphij// `ToolExecutorPluginRegistry`. CLI tools can use 23262617Sdelphij// `createExecutorFromCommandLineArgs` to create a specific registered executor 24262617Sdelphij// according to the command-line arguments. 25262617Sdelphij// 26262617Sdelphij//===----------------------------------------------------------------------===// 27262617Sdelphij 28262617Sdelphij#ifndef LLVM_CLANG_TOOLING_EXECUTION_H 29262617Sdelphij#define LLVM_CLANG_TOOLING_EXECUTION_H 30262617Sdelphij 31262617Sdelphij#include "clang/Tooling/CommonOptionsParser.h" 32262617Sdelphij#include "clang/Tooling/Tooling.h" 33262617Sdelphij#include "llvm/Support/Error.h" 34262685Sdelphij#include "llvm/Support/Registry.h" 35262617Sdelphij#include "llvm/Support/StringSaver.h" 36262617Sdelphij 37262685Sdelphijnamespace clang { 38262617Sdelphijnamespace tooling { 39262617Sdelphij 40262617Sdelphijextern llvm::cl::opt<std::string> ExecutorName; 41262617Sdelphij 42262617Sdelphij/// An abstraction for the result of a tool execution. For example, the 43262617Sdelphij/// underlying result can be in-memory or on-disk. 44262617Sdelphij/// 45262617Sdelphij/// Results should be string key-value pairs. For example, a refactoring tool 46262617Sdelphij/// can use source location as key and a replacement in YAML format as value. 47262617Sdelphijclass ToolResults { 48262617Sdelphijpublic: 49262617Sdelphij virtual ~ToolResults() = default; 50262617Sdelphij virtual void addResult(StringRef Key, StringRef Value) = 0; 51262617Sdelphij virtual std::vector<std::pair<llvm::StringRef, llvm::StringRef>> 52262617Sdelphij AllKVResults() = 0; 53262617Sdelphij virtual void forEachResult( 54262617Sdelphij llvm::function_ref<void(StringRef Key, StringRef Value)> Callback) = 0; 55262617Sdelphij}; 56262617Sdelphij 57262617Sdelphij/// Stores the key-value results in memory. It maintains the lifetime of 58262617Sdelphij/// the result. Clang tools using this class are expected to generate a small 59262617Sdelphij/// set of different results, or a large set of duplicated results. 60262617Sdelphijclass InMemoryToolResults : public ToolResults { 61262617Sdelphijpublic: 62262617Sdelphij InMemoryToolResults() : Strings(Arena) {} 63262617Sdelphij void addResult(StringRef Key, StringRef Value) override; 64262617Sdelphij std::vector<std::pair<llvm::StringRef, llvm::StringRef>> 65262617Sdelphij AllKVResults() override; 66262617Sdelphij void forEachResult(llvm::function_ref<void(StringRef Key, StringRef Value)> 67262617Sdelphij Callback) override; 68262617Sdelphij 69262617Sdelphijprivate: 70262617Sdelphij llvm::BumpPtrAllocator Arena; 71262617Sdelphij llvm::UniqueStringSaver Strings; 72262617Sdelphij 73262685Sdelphij std::vector<std::pair<llvm::StringRef, llvm::StringRef>> KVResults; 74262685Sdelphij}; 75 76/// The context of an execution, including the information about 77/// compilation and results. 78class ExecutionContext { 79public: 80 virtual ~ExecutionContext() {} 81 82 /// Initializes a context. This does not take ownership of `Results`. 83 explicit ExecutionContext(ToolResults *Results) : Results(Results) {} 84 85 /// Adds a KV pair to the result container of this execution. 86 void reportResult(StringRef Key, StringRef Value); 87 88 // Returns the source control system's revision number if applicable. 89 // Otherwise returns an empty string. 90 virtual std::string getRevision() { return ""; } 91 92 // Returns the corpus being analyzed, e.g. "llvm" for the LLVM codebase, if 93 // applicable. 94 virtual std::string getCorpus() { return ""; } 95 96 // Returns the currently processed compilation unit if available. 97 virtual std::string getCurrentCompilationUnit() { return ""; } 98 99private: 100 ToolResults *Results; 101}; 102 103/// Interface for executing clang frontend actions. 104/// 105/// This can be extended to support running tool actions in different 106/// execution mode, e.g. on a specific set of TUs or many TUs in parallel. 107/// 108/// New executors can be registered as ToolExecutorPlugins via the 109/// `ToolExecutorPluginRegistry`. CLI tools can use 110/// `createExecutorFromCommandLineArgs` to create a specific registered 111/// executor according to the command-line arguments. 112class ToolExecutor { 113public: 114 virtual ~ToolExecutor() {} 115 116 /// Returns the name of a specific executor. 117 virtual StringRef getExecutorName() const = 0; 118 119 /// Should return true iff executor runs all actions in a single process. 120 /// Clients can use this signal to find out if they can collect results 121 /// in-memory (e.g. to avoid serialization costs of using ToolResults). 122 /// The single-process executors can still run multiple threads, but all 123 /// executions are guaranteed to share the same memory. 124 virtual bool isSingleProcess() const = 0; 125 126 /// Executes each action with a corresponding arguments adjuster. 127 virtual llvm::Error 128 execute(llvm::ArrayRef< 129 std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>> 130 Actions) = 0; 131 132 /// Convenient functions for the above `execute`. 133 llvm::Error execute(std::unique_ptr<FrontendActionFactory> Action); 134 /// Executes an action with an argument adjuster. 135 llvm::Error execute(std::unique_ptr<FrontendActionFactory> Action, 136 ArgumentsAdjuster Adjuster); 137 138 /// Returns a reference to the execution context. 139 /// 140 /// This should be passed to tool callbacks, and tool callbacks should report 141 /// results via the returned context. 142 virtual ExecutionContext *getExecutionContext() = 0; 143 144 /// Returns a reference to the result container. 145 /// 146 /// NOTE: This should only be used after the execution finishes. Tool 147 /// callbacks should report results via `ExecutionContext` instead. 148 virtual ToolResults *getToolResults() = 0; 149 150 /// Map a virtual file to be used while running the tool. 151 /// 152 /// \param FilePath The path at which the content will be mapped. 153 /// \param Content A buffer of the file's content. 154 virtual void mapVirtualFile(StringRef FilePath, StringRef Content) = 0; 155}; 156 157/// Interface for factories that create specific executors. This is also 158/// used as a plugin to be registered into ToolExecutorPluginRegistry. 159class ToolExecutorPlugin { 160public: 161 virtual ~ToolExecutorPlugin() {} 162 163 /// Create an `ToolExecutor`. 164 /// 165 /// `OptionsParser` can be consumed (e.g. moved) if the creation succeeds. 166 virtual llvm::Expected<std::unique_ptr<ToolExecutor>> 167 create(CommonOptionsParser &OptionsParser) = 0; 168}; 169 170/// This creates a ToolExecutor that is in the global registry based on 171/// commandline arguments. 172/// 173/// This picks the right executor based on the `--executor` option. This parses 174/// the commandline arguments with `CommonOptionsParser`, so caller does not 175/// need to parse again. 176/// 177/// By default, this creates a `StandaloneToolExecutor` ("standalone") if 178/// `--executor` is not provided. 179llvm::Expected<std::unique_ptr<ToolExecutor>> 180createExecutorFromCommandLineArgs(int &argc, const char **argv, 181 llvm::cl::OptionCategory &Category, 182 const char *Overview = nullptr); 183 184namespace internal { 185llvm::Expected<std::unique_ptr<ToolExecutor>> 186createExecutorFromCommandLineArgsImpl(int &argc, const char **argv, 187 llvm::cl::OptionCategory &Category, 188 const char *Overview = nullptr); 189} // end namespace internal 190 191} // end namespace tooling 192} // end namespace clang 193 194#endif // LLVM_CLANG_TOOLING_EXECUTION_H 195