From: Daniel Dunbar Date: Wed, 16 Jun 2010 16:59:23 +0000 (+0000) Subject: Frontend: Allow passing -cc1 level arguments to plugins. Patch by Troy Straszheim! X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3177aae51a21f61ab483c52f97124bdb707da7f1;p=clang Frontend: Allow passing -cc1 level arguments to plugins. Patch by Troy Straszheim! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106113 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/examples/PrintFunctionNames/PrintFunctionNames.cpp b/examples/PrintFunctionNames/PrintFunctionNames.cpp index 5b7b66a4f7..397cf843fa 100644 --- a/examples/PrintFunctionNames/PrintFunctionNames.cpp +++ b/examples/PrintFunctionNames/PrintFunctionNames.cpp @@ -31,11 +31,24 @@ public: } }; -class PrintFunctionNamesAction : public ASTFrontendAction { +class PrintFunctionNamesAction : public PluginASTAction { protected: ASTConsumer *CreateASTConsumer(CompilerInstance &CI, llvm::StringRef) { return new PrintFunctionsConsumer(); } + + bool ParseArgs(const std::vector& args) { + for (unsigned i=0; i, def o : Separate<"-o">, MetaVarName<"">, HelpText<"Specify output file">; def load : Separate<"-load">, MetaVarName<"">, HelpText<"Load the named plugin (dynamic shared object)">; -def plugin : Separate<"-plugin">, +def plugin : Separate<"-plugin">, MetaVarName<"">, HelpText<"Use the named plugin action (use \"help\" to list available options)">; +def plugin_arg : JoinedAndSeparate<"-plugin-arg-">, + MetaVarName<" ">, + HelpText<"Pass to plugin ">; def resource_dir : Separate<"-resource-dir">, HelpText<"The directory which holds the compiler resource files">; def version : Flag<"-version">, diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h index b16a6aa509..f6a68bf69e 100644 --- a/include/clang/Frontend/FrontendAction.h +++ b/include/clang/Frontend/FrontendAction.h @@ -13,6 +13,11 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/OwningPtr.h" #include +#include + +namespace llvm { + class raw_ostream; +} namespace clang { class ASTConsumer; @@ -214,6 +219,16 @@ public: virtual bool usesPreprocessorOnly() const { return false; } }; +class PluginASTAction : public ASTFrontendAction { +protected: + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile) = 0; + +public: + virtual bool ParseArgs(const std::vector& arg) = 0; + virtual void PrintHelp(llvm::raw_ostream&) = 0; +}; + /// PreprocessorFrontendAction - Abstract base class to use for preprocessor /// based frontend actions. class PreprocessorFrontendAction : public FrontendAction { diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h index 07e062ed6b..0f4538976d 100644 --- a/include/clang/Frontend/FrontendOptions.h +++ b/include/clang/Frontend/FrontendOptions.h @@ -94,6 +94,9 @@ public: /// The name of the action to run when using a plugin action. std::string ActionName; + /// Arg to pass to the plugin + std::vector PluginArgs; + /// The list of plugins to load. std::vector Plugins; diff --git a/include/clang/Frontend/FrontendPluginRegistry.h b/include/clang/Frontend/FrontendPluginRegistry.h index 8341492cfd..ec925adb01 100644 --- a/include/clang/Frontend/FrontendPluginRegistry.h +++ b/include/clang/Frontend/FrontendPluginRegistry.h @@ -16,7 +16,7 @@ namespace clang { /// The frontend plugin registry. -typedef llvm::Registry FrontendPluginRegistry; +typedef llvm::Registry FrontendPluginRegistry; } // end namespace clang diff --git a/lib/Driver/OptTable.cpp b/lib/Driver/OptTable.cpp index 618ba8e996..39530f211d 100644 --- a/lib/Driver/OptTable.cpp +++ b/lib/Driver/OptTable.cpp @@ -267,7 +267,7 @@ static std::string getOptionHelpName(const OptTable &Opts, OptSpecifier Id) { case Option::GroupClass: case Option::InputClass: case Option::UnknownClass: assert(0 && "Invalid option with help text."); - case Option::MultiArgClass: case Option::JoinedAndSeparateClass: + case Option::MultiArgClass: assert(0 && "Cannot print metavar for this kind of option."); case Option::FlagClass: @@ -277,6 +277,7 @@ static std::string getOptionHelpName(const OptTable &Opts, OptSpecifier Id) { Name += ' '; // FALLTHROUGH case Option::JoinedClass: case Option::CommaJoinedClass: + case Option::JoinedAndSeparateClass: if (const char *MetaVarName = Opts.getOptionMetaVar(Id)) Name += MetaVarName; else diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index d74052fd99..a925047d94 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -397,6 +397,10 @@ static void FrontendOptsToArgs(const FrontendOptions &Opts, if (!Opts.ActionName.empty()) { Res.push_back("-plugin"); Res.push_back(Opts.ActionName); + for(unsigned i = 0, e = Opts.PluginArgs.size(); i != e; ++i) { + Res.push_back("-plugin-arg-" + Opts.ActionName); + Res.push_back(Opts.PluginArgs[i]); + } } for (unsigned i = 0, e = Opts.Plugins.size(); i != e; ++i) { Res.push_back("-load"); @@ -989,9 +993,17 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.ProgramAction = frontend::RunPreprocessorOnly; break; } } - if (const Arg *A = Args.getLastArg(OPT_plugin)) { + + if (const Arg* A = Args.getLastArg(OPT_plugin)) { + Opts.Plugins.push_back(A->getValue(Args,0)); Opts.ProgramAction = frontend::PluginAction; Opts.ActionName = A->getValue(Args); + + for (arg_iterator it = Args.filtered_begin(OPT_plugin_arg), + end = Args.filtered_end(); it != end; ++it) { + if ((*it)->getValue(Args, 0) == Opts.ActionName) + Opts.PluginArgs.push_back((*it)->getValue(Args, 1)); + } } if (const Arg *A = Args.getLastArg(OPT_code_completion_at)) { diff --git a/tools/driver/cc1_main.cpp b/tools/driver/cc1_main.cpp index c4c1bd9e8b..841e40abfc 100644 --- a/tools/driver/cc1_main.cpp +++ b/tools/driver/cc1_main.cpp @@ -85,21 +85,15 @@ static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) { case ParseSyntaxOnly: return new SyntaxOnlyAction(); case PluginAction: { - if (CI.getFrontendOpts().ActionName == "help") { - llvm::errs() << "clang -cc1 plugins:\n"; - for (FrontendPluginRegistry::iterator it = - FrontendPluginRegistry::begin(), - ie = FrontendPluginRegistry::end(); - it != ie; ++it) - llvm::errs() << " " << it->getName() << " - " << it->getDesc() << "\n"; - return 0; - } for (FrontendPluginRegistry::iterator it = FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); it != ie; ++it) { - if (it->getName() == CI.getFrontendOpts().ActionName) - return it->instantiate(); + if (it->getName() == CI.getFrontendOpts().ActionName) { + PluginASTAction* plugin = it->instantiate(); + plugin->ParseArgs(CI.getFrontendOpts().PluginArgs); + return plugin; + } } CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name)