Improve -fno-opt style option processing to not require an extra
authorMike Stump <mrs@apple.com>
Mon, 2 Feb 2009 22:48:49 +0000 (22:48 +0000)
committerMike Stump <mrs@apple.com>
Mon, 2 Feb 2009 22:48:49 +0000 (22:48 +0000)
option to make the -fno- form on the option.  We also document the new
form in the CommandLine documentation.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63559 91177308-0d34-0410-b5e6-96231b3b80d8

docs/CommandLine.html
include/llvm/Support/CommandLine.h
lib/Support/CommandLine.cpp

index 97df9f787cdc3cb69da373b4f3bc8a710a1385c7..013ff27d1921c3ee7e5c7206bea2b17201209a1a 100644 (file)
@@ -1447,6 +1447,16 @@ unrecognized option strings to it as values instead of signaling an
 error. As with <b><tt>cl::CommaSeparated</tt></b></a>, this modifier
 only makes sense with a <a href="#cl::list">cl::list</a> option.</li>
 
+<li><a name="cl::AllowInverse">The <b><tt>cl::AllowInverse</tt></b></a>
+modifier can be used on options that have the form <tt>-fopt</tt> to
+automatically create a corresponding
+<tt>-fno-opt</tt> option.  The <tt>f</tt> can be any single
+character, and the <tt>opt</tt> can be any one or more characters.
+The value of the created option is the logical complement of the value
+that would have been used if the base form of the option was used.
+This modifier only makes sense with an option that uses
+a <a href="#boolparser">bool parser</a>.</li>
+
 
 </ul>
 
@@ -1745,7 +1755,11 @@ for any data type.</li>
 <li><a name="boolparser">The <b><tt>parser&lt;bool&gt;</tt> specialization</b></a>
 is used to convert boolean strings to a boolean value.  Currently accepted
 strings are "<tt>true</tt>", "<tt>TRUE</tt>", "<tt>True</tt>", "<tt>1</tt>",
-"<tt>false</tt>", "<tt>FALSE</tt>", "<tt>False</tt>", and "<tt>0</tt>".</li>
+"<tt>false</tt>", "<tt>FALSE</tt>", "<tt>False</tt>", and "<tt>0</tt>".  The
+<b><tt>cl::AllowInverse</tt></b> modifier can be used on an option of the form
+<tt>-fopt</tt> that uses the <tt>parser&lt;bool&gt;</tt> specialization
+to create a corresponding option with the form <tt>-fno-opt</tt>.  See
+<a href="#cl::AllowInverse"><tt>cl::AllowInverse</tt></a> for details.</li>
 
 <li><a name="boolOrDefaultparser">The <b><tt>parser&lt;boolOrDefault&gt;</tt>
  specialization</b></a> is used for cases where the value is boolean,
index 9b218dab031cf39c4ab5ea6694957573169c70a3..def5ce750140931b2fab777b771dc9f3cc5c3f70 100644 (file)
@@ -126,7 +126,8 @@ enum MiscFlags {               // Miscellaneous flags to adjust argument
   CommaSeparated     = 0x200,  // Should this cl::list split between commas?
   PositionalEatsArgs = 0x400,  // Should this positional cl::list eat -args?
   Sink               = 0x800,  // Should this cl::list eat all unknown options?
-  MiscMask           = 0xE00   // Union of the above flags.
+  AllowInverse      = 0x1000, // Can this option take a -Xno- form?
+  MiscMask           = 0x1E00  // Union of the above flags.
 };
 
 
@@ -302,12 +303,6 @@ struct LocationClass {
 template<class Ty>
 LocationClass<Ty> location(Ty &L) { return LocationClass<Ty>(L); }
 
-// opposite_of - Allow the user to specify which other option this
-// option is the opposite of.
-//
-template<class Ty>
-LocationClass<bool> opposite_of(Ty &O) { return location(O.getValue()); }
-
 
 //===----------------------------------------------------------------------===//
 // Enum valued command line option
@@ -542,10 +537,33 @@ struct basic_parser : public basic_parser_impl {
 //
 template<>
 class parser<bool> : public basic_parser<bool> {
+  bool IsInvertable;   // Should we synthezise a -xno- style option?
+  const char *ArgStr;
 public:
+  void getExtraOptionNames(std::vector<const char*> &OptionNames) {
+    if (IsInvertable) {
+      char *s = new char [strlen(ArgStr) + 3 + 1];
+      s[0] = ArgStr[0];
+      s[1] = 'n';
+      s[2] = 'o';
+      s[3] = '-';
+      strcpy(&s[4], ArgStr+1);
+      OptionNames.push_back(s);
+    }
+  }
+
   // parse - Return true on error.
   bool parse(Option &O, const char *ArgName, const std::string &Arg, bool &Val);
 
+  template <class Opt>
+  void initialize(Opt &O) {
+    if (O.getMiscFlags() & llvm::cl::AllowInverse)
+      IsInvertable = true;
+    else
+      IsInvertable = false;
+    ArgStr = O.ArgStr;
+  }
+
   enum ValueExpected getValueExpectedFlagDefault() const {
     return ValueOptional;
   }
@@ -582,30 +600,6 @@ public:
 
 EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
 
-//--------------------------------------------------
-// parser<boolInverse>
-class boolInverse { };
-template<>
-class parser<boolInverse> : public basic_parser<bool> {
-public:
-  typedef bool parser_data_type;
-  // parse - Return true on error.
-  bool parse(Option &O, const char *ArgName, const std::string &Arg,
-             bool &Val);
-
-  enum ValueExpected getValueExpectedFlagDefault() const {
-    return ValueOptional;
-  }
-
-  // getValueName - Do not print =<value> at all.
-  virtual const char *getValueName() const { return 0; }
-
-  // An out-of-line virtual method to provide a 'home' for this class.
-  virtual void anchor();
-};
-
-EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>);
-
 //--------------------------------------------------
 // parser<int>
 //
@@ -947,9 +941,6 @@ EXTERN_TEMPLATE_INSTANTIATION(class opt<int>);
 EXTERN_TEMPLATE_INSTANTIATION(class opt<std::string>);
 EXTERN_TEMPLATE_INSTANTIATION(class opt<bool>);
 
-class boolInverse;
-typedef opt<bool, true, parser<boolInverse> > inverse_opt;
-
 //===----------------------------------------------------------------------===//
 // list_storage class
 
index e06f324c871573751fd4d66b2d39d17f0c9483b1..2c56e0ffb87eb0fc5e12c06d1f924466a06fd56d 100644 (file)
@@ -40,7 +40,6 @@ using namespace cl;
 //
 TEMPLATE_INSTANTIATION(class basic_parser<bool>);
 TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
-TEMPLATE_INSTANTIATION(class basic_parser<boolInverse>);
 TEMPLATE_INSTANTIATION(class basic_parser<int>);
 TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
 TEMPLATE_INSTANTIATION(class basic_parser<double>);
@@ -56,7 +55,6 @@ void Option::anchor() {}
 void basic_parser_impl::anchor() {}
 void parser<bool>::anchor() {}
 void parser<boolOrDefault>::anchor() {}
-void parser<boolInverse>::anchor() {}
 void parser<int>::anchor() {}
 void parser<unsigned>::anchor() {}
 void parser<double>::anchor() {}
@@ -874,6 +872,8 @@ bool parser<bool>::parse(Option &O, const char *ArgName,
     return O.error(": '" + Arg +
                    "' is invalid value for boolean argument! Try 0 or 1");
   }
+  if (IsInvertable && strncmp(ArgName+1, "no-", 3) == 0)
+    Value = !Value;
   return false;
 }
 
@@ -894,23 +894,6 @@ bool parser<boolOrDefault>::parse(Option &O, const char *ArgName,
   return false;
 }
 
-// parser<boolInverse> implementation
-//
-bool parser<boolInverse>::parse(Option &O, const char *ArgName,
-                                const std::string &Arg, bool &Value) {
-  if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" ||
-      Arg == "1") {
-    Value = false;
-  } else if (Arg == "false" || Arg == "FALSE"
-             || Arg == "False" || Arg == "0") {
-    Value = true;
-  } else {
-    return O.error(": '" + Arg +
-                   "' is invalid value for boolean argument! Try 0 or 1");
-  }
-  return false;
-}
-
 // parser<int> implementation
 //
 bool parser<int>::parse(Option &O, const char *ArgName,