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 |