diff options
-rw-r--r-- | examples/PrintFunctionNames/PrintFunctionNames.cpp | 15 | ||||
-rw-r--r-- | include/clang/Driver/CC1Options.td | 5 | ||||
-rw-r--r-- | include/clang/Frontend/FrontendAction.h | 15 | ||||
-rw-r--r-- | include/clang/Frontend/FrontendOptions.h | 3 | ||||
-rw-r--r-- | include/clang/Frontend/FrontendPluginRegistry.h | 2 | ||||
-rw-r--r-- | lib/Driver/OptTable.cpp | 3 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 14 | ||||
-rw-r--r-- | tools/driver/cc1_main.cpp | 16 |
8 files changed, 57 insertions, 16 deletions
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<std::string>& args) { + for (unsigned i=0; i<args.size(); ++i) + llvm::errs() << "PrintFunctionNames arg = " << args[i] << "\n"; + if (args.size() && args[0] == "help") + PrintHelp(llvm::errs()); + + return true; + } + void PrintHelp(llvm::raw_ostream& ros) { + ros << "Help for PrintFunctionNames plugin goes here\n"; + } + }; } diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 7e639b514e..ab9f902743 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -264,8 +264,11 @@ def cxx_inheritance_view : Separate<"-cxx-inheritance-view">, def o : Separate<"-o">, MetaVarName<"<path>">, HelpText<"Specify output file">; def load : Separate<"-load">, MetaVarName<"<dsopath>">, HelpText<"Load the named plugin (dynamic shared object)">; -def plugin : Separate<"-plugin">, +def plugin : Separate<"-plugin">, MetaVarName<"<name>">, HelpText<"Use the named plugin action (use \"help\" to list available options)">; +def plugin_arg : JoinedAndSeparate<"-plugin-arg-">, + MetaVarName<"<name> <arg>">, + HelpText<"Pass <arg> to plugin <name>">; 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 <string> +#include <vector> + +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<std::string>& 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<std::string> PluginArgs; + /// The list of plugins to load. std::vector<std::string> 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<FrontendAction> FrontendPluginRegistry; +typedef llvm::Registry<PluginASTAction> 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) |