]> granicus.if.org Git - clang/commitdiff
Frontend: Allow passing -cc1 level arguments to plugins. Patch by Troy Straszheim!
authorDaniel Dunbar <daniel@zuster.org>
Wed, 16 Jun 2010 16:59:23 +0000 (16:59 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Wed, 16 Jun 2010 16:59:23 +0000 (16:59 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106113 91177308-0d34-0410-b5e6-96231b3b80d8

examples/PrintFunctionNames/PrintFunctionNames.cpp
include/clang/Driver/CC1Options.td
include/clang/Frontend/FrontendAction.h
include/clang/Frontend/FrontendOptions.h
include/clang/Frontend/FrontendPluginRegistry.h
lib/Driver/OptTable.cpp
lib/Frontend/CompilerInvocation.cpp
tools/driver/cc1_main.cpp

index 5b7b66a4f7ffda167820aa4ecf313a2f4fa1a8ef..397cf843fa7f99af5dc38ca17b1d7690b2a32024 100644 (file)
@@ -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";
+  }
+
 };
 
 }
index 7e639b514ed472baa8399ea1f0ca146e43f8a5b1..ab9f902743507567f5252767bf5e4a58f94803ff 100644 (file)
@@ -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">,
index b16a6aa5093de45b8b4bfb63c58a366e75a05a74..f6a68bf69e891c79ffa346e82daca302138e5654 100644 (file)
 #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 {
index 07e062ed6ba6926ea87eeedf222f9422fc44d729..0f4538976d5746910cba9bf7a2d0d747681de5fa 100644 (file)
@@ -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;
 
index 8341492cfd23b78b7eb6c34f6f924124c6ad6914..ec925adb01860846d9510de326c4296bbd11ba6f 100644 (file)
@@ -16,7 +16,7 @@
 namespace clang {
 
 /// The frontend plugin registry.
-typedef llvm::Registry<FrontendAction> FrontendPluginRegistry;
+typedef llvm::Registry<PluginASTAction> FrontendPluginRegistry;
 
 } // end namespace clang
 
index 618ba8e9964e158f2ec779007913de2a0627e27e..39530f211d808c1fb4fb7e967c768c23cd446c6c 100644 (file)
@@ -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
index d74052fd99d0e31c66406f396a41e0f0a753b91c..a925047d9456b7418fa0084b56784735dcbfd1ff 100644 (file)
@@ -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)) {
index c4c1bd9e8bf624bed4457c5b21bf2b0714d52ebf..841e40abfc7509daeffedcee912832110d4d5571 100644 (file)
@@ -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)