aeubanks created this revision.
aeubanks added reviewers: hans, dblaikie.
Herald added a subscriber: mgorny.
aeubanks requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Currently we have a way to run a plugin if specified on the command line
after the main action, and ways to unconditionally run the plugin before
or after the main action, but no way to run a plugin if specified on the
command line before the main action.

This introduces the missing option.

This is helpful because -clear-ast-before-backend clears the AST before
codegen, while some plugins may want access to the AST.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D112096

Files:
  clang/examples/CMakeLists.txt
  clang/examples/PluginsOrder/CMakeLists.txt
  clang/examples/PluginsOrder/PluginsOrder.cpp
  clang/include/clang/Frontend/FrontendAction.h
  clang/lib/Frontend/FrontendAction.cpp
  clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
  clang/test/CMakeLists.txt
  clang/test/Frontend/plugins-order.c

Index: clang/test/Frontend/plugins-order.c
===================================================================
--- /dev/null
+++ clang/test/Frontend/plugins-order.c
@@ -0,0 +1,12 @@
+// REQUIRES: plugins, examples
+
+// RUN: %clang_cc1 -load %llvmshlibdir/PluginsOrder%pluginext %s 2>&1 | FileCheck %s --check-prefix=ALWAYS
+// ALWAYS: always-before
+// ALWAYS-NEXT: always-after
+
+// RUN: %clang_cc1 -load %llvmshlibdir/PluginsOrder%pluginext %s -add-plugin cmd-after -add-plugin cmd-before 2>&1 | FileCheck %s --check-prefix=ALL
+// RUN: %clang_cc1 -load %llvmshlibdir/PluginsOrder%pluginext %s -add-plugin cmd-before -add-plugin cmd-after 2>&1 | FileCheck %s --check-prefix=ALL
+// ALL: cmd-before
+// ALL-NEXT: always-before
+// ALL-NEXT: cmd-after
+// ALL-NEXT: always-after
Index: clang/test/CMakeLists.txt
===================================================================
--- clang/test/CMakeLists.txt
+++ clang/test/CMakeLists.txt
@@ -97,6 +97,7 @@
     AnnotateFunctions
     CallSuperAttr
     clang-interpreter
+    PluginsOrder
     PrintFunctionNames
     )
 endif ()
Index: clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
===================================================================
--- clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -79,7 +79,7 @@
       if (Plugin.getName() == CI.getFrontendOpts().ActionName) {
         std::unique_ptr<PluginASTAction> P(Plugin.instantiate());
         if ((P->getActionType() != PluginASTAction::ReplaceAction &&
-             P->getActionType() != PluginASTAction::Cmdline) ||
+             P->getActionType() != PluginASTAction::CmdlineAfterMainAction) ||
             !P->ParseArgs(
                 CI,
                 CI.getFrontendOpts().PluginArgs[std::string(Plugin.getName())]))
Index: clang/lib/Frontend/FrontendAction.cpp
===================================================================
--- clang/lib/Frontend/FrontendAction.cpp
+++ clang/lib/Frontend/FrontendAction.cpp
@@ -187,14 +187,19 @@
        FrontendPluginRegistry::entries()) {
     std::unique_ptr<PluginASTAction> P = Plugin.instantiate();
     PluginASTAction::ActionType ActionType = P->getActionType();
-    if (ActionType == PluginASTAction::Cmdline) {
+    if (ActionType == PluginASTAction::CmdlineAfterMainAction ||
+        ActionType == PluginASTAction::CmdlineBeforeMainAction) {
       // This is O(|plugins| * |add_plugins|), but since both numbers are
       // way below 50 in practice, that's ok.
       if (llvm::any_of(CI.getFrontendOpts().AddPluginActions,
                        [&](const std::string &PluginAction) {
                          return PluginAction == Plugin.getName();
-                       }))
-        ActionType = PluginASTAction::AddAfterMainAction;
+                       })) {
+        if (ActionType == PluginASTAction::CmdlineBeforeMainAction)
+          ActionType = PluginASTAction::AddBeforeMainAction;
+        else
+          ActionType = PluginASTAction::AddAfterMainAction;
+      }
     }
     if ((ActionType == PluginASTAction::AddBeforeMainAction ||
          ActionType == PluginASTAction::AddAfterMainAction) &&
Index: clang/include/clang/Frontend/FrontendAction.h
===================================================================
--- clang/include/clang/Frontend/FrontendAction.h
+++ clang/include/clang/Frontend/FrontendAction.h
@@ -270,17 +270,18 @@
                          const std::vector<std::string> &arg) = 0;
 
   enum ActionType {
-    Cmdline,             ///< Action is determined by the cc1 command-line
-    ReplaceAction,       ///< Replace the main action
-    AddBeforeMainAction, ///< Execute the action before the main action
-    AddAfterMainAction   ///< Execute the action after the main action
+    CmdlineBeforeMainAction, ///< Execute the action before the main action if
+                             ///< on the command line
+    CmdlineAfterMainAction,  ///< Execute the action after the main action if on
+                             ///< the command line
+    ReplaceAction,           ///< Replace the main action
+    AddBeforeMainAction,     ///< Execute the action before the main action
+    AddAfterMainAction       ///< Execute the action after the main action
   };
   /// Get the action type for this plugin
   ///
-  /// \return The action type. If the type is Cmdline then by default the
-  /// plugin does nothing and what it does is determined by the cc1
-  /// command-line.
-  virtual ActionType getActionType() { return Cmdline; }
+  /// \return The action type. By default we use CmdlineAfterMainAction.
+  virtual ActionType getActionType() { return CmdlineAfterMainAction; }
 };
 
 /// Abstract base class to use for preprocessor-based frontend actions.
Index: clang/examples/PluginsOrder/PluginsOrder.cpp
===================================================================
--- /dev/null
+++ clang/examples/PluginsOrder/PluginsOrder.cpp
@@ -0,0 +1,117 @@
+//===- PluginsOrder.cpp ---------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/Frontend/FrontendPluginRegistry.h"
+using namespace clang;
+
+namespace {
+
+class AlwaysBeforeConsumer : public ASTConsumer {
+public:
+  void HandleTranslationUnit(ASTContext &) override {
+    llvm::errs() << "always-before\n";
+  }
+};
+
+class AlwaysBeforeAction : public PluginASTAction {
+public:
+  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+                                                 llvm::StringRef) override {
+    return std::make_unique<AlwaysBeforeConsumer>();
+  }
+
+  bool ParseArgs(const CompilerInstance &CI,
+                 const std::vector<std::string> &args) override {
+    return true;
+  }
+
+  PluginASTAction::ActionType getActionType() override {
+    return AddBeforeMainAction;
+  }
+};
+
+class AlwaysAfterConsumer : public ASTConsumer {
+public:
+  void HandleTranslationUnit(ASTContext &) override {
+    llvm::errs() << "always-after\n";
+  }
+};
+
+class AlwaysAfterAction : public PluginASTAction {
+public:
+  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+                                                 llvm::StringRef) override {
+    return std::make_unique<AlwaysAfterConsumer>();
+  }
+
+  bool ParseArgs(const CompilerInstance &CI,
+                 const std::vector<std::string> &args) override {
+    return true;
+  }
+
+  PluginASTAction::ActionType getActionType() override {
+    return AddAfterMainAction;
+  }
+};
+
+class CmdAfterConsumer : public ASTConsumer {
+public:
+  void HandleTranslationUnit(ASTContext &) override {
+    llvm::errs() << "cmd-after\n";
+  }
+};
+
+class CmdAfterAction : public PluginASTAction {
+public:
+  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+                                                 llvm::StringRef) override {
+    return std::make_unique<CmdAfterConsumer>();
+  }
+
+  bool ParseArgs(const CompilerInstance &CI,
+                 const std::vector<std::string> &args) override {
+    return true;
+  }
+
+  PluginASTAction::ActionType getActionType() override {
+    return CmdlineAfterMainAction;
+  }
+};
+
+class CmdBeforeConsumer : public ASTConsumer {
+public:
+  void HandleTranslationUnit(ASTContext &) override {
+    llvm::errs() << "cmd-before\n";
+  }
+};
+
+class CmdBeforeAction : public PluginASTAction {
+public:
+  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+                                                 llvm::StringRef) override {
+    return std::make_unique<CmdBeforeConsumer>();
+  }
+
+  bool ParseArgs(const CompilerInstance &CI,
+                 const std::vector<std::string> &args) override {
+    return true;
+  }
+
+  PluginASTAction::ActionType getActionType() override {
+    return CmdlineBeforeMainAction;
+  }
+};
+
+} // namespace
+
+static FrontendPluginRegistry::Add<CmdBeforeAction> X1("cmd-before", "");
+static FrontendPluginRegistry::Add<CmdAfterAction> X2("cmd-after", "");
+static FrontendPluginRegistry::Add<AlwaysBeforeAction> X3("always-before", "");
+static FrontendPluginRegistry::Add<AlwaysAfterAction> X4("always-after", "");
Index: clang/examples/PluginsOrder/CMakeLists.txt
===================================================================
--- /dev/null
+++ clang/examples/PluginsOrder/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_llvm_library(PluginsOrder MODULE PluginsOrder.cpp PLUGIN_TOOL clang)
+
+if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN))
+  set(LLVM_LINK_COMPONENTS
+    Support
+  )
+  clang_target_link_libraries(PluginsOrder PRIVATE
+    clangAST
+    clangFrontend
+    )
+endif()
Index: clang/examples/CMakeLists.txt
===================================================================
--- clang/examples/CMakeLists.txt
+++ clang/examples/CMakeLists.txt
@@ -8,3 +8,4 @@
 add_subdirectory(AnnotateFunctions)
 add_subdirectory(Attribute)
 add_subdirectory(CallSuperAttribute)
+add_subdirectory(PluginsOrder)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to