Index: clang/docs/ClangPlugins.rst =================================================================== --- clang/docs/ClangPlugins.rst +++ clang/docs/ClangPlugins.rst @@ -125,6 +125,27 @@ ================== +Using the compiler driver +-------------------------- + +The clang compiler driver accepts the `fplugin` option to load a plugin. +Clang plugins can receive arguments from the compiler driver command +line via the `fplugin-arg--` option. + + +.. code-block:: console + + $ export BD=/path/to/build/directory + $ (cd $BD && make CallSuperAttr ) + $ clang++ -fplugin=$BD/lib/CallSuperAttr.so \ + -fplugin-arg-call_super_plugin-help \ + test.cpp + +Note that using this method, the plugin name cannot contain dashes itself. +Try renaming your plugin or use the cc1 command line options listed below +when needed. + + Using the cc1 command line -------------------------- Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -62,7 +62,8 @@ 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 ------------------------- Index: clang/examples/CallSuperAttribute/CallSuperAttrInfo.cpp =================================================================== --- clang/examples/CallSuperAttribute/CallSuperAttrInfo.cpp +++ clang/examples/CallSuperAttribute/CallSuperAttrInfo.cpp @@ -145,6 +145,14 @@ bool ParseArgs(const CompilerInstance &CI, const std::vector &args) override { + if (!args.empty()) { + if (args[0] == "help") { + llvm::errs() << "Help text for CallSuper plugin goes here\n"; + } else if (args[0] == "help-long") { + llvm::errs() << "A longer help text describing what the CallSuper " + << "plugin does goes here\n"; + } + } return true; } Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -2504,6 +2504,9 @@ NegFlag>; def fplugin_EQ : Joined<["-"], "fplugin=">, Group, Flags<[NoXarchOption]>, MetaVarName<"">, HelpText<"Load the named plugin (dynamic shared object)">; +def fplugin_arg : Joined<["-"], "fplugin-arg-">, + MetaVarName<"-">, + HelpText<"Pass to plugin ">; def fpass_plugin_EQ : Joined<["-"], "fpass-plugin=">, Group, Flags<[CC1Option]>, MetaVarName<"">, HelpText<"Load pass plugin from a dynamic shared object file (only with new pass manager).">, Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -6660,6 +6660,29 @@ 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('-'); + + if (FirstDashIndex == StringRef::npos) + continue; + + auto Arg = ArgValue.substr(FirstDashIndex + 1); + auto PluginName = ArgValue.substr(0, FirstDashIndex); + + CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-arg-") + PluginName)); + CmdArgs.push_back(Args.MakeArgString(Arg)); + A->claim(); + } + // Forward -fpass-plugin=name.so to -cc1. for (const Arg *A : Args.filtered(options::OPT_fpass_plugin_EQ)) { CmdArgs.push_back( Index: clang/test/Frontend/plugin-driver-args.cpp =================================================================== --- /dev/null +++ clang/test/Frontend/plugin-driver-args.cpp @@ -0,0 +1,15 @@ +// 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 +// REQUIRES: plugins, examples + +// CHECK: Help text for CallSuper plugin goes here + + +// 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-LONG +// CHECK-LONG: A longer help text describing what the CallSuper plugin does goes 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"