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