[clang] 3e67cf2 - [clang][driver] Add -fplugin-arg- to pass arguments to plugins
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Thu Nov 25 01:54:50 PST 2021
Author: Timm Bäder
Date: 2021-11-25T10:47:55+01:00
New Revision: 3e67cf21a19a0e8917bdbab6f0cecd4880f3fbe2
URL: https://github.com/llvm/llvm-project/commit/3e67cf21a19a0e8917bdbab6f0cecd4880f3fbe2
DIFF: https://github.com/llvm/llvm-project/commit/3e67cf21a19a0e8917bdbab6f0cecd4880f3fbe2.diff
LOG: [clang][driver] Add -fplugin-arg- to pass arguments to plugins
>From GCC's manpage:
-fplugin-arg-name-key=value
Define an argument called key with a value of value for the
plugin called name.
Since we don't have a key-value pair similar to gcc's plugin_argument
struct, simply accept key=value here anyway and pass it along as-is to
plugins.
This translates to the already existing '-plugin-arg-pluginname arg'
that clang cc1 accepts.
There is an ambiguity here because in clang, both the plugin name
as well as the option name can contain dashes, so when e.g. passing
-fplugin-arg-foo-bar-foo
it is not clear whether the plugin is foo-bar and the option is foo,
or the plugin is foo and the option is bar-foo. GCC solves this by
interpreting all dashes as part of the option name. So dashes can't be
part of the plugin name in this case.
Differential Revision: https://reviews.llvm.org/D113250
Added:
clang/test/Driver/plugin-driver-args.cpp
Modified:
clang/docs/ClangPlugins.rst
clang/docs/ReleaseNotes.rst
clang/examples/CallSuperAttribute/CallSuperAttrInfo.cpp
clang/include/clang/Basic/DiagnosticDriverKinds.td
clang/include/clang/Driver/Options.td
clang/lib/Driver/ToolChains/Clang.cpp
clang/test/Frontend/plugin-call-super.cpp
Removed:
################################################################################
diff --git a/clang/docs/ClangPlugins.rst b/clang/docs/ClangPlugins.rst
index 3183eec1823d6..cf2c8721c12ae 100644
--- a/clang/docs/ClangPlugins.rst
+++ b/clang/docs/ClangPlugins.rst
@@ -125,6 +125,28 @@ Running the plugin
==================
+Using the compiler driver
+--------------------------
+
+The Clang driver accepts the `-fplugin` option to load a plugin.
+Clang plugins can receive arguments from the compiler driver command
+line via the `fplugin-arg-<plugin name>-<argument>` option. Using this
+method, the plugin name cannot contain dashes itself, but the argument
+passed to the plugin can.
+
+
+.. code-block:: console
+
+ $ export BD=/path/to/build/directory
+ $ make -C $BD CallSuperAttr
+ $ clang++ -fplugin=$BD/lib/CallSuperAttr.so \
+ -fplugin-arg-call_super_plugin-help \
+ test.cpp
+
+If your plugin name contains dashes, either rename the plugin or used the
+cc1 command line options listed below.
+
+
Using the cc1 command line
--------------------------
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 104d2e908d809..df2a6e71c534b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -62,7 +62,8 @@ Non-comprehensive list of changes in this release
New Compiler Flags
------------------
-- ...
+- Clang plugin arguments can now be passed through the compiler driver via
+ ``-fplugin-arg-pluginname-arg``, similar to GCC's ``-fplugin-arg``.
Deprecated Compiler Flags
-------------------------
diff --git a/clang/examples/CallSuperAttribute/CallSuperAttrInfo.cpp b/clang/examples/CallSuperAttribute/CallSuperAttrInfo.cpp
index 331f63508045b..21460e4f6bd06 100644
--- a/clang/examples/CallSuperAttribute/CallSuperAttrInfo.cpp
+++ b/clang/examples/CallSuperAttribute/CallSuperAttrInfo.cpp
@@ -145,6 +145,8 @@ class CallSuperAction : public PluginASTAction {
bool ParseArgs(const CompilerInstance &CI,
const std::vector<std::string> &args) override {
+ if (!args.empty() && args[0] == "help")
+ llvm::errs() << "Help for the CallSuperAttr plugin goes here\n";
return true;
}
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index ff8c36910e13e..74dbb3d98a864 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -189,6 +189,12 @@ def err_drv_invalid_mtp : Error<
"invalid thread pointer reading mode '%0'">;
def err_drv_missing_arg_mtp : Error<
"missing argument to '%0'">;
+def warn_drv_missing_plugin_name : Warning<
+ "missing plugin name in %0">,
+ InGroup<InvalidCommandLineArgument>;
+def warn_drv_missing_plugin_arg : Warning<
+ "missing plugin argument for plugin %0 in %1">,
+ InGroup<InvalidCommandLineArgument>;
def err_drv_invalid_libcxx_deployment : Error<
"invalid deployment target for -stdlib=libc++ (requires %0 or later)">;
def err_drv_invalid_argument_to_option : Error<
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 7730b7d1915e4..cf314bc73bf31 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2504,6 +2504,9 @@ defm rwpi : BoolFOption<"rwpi",
NegFlag<SetFalse>>;
def fplugin_EQ : Joined<["-"], "fplugin=">, Group<f_Group>, Flags<[NoXarchOption]>, MetaVarName<"<dsopath>">,
HelpText<"Load the named plugin (dynamic shared object)">;
+def fplugin_arg : Joined<["-"], "fplugin-arg-">,
+ MetaVarName<"<name>-<arg>">,
+ HelpText<"Pass <arg> to plugin <name>">;
def fpass_plugin_EQ : Joined<["-"], "fpass-plugin=">,
Group<f_Group>, Flags<[CC1Option]>, MetaVarName<"<dsopath>">,
HelpText<"Load pass plugin from a dynamic shared object file (only with new pass manager).">,
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 55518cd7926fb..0f20abac043ca 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6659,6 +6659,35 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
A->claim();
}
+ // Turn -fplugin-arg-pluginname-key=value into
+ // -plugin-arg-pluginname key=value
+ // GCC has an actual plugin_argument struct with key/value pairs that it
+ // passes to its plugins, but we don't, so just pass it on as-is.
+ //
+ // The syntax for -fplugin-arg- is ambiguous if both plugin name and
+ // argument key are allowed to contain dashes. GCC therefore only
+ // allows dashes in the key. We do the same.
+ for (const Arg *A : Args.filtered(options::OPT_fplugin_arg)) {
+ auto ArgValue = StringRef(A->getValue());
+ auto FirstDashIndex = ArgValue.find('-');
+ StringRef PluginName = ArgValue.substr(0, FirstDashIndex);
+ StringRef Arg = ArgValue.substr(FirstDashIndex + 1);
+
+ A->claim();
+ if (FirstDashIndex == StringRef::npos || Arg.empty()) {
+ if (PluginName.empty()) {
+ D.Diag(diag::warn_drv_missing_plugin_name) << A->getAsString(Args);
+ } else {
+ D.Diag(diag::warn_drv_missing_plugin_arg)
+ << PluginName << A->getAsString(Args);
+ }
+ continue;
+ }
+
+ CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-arg-") + PluginName));
+ CmdArgs.push_back(Args.MakeArgString(Arg));
+ }
+
// Forward -fpass-plugin=name.so to -cc1.
for (const Arg *A : Args.filtered(options::OPT_fpass_plugin_EQ)) {
CmdArgs.push_back(
diff --git a/clang/test/Driver/plugin-driver-args.cpp b/clang/test/Driver/plugin-driver-args.cpp
new file mode 100644
index 0000000000000..d6475b4b3d733
--- /dev/null
+++ b/clang/test/Driver/plugin-driver-args.cpp
@@ -0,0 +1,22 @@
+/// Test passing args to plugins via the clang driver and -fplugin-arg
+// RUN: %clang -fplugin=%llvmshlibdir/CallSuperAttr%pluginext -fplugin-arg-call_super_plugin-help -fsyntax-only -### %s 2>&1 | FileCheck %s
+
+// CHECK: "-load"
+// CHECK-SAME: CallSuperAttr
+// CHECK-SAME: "-plugin-arg-call_super_plugin"
+// CHECK-SAME: "help"
+
+/// Check that dashed-args get forwarded like this to the plugin.
+/// Dashes cannot be part of the plugin name here
+// RUN: %clang -fplugin=%llvmshlibdir/CallSuperAttr%pluginext -fplugin-arg-call_super_plugin-help-long -fsyntax-only %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CMD
+// CHECK-CMD: "-plugin-arg-call_super_plugin" "help-long"
+
+/// Error handling for -fplugin-arg-
+// RUN: %clang -fplugin=%llvmshlibdir/CallSuperAttr%pluginext -fplugin-arg- -fsyntax-only %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-PLUGIN-NAME
+// CHECK-NO-PLUGIN-NAME: missing plugin name in -fplugin-arg-
+
+// RUN: %clang -fplugin=%llvmshlibdir/CallSuperAttr%pluginext -fplugin-arg-testname -fsyntax-only %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-PLUGIN-ARG1
+// CHECK-NO-PLUGIN-ARG1: missing plugin argument for plugin testname in -fplugin-arg-testname
+
+// RUN: %clang -fplugin=%llvmshlibdir/CallSuperAttr%pluginext -fplugin-arg-testname- -fsyntax-only %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-PLUGIN-ARG2
+// CHECK-NO-PLUGIN-ARG2: missing plugin argument for plugin testname in -fplugin-arg-testname-
diff --git a/clang/test/Frontend/plugin-call-super.cpp b/clang/test/Frontend/plugin-call-super.cpp
index 46b4adf9bebba..4049eb0a86c60 100644
--- a/clang/test/Frontend/plugin-call-super.cpp
+++ b/clang/test/Frontend/plugin-call-super.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang -fplugin=%llvmshlibdir/CallSuperAttr%pluginext -fsyntax-only -Xclang -verify=callsuper %s
-// RUN: %clang -fplugin=%llvmshlibdir/CallSuperAttr%pluginext -DBAD_CALLSUPER -fsyntax-only -Xclang -verify=badcallsuper %s
+// RUN: %clang_cc1 -load %llvmshlibdir/CallSuperAttr%pluginext -fsyntax-only -verify=callsuper %s
+// RUN: %clang_cc1 -load %llvmshlibdir/CallSuperAttr%pluginext -DBAD_CALLSUPER -fsyntax-only -verify=badcallsuper %s
// REQUIRES: plugins, examples
// callsuper-no-diagnostics
More information about the cfe-commits
mailing list