Reinstate r133513 (reverted in r133700) with an additional fix for a
[oota-llvm.git] / include / llvm / Support / CommandLine.h
index 60be345726a209adac93a905dcda0041d4a91cf3..d6098711a07af3c19811e626de3fd9ad1431296f 100644 (file)
@@ -31,7 +31,7 @@
 #include <vector>
 
 namespace llvm {
-  
+
 /// cl Namespace - This namespace contains all of the command line option
 /// processing machinery.  It is intentionally a short name to make qualified
 /// usage concise.
@@ -60,6 +60,12 @@ void ParseEnvironmentOptions(const char *progName, const char *envvar,
 void SetVersionPrinter(void (*func)());
 
 
+// PrintOptionValues - Print option values.
+// With -print-options print the difference between option values and defaults.
+// With -print-all-options print all option values.
+// (Currently not perfect, but best-effort.)
+void PrintOptionValues();
+
 // MarkOptionsChanged - Internal helper function.
 void MarkOptionsChanged();
 
@@ -93,9 +99,9 @@ enum ValueExpected {           // Is a value required for the option?
 };
 
 enum OptionHidden {            // Control whether -help shows this option
-  NotHidden       = 0x20,      // Option included in --help & --help-hidden
-  Hidden          = 0x40,      // -help doesn't, but --help-hidden does
-  ReallyHidden    = 0x60,      // Neither --help nor --help-hidden show this arg
+  NotHidden       = 0x20,      // Option included in -help & -help-hidden
+  Hidden          = 0x40,      // -help doesn't, but -help-hidden does
+  ReallyHidden    = 0x60,      // Neither -help nor -help-hidden show this arg
   HiddenMask      = 0x60
 };
 
@@ -159,7 +165,7 @@ class Option {
   Option *NextRegistered; // Singly linked list of registered options.
 public:
   const char *ArgStr;     // The argument string itself (ex: "help", "o")
-  const char *HelpStr;    // The descriptive text message for --help
+  const char *HelpStr;    // The descriptive text message for -help
   const char *ValueStr;   // String describing what the value of this option is
 
   inline enum NumOccurrencesFlag getNumOccurrencesFlag() const {
@@ -230,6 +236,8 @@ public:
   //
   virtual void printOptionInfo(size_t GlobalWidth) const = 0;
 
+  virtual void printOptionValue(size_t GlobalWidth, bool Force) const = 0;
+
   virtual void getExtraOptionNames(SmallVectorImpl<const char*> &) {}
 
   // addOccurrence - Wrapper around handleOccurrence that enforces Flags.
@@ -251,14 +259,14 @@ public:
 // command line option parsers...
 //
 
-// desc - Modifier to set the description shown in the --help output...
+// desc - Modifier to set the description shown in the -help output...
 struct desc {
   const char *Desc;
   desc(const char *Str) : Desc(Str) {}
   void apply(Option &O) const { O.setDescription(Desc); }
 };
 
-// value_desc - Modifier to set the value description shown in the --help
+// value_desc - Modifier to set the value description shown in the -help
 // output...
 struct value_desc {
   const char *Desc;
@@ -302,6 +310,120 @@ template<class Ty>
 LocationClass<Ty> location(Ty &L) { return LocationClass<Ty>(L); }
 
 
+//===----------------------------------------------------------------------===//
+// OptionValue class
+
+// Support value comparison outside the template.
+struct GenericOptionValue {
+  virtual ~GenericOptionValue() {}
+  virtual bool compare(const GenericOptionValue &V) const = 0;
+};
+
+template<class DataType> struct OptionValue;
+
+// The default value safely does nothing. Option value printing is only
+// best-effort.
+template<class DataType, bool isClass>
+struct OptionValueBase : public GenericOptionValue {
+  // Temporary storage for argument passing.
+  typedef OptionValue<DataType> WrapperType;
+
+  bool hasValue() const { return false; }
+
+  const DataType &getValue() const { assert(false && "no default value"); }
+
+  // Some options may take their value from a different data type.
+  template<class DT>
+  void setValue(const DT& /*V*/) {}
+
+  bool compare(const DataType &/*V*/) const { return false; }
+
+  virtual bool compare(const GenericOptionValue& /*V*/) const { return false; }
+};
+
+// Simple copy of the option value.
+template<class DataType>
+class OptionValueCopy : public GenericOptionValue {
+  DataType Value;
+  bool Valid;
+public:
+  OptionValueCopy() : Valid(false) {}
+
+  bool hasValue() const { return Valid; }
+
+  const DataType &getValue() const {
+    assert(Valid && "invalid option value");
+    return Value;
+  }
+
+  void setValue(const DataType &V) { Valid = true; Value = V; }
+
+  bool compare(const DataType &V) const {
+    return Valid && (Value != V);
+  }
+
+  virtual bool compare(const GenericOptionValue &V) const {
+    const OptionValueCopy<DataType> &VC =
+      static_cast< const OptionValueCopy<DataType>& >(V);
+    if (!VC.hasValue()) return false;
+    return compare(VC.getValue());
+  }
+};
+
+// Non-class option values.
+template<class DataType>
+struct OptionValueBase<DataType, false> : OptionValueCopy<DataType> {
+  typedef DataType WrapperType;
+};
+
+// Top-level option class.
+template<class DataType>
+struct OptionValue : OptionValueBase<DataType, is_class<DataType>::value> {
+  OptionValue() {}
+
+  OptionValue(const DataType& V) {
+    this->setValue(V);
+  }
+  // Some options may take their value from a different data type.
+  template<class DT>
+  OptionValue<DataType> &operator=(const DT& V) {
+    this->setValue(V);
+    return *this;
+  }
+};
+
+// Other safe-to-copy-by-value common option types.
+enum boolOrDefault { BOU_UNSET, BOU_TRUE, BOU_FALSE };
+template<>
+struct OptionValue<cl::boolOrDefault> : OptionValueCopy<cl::boolOrDefault> {
+  typedef cl::boolOrDefault WrapperType;
+
+  OptionValue() {}
+
+  OptionValue(const cl::boolOrDefault& V) {
+    this->setValue(V);
+  }
+  OptionValue<cl::boolOrDefault> &operator=(const cl::boolOrDefault& V) {
+    setValue(V);
+    return *this;
+  }
+};
+
+template<>
+struct OptionValue<std::string> : OptionValueCopy<std::string> {
+  typedef StringRef WrapperType;
+
+  OptionValue() {}
+
+  OptionValue(const std::string& V) {
+    this->setValue(V);
+  }
+  OptionValue<std::string> &operator=(const std::string& V) {
+    setValue(V);
+    return *this;
+  }
+};
+
 //===----------------------------------------------------------------------===//
 // Enum valued command line option
 //
@@ -355,7 +477,6 @@ ValuesClass<DataType> END_WITH_NULL values(const char *Arg, DataType Val,
     return Vals;
 }
 
-
 //===----------------------------------------------------------------------===//
 // parser class - Parameterizable parser for different data types.  By default,
 // known data types (string, int, bool) have specialized parsers, that do what
@@ -368,7 +489,16 @@ ValuesClass<DataType> END_WITH_NULL values(const char *Arg, DataType Val,
 // not need replicated for every instance of the generic parser.  This also
 // allows us to put stuff into CommandLine.cpp
 //
-struct generic_parser_base {
+class generic_parser_base {
+protected:
+  class GenericOptionInfo {
+  public:
+    GenericOptionInfo(const char *name, const char *helpStr) :
+      Name(name), HelpStr(helpStr) {}
+    const char *Name;
+    const char *HelpStr;
+  };
+public:
   virtual ~generic_parser_base() {}  // Base class should have virtual-dtor
 
   // getNumOptions - Virtual function implemented by generic subclass to
@@ -385,11 +515,28 @@ struct generic_parser_base {
   // Return the width of the option tag for printing...
   virtual size_t getOptionWidth(const Option &O) const;
 
+  virtual const GenericOptionValue &getOptionValue(unsigned N) const = 0;
+
   // printOptionInfo - Print out information about this option.  The
   // to-be-maintained width is specified.
   //
   virtual void printOptionInfo(const Option &O, size_t GlobalWidth) const;
 
+  void printGenericOptionDiff(const Option &O, const GenericOptionValue &V,
+                              const GenericOptionValue &Default,
+                              size_t GlobalWidth) const;
+
+  // printOptionDiff - print the value of an option and it's default.
+  //
+  // Template definition ensures that the option and default have the same
+  // DataType (via the same AnyOptionValue).
+  template<class AnyOptionValue>
+  void printOptionDiff(const Option &O, const AnyOptionValue &V,
+                       const AnyOptionValue &Default,
+                       size_t GlobalWidth) const {
+    printGenericOptionDiff(O, V, Default, GlobalWidth);
+  }
+
   void initialize(Option &O) {
     // All of the modifiers for the option have been processed by now, so the
     // argstr field should be stable, copy it down now.
@@ -437,22 +584,32 @@ protected:
 // Default parser implementation - This implementation depends on having a
 // mapping of recognized options to values of some sort.  In addition to this,
 // each entry in the mapping also tracks a help message that is printed with the
-// command line option for --help.  Because this is a simple mapping parser, the
+// command line option for -help.  Because this is a simple mapping parser, the
 // data type can be any unsupported type.
 //
 template <class DataType>
 class parser : public generic_parser_base {
 protected:
-  SmallVector<std::pair<const char *,
-                        std::pair<DataType, const char *> >, 8> Values;
+  class OptionInfo : public GenericOptionInfo {
+  public:
+    OptionInfo(const char *name, DataType v, const char *helpStr) :
+      GenericOptionInfo(name, helpStr), V(v) {}
+    OptionValue<DataType> V;
+  };
+  SmallVector<OptionInfo, 8> Values;
 public:
   typedef DataType parser_data_type;
 
   // Implement virtual functions needed by generic_parser_base
   unsigned getNumOptions() const { return unsigned(Values.size()); }
-  const char *getOption(unsigned N) const { return Values[N].first; }
+  const char *getOption(unsigned N) const { return Values[N].Name; }
   const char *getDescription(unsigned N) const {
-    return Values[N].second.second;
+    return Values[N].HelpStr;
+  }
+
+  // getOptionValue - Return the value of option name N.
+  virtual const GenericOptionValue &getOptionValue(unsigned N) const {
+    return Values[N].V;
   }
 
   // parse - Return true on error.
@@ -465,8 +622,8 @@ public:
 
     for (unsigned i = 0, e = static_cast<unsigned>(Values.size());
          i != e; ++i)
-      if (Values[i].first == ArgVal) {
-        V = Values[i].second.first;
+      if (Values[i].Name == ArgVal) {
+        V = Values[i].V.getValue();
         return false;
       }
 
@@ -478,8 +635,8 @@ public:
   template <class DT>
   void addLiteralOption(const char *Name, const DT &V, const char *HelpStr) {
     assert(findOption(Name) == Values.size() && "Option already exists!");
-    Values.push_back(std::make_pair(Name,
-                             std::make_pair(static_cast<DataType>(V),HelpStr)));
+    OptionInfo X(Name, static_cast<DataType>(V), HelpStr);
+    Values.push_back(X);
     MarkOptionsChanged();
   }
 
@@ -515,11 +672,19 @@ public:
   //
   void printOptionInfo(const Option &O, size_t GlobalWidth) const;
 
+  // printOptionNoValue - Print a placeholder for options that don't yet support
+  // printOptionDiff().
+  void printOptionNoValue(const Option &O, size_t GlobalWidth) const;
+
   // getValueName - Overload in subclass to provide a better default value.
   virtual const char *getValueName() const { return "value"; }
 
   // An out-of-line virtual method to provide a 'home' for this class.
   virtual void anchor();
+
+protected:
+  // A helper for basic_parser::printOptionDiff.
+  void printOptionName(const Option &O, size_t GlobalWidth) const;
 };
 
 // basic_parser - The real basic parser is just a template wrapper that provides
@@ -529,6 +694,7 @@ template<class DataType>
 class basic_parser : public basic_parser_impl {
 public:
   typedef DataType parser_data_type;
+  typedef OptionValue<DataType> OptVal;
 };
 
 //--------------------------------------------------
@@ -554,6 +720,9 @@ public:
   // getValueName - Do not print =<value> at all.
   virtual const char *getValueName() const { return 0; }
 
+  void printOptionDiff(const Option &O, bool V, OptVal Default,
+                       size_t GlobalWidth) const;
+
   // An out-of-line virtual method to provide a 'home' for this class.
   virtual void anchor();
 };
@@ -562,7 +731,6 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>);
 
 //--------------------------------------------------
 // parser<boolOrDefault>
-enum boolOrDefault { BOU_UNSET, BOU_TRUE, BOU_FALSE };
 template<>
 class parser<boolOrDefault> : public basic_parser<boolOrDefault> {
 public:
@@ -576,6 +744,9 @@ public:
   // getValueName - Do not print =<value> at all.
   virtual const char *getValueName() const { return 0; }
 
+  void printOptionDiff(const Option &O, boolOrDefault V, OptVal Default,
+                       size_t GlobalWidth) const;
+
   // An out-of-line virtual method to provide a 'home' for this class.
   virtual void anchor();
 };
@@ -594,6 +765,9 @@ public:
   // getValueName - Overload in subclass to provide a better default value.
   virtual const char *getValueName() const { return "int"; }
 
+  void printOptionDiff(const Option &O, int V, OptVal Default,
+                       size_t GlobalWidth) const;
+
   // An out-of-line virtual method to provide a 'home' for this class.
   virtual void anchor();
 };
@@ -613,6 +787,9 @@ public:
   // getValueName - Overload in subclass to provide a better default value.
   virtual const char *getValueName() const { return "uint"; }
 
+  void printOptionDiff(const Option &O, unsigned V, OptVal Default,
+                       size_t GlobalWidth) const;
+
   // An out-of-line virtual method to provide a 'home' for this class.
   virtual void anchor();
 };
@@ -631,6 +808,9 @@ public:
   // getValueName - Overload in subclass to provide a better default value.
   virtual const char *getValueName() const { return "number"; }
 
+  void printOptionDiff(const Option &O, double V, OptVal Default,
+                       size_t GlobalWidth) const;
+
   // An out-of-line virtual method to provide a 'home' for this class.
   virtual void anchor();
 };
@@ -649,6 +829,9 @@ public:
   // getValueName - Overload in subclass to provide a better default value.
   virtual const char *getValueName() const { return "number"; }
 
+  void printOptionDiff(const Option &O, float V, OptVal Default,
+                       size_t GlobalWidth) const;
+
   // An out-of-line virtual method to provide a 'home' for this class.
   virtual void anchor();
 };
@@ -670,6 +853,9 @@ public:
   // getValueName - Overload in subclass to provide a better default value.
   virtual const char *getValueName() const { return "string"; }
 
+  void printOptionDiff(const Option &O, StringRef V, OptVal Default,
+                       size_t GlobalWidth) const;
+
   // An out-of-line virtual method to provide a 'home' for this class.
   virtual void anchor();
 };
@@ -691,12 +877,63 @@ public:
   // getValueName - Overload in subclass to provide a better default value.
   virtual const char *getValueName() const { return "char"; }
 
+  void printOptionDiff(const Option &O, char V, OptVal Default,
+                       size_t GlobalWidth) const;
+
   // An out-of-line virtual method to provide a 'home' for this class.
   virtual void anchor();
 };
 
 EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<char>);
 
+//--------------------------------------------------
+// PrintOptionDiff
+//
+// This collection of wrappers is the intermediary between class opt and class
+// parser to handle all the template nastiness.
+
+// This overloaded function is selected by the generic parser.
+template<class ParserClass, class DT>
+void printOptionDiff(const Option &O, const generic_parser_base &P, const DT &V,
+                     const OptionValue<DT> &Default, size_t GlobalWidth) {
+  OptionValue<DT> OV = V;
+  P.printOptionDiff(O, OV, Default, GlobalWidth);
+}
+
+// This is instantiated for basic parsers when the parsed value has a different
+// type than the option value. e.g. HelpPrinter.
+template<class ParserDT, class ValDT>
+struct OptionDiffPrinter {
+  void print(const Option &O, const parser<ParserDT> P, const ValDT &/*V*/,
+             const OptionValue<ValDT> &/*Default*/, size_t GlobalWidth) {
+    P.printOptionNoValue(O, GlobalWidth);
+  }
+};
+
+// This is instantiated for basic parsers when the parsed value has the same
+// type as the option value.
+template<class DT>
+struct OptionDiffPrinter<DT, DT> {
+  void print(const Option &O, const parser<DT> P, const DT &V,
+             const OptionValue<DT> &Default, size_t GlobalWidth) {
+    P.printOptionDiff(O, V, Default, GlobalWidth);
+  }
+};
+
+// This overloaded function is selected by the basic parser, which may parse a
+// different type than the option type.
+template<class ParserClass, class ValDT>
+void printOptionDiff(
+  const Option &O,
+  const basic_parser<typename ParserClass::parser_data_type> &P,
+  const ValDT &V, const OptionValue<ValDT> &Default,
+  size_t GlobalWidth) {
+
+  OptionDiffPrinter<typename ParserClass::parser_data_type, ValDT> printer;
+  printer.print(O, static_cast<const ParserClass&>(P), V, Default,
+                GlobalWidth);
+}
+
 //===----------------------------------------------------------------------===//
 // applicator class - This class is used because we must use partial
 // specialization to handle literal string arguments specially (const char* does
@@ -746,7 +983,6 @@ void apply(const Mod &M, Opt *O) {
   applicator<Mod>::opt(M, *O);
 }
 
-
 //===----------------------------------------------------------------------===//
 // opt_storage class
 
@@ -757,6 +993,7 @@ void apply(const Mod &M, Opt *O) {
 template<class DataType, bool ExternalStorage, bool isClass>
 class opt_storage {
   DataType *Location;   // Where to store the object...
+  OptionValue<DataType> Default;
 
   void check() const {
     assert(Location != 0 && "cl::location(...) not specified for a command "
@@ -770,19 +1007,25 @@ public:
     if (Location)
       return O.error("cl::location(x) specified more than once!");
     Location = &L;
+    Default = L;
     return false;
   }
 
   template<class T>
-  void setValue(const T &V) {
+  void setValue(const T &V, bool initial = false) {
     check();
     *Location = V;
+    if (initial)
+      Default = V;
   }
 
   DataType &getValue() { check(); return *Location; }
   const DataType &getValue() const { check(); return *Location; }
-};
 
+  operator DataType() const { return this->getValue(); }
+
+  const OptionValue<DataType> &getDefault() const { return Default; }
+};
 
 // Define how to hold a class type object, such as a string.  Since we can
 // inherit from a class, we do so.  This makes us exactly compatible with the
@@ -791,11 +1034,19 @@ public:
 template<class DataType>
 class opt_storage<DataType,false,true> : public DataType {
 public:
+  OptionValue<DataType> Default;
+
   template<class T>
-  void setValue(const T &V) { DataType::operator=(V); }
+  void setValue(const T &V, bool initial = false) {
+    DataType::operator=(V);
+    if (initial)
+      Default = V;
+  }
 
   DataType &getValue() { return *this; }
   const DataType &getValue() const { return *this; }
+
+  const OptionValue<DataType> &getDefault() const { return Default; }
 };
 
 // Define a partial specialization to handle things we cannot inherit from.  In
@@ -806,16 +1057,25 @@ template<class DataType>
 class opt_storage<DataType, false, false> {
 public:
   DataType Value;
+  OptionValue<DataType> Default;
 
   // Make sure we initialize the value with the default constructor for the
   // type.
   opt_storage() : Value(DataType()) {}
 
   template<class T>
-  void setValue(const T &V) { Value = V; }
+  void setValue(const T &V, bool initial = false) {
+    Value = V;
+    if (initial)
+      Default = V;
+  }
   DataType &getValue() { return Value; }
   DataType getValue() const { return Value; }
 
+  const OptionValue<DataType> &getDefault() const { return Default; }
+
+  operator DataType() const { return getValue(); }
+
   // If the datatype is a pointer, support -> on it.
   DataType operator->() const { return Value; }
 };
@@ -855,18 +1115,23 @@ class opt : public Option,
     Parser.printOptionInfo(*this, GlobalWidth);
   }
 
+  virtual void printOptionValue(size_t GlobalWidth, bool Force) const {
+    if (Force || this->getDefault().compare(this->getValue())) {
+      cl::printOptionDiff<ParserClass>(
+        *this, Parser, this->getValue(), this->getDefault(), GlobalWidth);
+    }
+  }
+
   void done() {
     addArgument();
     Parser.initialize(*this);
   }
 public:
   // setInitialValue - Used by the cl::init modifier...
-  void setInitialValue(const DataType &V) { this->setValue(V); }
+  void setInitialValue(const DataType &V) { this->setValue(V, true); }
 
   ParserClass &getParser() { return Parser; }
 
-  operator DataType() const { return this->getValue(); }
-
   template<class T>
   DataType &operator=(const T &Val) {
     this->setValue(Val);
@@ -984,7 +1249,7 @@ template<class DataType>
 class list_storage<DataType, bool> : public std::vector<DataType> {
 public:
   template<class T>
-  void addValue(const T &V) { push_back(V); }
+  void addValue(const T &V) { std::vector<DataType>::push_back(V); }
 };
 
 
@@ -1009,7 +1274,7 @@ class list : public Option, public list_storage<DataType, Storage> {
       typename ParserClass::parser_data_type();
     if (Parser.parse(*this, ArgName, Arg, Val))
       return true;  // Parse Error!
-    addValue(Val);
+    list_storage<DataType, Storage>::addValue(Val);
     setPosition(pos);
     Positions.push_back(pos);
     return false;
@@ -1021,6 +1286,9 @@ class list : public Option, public list_storage<DataType, Storage> {
     Parser.printOptionInfo(*this, GlobalWidth);
   }
 
+  // Unimplemented: list options don't currently store their default value.
+  virtual void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const {}
+
   void done() {
     addArgument();
     Parser.initialize(*this);
@@ -1166,7 +1434,7 @@ class bits_storage<DataType, bool> {
 
   template<class T>
   static unsigned Bit(const T &V) {
-    unsigned BitPos = reinterpret_cast<unsigned>(V);
+    unsigned BitPos = (unsigned)V;
     assert(BitPos < sizeof(unsigned) * CHAR_BIT &&
           "enum exceeds width of bit vector!");
     return 1 << BitPos;
@@ -1220,6 +1488,9 @@ class bits : public Option, public bits_storage<DataType, Storage> {
     Parser.printOptionInfo(*this, GlobalWidth);
   }
 
+  // Unimplemented: bits options don't currently store their default values.
+  virtual void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const {}
+
   void done() {
     addArgument();
     Parser.initialize(*this);
@@ -1311,6 +1582,9 @@ class alias : public Option {
   virtual size_t getOptionWidth() const;
   virtual void printOptionInfo(size_t GlobalWidth) const;
 
+  // Aliases do not need to print their values.
+  virtual void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const {}
+
   void done() {
     if (!hasArgStr())
       error("cl::alias must have argument name specified!");
@@ -1371,7 +1645,7 @@ struct extrahelp {
 
 void PrintVersionMessage();
 // This function just prints the help message, exactly the same way as if the
-// --help option had been given on the command line.
+// -help option had been given on the command line.
 // NOTE: THIS FUNCTION TERMINATES THE PROGRAM!
 void PrintHelpMessage();