<div dir="ltr">It's not intended, but r<span style="color:rgb(33,33,33)">316661 indeed fixed </span><font color="#212121"><a href="http://lab.llvm.org:8011/builders/clang-cmake-thumbv7-a15">http://lab.llvm.org:8011/builders/clang-cmake-thumbv7-a15</a> ;)</font></div><br><div class="gmail_quote"><div dir="ltr">On Thu, Oct 26, 2017 at 3:16 PM Eric Liu <<a href="mailto:ioeric@google.com">ioeric@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Maxim,<div><br></div><div>Thanks for the email! I'll look into this right now.</div><div><br></div><div>Thanks,</div><div>Eric</div></div><br><div class="gmail_quote"><div dir="ltr">On Thu, Oct 26, 2017 at 3:11 PM Maxim Kuvyrkov <<a href="mailto:maxim.kuvyrkov@linaro.org" target="_blank">maxim.kuvyrkov@linaro.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Eric,<br>
<br>
This seems to have broken clang-cmake-thumbv7-a15 buildbot [*]. Would you please investigate?<br>
<br>
Or did you fix this while I was writing this email in 316661 :-) ?<br>
<br>
Thank you,<br>
<br>
[*] <a href="http://lab.llvm.org:8011/builders/clang-cmake-thumbv7-a15/builds/12511" rel="noreferrer" target="_blank">http://lab.llvm.org:8011/builders/clang-cmake-thumbv7-a15/builds/12511</a><br>
<br>
--<br>
Maxim Kuvyrkov<br>
<a href="http://www.linaro.org" rel="noreferrer" target="_blank">www.linaro.org</a><br>
<br>
<br>
<br>
> On Oct 26, 2017, at 1:38 PM, Eric Liu via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:<br>
><br>
> Author: ioeric<br>
> Date: Thu Oct 26 03:38:14 2017<br>
> New Revision: 316653<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=316653&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=316653&view=rev</a><br>
> Log:<br>
> [Tooling] A new framework for executing clang frontend actions.<br>
><br>
> Summary:<br>
> This defines a `clang::tooling::ToolExecutor` interface that can be extended to support different execution plans including standalone execution on a given set of TUs or parallel execution on all TUs in a codebase.<br>
><br>
> In order to enable multiprocessing execution, tool actions are expected to output result into a `ToolResults` interface provided by executors. The `ToolResults` interface abstracts how results are stored e.g. in-memory for standalone executions or on-disk for large-scale execution.<br>
><br>
> New executors can be registered as `ToolExecutorPlugin`s via the `ToolExecutorPluginRegistry`. CLI tools can use `createExecutorFromCommandLineArgs` to create a specific registered executor according to the command-line arguments.<br>
><br>
> This patch also implements `StandaloneToolExecutor` which has the same behavior as the current `ClangTool` interface, i.e. execute frontend actions on a given set of TUs. At this point, it's simply a wrapper around `ClangTool` at this point.<br>
><br>
> This is still experimental but expected to replace the existing `ClangTool` interface so that specific tools would not need to worry about execution.<br>
><br>
> Reviewers: klimek, arphaman, hokein, sammccall<br>
><br>
> Reviewed By: klimek<br>
><br>
> Subscribers: cfe-commits, djasper, mgorny, omtcyfz<br>
><br>
> Differential Revision: <a href="https://reviews.llvm.org/D34272" rel="noreferrer" target="_blank">https://reviews.llvm.org/D34272</a><br>
><br>
> Added:<br>
> cfe/trunk/include/clang/Tooling/Execution.h<br>
> cfe/trunk/include/clang/Tooling/StandaloneExecution.h<br>
> cfe/trunk/include/clang/Tooling/ToolExecutorPluginRegistry.h<br>
> cfe/trunk/lib/Tooling/Execution.cpp<br>
> cfe/trunk/lib/Tooling/StandaloneExecution.cpp<br>
> cfe/trunk/unittests/Tooling/ExecutionTest.cpp<br>
> Modified:<br>
> cfe/trunk/include/clang/Tooling/CommonOptionsParser.h<br>
> cfe/trunk/include/clang/Tooling/Tooling.h<br>
> cfe/trunk/lib/Tooling/ArgumentsAdjusters.cpp<br>
> cfe/trunk/lib/Tooling/CMakeLists.txt<br>
> cfe/trunk/lib/Tooling/CommonOptionsParser.cpp<br>
> cfe/trunk/lib/Tooling/Tooling.cpp<br>
> cfe/trunk/unittests/Tooling/CMakeLists.txt<br>
><br>
> Modified: cfe/trunk/include/clang/Tooling/CommonOptionsParser.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/CommonOptionsParser.h?rev=316653&r1=316652&r2=316653&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/CommonOptionsParser.h?rev=316653&r1=316652&r2=316653&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/Tooling/CommonOptionsParser.h (original)<br>
> +++ cfe/trunk/include/clang/Tooling/CommonOptionsParser.h Thu Oct 26 03:38:14 2017<br>
> @@ -109,6 +109,10 @@ public:<br>
> return SourcePathList;<br>
> }<br>
><br>
> + /// Returns the argument adjuster calculated from "--extra-arg" and<br>
> + //"--extra-arg-before" options.<br>
> + ArgumentsAdjuster getArgumentsAdjuster() { return Adjuster; }<br>
> +<br>
> static const char *const HelpMessage;<br>
><br>
> private:<br>
> @@ -121,6 +125,7 @@ private:<br>
><br>
> std::unique_ptr<CompilationDatabase> Compilations;<br>
> std::vector<std::string> SourcePathList;<br>
> + ArgumentsAdjuster Adjuster;<br>
> };<br>
><br>
> class ArgumentsAdjustingCompilations : public CompilationDatabase {<br>
><br>
> Added: cfe/trunk/include/clang/Tooling/Execution.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Execution.h?rev=316653&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Execution.h?rev=316653&view=auto</a><br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/Tooling/Execution.h (added)<br>
> +++ cfe/trunk/include/clang/Tooling/Execution.h Thu Oct 26 03:38:14 2017<br>
> @@ -0,0 +1,168 @@<br>
> +//===--- Execution.h - Executing clang frontend actions -*- C++ ---------*-===//<br>
> +//<br>
> +// The LLVM Compiler Infrastructure<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open Source<br>
> +// License. See LICENSE.TXT for details.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +//<br>
> +// This file defines framework for executing clang frontend actions.<br>
> +//<br>
> +// The framework can be extended to support different execution plans including<br>
> +// standalone execution on the given TUs or parallel execution on all TUs in<br>
> +// the codebase.<br>
> +//<br>
> +// In order to enable multiprocessing execution, tool actions are expected to<br>
> +// output result into the ToolResults provided by the executor. The<br>
> +// `ToolResults` is an interface that abstracts how results are stored e.g.<br>
> +// in-memory for standalone execution or on-disk for large-scale execution.<br>
> +//<br>
> +// New executors can be registered as ToolExecutorPlugins via the<br>
> +// `ToolExecutorPluginRegistry`. CLI tools can use<br>
> +// `createExecutorFromCommandLineArgs` to create a specific registered executor<br>
> +// according to the command-line arguments.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +<br>
> +#ifndef LLVM_CLANG_TOOLING_EXECUTION_H<br>
> +#define LLVM_CLANG_TOOLING_EXECUTION_H<br>
> +<br>
> +#include "clang/Tooling/CommonOptionsParser.h"<br>
> +#include "clang/Tooling/Tooling.h"<br>
> +#include "llvm/Support/Error.h"<br>
> +#include "llvm/Support/Registry.h"<br>
> +<br>
> +namespace clang {<br>
> +namespace tooling {<br>
> +<br>
> +/// \brief An abstraction for the result of a tool execution. For example, the<br>
> +/// underlying result can be in-memory or on-disk.<br>
> +///<br>
> +/// Results should be string key-value pairs. For example, a refactoring tool<br>
> +/// can use source location as key and a replacement in YAML format as value.<br>
> +class ToolResults {<br>
> +public:<br>
> + virtual ~ToolResults() = default;<br>
> + virtual void addResult(StringRef Key, StringRef Value) = 0;<br>
> + virtual std::vector<std::pair<std::string, std::string>> AllKVResults() = 0;<br>
> + virtual void forEachResult(<br>
> + llvm::function_ref<void(StringRef Key, StringRef Value)> Callback) = 0;<br>
> +};<br>
> +<br>
> +class InMemoryToolResults : public ToolResults {<br>
> +public:<br>
> + void addResult(StringRef Key, StringRef Value) override;<br>
> + std::vector<std::pair<std::string, std::string>> AllKVResults() override;<br>
> + void forEachResult(llvm::function_ref<void(StringRef Key, StringRef Value)><br>
> + Callback) override;<br>
> +<br>
> +private:<br>
> + std::vector<std::pair<std::string, std::string>> KVResults;<br>
> +};<br>
> +<br>
> +/// \brief The context of an execution, including the information about<br>
> +/// compilation and results.<br>
> +class ExecutionContext {<br>
> +public:<br>
> + virtual ~ExecutionContext() {}<br>
> +<br>
> + /// \brief Initializes a context. This does not take ownership of `Results`.<br>
> + explicit ExecutionContext(ToolResults *Results) : Results(Results) {}<br>
> +<br>
> + /// \brief Adds a KV pair to the result container of this execution.<br>
> + void reportResult(StringRef Key, StringRef Value);<br>
> +<br>
> + // Returns the source control system's revision number if applicable.<br>
> + // Otherwise returns an empty string.<br>
> + virtual std::string getRevision() { return ""; }<br>
> +<br>
> + // Returns the corpus being analyzed, e.g. "llvm" for the LLVM codebase, if<br>
> + // applicable.<br>
> + virtual std::string getCorpus() { return ""; }<br>
> +<br>
> + // Returns the currently processed compilation unit if available.<br>
> + virtual std::string getCurrentCompilationUnit() { return ""; }<br>
> +<br>
> +private:<br>
> + ToolResults *Results;<br>
> +};<br>
> +<br>
> +/// \brief Interface for executing clang frontend actions.<br>
> +///<br>
> +/// This can be extended to support running tool actions in different<br>
> +/// execution mode, e.g. on a specific set of TUs or many TUs in parallel.<br>
> +///<br>
> +/// New executors can be registered as ToolExecutorPlugins via the<br>
> +/// `ToolExecutorPluginRegistry`. CLI tools can use<br>
> +/// `createExecutorFromCommandLineArgs` to create a specific registered<br>
> +/// executor according to the command-line arguments.<br>
> +class ToolExecutor {<br>
> +public:<br>
> + virtual ~ToolExecutor() {}<br>
> +<br>
> + /// \brief Returns the name of a specific executor.<br>
> + virtual StringRef getExecutorName() const = 0;<br>
> +<br>
> + /// \brief Executes each action with a corresponding arguments adjuster.<br>
> + virtual llvm::Error<br>
> + execute(llvm::ArrayRef<<br>
> + std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>><br>
> + Actions) = 0;<br>
> +<br>
> + /// \brief Convenient functions for the above `execute`.<br>
> + llvm::Error execute(std::unique_ptr<FrontendActionFactory> Action);<br>
> + /// Executes an action with an argument adjuster.<br>
> + llvm::Error execute(std::unique_ptr<FrontendActionFactory> Action,<br>
> + ArgumentsAdjuster Adjuster);<br>
> +<br>
> + /// \brief Returns a reference to the execution context.<br>
> + ///<br>
> + /// This should be passed to tool callbacks, and tool callbacks should report<br>
> + /// results via the returned context.<br>
> + virtual ExecutionContext *getExecutionContext() = 0;<br>
> +<br>
> + /// \brief Returns a reference to the result container.<br>
> + ///<br>
> + /// NOTE: This should only be used after the execution finishes. Tool<br>
> + /// callbacks should report results via `ExecutionContext` instead.<br>
> + virtual ToolResults *getToolResults() = 0;<br>
> +<br>
> + /// \brief Map a virtual file to be used while running the tool.<br>
> + ///<br>
> + /// \param FilePath The path at which the content will be mapped.<br>
> + /// \param Content A buffer of the file's content.<br>
> + virtual void mapVirtualFile(StringRef FilePath, StringRef Content) = 0;<br>
> +};<br>
> +<br>
> +/// \brief Interface for factories that create specific executors. This is also<br>
> +/// used as a plugin to be registered into ToolExecutorPluginRegistry.<br>
> +class ToolExecutorPlugin {<br>
> +public:<br>
> + virtual ~ToolExecutorPlugin() {}<br>
> +<br>
> + /// \brief Create an `ToolExecutor`.<br>
> + ///<br>
> + /// `OptionsParser` can be consumed (e.g. moved) if the creation succeeds.<br>
> + virtual llvm::Expected<std::unique_ptr<ToolExecutor>><br>
> + create(CommonOptionsParser &OptionsParser) = 0;<br>
> +};<br>
> +<br>
> +/// \brief This creates a ToolExecutor that is in the global registry based on<br>
> +/// commandline arguments.<br>
> +///<br>
> +/// This picks the right executor based on the `--executor` option. This parses<br>
> +/// the commandline arguments with `CommonOptionsParser`, so caller does not<br>
> +/// need to parse again.<br>
> +///<br>
> +/// By default, this creates a `StandaloneToolExecutor` ("standalone") if<br>
> +/// `--executor` is not provided.<br>
> +llvm::Expected<std::unique_ptr<ToolExecutor>><br>
> +createExecutorFromCommandLineArgs(int &argc, const char **argv,<br>
> + llvm::cl::OptionCategory &Category,<br>
> + const char *Overview = nullptr);<br>
> +<br>
> +} // end namespace tooling<br>
> +} // end namespace clang<br>
> +<br>
> +#endif // LLVM_CLANG_TOOLING_EXECUTION_H<br>
><br>
> Added: cfe/trunk/include/clang/Tooling/StandaloneExecution.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/StandaloneExecution.h?rev=316653&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/StandaloneExecution.h?rev=316653&view=auto</a><br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/Tooling/StandaloneExecution.h (added)<br>
> +++ cfe/trunk/include/clang/Tooling/StandaloneExecution.h Thu Oct 26 03:38:14 2017<br>
> @@ -0,0 +1,97 @@<br>
> +//===--- StandaloneExecution.h - Standalone execution. -*- C++ ----------*-===//<br>
> +//<br>
> +// The LLVM Compiler Infrastructure<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open Source<br>
> +// License. See LICENSE.TXT for details.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +//<br>
> +// This file defines standalone execution of clang tools.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +<br>
> +#ifndef LLVM_CLANG_TOOLING_STANDALONEEXECUTION_H<br>
> +#define LLVM_CLANG_TOOLING_STANDALONEEXECUTION_H<br>
> +<br>
> +#include "clang/Tooling/ArgumentsAdjusters.h"<br>
> +#include "clang/Tooling/Execution.h"<br>
> +<br>
> +namespace clang {<br>
> +namespace tooling {<br>
> +<br>
> +/// \brief A standalone executor that runs FrontendActions on a given set of<br>
> +/// TUs in sequence.<br>
> +///<br>
> +/// By default, this executor uses the following arguments adjusters (as defined<br>
> +/// in `clang/Tooling/ArgumentsAdjusters.h`):<br>
> +/// - `getClangStripOutputAdjuster()`<br>
> +/// - `getClangSyntaxOnlyAdjuster()`<br>
> +/// - `getClangStripDependencyFileAdjuster()`<br>
> +class StandaloneToolExecutor : public ToolExecutor {<br>
> +public:<br>
> + static const char *ExecutorName;<br>
> +<br>
> + /// \brief Init with \p CompilationDatabase and the paths of all files to be<br>
> + /// proccessed.<br>
> + StandaloneToolExecutor(<br>
> + const CompilationDatabase &Compilations,<br>
> + llvm::ArrayRef<std::string> SourcePaths,<br>
> + std::shared_ptr<PCHContainerOperations> PCHContainerOps =<br>
> + std::make_shared<PCHContainerOperations>());<br>
> +<br>
> + /// \brief Init with \p CommonOptionsParser. This is expected to be used by<br>
> + /// `createExecutorFromCommandLineArgs` based on commandline options.<br>
> + ///<br>
> + /// The executor takes ownership of \p Options.<br>
> + StandaloneToolExecutor(<br>
> + CommonOptionsParser Options,<br>
> + std::shared_ptr<PCHContainerOperations> PCHContainerOps =<br>
> + std::make_shared<PCHContainerOperations>());<br>
> +<br>
> + StringRef getExecutorName() const override { return ExecutorName; }<br>
> +<br>
> + using ToolExecutor::execute;<br>
> +<br>
> + llvm::Error<br>
> + execute(llvm::ArrayRef<<br>
> + std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>><br>
> + Actions) override;<br>
> +<br>
> + /// \brief Set a \c DiagnosticConsumer to use during parsing.<br>
> + void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {<br>
> + Tool.setDiagnosticConsumer(DiagConsumer);<br>
> + }<br>
> +<br>
> + ExecutionContext *getExecutionContext() override { return &Context; };<br>
> +<br>
> + ToolResults *getToolResults() override { return &Results; }<br>
> +<br>
> + llvm::ArrayRef<std::string> getSourcePaths() const {<br>
> + return Tool.getSourcePaths();<br>
> + }<br>
> +<br>
> + void mapVirtualFile(StringRef FilePath, StringRef Content) override {<br>
> + Tool.mapVirtualFile(FilePath, Content);<br>
> + }<br>
> +<br>
> + /// \brief Returns the file manager used in the tool.<br>
> + ///<br>
> + /// The file manager is shared between all translation units.<br>
> + FileManager &getFiles() { return Tool.getFiles(); }<br>
> +<br>
> +private:<br>
> + // Used to store the parser when the executor is initialized with parser.<br>
> + llvm::Optional<CommonOptionsParser> OptionsParser;<br>
> + // FIXME: The standalone executor is currently just a wrapper of `ClangTool`.<br>
> + // Merge `ClangTool` implementation into the this.<br>
> + ClangTool Tool;<br>
> + ExecutionContext Context;<br>
> + InMemoryToolResults Results;<br>
> + ArgumentsAdjuster ArgsAdjuster;<br>
> +};<br>
> +<br>
> +} // end namespace tooling<br>
> +} // end namespace clang<br>
> +<br>
> +#endif // LLVM_CLANG_TOOLING_STANDALONEEXECUTION_H<br>
><br>
> Added: cfe/trunk/include/clang/Tooling/ToolExecutorPluginRegistry.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/ToolExecutorPluginRegistry.h?rev=316653&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/ToolExecutorPluginRegistry.h?rev=316653&view=auto</a><br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/Tooling/ToolExecutorPluginRegistry.h (added)<br>
> +++ cfe/trunk/include/clang/Tooling/ToolExecutorPluginRegistry.h Thu Oct 26 03:38:14 2017<br>
> @@ -0,0 +1,24 @@<br>
> +//===--- ToolExecutorPluginRegistry.h - -------------------------*- C++ -*-===//<br>
> +//<br>
> +// The LLVM Compiler Infrastructure<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open Source<br>
> +// License. See LICENSE.TXT for details.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +<br>
> +#ifndef LLVM_CLANG_TOOLING_TOOLEXECUTORPLUGINREGISTRY_H<br>
> +#define LLVM_CLANG_TOOLING_TOOLEXECUTORPLUGINREGISTRY_H<br>
> +<br>
> +#include "clang/Tooling/Execution.h"<br>
> +#include "llvm/Support/Registry.h"<br>
> +<br>
> +namespace clang {<br>
> +namespace tooling {<br>
> +<br>
> +typedef llvm::Registry<ToolExecutorPlugin> ToolExecutorPluginRegistry;<br>
> +<br>
> +} // end namespace tooling<br>
> +} // end namespace clang<br>
> +<br>
> +#endif // LLVM_CLANG_TOOLING_TOOLEXECUTORPLUGINREGISTRY_H<br>
><br>
> Modified: cfe/trunk/include/clang/Tooling/Tooling.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Tooling.h?rev=316653&r1=316652&r2=316653&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Tooling.h?rev=316653&r1=316652&r2=316653&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/Tooling/Tooling.h (original)<br>
> +++ cfe/trunk/include/clang/Tooling/Tooling.h Thu Oct 26 03:38:14 2017<br>
> @@ -31,12 +31,12 @@<br>
> #define LLVM_CLANG_TOOLING_TOOLING_H<br>
><br>
> #include "clang/AST/ASTConsumer.h"<br>
> -#include "clang/Frontend/PCHContainerOperations.h"<br>
> #include "clang/Basic/Diagnostic.h"<br>
> #include "clang/Basic/FileManager.h"<br>
> #include "clang/Basic/LLVM.h"<br>
> #include "clang/Driver/Util.h"<br>
> #include "clang/Frontend/FrontendAction.h"<br>
> +#include "clang/Frontend/PCHContainerOperations.h"<br>
> #include "clang/Lex/ModuleLoader.h"<br>
> #include "clang/Tooling/ArgumentsAdjusters.h"<br>
> #include "clang/Tooling/CompilationDatabase.h"<br>
> @@ -337,7 +337,9 @@ class ClangTool {<br>
> /// The file manager is shared between all translation units.<br>
> FileManager &getFiles() { return *Files; }<br>
><br>
> - private:<br>
> + llvm::ArrayRef<std::string> getSourcePaths() const { return SourcePaths; }<br>
> +<br>
> +private:<br>
> const CompilationDatabase &Compilations;<br>
> std::vector<std::string> SourcePaths;<br>
> std::shared_ptr<PCHContainerOperations> PCHContainerOps;<br>
><br>
> Modified: cfe/trunk/lib/Tooling/ArgumentsAdjusters.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/ArgumentsAdjusters.cpp?rev=316653&r1=316652&r2=316653&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/ArgumentsAdjusters.cpp?rev=316653&r1=316652&r2=316653&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Tooling/ArgumentsAdjusters.cpp (original)<br>
> +++ cfe/trunk/lib/Tooling/ArgumentsAdjusters.cpp Thu Oct 26 03:38:14 2017<br>
> @@ -96,6 +96,10 @@ ArgumentsAdjuster getInsertArgumentAdjus<br>
><br>
> ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First,<br>
> ArgumentsAdjuster Second) {<br>
> + if (!First)<br>
> + return Second;<br>
> + if (!Second)<br>
> + return First;<br>
> return [First, Second](const CommandLineArguments &Args, StringRef File) {<br>
> return Second(First(Args, File), File);<br>
> };<br>
><br>
> Modified: cfe/trunk/lib/Tooling/CMakeLists.txt<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/CMakeLists.txt?rev=316653&r1=316652&r2=316653&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/CMakeLists.txt?rev=316653&r1=316652&r2=316653&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Tooling/CMakeLists.txt (original)<br>
> +++ cfe/trunk/lib/Tooling/CMakeLists.txt Thu Oct 26 03:38:14 2017<br>
> @@ -11,11 +11,13 @@ add_clang_library(clangTooling<br>
> ArgumentsAdjusters.cpp<br>
> CommonOptionsParser.cpp<br>
> CompilationDatabase.cpp<br>
> + Execution.cpp<br>
> FileMatchTrie.cpp<br>
> FixIt.cpp<br>
> JSONCompilationDatabase.cpp<br>
> Refactoring.cpp<br>
> RefactoringCallbacks.cpp<br>
> + StandaloneExecution.cpp<br>
> Tooling.cpp<br>
><br>
> DEPENDS<br>
><br>
> Modified: cfe/trunk/lib/Tooling/CommonOptionsParser.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/CommonOptionsParser.cpp?rev=316653&r1=316652&r2=316653&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/CommonOptionsParser.cpp?rev=316653&r1=316652&r2=316653&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Tooling/CommonOptionsParser.cpp (original)<br>
> +++ cfe/trunk/lib/Tooling/CommonOptionsParser.cpp Thu Oct 26 03:38:14 2017<br>
> @@ -147,10 +147,12 @@ llvm::Error CommonOptionsParser::init(<br>
> auto AdjustingCompilations =<br>
> llvm::make_unique<ArgumentsAdjustingCompilations>(<br>
> std::move(Compilations));<br>
> - AdjustingCompilations->appendArgumentsAdjuster(<br>
> - getInsertArgumentAdjuster(ArgsBefore, ArgumentInsertPosition::BEGIN));<br>
> - AdjustingCompilations->appendArgumentsAdjuster(<br>
> + Adjuster =<br>
> + getInsertArgumentAdjuster(ArgsBefore, ArgumentInsertPosition::BEGIN);<br>
> + Adjuster = combineAdjusters(<br>
> + std::move(Adjuster),<br>
> getInsertArgumentAdjuster(ArgsAfter, ArgumentInsertPosition::END));<br>
> + AdjustingCompilations->appendArgumentsAdjuster(Adjuster);<br>
> Compilations = std::move(AdjustingCompilations);<br>
> return llvm::Error::success();<br>
> }<br>
><br>
> Added: cfe/trunk/lib/Tooling/Execution.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Execution.cpp?rev=316653&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Execution.cpp?rev=316653&view=auto</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Tooling/Execution.cpp (added)<br>
> +++ cfe/trunk/lib/Tooling/Execution.cpp Thu Oct 26 03:38:14 2017<br>
> @@ -0,0 +1,89 @@<br>
> +//===- lib/Tooling/Execution.cpp - Implements tool execution framework. ---===//<br>
> +//<br>
> +// The LLVM Compiler Infrastructure<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open Source<br>
> +// License. See LICENSE.TXT for details.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +<br>
> +#include "clang/Tooling/Execution.h"<br>
> +#include "clang/Tooling/ToolExecutorPluginRegistry.h"<br>
> +#include "clang/Tooling/Tooling.h"<br>
> +<br>
> +LLVM_INSTANTIATE_REGISTRY(clang::tooling::ToolExecutorPluginRegistry)<br>
> +<br>
> +namespace clang {<br>
> +namespace tooling {<br>
> +<br>
> +static llvm::cl::opt<std::string><br>
> + ExecutorName("executor", llvm::cl::desc("The name of the executor to use."),<br>
> + llvm::cl::init("standalone"));<br>
> +<br>
> +void InMemoryToolResults::addResult(StringRef Key, StringRef Value) {<br>
> + KVResults.push_back({Key.str(), Value.str()});<br>
> +}<br>
> +<br>
> +std::vector<std::pair<std::string, std::string>><br>
> +InMemoryToolResults::AllKVResults() {<br>
> + return KVResults;<br>
> +}<br>
> +<br>
> +void InMemoryToolResults::forEachResult(<br>
> + llvm::function_ref<void(StringRef Key, StringRef Value)> Callback) {<br>
> + for (const auto &KV : KVResults) {<br>
> + Callback(KV.first, KV.second);<br>
> + }<br>
> +}<br>
> +<br>
> +void ExecutionContext::reportResult(StringRef Key, StringRef Value) {<br>
> + Results->addResult(Key, Value);<br>
> +}<br>
> +<br>
> +llvm::Error<br>
> +ToolExecutor::execute(std::unique_ptr<FrontendActionFactory> Action) {<br>
> + return execute(std::move(Action), ArgumentsAdjuster());<br>
> +}<br>
> +<br>
> +llvm::Error ToolExecutor::execute(std::unique_ptr<FrontendActionFactory> Action,<br>
> + ArgumentsAdjuster Adjuster) {<br>
> + std::vector<<br>
> + std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>><br>
> + Actions;<br>
> + Actions.emplace_back(std::move(Action), std::move(Adjuster));<br>
> + return execute(Actions);<br>
> +}<br>
> +<br>
> +llvm::Expected<std::unique_ptr<ToolExecutor>><br>
> +createExecutorFromCommandLineArgs(int &argc, const char **argv,<br>
> + llvm::cl::OptionCategory &Category,<br>
> + const char *Overview) {<br>
> + auto OptionsParser =<br>
> + CommonOptionsParser::create(argc, argv, Category, llvm::cl::ZeroOrMore,<br>
> + /*Overview=*/nullptr);<br>
> + if (!OptionsParser)<br>
> + return OptionsParser.takeError();<br>
> + for (auto I = ToolExecutorPluginRegistry::begin(),<br>
> + E = ToolExecutorPluginRegistry::end();<br>
> + I != E; ++I) {<br>
> + if (I->getName() != ExecutorName) {<br>
> + continue;<br>
> + }<br>
> + std::unique_ptr<ToolExecutorPlugin> Plugin(I->instantiate());<br>
> + llvm::Expected<std::unique_ptr<ToolExecutor>> Executor =<br>
> + Plugin->create(*OptionsParser);<br>
> + if (!Executor) {<br>
> + return llvm::make_error<llvm::StringError>(<br>
> + llvm::Twine("Failed to create '") + I->getName() +<br>
> + "': " + llvm::toString(Executor.takeError()) + "\n",<br>
> + llvm::inconvertibleErrorCode());<br>
> + }<br>
> + return std::move(*Executor);<br>
> + }<br>
> + return llvm::make_error<llvm::StringError>(<br>
> + llvm::Twine("Executor \"") + ExecutorName + "\" is not registered.",<br>
> + llvm::inconvertibleErrorCode());<br>
> +}<br>
> +<br>
> +} // end namespace tooling<br>
> +} // end namespace clang<br>
><br>
> Added: cfe/trunk/lib/Tooling/StandaloneExecution.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/StandaloneExecution.cpp?rev=316653&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/StandaloneExecution.cpp?rev=316653&view=auto</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Tooling/StandaloneExecution.cpp (added)<br>
> +++ cfe/trunk/lib/Tooling/StandaloneExecution.cpp Thu Oct 26 03:38:14 2017<br>
> @@ -0,0 +1,91 @@<br>
> +//===- lib/Tooling/Execution.cpp - Standalone clang action execution. -----===//<br>
> +//<br>
> +// The LLVM Compiler Infrastructure<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open Source<br>
> +// License. See LICENSE.TXT for details.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +<br>
> +#include "clang/Tooling/StandaloneExecution.h"<br>
> +#include "clang/Tooling/ToolExecutorPluginRegistry.h"<br>
> +<br>
> +namespace clang {<br>
> +namespace tooling {<br>
> +<br>
> +static llvm::Error make_string_error(const llvm::Twine &Message) {<br>
> + return llvm::make_error<llvm::StringError>(Message,<br>
> + llvm::inconvertibleErrorCode());<br>
> +}<br>
> +<br>
> +const char *StandaloneToolExecutor::ExecutorName = "StandaloneToolExecutor";<br>
> +<br>
> +static ArgumentsAdjuster getDefaultArgumentsAdjusters() {<br>
> + return combineAdjusters(<br>
> + getClangStripOutputAdjuster(),<br>
> + combineAdjusters(getClangSyntaxOnlyAdjuster(),<br>
> + getClangStripDependencyFileAdjuster()));<br>
> +}<br>
> +<br>
> +StandaloneToolExecutor::StandaloneToolExecutor(<br>
> + const CompilationDatabase &Compilations,<br>
> + llvm::ArrayRef<std::string> SourcePaths,<br>
> + std::shared_ptr<PCHContainerOperations> PCHContainerOps)<br>
> + : Tool(Compilations, SourcePaths), Context(&Results),<br>
> + ArgsAdjuster(getDefaultArgumentsAdjusters()) {<br>
> + // Use self-defined default argument adjusters instead of the default<br>
> + // adjusters that come with the old `ClangTool`.<br>
> + Tool.clearArgumentsAdjusters();<br>
> +}<br>
> +<br>
> +StandaloneToolExecutor::StandaloneToolExecutor(<br>
> + CommonOptionsParser Options,<br>
> + std::shared_ptr<PCHContainerOperations> PCHContainerOps)<br>
> + : OptionsParser(std::move(Options)),<br>
> + Tool(OptionsParser->getCompilations(), OptionsParser->getSourcePathList(),<br>
> + PCHContainerOps),<br>
> + Context(&Results), ArgsAdjuster(getDefaultArgumentsAdjusters()) {<br>
> + Tool.clearArgumentsAdjusters();<br>
> +}<br>
> +<br>
> +llvm::Error StandaloneToolExecutor::execute(<br>
> + llvm::ArrayRef<<br>
> + std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>><br>
> + Actions) {<br>
> + if (Actions.empty())<br>
> + return make_string_error("No action to execute.");<br>
> +<br>
> + if (Actions.size() != 1)<br>
> + return make_string_error(<br>
> + "Only support executing exactly 1 action at this point.");<br>
> +<br>
> + auto &Action = Actions.front();<br>
> + Tool.appendArgumentsAdjuster(Action.second);<br>
> + Tool.appendArgumentsAdjuster(ArgsAdjuster);<br>
> + if (int Ret = Tool.run(Action.first.get()))<br>
> + return make_string_error("Failed to run action.");<br>
> +<br>
> + return llvm::Error::success();<br>
> +}<br>
> +<br>
> +class StandaloneToolExecutorPlugin : public ToolExecutorPlugin {<br>
> +public:<br>
> + llvm::Expected<std::unique_ptr<ToolExecutor>><br>
> + create(CommonOptionsParser &OptionsParser) override {<br>
> + if (OptionsParser.getSourcePathList().empty())<br>
> + return make_string_error(<br>
> + "[StandaloneToolExecutorPlugin] No positional argument found.");<br>
> + return llvm::make_unique<StandaloneToolExecutor>(std::move(OptionsParser));<br>
> + }<br>
> +};<br>
> +<br>
> +// This anchor is used to force the linker to link in the generated object file<br>
> +// and thus register the plugin.<br>
> +volatile int ToolExecutorPluginAnchorSource = 0;<br>
> +<br>
> +static ToolExecutorPluginRegistry::Add<StandaloneToolExecutorPlugin><br>
> + X("standalone", "Runs FrontendActions on a set of files provided "<br>
> + "via positional arguments.");<br>
> +<br>
> +} // end namespace tooling<br>
> +} // end namespace clang<br>
><br>
> Modified: cfe/trunk/lib/Tooling/Tooling.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Tooling.cpp?rev=316653&r1=316652&r2=316653&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Tooling.cpp?rev=316653&r1=316652&r2=316653&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Tooling/Tooling.cpp (original)<br>
> +++ cfe/trunk/lib/Tooling/Tooling.cpp Thu Oct 26 03:38:14 2017<br>
> @@ -29,6 +29,7 @@<br>
> #include "llvm/Config/llvm-config.h"<br>
> #include "llvm/Option/ArgList.h"<br>
> #include "llvm/Option/Option.h"<br>
> +#include "llvm/Support/CommandLine.h"<br>
> #include "llvm/Support/Debug.h"<br>
> #include "llvm/Support/FileSystem.h"<br>
> #include "llvm/Support/Host.h"<br>
> @@ -347,11 +348,7 @@ void ClangTool::mapVirtualFile(StringRef<br>
> }<br>
><br>
> void ClangTool::appendArgumentsAdjuster(ArgumentsAdjuster Adjuster) {<br>
> - if (ArgsAdjuster)<br>
> - ArgsAdjuster =<br>
> - combineAdjusters(std::move(ArgsAdjuster), std::move(Adjuster));<br>
> - else<br>
> - ArgsAdjuster = std::move(Adjuster);<br>
> + ArgsAdjuster = combineAdjusters(std::move(ArgsAdjuster), std::move(Adjuster));<br>
> }<br>
><br>
> void ClangTool::clearArgumentsAdjusters() {<br>
><br>
> Modified: cfe/trunk/unittests/Tooling/CMakeLists.txt<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/CMakeLists.txt?rev=316653&r1=316652&r2=316653&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/CMakeLists.txt?rev=316653&r1=316652&r2=316653&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/unittests/Tooling/CMakeLists.txt (original)<br>
> +++ cfe/trunk/unittests/Tooling/CMakeLists.txt Thu Oct 26 03:38:14 2017<br>
> @@ -16,6 +16,7 @@ add_clang_unittest(ToolingTests<br>
> CommentHandlerTest.cpp<br>
> CompilationDatabaseTest.cpp<br>
> DiagnosticsYamlTest.cpp<br>
> + ExecutionTest.cpp<br>
> FixItTest.cpp<br>
> LexicallyOrderedRecursiveASTVisitorTest.cpp<br>
> LookupTest.cpp<br>
><br>
> Added: cfe/trunk/unittests/Tooling/ExecutionTest.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/ExecutionTest.cpp?rev=316653&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/ExecutionTest.cpp?rev=316653&view=auto</a><br>
> ==============================================================================<br>
> --- cfe/trunk/unittests/Tooling/ExecutionTest.cpp (added)<br>
> +++ cfe/trunk/unittests/Tooling/ExecutionTest.cpp Thu Oct 26 03:38:14 2017<br>
> @@ -0,0 +1,228 @@<br>
> +//===- unittest/Tooling/ExecutionTest.cpp - Tool execution tests. --------===//<br>
> +//<br>
> +// The LLVM Compiler Infrastructure<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open Source<br>
> +// License. See LICENSE.TXT for details.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +<br>
> +#include "clang/AST/ASTConsumer.h"<br>
> +#include "clang/AST/DeclCXX.h"<br>
> +#include "clang/AST/RecursiveASTVisitor.h"<br>
> +#include "clang/Frontend/ASTUnit.h"<br>
> +#include "clang/Frontend/FrontendAction.h"<br>
> +#include "clang/Frontend/FrontendActions.h"<br>
> +#include "clang/Tooling/CompilationDatabase.h"<br>
> +#include "clang/Tooling/Execution.h"<br>
> +#include "clang/Tooling/StandaloneExecution.h"<br>
> +#include "clang/Tooling/ToolExecutorPluginRegistry.h"<br>
> +#include "clang/Tooling/Tooling.h"<br>
> +#include "gtest/gtest.h"<br>
> +#include <algorithm><br>
> +#include <string><br>
> +<br>
> +namespace clang {<br>
> +namespace tooling {<br>
> +<br>
> +namespace {<br>
> +<br>
> +// This traverses the AST and outputs function name as key and "1" as value for<br>
> +// each function declaration.<br>
> +class ASTConsumerWithResult<br>
> + : public ASTConsumer,<br>
> + public RecursiveASTVisitor<ASTConsumerWithResult> {<br>
> +public:<br>
> + using ASTVisitor = RecursiveASTVisitor<ASTConsumerWithResult>;<br>
> +<br>
> + explicit ASTConsumerWithResult(ExecutionContext *Context) : Context(Context) {<br>
> + assert(Context != nullptr);<br>
> + }<br>
> +<br>
> + void HandleTranslationUnit(clang::ASTContext &Context) override {<br>
> + TraverseDecl(Context.getTranslationUnitDecl());<br>
> + }<br>
> +<br>
> + bool TraverseFunctionDecl(clang::FunctionDecl *Decl) {<br>
> + Context->reportResult(Decl->getNameAsString(), "1");<br>
> + return ASTVisitor::TraverseFunctionDecl(Decl);<br>
> + }<br>
> +<br>
> +private:<br>
> + ExecutionContext *const Context;<br>
> +};<br>
> +<br>
> +class ReportResultAction : public ASTFrontendAction {<br>
> +public:<br>
> + explicit ReportResultAction(ExecutionContext *Context) : Context(Context) {<br>
> + assert(Context != nullptr);<br>
> + }<br>
> +<br>
> +protected:<br>
> + std::unique_ptr<clang::ASTConsumer><br>
> + CreateASTConsumer(clang::CompilerInstance &compiler,<br>
> + StringRef /* dummy */) override {<br>
> + std::unique_ptr<clang::ASTConsumer> ast_consumer{<br>
> + new ASTConsumerWithResult(Context)};<br>
> + return ast_consumer;<br>
> + }<br>
> +<br>
> +private:<br>
> + ExecutionContext *const Context;<br>
> +};<br>
> +<br>
> +class ReportResultActionFactory : public FrontendActionFactory {<br>
> +public:<br>
> + ReportResultActionFactory(ExecutionContext *Context) : Context(Context) {}<br>
> + FrontendAction *create() override { return new ReportResultAction(Context); }<br>
> +<br>
> +private:<br>
> + ExecutionContext *const Context;<br>
> +};<br>
> +<br>
> +} // namespace<br>
> +<br>
> +class TestToolExecutor : public ToolExecutor {<br>
> +public:<br>
> + static const char *ExecutorName;<br>
> +<br>
> + TestToolExecutor(CommonOptionsParser Options)<br>
> + : OptionsParser(std::move(Options)) {}<br>
> +<br>
> + StringRef getExecutorName() const override { return ExecutorName; }<br>
> +<br>
> + llvm::Error<br>
> + execute(llvm::ArrayRef<std::pair<std::unique_ptr<FrontendActionFactory>,<br>
> + ArgumentsAdjuster>>) override {<br>
> + return llvm::Error::success();<br>
> + }<br>
> +<br>
> + ExecutionContext *getExecutionContext() override { return nullptr; };<br>
> +<br>
> + ToolResults *getToolResults() override { return nullptr; }<br>
> +<br>
> + llvm::ArrayRef<std::string> getSourcePaths() const {<br>
> + return OptionsParser.getSourcePathList();<br>
> + }<br>
> +<br>
> + void mapVirtualFile(StringRef FilePath, StringRef Content) override {<br>
> + VFS[FilePath] = Content;<br>
> + }<br>
> +<br>
> +private:<br>
> + CommonOptionsParser OptionsParser;<br>
> + std::string SourcePaths;<br>
> + std::map<std::string, std::string> VFS;<br>
> +};<br>
> +<br>
> +const char *TestToolExecutor::ExecutorName = "test-executor";<br>
> +<br>
> +class TestToolExecutorPlugin : public ToolExecutorPlugin {<br>
> +public:<br>
> + llvm::Expected<std::unique_ptr<ToolExecutor>><br>
> + create(CommonOptionsParser &OptionsParser) override {<br>
> + return llvm::make_unique<TestToolExecutor>(std::move(OptionsParser));<br>
> + }<br>
> +};<br>
> +<br>
> +// This anchor is used to force the linker to link in the generated object file<br>
> +// and thus register the plugin.<br>
> +extern volatile int ToolExecutorPluginAnchorSource;<br>
> +<br>
> +static int LLVM_ATTRIBUTE_UNUSED TestToolExecutorPluginAnchorDest =<br>
> + ToolExecutorPluginAnchorSource;<br>
> +<br>
> +static ToolExecutorPluginRegistry::Add<TestToolExecutorPlugin><br>
> + X("test-executor", "Plugin for TestToolExecutor.");<br>
> +<br>
> +llvm::cl::OptionCategory TestCategory("execution-test options");<br>
> +<br>
> +TEST(CreateToolExecutorTest, FailedCreateExecutorUndefinedFlag) {<br>
> + std::vector<const char *> argv = {"prog", "--fake_flag_no_no_no", "f"};<br>
> + int argc = argv.size();<br>
> + auto Executor =<br>
> + createExecutorFromCommandLineArgs(argc, &argv[0], TestCategory);<br>
> + ASSERT_FALSE((bool)Executor);<br>
> + llvm::consumeError(Executor.takeError());<br>
> +}<br>
> +<br>
> +TEST(CreateToolExecutorTest, RegisterFlagsBeforeReset) {<br>
> + llvm::cl::opt<std::string> BeforeReset(<br>
> + "before_reset", llvm::cl::desc("Defined before reset."),<br>
> + llvm::cl::init(""));<br>
> +<br>
> + llvm::cl::ResetAllOptionOccurrences();<br>
> +<br>
> + std::vector<const char *> argv = {"prog", "--before_reset=set", "f"};<br>
> + int argc = argv.size();<br>
> + auto Executor =<br>
> + createExecutorFromCommandLineArgs(argc, &argv[0], TestCategory);<br>
> + ASSERT_TRUE((bool)Executor);<br>
> + EXPECT_EQ(BeforeReset, "set");<br>
> + BeforeReset.removeArgument();<br>
> +}<br>
> +<br>
> +TEST(CreateToolExecutorTest, CreateStandaloneToolExecutor) {<br>
> + std::vector<const char *> argv = {"prog", "standalone.cpp"};<br>
> + int argc = argv.size();<br>
> + auto Executor =<br>
> + createExecutorFromCommandLineArgs(argc, &argv[0], TestCategory);<br>
> + ASSERT_TRUE((bool)Executor);<br>
> + EXPECT_EQ(Executor->get()->getExecutorName(),<br>
> + StandaloneToolExecutor::ExecutorName);<br>
> +}<br>
> +<br>
> +TEST(CreateToolExecutorTest, CreateTestToolExecutor) {<br>
> + std::vector<const char *> argv = {"prog", "test.cpp",<br>
> + "--executor=test-executor"};<br>
> + int argc = argv.size();<br>
> + auto Executor =<br>
> + createExecutorFromCommandLineArgs(argc, &argv[0], TestCategory);<br>
> + ASSERT_TRUE((bool)Executor);<br>
> + EXPECT_EQ(Executor->get()->getExecutorName(), TestToolExecutor::ExecutorName);<br>
> +}<br>
> +<br>
> +TEST(StandaloneToolTest, SynctaxOnlyActionOnSimpleCode) {<br>
> + FixedCompilationDatabase Compilations("/", std::vector<std::string>());<br>
> + StandaloneToolExecutor Executor(Compilations,<br>
> + std::vector<std::string>(1, "/a.cc"));<br>
> + Executor.mapVirtualFile("/a.cc", "int x = 0;");<br>
> +<br>
> + auto Err = Executor.execute(newFrontendActionFactory<SyntaxOnlyAction>(),<br>
> + getClangSyntaxOnlyAdjuster());<br>
> + ASSERT_TRUE(!Err);<br>
> +}<br>
> +<br>
> +TEST(StandaloneToolTest, SimpleAction) {<br>
> + FixedCompilationDatabase Compilations("/", std::vector<std::string>());<br>
> + StandaloneToolExecutor Executor(Compilations,<br>
> + std::vector<std::string>(1, "/a.cc"));<br>
> + Executor.mapVirtualFile("/a.cc", "int x = 0;");<br>
> +<br>
> + auto Err = Executor.execute(std::unique_ptr<FrontendActionFactory>(<br>
> + new ReportResultActionFactory(Executor.getExecutionContext())));<br>
> + ASSERT_TRUE(!Err);<br>
> + auto KVs = Executor.getToolResults()->AllKVResults();<br>
> + ASSERT_EQ(KVs.size(), 0u);<br>
> +}<br>
> +<br>
> +TEST(StandaloneToolTest, SimpleActionWithResult) {<br>
> + FixedCompilationDatabase Compilations("/", std::vector<std::string>());<br>
> + StandaloneToolExecutor Executor(Compilations,<br>
> + std::vector<std::string>(1, "/a.cc"));<br>
> + Executor.mapVirtualFile("/a.cc", "int x = 0; void f() {}");<br>
> +<br>
> + auto Err = Executor.execute(std::unique_ptr<FrontendActionFactory>(<br>
> + new ReportResultActionFactory(Executor.getExecutionContext())));<br>
> + ASSERT_TRUE(!Err);<br>
> + auto KVs = Executor.getToolResults()->AllKVResults();<br>
> + ASSERT_EQ(KVs.size(), 1u);<br>
> + EXPECT_EQ("f", KVs[0].first);<br>
> + EXPECT_EQ("1", KVs[0].second);<br>
> +<br>
> + Executor.getToolResults()->forEachResult(<br>
> + [](StringRef, StringRef Value) { EXPECT_EQ("1", Value); });<br>
> +}<br>
> +<br>
> +} // end namespace tooling<br>
> +} // end namespace clang<br>
><br>
><br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
<br>
</blockquote></div></blockquote></div>