1326941Sdim//===--- Execution.h - Executing clang frontend actions -*- C++ ---------*-===// 2326941Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6326941Sdim// 7326941Sdim//===----------------------------------------------------------------------===// 8326941Sdim// 9326941Sdim// This file defines framework for executing clang frontend actions. 10326941Sdim// 11326941Sdim// The framework can be extended to support different execution plans including 12326941Sdim// standalone execution on the given TUs or parallel execution on all TUs in 13326941Sdim// the codebase. 14326941Sdim// 15326941Sdim// In order to enable multiprocessing execution, tool actions are expected to 16326941Sdim// output result into the ToolResults provided by the executor. The 17326941Sdim// `ToolResults` is an interface that abstracts how results are stored e.g. 18326941Sdim// in-memory for standalone execution or on-disk for large-scale execution. 19326941Sdim// 20326941Sdim// New executors can be registered as ToolExecutorPlugins via the 21326941Sdim// `ToolExecutorPluginRegistry`. CLI tools can use 22326941Sdim// `createExecutorFromCommandLineArgs` to create a specific registered executor 23326941Sdim// according to the command-line arguments. 24326941Sdim// 25326941Sdim//===----------------------------------------------------------------------===// 26326941Sdim 27326941Sdim#ifndef LLVM_CLANG_TOOLING_EXECUTION_H 28326941Sdim#define LLVM_CLANG_TOOLING_EXECUTION_H 29326941Sdim 30326941Sdim#include "clang/Tooling/CommonOptionsParser.h" 31326941Sdim#include "clang/Tooling/Tooling.h" 32326941Sdim#include "llvm/Support/Error.h" 33326941Sdim#include "llvm/Support/Registry.h" 34341825Sdim#include "llvm/Support/StringSaver.h" 35326941Sdim 36326941Sdimnamespace clang { 37326941Sdimnamespace tooling { 38326941Sdim 39344779Sdimextern llvm::cl::opt<std::string> ExecutorName; 40344779Sdim 41341825Sdim/// An abstraction for the result of a tool execution. For example, the 42326941Sdim/// underlying result can be in-memory or on-disk. 43326941Sdim/// 44326941Sdim/// Results should be string key-value pairs. For example, a refactoring tool 45326941Sdim/// can use source location as key and a replacement in YAML format as value. 46326941Sdimclass ToolResults { 47326941Sdimpublic: 48326941Sdim virtual ~ToolResults() = default; 49326941Sdim virtual void addResult(StringRef Key, StringRef Value) = 0; 50341825Sdim virtual std::vector<std::pair<llvm::StringRef, llvm::StringRef>> 51341825Sdim AllKVResults() = 0; 52326941Sdim virtual void forEachResult( 53326941Sdim llvm::function_ref<void(StringRef Key, StringRef Value)> Callback) = 0; 54326941Sdim}; 55326941Sdim 56341825Sdim/// Stores the key-value results in memory. It maintains the lifetime of 57341825Sdim/// the result. Clang tools using this class are expected to generate a small 58341825Sdim/// set of different results, or a large set of duplicated results. 59326941Sdimclass InMemoryToolResults : public ToolResults { 60326941Sdimpublic: 61341825Sdim InMemoryToolResults() : Strings(Arena) {} 62326941Sdim void addResult(StringRef Key, StringRef Value) override; 63341825Sdim std::vector<std::pair<llvm::StringRef, llvm::StringRef>> 64341825Sdim AllKVResults() override; 65326941Sdim void forEachResult(llvm::function_ref<void(StringRef Key, StringRef Value)> 66326941Sdim Callback) override; 67326941Sdim 68326941Sdimprivate: 69341825Sdim llvm::BumpPtrAllocator Arena; 70341825Sdim llvm::UniqueStringSaver Strings; 71341825Sdim 72341825Sdim std::vector<std::pair<llvm::StringRef, llvm::StringRef>> KVResults; 73326941Sdim}; 74326941Sdim 75341825Sdim/// The context of an execution, including the information about 76326941Sdim/// compilation and results. 77326941Sdimclass ExecutionContext { 78326941Sdimpublic: 79326941Sdim virtual ~ExecutionContext() {} 80326941Sdim 81341825Sdim /// Initializes a context. This does not take ownership of `Results`. 82326941Sdim explicit ExecutionContext(ToolResults *Results) : Results(Results) {} 83326941Sdim 84341825Sdim /// Adds a KV pair to the result container of this execution. 85326941Sdim void reportResult(StringRef Key, StringRef Value); 86326941Sdim 87326941Sdim // Returns the source control system's revision number if applicable. 88326941Sdim // Otherwise returns an empty string. 89326941Sdim virtual std::string getRevision() { return ""; } 90326941Sdim 91326941Sdim // Returns the corpus being analyzed, e.g. "llvm" for the LLVM codebase, if 92326941Sdim // applicable. 93326941Sdim virtual std::string getCorpus() { return ""; } 94326941Sdim 95326941Sdim // Returns the currently processed compilation unit if available. 96326941Sdim virtual std::string getCurrentCompilationUnit() { return ""; } 97326941Sdim 98326941Sdimprivate: 99326941Sdim ToolResults *Results; 100326941Sdim}; 101326941Sdim 102341825Sdim/// Interface for executing clang frontend actions. 103326941Sdim/// 104326941Sdim/// This can be extended to support running tool actions in different 105326941Sdim/// execution mode, e.g. on a specific set of TUs or many TUs in parallel. 106326941Sdim/// 107326941Sdim/// New executors can be registered as ToolExecutorPlugins via the 108326941Sdim/// `ToolExecutorPluginRegistry`. CLI tools can use 109326941Sdim/// `createExecutorFromCommandLineArgs` to create a specific registered 110326941Sdim/// executor according to the command-line arguments. 111326941Sdimclass ToolExecutor { 112326941Sdimpublic: 113326941Sdim virtual ~ToolExecutor() {} 114326941Sdim 115341825Sdim /// Returns the name of a specific executor. 116326941Sdim virtual StringRef getExecutorName() const = 0; 117326941Sdim 118341825Sdim /// Executes each action with a corresponding arguments adjuster. 119326941Sdim virtual llvm::Error 120326941Sdim execute(llvm::ArrayRef< 121326941Sdim std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>> 122326941Sdim Actions) = 0; 123326941Sdim 124341825Sdim /// Convenient functions for the above `execute`. 125326941Sdim llvm::Error execute(std::unique_ptr<FrontendActionFactory> Action); 126326941Sdim /// Executes an action with an argument adjuster. 127326941Sdim llvm::Error execute(std::unique_ptr<FrontendActionFactory> Action, 128326941Sdim ArgumentsAdjuster Adjuster); 129326941Sdim 130341825Sdim /// Returns a reference to the execution context. 131326941Sdim /// 132326941Sdim /// This should be passed to tool callbacks, and tool callbacks should report 133326941Sdim /// results via the returned context. 134326941Sdim virtual ExecutionContext *getExecutionContext() = 0; 135326941Sdim 136341825Sdim /// Returns a reference to the result container. 137326941Sdim /// 138326941Sdim /// NOTE: This should only be used after the execution finishes. Tool 139326941Sdim /// callbacks should report results via `ExecutionContext` instead. 140326941Sdim virtual ToolResults *getToolResults() = 0; 141326941Sdim 142341825Sdim /// Map a virtual file to be used while running the tool. 143326941Sdim /// 144326941Sdim /// \param FilePath The path at which the content will be mapped. 145326941Sdim /// \param Content A buffer of the file's content. 146326941Sdim virtual void mapVirtualFile(StringRef FilePath, StringRef Content) = 0; 147326941Sdim}; 148326941Sdim 149341825Sdim/// Interface for factories that create specific executors. This is also 150326941Sdim/// used as a plugin to be registered into ToolExecutorPluginRegistry. 151326941Sdimclass ToolExecutorPlugin { 152326941Sdimpublic: 153326941Sdim virtual ~ToolExecutorPlugin() {} 154326941Sdim 155341825Sdim /// Create an `ToolExecutor`. 156326941Sdim /// 157326941Sdim /// `OptionsParser` can be consumed (e.g. moved) if the creation succeeds. 158326941Sdim virtual llvm::Expected<std::unique_ptr<ToolExecutor>> 159326941Sdim create(CommonOptionsParser &OptionsParser) = 0; 160326941Sdim}; 161326941Sdim 162341825Sdim/// This creates a ToolExecutor that is in the global registry based on 163326941Sdim/// commandline arguments. 164326941Sdim/// 165326941Sdim/// This picks the right executor based on the `--executor` option. This parses 166326941Sdim/// the commandline arguments with `CommonOptionsParser`, so caller does not 167326941Sdim/// need to parse again. 168326941Sdim/// 169326941Sdim/// By default, this creates a `StandaloneToolExecutor` ("standalone") if 170326941Sdim/// `--executor` is not provided. 171326941Sdimllvm::Expected<std::unique_ptr<ToolExecutor>> 172326941SdimcreateExecutorFromCommandLineArgs(int &argc, const char **argv, 173326941Sdim llvm::cl::OptionCategory &Category, 174326941Sdim const char *Overview = nullptr); 175326941Sdim 176326941Sdimnamespace internal { 177326941Sdimllvm::Expected<std::unique_ptr<ToolExecutor>> 178326941SdimcreateExecutorFromCommandLineArgsImpl(int &argc, const char **argv, 179326941Sdim llvm::cl::OptionCategory &Category, 180326941Sdim const char *Overview = nullptr); 181326941Sdim} // end namespace internal 182326941Sdim 183326941Sdim} // end namespace tooling 184326941Sdim} // end namespace clang 185326941Sdim 186326941Sdim#endif // LLVM_CLANG_TOOLING_EXECUTION_H 187