[llvm-commits] [llvm] r63172 - in /llvm/trunk: include/llvm/CompilerDriver/Common.td test/LLVMC/ExternOptions.td test/LLVMC/MultiValuedOption.td test/LLVMC/OneOrMore.td tools/llvmc/doc/LLVMC-Reference.rst utils/TableGen/LLVMCConfigurationEmitter.cpp

Mikhail Glushenkov foldr at codedgers.com
Tue Jan 27 19:47:20 PST 2009


Author: foldr
Date: Tue Jan 27 21:47:20 2009
New Revision: 63172

URL: http://llvm.org/viewvc/llvm-project?rev=63172&view=rev
Log:
Add three new option properties.

Adds new option properties 'multi_val', 'one_or_more' and 'zero_or_one'.

Added:
    llvm/trunk/test/LLVMC/MultiValuedOption.td
    llvm/trunk/test/LLVMC/OneOrMore.td
Modified:
    llvm/trunk/include/llvm/CompilerDriver/Common.td
    llvm/trunk/test/LLVMC/ExternOptions.td
    llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst
    llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp

Modified: llvm/trunk/include/llvm/CompilerDriver/Common.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/Common.td?rev=63172&r1=63171&r2=63172&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CompilerDriver/Common.td (original)
+++ llvm/trunk/include/llvm/CompilerDriver/Common.td Tue Jan 27 21:47:20 2009
@@ -36,11 +36,14 @@
 
 // Possible option properties.
 
+def extern;
 def help;
 def hidden;
+def multi_val;
+def one_or_more;
 def really_hidden;
 def required;
-def extern;
+def zero_or_one;
 
 // Empty DAG marker.
 def empty;

Modified: llvm/trunk/test/LLVMC/ExternOptions.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/ExternOptions.td?rev=63172&r1=63171&r2=63172&view=diff

==============================================================================
--- llvm/trunk/test/LLVMC/ExternOptions.td (original)
+++ llvm/trunk/test/LLVMC/ExternOptions.td Tue Jan 27 21:47:20 2009
@@ -1,6 +1,7 @@
 // Check that extern options work.
 // The dummy tool and graph are required to silence warnings.
-// RUN: tblgen -I $srcroot/include --gen-llvmc %s | grep {extern .* AutoGeneratedSwitch_Wall}
+// RUN: tblgen -I $srcroot/include --gen-llvmc %s -o %t
+// RUN: grep {extern .* AutoGeneratedSwitch_Wall} %t
 
 include "llvm/CompilerDriver/Common.td"
 

Added: llvm/trunk/test/LLVMC/MultiValuedOption.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/MultiValuedOption.td?rev=63172&view=auto

==============================================================================
--- llvm/trunk/test/LLVMC/MultiValuedOption.td (added)
+++ llvm/trunk/test/LLVMC/MultiValuedOption.td Tue Jan 27 21:47:20 2009
@@ -0,0 +1,21 @@
+// Check that multivalued options work.
+// The dummy tool and graph are required to silence warnings.
+// RUN: tblgen -I $srcroot/include --gen-llvmc %s -o %t
+// RUN: grep cl::multi_val(2) %t | count 1
+
+include "llvm/CompilerDriver/Common.td"
+
+def OptList : OptionList<[
+    (prefix_list_option "foo", (multi_val 2)),
+    (parameter_list_option "baz", (multi_val 2), (extern))]>;
+
+def dummy_tool : Tool<[
+(cmd_line "dummy_cmd"),
+(in_language "dummy"),
+(out_language "dummy"),
+(actions (case
+         (not_empty "foo"), (forward_as "foo", "bar"),
+         (not_empty "baz"), (forward "baz")))
+]>;
+
+def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>;

Added: llvm/trunk/test/LLVMC/OneOrMore.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/OneOrMore.td?rev=63172&view=auto

==============================================================================
--- llvm/trunk/test/LLVMC/OneOrMore.td (added)
+++ llvm/trunk/test/LLVMC/OneOrMore.td Tue Jan 27 21:47:20 2009
@@ -0,0 +1,22 @@
+// Check that (one_or_more) and (zero_or_one) properties work.
+// The dummy tool and graph are required to silence warnings.
+// RUN: tblgen -I $srcroot/include --gen-llvmc %s -o %t
+// RUN: grep cl::ZeroOrOne %t | count 1
+// RUN: grep cl::OneOrMore %t | count 1
+
+include "llvm/CompilerDriver/Common.td"
+
+def OptList : OptionList<[
+    (prefix_list_option "foo", (one_or_more)),
+    (parameter_list_option "baz", (zero_or_one))]>;
+
+def dummy_tool : Tool<[
+(cmd_line "dummy_cmd"),
+(in_language "dummy"),
+(out_language "dummy"),
+(actions (case
+         (not_empty "foo"), (forward_as "foo", "bar"),
+         (not_empty "baz"), (forward "baz")))
+]>;
+
+def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>;

Modified: llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst?rev=63172&r1=63171&r2=63172&view=diff

==============================================================================
--- llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst (original)
+++ llvm/trunk/tools/llvmc/doc/LLVMC-Reference.rst Tue Jan 27 21:47:20 2009
@@ -262,37 +262,47 @@
 
 * Possible option types:
 
-   - ``switch_option`` - a simple boolean switch without arguments,
-     for example ``-O2`` or ``-time``.
+   - ``switch_option`` - a simple boolean switch without arguments, for example
+     ``-O2`` or ``-time``. At most one occurrence is allowed.
 
-   - ``parameter_option`` - option that takes one argument, for
-     example ``-std=c99``. It is also allowed to use spaces instead of
-     the equality sign: ``-std c99``.
-
-   - ``parameter_list_option`` - same as the above, but more than one
-     option occurence is allowed.
-
-   - ``prefix_option`` - same as the parameter_option, but the option
-     name and argument do not have to be separated. Example:
-     ``-ofile``. This can be also specified as ``-o file``; however,
-     ``-o=file`` will be parsed incorrectly (``=file`` will be
-     interpreted as option value).
-
-   - ``prefix_list_option`` - same as the above, but more than one
-     occurence of the option is allowed; example: ``-lm -lpthread``.
-
-   - ``alias_option`` - a special option type for creating
-     aliases. Unlike other option types, aliases are not allowed to
-     have any properties besides the aliased option name. Usage
-     example: ``(alias_option "preprocess", "E")``
+   - ``parameter_option`` - option that takes one argument, for example
+     ``-std=c99``. It is also allowed to use spaces instead of the equality
+     sign: ``-std c99``. At most one occurrence is allowed.
+
+   - ``parameter_list_option`` - same as the above, but more than one option
+     occurence is allowed.
+
+   - ``prefix_option`` - same as the parameter_option, but the option name and
+     argument do not have to be separated. Example: ``-ofile``. This can be also
+     specified as ``-o file``; however, ``-o=file`` will be parsed incorrectly
+     (``=file`` will be interpreted as option value). At most one occurrence is
+     allowed.
+
+   - ``prefix_list_option`` - same as the above, but more than one occurence of
+     the option is allowed; example: ``-lm -lpthread``.
+
+   - ``alias_option`` - a special option type for creating aliases. Unlike other
+     option types, aliases are not allowed to have any properties besides the
+     aliased option name. Usage example: ``(alias_option "preprocess", "E")``
 
 
 * Possible option properties:
 
-   - ``help`` - help string associated with this option. Used for
-     ``--help`` output.
+   - ``help`` - help string associated with this option. Used for ``--help``
+     output.
 
-   - ``required`` - this option is obligatory.
+   - ``required`` - this option must be specified exactly once (or, in case of
+     the list options without the ``multi_val`` property, at least
+     once). Incompatible with ``zero_or_one`` and ``one_or_more``.
+
+   - ``one_or_more`` - the option must be specified at least one time. Useful
+     only for list options in conjunction with ``multi_val``; for ordinary lists
+     it is synonymous with ``required``. Incompatible with ``required`` and
+     ``zero_or_one``.
+
+   - ``zero_or_one`` - the option can be specified zero or one times. Useful
+     only for list options in conjunction with ``multi_val``. Incompatible with
+     ``required`` and ``one_or_more``.
 
    - ``hidden`` - the description of this option will not appear in
      the ``--help`` output (but will appear in the ``--help-hidden``
@@ -301,6 +311,11 @@
    - ``really_hidden`` - the option will not be mentioned in any help
      output.
 
+   - ``multi_val n`` - this option takes *n* arguments (can be useful in some
+     special cases). Usage example: ``(parameter_list_option "foo", (multi_val
+     3))``. Only list options can have this attribute; you can, however, use
+     the ``one_or_more`` and ``zero_or_one`` properties.
+
    - ``extern`` - this option is defined in some other plugin, see below.
 
 External options

Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=63172&r1=63171&r2=63172&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Tue Jan 27 21:47:20 2009
@@ -127,13 +127,19 @@
   return false;
 }
 
+template <class I, class S>
+void checkedIncrement(I& P, I E, S ErrorString) {
+  ++P;
+  if (P == E)
+    throw ErrorString;
+}
+
 //===----------------------------------------------------------------------===//
 /// Back-end specific code
 
 
 /// OptionType - One of six different option types. See the
 /// documentation for detailed description of differences.
-/// Extern* options are those that are defined in some other plugin.
 namespace OptionType {
   enum OptionType { Alias, Switch, Parameter, ParameterList,
                     Prefix, PrefixList};
@@ -171,7 +177,8 @@
 
 namespace OptionDescriptionFlags {
   enum OptionDescriptionFlags { Required = 0x1, Hidden = 0x2,
-                                ReallyHidden = 0x4, Extern = 0x8 };
+                                ReallyHidden = 0x4, Extern = 0x8,
+                                OneOrMore = 0x10, ZeroOrOne = 0x20 };
 }
 
 /// OptionDescription - Represents data contained in a single
@@ -181,11 +188,12 @@
   std::string Name;
   unsigned Flags;
   std::string Help;
+  unsigned MultiVal;
 
   OptionDescription(OptionType::OptionType t = OptionType::Switch,
                     const std::string& n = "",
                     const std::string& h = DefaultHelpString)
-    : Type(t), Name(n), Flags(0x0), Help(h)
+    : Type(t), Name(n), Flags(0x0), Help(h), MultiVal(1)
   {}
 
   /// GenTypeDeclaration - Returns the C++ variable type of this
@@ -203,17 +211,26 @@
 
   bool isAlias() const;
 
+  bool isMultiVal() const;
+
   bool isExtern() const;
   void setExtern();
 
   bool isRequired() const;
   void setRequired();
 
+  bool isOneOrMore() const;
+  void setOneOrMore();
+
+  bool isZeroOrOne() const;
+  void setZeroOrOne();
+
   bool isHidden() const;
   void setHidden();
 
   bool isReallyHidden() const;
   void setReallyHidden();
+
 };
 
 void OptionDescription::Merge (const OptionDescription& other)
@@ -235,6 +252,10 @@
   return Type == OptionType::Alias;
 }
 
+bool OptionDescription::isMultiVal() const {
+  return MultiVal == 1;
+}
+
 bool OptionDescription::isExtern() const {
   return Flags & OptionDescriptionFlags::Extern;
 }
@@ -249,6 +270,20 @@
   Flags |= OptionDescriptionFlags::Required;
 }
 
+bool OptionDescription::isOneOrMore() const {
+  return Flags & OptionDescriptionFlags::OneOrMore;
+}
+void OptionDescription::setOneOrMore() {
+  Flags |= OptionDescriptionFlags::OneOrMore;
+}
+
+bool OptionDescription::isZeroOrOne() const {
+  return Flags & OptionDescriptionFlags::ZeroOrOne;
+}
+void OptionDescription::setZeroOrOne() {
+  Flags |= OptionDescriptionFlags::ZeroOrOne;
+}
+
 bool OptionDescription::isHidden() const {
   return Flags & OptionDescriptionFlags::Hidden;
 }
@@ -405,8 +440,11 @@
       AddHandler("extern", &CollectOptionProperties::onExtern);
       AddHandler("help", &CollectOptionProperties::onHelp);
       AddHandler("hidden", &CollectOptionProperties::onHidden);
+      AddHandler("multi_val", &CollectOptionProperties::onMultiVal);
+      AddHandler("one_or_more", &CollectOptionProperties::onOneOrMore);
       AddHandler("really_hidden", &CollectOptionProperties::onReallyHidden);
       AddHandler("required", &CollectOptionProperties::onRequired);
+      AddHandler("zero_or_one", &CollectOptionProperties::onZeroOrOne);
 
       staticMembersInitialized_ = true;
     }
@@ -439,9 +477,46 @@
 
   void onRequired (const DagInit* d) {
     checkNumberOfArguments(d, 0);
+    if (optDesc_.isOneOrMore())
+      throw std::string("An option can't have both (required) "
+                        "and (one_or_more) properties!");
     optDesc_.setRequired();
   }
 
+  void onOneOrMore (const DagInit* d) {
+    checkNumberOfArguments(d, 0);
+    if (optDesc_.isRequired() || optDesc_.isZeroOrOne())
+      throw std::string("Only one of (required), (zero_or_one) or "
+                        "(one_or_more) properties is allowed!");
+    if (!OptionType::IsList(optDesc_.Type))
+      llvm::cerr << "Warning: specifying the 'one_or_more' property "
+        "on a non-list option will have no effect.\n";
+    optDesc_.setOneOrMore();
+  }
+
+  void onZeroOrOne (const DagInit* d) {
+    checkNumberOfArguments(d, 0);
+    if (optDesc_.isRequired() || optDesc_.isOneOrMore())
+      throw std::string("Only one of (required), (zero_or_one) or "
+                        "(one_or_more) properties is allowed!");
+    if (!OptionType::IsList(optDesc_.Type))
+      llvm::cerr << "Warning: specifying the 'zero_or_one' property"
+        "on a non-list option will have no effect.\n";
+    optDesc_.setZeroOrOne();
+  }
+
+  void onMultiVal (const DagInit* d) {
+    checkNumberOfArguments(d, 1);
+    int val = InitPtrToInt(d->getArg(0));
+    if (val < 2)
+      throw std::string("Error in the 'multi_val' property: "
+                        "the value must be greater than 1!");
+    if (!OptionType::IsList(optDesc_.Type))
+      throw std::string("The multi_val property is valid only "
+                        "on list options!");
+    optDesc_.MultiVal = val;
+  }
+
 };
 
 /// AddOption - A function object that is applied to every option
@@ -639,7 +714,6 @@
 
 };
 
-
 /// CollectToolDescriptions - Gather information about tool properties
 /// from the parsed TableGen data (basically a wrapper for the
 /// CollectToolProperties function object).
@@ -1131,13 +1205,6 @@
   }
 }
 
-template <class I, class S>
-void checkedIncrement(I& P, I E, S ErrorString) {
-  ++P;
-  if (P == E)
-    throw ErrorString;
-}
-
 /// SubstituteSpecialCommands - Perform string substitution for $CALL
 /// and $ENV. Helper function used by EmitCmdLineVecFill().
 StrVector::const_iterator SubstituteSpecialCommands
@@ -1308,18 +1375,31 @@
   case OptionType::PrefixList:
     O << Indent << "for (" << D.GenTypeDeclaration()
       << "::iterator B = " << D.GenVariableName() << ".begin(),\n"
-      << Indent << "E = " << D.GenVariableName() << ".end(); B != E; ++B)\n"
+      << Indent << "E = " << D.GenVariableName() << ".end(); B != E;) {\n"
       << Indent << Indent1 << "vec.push_back(\"" << Name << "\" + "
-      << "*B);\n";
+      << "*B);\n"
+      << Indent << Indent1 << "++B;\n";
+
+    for (int i = 1, j = D.MultiVal; i < j; ++i) {
+      O << Indent << Indent1 << "vec.push_back(*B);\n"
+        << Indent << Indent1 << "++B;\n";
+    }
+
+    O << Indent << "}\n";
     break;
   case OptionType::ParameterList:
     O << Indent << "for (" << D.GenTypeDeclaration()
       << "::iterator B = " << D.GenVariableName() << ".begin(),\n"
       << Indent << "E = " << D.GenVariableName()
-      << ".end() ; B != E; ++B) {\n"
-      << Indent << Indent1 << "vec.push_back(\"" << Name << "\");\n"
-      << Indent << Indent1 << "vec.push_back(*B);\n"
-      << Indent << "}\n";
+      << ".end() ; B != E;) {\n"
+      << Indent << Indent1 << "vec.push_back(\"" << Name << "\");\n";
+
+    for (int i = 0, j = D.MultiVal; i < j; ++i) {
+      O << Indent << Indent1 << "vec.push_back(*B);\n"
+        << Indent << Indent1 << "++B;\n";
+    }
+
+    O << Indent << "}\n";
     break;
   case OptionType::Alias:
   default:
@@ -1376,6 +1456,9 @@
       const std::string& Name = InitPtrToString(Dag.getArg(0));
       const OptionDescription& D = OptDescs.FindOption(Name);
 
+      if (D.isMultiVal())
+        throw std::string("Can't use unpack_values with multi-valued options!");
+
       if (OptionType::IsList(D.Type)) {
         O << IndentLevel << "for (" << D.GenTypeDeclaration()
           << "::iterator B = " << D.GenVariableName() << ".begin(),\n"
@@ -1599,27 +1682,28 @@
       O << ", cl::Prefix";
 
     if (val.isRequired()) {
-      switch (val.Type) {
-      case OptionType::PrefixList:
-      case OptionType::ParameterList:
+      if (OptionType::IsList(val.Type) && !val.isMultiVal())
         O << ", cl::OneOrMore";
-        break;
-      default:
+      else
         O << ", cl::Required";
-      }
+    }
+    else if (val.isOneOrMore() && OptionType::IsList(val.Type)) {
+        O << ", cl::OneOrMore";
+    }
+    else if (val.isZeroOrOne() && OptionType::IsList(val.Type)) {
+        O << ", cl::ZeroOrOne";
     }
 
-    if (val.isReallyHidden() || val.isHidden()) {
-      if (val.isRequired())
-        O << " |";
-      else
-        O << ",";
-      if (val.isReallyHidden())
-        O << " cl::ReallyHidden";
-      else
-        O << " cl::Hidden";
+    if (val.isReallyHidden()) {
+      O << ", cl::ReallyHidden";
+    }
+    else if (val.isHidden()) {
+      O << ", cl::Hidden";
     }
 
+    if (val.MultiVal > 1)
+      O << ", cl::multi_val(" << val.MultiVal << ")";
+
     if (!val.Help.empty())
       O << ", cl::desc(\"" << val.Help << "\")";
 





More information about the llvm-commits mailing list