[clang] fe66433 - [clang] Add plugin ActionType to run command line plugin before main action
Arthur Eubanks via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 20 08:58:31 PDT 2021
Author: Arthur Eubanks
Date: 2021-10-20T08:58:20-07:00
New Revision: fe66433fe119819a033827610f7eae4cdd8b1470
URL: https://github.com/llvm/llvm-project/commit/fe66433fe119819a033827610f7eae4cdd8b1470
DIFF: https://github.com/llvm/llvm-project/commit/fe66433fe119819a033827610f7eae4cdd8b1470.diff
LOG: [clang] Add plugin ActionType to run command line plugin before main action
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.
Reviewed By: dblaikie
Differential Revision: https://reviews.llvm.org/D112096
Added:
clang/examples/PluginsOrder/CMakeLists.txt
clang/examples/PluginsOrder/PluginsOrder.cpp
clang/test/Frontend/plugins-order.c
Modified:
clang/examples/CMakeLists.txt
clang/include/clang/Frontend/FrontendAction.h
clang/lib/Frontend/FrontendAction.cpp
clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
clang/test/CMakeLists.txt
Removed:
################################################################################
diff --git a/clang/examples/CMakeLists.txt b/clang/examples/CMakeLists.txt
index 300d8d795c674..684d81d180278 100644
--- a/clang/examples/CMakeLists.txt
+++ b/clang/examples/CMakeLists.txt
@@ -8,3 +8,4 @@ add_subdirectory(PrintFunctionNames)
add_subdirectory(AnnotateFunctions)
add_subdirectory(Attribute)
add_subdirectory(CallSuperAttribute)
+add_subdirectory(PluginsOrder)
diff --git a/clang/examples/PluginsOrder/CMakeLists.txt b/clang/examples/PluginsOrder/CMakeLists.txt
new file mode 100644
index 0000000000000..289e234ac28c4
--- /dev/null
+++ b/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()
diff --git a/clang/examples/PluginsOrder/PluginsOrder.cpp b/clang/examples/PluginsOrder/PluginsOrder.cpp
new file mode 100644
index 0000000000000..e25ab7aceca85
--- /dev/null
+++ b/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", "");
diff --git a/clang/include/clang/Frontend/FrontendAction.h b/clang/include/clang/Frontend/FrontendAction.h
index dfefddfb45279..039f6f247b6d8 100644
--- a/clang/include/clang/Frontend/FrontendAction.h
+++ b/clang/include/clang/Frontend/FrontendAction.h
@@ -270,17 +270,18 @@ class PluginASTAction : public ASTFrontendAction {
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.
diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp
index 6b0a55d79039c..b56db78d3e71a 100644
--- a/clang/lib/Frontend/FrontendAction.cpp
+++ b/clang/lib/Frontend/FrontendAction.cpp
@@ -187,14 +187,19 @@ FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
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) &&
diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index dc8409f88dfad..8e18f33af0cbc 100644
--- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -79,7 +79,7 @@ CreateFrontendBaseAction(CompilerInstance &CI) {
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())]))
diff --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt
index 9bf791f93f32e..9a822f2915afd 100644
--- a/clang/test/CMakeLists.txt
+++ b/clang/test/CMakeLists.txt
@@ -97,6 +97,7 @@ if (CLANG_BUILD_EXAMPLES)
AnnotateFunctions
CallSuperAttr
clang-interpreter
+ PluginsOrder
PrintFunctionNames
)
endif ()
diff --git a/clang/test/Frontend/plugins-order.c b/clang/test/Frontend/plugins-order.c
new file mode 100644
index 0000000000000..355ec4fb0b257
--- /dev/null
+++ b/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
More information about the cfe-commits
mailing list