sammccall updated this revision to Diff 540657.
sammccall added a comment.

tweak comment, remove unused overload


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155361/new/

https://reviews.llvm.org/D155361

Files:
  clang/include/clang/Tooling/AllTUsExecution.h
  clang/include/clang/Tooling/Execution.h
  clang/include/clang/Tooling/StandaloneExecution.h
  clang/include/clang/Tooling/Tooling.h
  clang/lib/Tooling/AllTUsExecution.cpp
  clang/lib/Tooling/Execution.cpp
  clang/lib/Tooling/StandaloneExecution.cpp
  clang/lib/Tooling/Tooling.cpp
  clang/unittests/Tooling/ExecutionTest.cpp
  clang/unittests/Tooling/ToolingTest.cpp

Index: clang/unittests/Tooling/ToolingTest.cpp
===================================================================
--- clang/unittests/Tooling/ToolingTest.cpp
+++ clang/unittests/Tooling/ToolingTest.cpp
@@ -10,6 +10,7 @@
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclGroup.h"
+#include "clang/AST/DeclarationName.h"
 #include "clang/Driver/Compilation.h"
 #include "clang/Driver/Driver.h"
 #include "clang/Frontend/ASTUnit.h"
@@ -511,6 +512,18 @@
 }
 #endif
 
+TEST(newFrontendActionFactory, ConsumeASTs) {
+  FixedCompilationDatabase Compilations(".", std::vector<std::string>());
+  ClangTool Tool(Compilations, {"a.cc"});
+  Tool.mapVirtualFile("a.cc", "int x = 1;");
+  bool FoundX = false;
+  Tool.run(consumeASTs([&](ASTContext &Ctx) {
+             DeclarationName X(&Ctx.Idents.get("x"));
+             FoundX = Ctx.getTranslationUnitDecl()->lookup(X).isSingleResult();
+           }).get());
+  EXPECT_TRUE(FoundX);
+}
+
 struct SkipBodyConsumer : public clang::ASTConsumer {
   /// Skip the 'skipMe' function.
   bool shouldSkipFunctionBody(Decl *D) override {
Index: clang/unittests/Tooling/ExecutionTest.cpp
===================================================================
--- clang/unittests/Tooling/ExecutionTest.cpp
+++ clang/unittests/Tooling/ExecutionTest.cpp
@@ -9,6 +9,7 @@
 #include "clang/Tooling/Execution.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclarationName.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/FrontendAction.h"
@@ -18,10 +19,12 @@
 #include "clang/Tooling/StandaloneExecution.h"
 #include "clang/Tooling/ToolExecutorPluginRegistry.h"
 #include "clang/Tooling/Tooling.h"
+#include "llvm/Testing/Support/SupportHelpers.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include <algorithm>
 #include <string>
+#include <vector>
 
 namespace clang {
 namespace tooling {
@@ -97,9 +100,7 @@
 
   StringRef getExecutorName() const override { return ExecutorName; }
 
-  llvm::Error
-  execute(llvm::ArrayRef<std::pair<std::unique_ptr<FrontendActionFactory>,
-                                   ArgumentsAdjuster>>) override {
+  llvm::Error execute(llvm::ArrayRef<Action>) override {
     return llvm::Error::success();
   }
 
@@ -181,14 +182,32 @@
   EXPECT_EQ(Executor->get()->getExecutorName(), TestToolExecutor::ExecutorName);
 }
 
+TEST(CreateToolExecutorTest, ExecuteFromCommandLine) {
+  llvm::unittest::TempFile Source1("test1", ".cpp", "int x = 0;", true);
+  llvm::unittest::TempFile Source2("test2", ".cpp", "int y = 0;", true);
+  std::string Path1 = Source1.path().str();
+  std::string Path2 = Source2.path().str();
+  std::vector<const char *> argv = {"prog", Path1.c_str(), Path2.c_str()};
+
+  int argc = argv.size();
+  int YCount = 0;
+  int Result = executeFromCommandLineArgs(
+      argc, &argv[0], consumeASTs([&](ASTContext &Ctx) {
+        DeclarationName Y(&Ctx.Idents.get("y"));
+        YCount += Ctx.getTranslationUnitDecl()->lookup(Y).isSingleResult();
+      }));
+  EXPECT_EQ(Result, 0);
+  EXPECT_EQ(YCount, 1);
+}
+
 TEST(StandaloneToolTest, SynctaxOnlyActionOnSimpleCode) {
   FixedCompilationDatabase Compilations(".", std::vector<std::string>());
   StandaloneToolExecutor Executor(Compilations,
                                   std::vector<std::string>(1, "a.cc"));
   Executor.mapVirtualFile("a.cc", "int x = 0;");
 
-  auto Err = Executor.execute(newFrontendActionFactory<SyntaxOnlyAction>(),
-                              getClangSyntaxOnlyAdjuster());
+  auto Err = Executor.execute({newFrontendActionFactory<SyntaxOnlyAction>(),
+                               getClangSyntaxOnlyAdjuster()});
   ASSERT_TRUE(!Err);
 }
 
Index: clang/lib/Tooling/Tooling.cpp
===================================================================
--- clang/lib/Tooling/Tooling.cpp
+++ clang/lib/Tooling/Tooling.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Tooling/Tooling.h"
+#include "clang/AST/ASTConsumer.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticIDs.h"
 #include "clang/Basic/DiagnosticOptions.h"
@@ -27,6 +28,7 @@
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/FrontendAction.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/FrontendOptions.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
@@ -35,7 +37,9 @@
 #include "clang/Tooling/ArgumentsAdjusters.h"
 #include "clang/Tooling/CompilationDatabase.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/FunctionExtras.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/STLFunctionalExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Twine.h"
@@ -709,5 +713,31 @@
   return std::move(ASTs[0]);
 }
 
+std::unique_ptr<FrontendActionFactory>
+consumeASTs(llvm::unique_function<void(ASTContext &) const> Func) {
+  using Delegate = llvm::unique_function<void(ASTContext &) const>;
+  struct Consumer : public ASTConsumer {
+    const Delegate &Func;
+    Consumer(const Delegate &Func) : Func(Func) {}
+    void HandleTranslationUnit(ASTContext &Ctx) override { Func(Ctx); }
+  };
+  struct Action : public ASTFrontendAction {
+    const Delegate &Func;
+    Action(const Delegate &Func) : Func(Func) {}
+    std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &,
+                                                   StringRef) override {
+      return std::make_unique<Consumer>(Func);
+    }
+  };
+  struct Factory : public FrontendActionFactory {
+    Delegate Func;
+    Factory(Delegate Func) : Func(std::move(Func)) {}
+    std::unique_ptr<FrontendAction> create() override {
+      return std::make_unique<Action>(Func);
+    }
+  };
+  return std::make_unique<Factory>(std::move(Func));
+}
+
 } // namespace tooling
 } // namespace clang
Index: clang/lib/Tooling/StandaloneExecution.cpp
===================================================================
--- clang/lib/Tooling/StandaloneExecution.cpp
+++ clang/lib/Tooling/StandaloneExecution.cpp
@@ -49,10 +49,7 @@
   Tool.clearArgumentsAdjusters();
 }
 
-llvm::Error StandaloneToolExecutor::execute(
-    llvm::ArrayRef<
-        std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
-        Actions) {
+llvm::Error StandaloneToolExecutor::execute(llvm::ArrayRef<Action> Actions) {
   if (Actions.empty())
     return make_string_error("No action to execute.");
 
@@ -61,9 +58,9 @@
         "Only support executing exactly 1 action at this point.");
 
   auto &Action = Actions.front();
-  Tool.appendArgumentsAdjuster(Action.second);
+  Tool.appendArgumentsAdjuster(Action.Adjuster);
   Tool.appendArgumentsAdjuster(ArgsAdjuster);
-  if (Tool.run(Action.first.get()))
+  if (Tool.run(Action.Factory.get()))
     return make_string_error("Failed to run action.");
 
   return llvm::Error::success();
Index: clang/lib/Tooling/Execution.cpp
===================================================================
--- clang/lib/Tooling/Execution.cpp
+++ clang/lib/Tooling/Execution.cpp
@@ -9,6 +9,10 @@
 #include "clang/Tooling/Execution.h"
 #include "clang/Tooling/ToolExecutorPluginRegistry.h"
 #include "clang/Tooling/Tooling.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/raw_ostream.h"
+#include <utility>
 
 LLVM_INSTANTIATE_REGISTRY(clang::tooling::ToolExecutorPluginRegistry)
 
@@ -39,19 +43,7 @@
   Results->addResult(Key, Value);
 }
 
-llvm::Error
-ToolExecutor::execute(std::unique_ptr<FrontendActionFactory> Action) {
-  return execute(std::move(Action), ArgumentsAdjuster());
-}
-
-llvm::Error ToolExecutor::execute(std::unique_ptr<FrontendActionFactory> Action,
-                                  ArgumentsAdjuster Adjuster) {
-  std::vector<
-      std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
-      Actions;
-  Actions.emplace_back(std::move(Action), std::move(Adjuster));
-  return execute(Actions);
-}
+llvm::Error ToolExecutor::execute(Action A) { return execute(ArrayRef(A)); }
 
 namespace internal {
 llvm::Expected<std::unique_ptr<ToolExecutor>>
@@ -92,6 +84,23 @@
                                                          Overview);
 }
 
+int executeFromCommandLineArgs(int &argc, const char **argv,
+                               ToolExecutor::Action Action,
+                               const char *Overview) {
+  static llvm::cl::OptionCategory Category("Execution options");
+  auto Exec = createExecutorFromCommandLineArgs(argc, argv, Category, Overview);
+  if (!Exec) {
+    llvm::errs() << toString(Exec.takeError());
+    return 1;
+  }
+  auto Err = (*Exec)->execute(std::move(Action));
+  if (Err) {
+    llvm::errs() << toString(std::move(Err));
+    return 2;
+  }
+  return 0;
+}
+
 // This anchor is used to force the linker to link in the generated object file
 // and thus register the StandaloneToolExecutorPlugin etc.
 extern volatile int StandaloneToolExecutorAnchorSource;
Index: clang/lib/Tooling/AllTUsExecution.cpp
===================================================================
--- clang/lib/Tooling/AllTUsExecution.cpp
+++ clang/lib/Tooling/AllTUsExecution.cpp
@@ -75,10 +75,7 @@
       Results(new ThreadSafeToolResults), Context(Results.get()),
       ThreadCount(ThreadCount) {}
 
-llvm::Error AllTUsToolExecutor::execute(
-    llvm::ArrayRef<
-        std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
-        Actions) {
+llvm::Error AllTUsToolExecutor::execute(llvm::ArrayRef<Action> Actions) {
   if (Actions.empty())
     return make_string_error("No action to execute.");
 
@@ -127,12 +124,12 @@
                 llvm::vfs::createPhysicalFileSystem();
             ClangTool Tool(Compilations, {Path},
                            std::make_shared<PCHContainerOperations>(), FS);
-            Tool.appendArgumentsAdjuster(Action.second);
+            Tool.appendArgumentsAdjuster(Action.Adjuster);
             Tool.appendArgumentsAdjuster(getDefaultArgumentsAdjusters());
             for (const auto &FileAndContent : OverlayFiles)
               Tool.mapVirtualFile(FileAndContent.first(),
                                   FileAndContent.second);
-            if (Tool.run(Action.first.get()))
+            if (Tool.run(Action.Factory.get()))
               AppendError(llvm::Twine("Failed to run action on ") + Path +
                           "\n");
           },
Index: clang/include/clang/Tooling/Tooling.h
===================================================================
--- clang/include/clang/Tooling/Tooling.h
+++ clang/include/clang/Tooling/Tooling.h
@@ -36,6 +36,7 @@
 #include "clang/Frontend/PCHContainerOperations.h"
 #include "clang/Tooling/ArgumentsAdjusters.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/FunctionExtras.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
@@ -122,6 +123,18 @@
                                     std::is_base_of_v<ASTConsumer, T>>>
 std::unique_ptr<FrontendActionFactory> newFrontendActionFactory();
 
+/// Allows a function that accepts ASTs to be used as a FrontendActionFactory.
+///
+/// Example:
+///   Executor->execute(consumeASTs([&](ASTContext &Ctx) {
+///      Ctx.getTranslationUnitDecl()->dump();
+///   }));
+///
+/// This is suitable for actions that merely consume the AST that clang builds.
+/// It does not provide a way to customize the preprocessor etc.
+std::unique_ptr<FrontendActionFactory>
+    consumeASTs(llvm::unique_function<void(ASTContext &) const>);
+
 /// Callbacks called before and after each source file processed by a
 /// FrontendAction created by the FrontedActionFactory returned by \c
 /// newFrontendActionFactory.
Index: clang/include/clang/Tooling/StandaloneExecution.h
===================================================================
--- clang/include/clang/Tooling/StandaloneExecution.h
+++ clang/include/clang/Tooling/StandaloneExecution.h
@@ -55,10 +55,7 @@
 
   using ToolExecutor::execute;
 
-  llvm::Error
-  execute(llvm::ArrayRef<
-          std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
-              Actions) override;
+  llvm::Error execute(llvm::ArrayRef<Action> Actions) override;
 
   /// Set a \c DiagnosticConsumer to use during parsing.
   void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
Index: clang/include/clang/Tooling/Execution.h
===================================================================
--- clang/include/clang/Tooling/Execution.h
+++ clang/include/clang/Tooling/Execution.h
@@ -115,17 +115,23 @@
   /// Returns the name of a specific executor.
   virtual StringRef getExecutorName() const = 0;
 
+  /// A frontend action to be executed, with optional ArgumentsAdjuster.
+  struct Action {
+    Action(std::unique_ptr<FrontendActionFactory> Factory)
+        : Factory(std::move(Factory)) {}
+    Action(std::unique_ptr<FrontendActionFactory> Factory,
+           ArgumentsAdjuster Adjuster)
+        : Factory(std::move(Factory)), Adjuster(std::move(Adjuster)) {}
+
+    std::unique_ptr<FrontendActionFactory> Factory;
+    ArgumentsAdjuster Adjuster;
+  };
   /// Executes each action with a corresponding arguments adjuster.
-  virtual llvm::Error
-  execute(llvm::ArrayRef<
-          std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
-              Actions) = 0;
+  /// FIXME: the ability to execute multiple actions appears unused, remove it?
+  virtual llvm::Error execute(llvm::ArrayRef<Action> Actions) = 0;
 
   /// Convenient functions for the above `execute`.
-  llvm::Error execute(std::unique_ptr<FrontendActionFactory> Action);
-  /// Executes an action with an argument adjuster.
-  llvm::Error execute(std::unique_ptr<FrontendActionFactory> Action,
-                      ArgumentsAdjuster Adjuster);
+  llvm::Error execute(Action);
 
   /// Returns a reference to the execution context.
   ///
@@ -178,8 +184,24 @@
 createExecutorFromCommandLineArgsImpl(int &argc, const char **argv,
                                       llvm::cl::OptionCategory &Category,
                                       const char *Overview = nullptr);
+
 } // end namespace internal
 
+/// Runs an action on inputs specified by the command-line arguments.
+///
+/// If errors occur, they are reported to llvm::errs() and nonzero is returned:
+///   1 indicates bad tooling flags (failed to initialize executor)
+///   2 indicates parsing errors on some files
+///
+/// Expected usage is from main():
+///   int main(int argc, const char **argv) {
+///     return executeFromCommandLineArgs(argc, argv,
+///       consumeASTs([](ASTContext &C){ C.getTranslationUnitDecl()->dump(); });
+///   }
+int executeFromCommandLineArgs(int &argc, const char **argv,
+                               ToolExecutor::Action,
+                               const char *Overview = nullptr);
+
 } // end namespace tooling
 } // end namespace clang
 
Index: clang/include/clang/Tooling/AllTUsExecution.h
===================================================================
--- clang/include/clang/Tooling/AllTUsExecution.h
+++ clang/include/clang/Tooling/AllTUsExecution.h
@@ -47,10 +47,7 @@
 
   using ToolExecutor::execute;
 
-  llvm::Error
-  execute(llvm::ArrayRef<
-          std::pair<std::unique_ptr<FrontendActionFactory>, ArgumentsAdjuster>>
-              Actions) override;
+  llvm::Error execute(llvm::ArrayRef<Action> Actions) override;
 
   ExecutionContext *getExecutionContext() override { return &Context; };
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to