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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits