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 @@ -2501,6 +2501,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 @@ -6612,6 +6612,25 @@ 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('-'); + 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(