diff options
-rw-r--r-- | include/llvm/Support/CommandLine.h | 295 | ||||
-rw-r--r-- | lib/Support/CommandLine.cpp | 176 | ||||
-rw-r--r-- | tools/llc/llc.cpp | 3 | ||||
-rw-r--r-- | tools/opt/opt.cpp | 3 |
4 files changed, 436 insertions, 41 deletions
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h index 9ae3d6af32..8f1dbe0f54 100644 --- a/include/llvm/Support/CommandLine.h +++ b/include/llvm/Support/CommandLine.h @@ -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(); @@ -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. @@ -303,6 +311,120 @@ 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 // #define clEnumVal(ENUMVAL, DESC) #ENUMVAL, int(ENUMVAL), DESC @@ -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. @@ -443,13 +590,11 @@ protected: template <class DataType> class parser : public generic_parser_base { protected: - class OptionInfo { + class OptionInfo : public GenericOptionInfo { public: OptionInfo(const char *name, DataType v, const char *helpStr) : - Name(name), V(v), HelpStr(helpStr) {} - const char *Name; - DataType V; - const char *HelpStr; + GenericOptionInfo(name, helpStr), V(v) {} + OptionValue<DataType> V; }; SmallVector<OptionInfo, 8> Values; public: @@ -462,6 +607,11 @@ public: 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. bool parse(Option &O, StringRef ArgName, StringRef Arg, DataType &V) { StringRef ArgVal; @@ -473,7 +623,7 @@ public: for (unsigned i = 0, e = static_cast<unsigned>(Values.size()); i != e; ++i) if (Values[i].Name == ArgVal) { - V = Values[i].V; + V = Values[i].V.getValue(); return false; } @@ -522,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 @@ -536,6 +694,7 @@ template<class DataType> class basic_parser : public basic_parser_impl { public: typedef DataType parser_data_type; + typedef OptionValue<DataType> OptVal; }; //-------------------------------------------------- @@ -561,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(); }; @@ -569,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: @@ -583,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(); }; @@ -601,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(); }; @@ -620,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(); }; @@ -638,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(); }; @@ -656,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(); }; @@ -677,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(); }; @@ -698,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 @@ -753,7 +983,6 @@ void apply(const Mod &M, Opt *O) { applicator<Mod>::opt(M, *O); } - //===----------------------------------------------------------------------===// // opt_storage class @@ -764,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 " @@ -777,21 +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 @@ -800,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 @@ -815,16 +1057,23 @@ 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. @@ -866,13 +1115,20 @@ 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; } @@ -1030,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); @@ -1229,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); @@ -1320,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!"); diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp index 7e744993a7..164177f497 100644 --- a/lib/Support/CommandLine.cpp +++ b/lib/Support/CommandLine.cpp @@ -908,8 +908,6 @@ void alias::printOptionInfo(size_t GlobalWidth) const { errs().indent(GlobalWidth-L-6) << " - " << HelpStr << "\n"; } - - //===----------------------------------------------------------------------===// // Parser Implementation code... // @@ -939,7 +937,11 @@ void basic_parser_impl::printOptionInfo(const Option &O, outs().indent(GlobalWidth-getOptionWidth(O)) << " - " << O.HelpStr << '\n'; } - +void basic_parser_impl::printOptionName(const Option &O, + size_t GlobalWidth) const { + outs() << " -" << O.ArgStr; + outs().indent(GlobalWidth-std::strlen(O.ArgStr)); +} // parser<bool> implementation @@ -1083,6 +1085,89 @@ void generic_parser_base::printOptionInfo(const Option &O, } } +static const size_t MaxOptWidth = 8; // arbitrary spacing for printOptionDiff + +// printGenericOptionDiff - Print the value of this option and it's default. +// +// "Generic" options have each value mapped to a name. +void generic_parser_base:: +printGenericOptionDiff(const Option &O, const GenericOptionValue &Value, + const GenericOptionValue &Default, + size_t GlobalWidth) const { + outs() << " -" << O.ArgStr; + outs().indent(GlobalWidth-std::strlen(O.ArgStr)); + + unsigned NumOpts = getNumOptions(); + for (unsigned i = 0; i != NumOpts; ++i) { + if (Value.compare(getOptionValue(i))) + continue; + + outs() << "= " << getOption(i); + size_t L = std::strlen(getOption(i)); + size_t NumSpaces = MaxOptWidth > L ? MaxOptWidth - L : 0; + outs().indent(NumSpaces) << " (default: "; + for (unsigned j = 0; j != NumOpts; ++j) { + if (Default.compare(getOptionValue(j))) + continue; + outs() << getOption(j); + break; + } + outs() << ")\n"; + return; + } + outs() << "= *unknown option value*\n"; +} + +// printOptionDiff - Specializations for printing basic value types. +// +#define PRINT_OPT_DIFF(T) \ + void parser<T>:: \ + printOptionDiff(const Option &O, T V, OptionValue<T> D, \ + size_t GlobalWidth) const { \ + printOptionName(O, GlobalWidth); \ + std::string Str; \ + { \ + raw_string_ostream SS(Str); \ + SS << V; \ + } \ + outs() << "= " << Str; \ + size_t NumSpaces = MaxOptWidth > Str.size() ? MaxOptWidth - Str.size() : 0;\ + outs().indent(NumSpaces) << " (default: "; \ + if (D.hasValue()) \ + outs() << D.getValue(); \ + else \ + outs() << "*no default*"; \ + outs() << ")\n"; \ + } \ + +PRINT_OPT_DIFF(bool); +PRINT_OPT_DIFF(boolOrDefault); +PRINT_OPT_DIFF(int); +PRINT_OPT_DIFF(unsigned); +PRINT_OPT_DIFF(double); +PRINT_OPT_DIFF(float); +PRINT_OPT_DIFF(char); + +void parser<std::string>:: +printOptionDiff(const Option &O, StringRef V, OptionValue<std::string> D, + size_t GlobalWidth) const { + printOptionName(O, GlobalWidth); + outs() << "= " << V; + size_t NumSpaces = MaxOptWidth > V.size() ? MaxOptWidth - V.size() : 0; + outs().indent(NumSpaces) << " (default: "; + if (D.hasValue()) + outs() << D.getValue(); + else + outs() << "*no default*"; + outs() << ")\n"; +} + +// Print a placeholder for options that don't yet support printOptionDiff(). +void basic_parser_impl:: +printOptionNoValue(const Option &O, size_t GlobalWidth) const { + printOptionName(O, GlobalWidth); + outs() << "= *cannot print option value*\n"; +} //===----------------------------------------------------------------------===// // -help and -help-hidden option implementation @@ -1094,6 +1179,35 @@ static int OptNameCompare(const void *LHS, const void *RHS) { return strcmp(((pair_ty*)LHS)->first, ((pair_ty*)RHS)->first); } +// Copy Options into a vector so we can sort them as we like. +static void +sortOpts(StringMap<Option*> &OptMap, + SmallVectorImpl< std::pair<const char *, Option*> > &Opts, + bool ShowHidden) { + SmallPtrSet<Option*, 128> OptionSet; // Duplicate option detection. + + for (StringMap<Option*>::iterator I = OptMap.begin(), E = OptMap.end(); + I != E; ++I) { + // Ignore really-hidden options. + if (I->second->getOptionHiddenFlag() == ReallyHidden) + continue; + + // Unless showhidden is set, ignore hidden flags. + if (I->second->getOptionHiddenFlag() == Hidden && !ShowHidden) + continue; + + // If we've already seen this option, don't add it to the list again. + if (!OptionSet.insert(I->second)) + continue; + + Opts.push_back(std::pair<const char *, Option*>(I->getKey().data(), + I->second)); + } + + // Sort the options list alphabetically. + qsort(Opts.data(), Opts.size(), sizeof(Opts[0]), OptNameCompare); +} + namespace { class HelpPrinter { @@ -1115,30 +1229,8 @@ public: StringMap<Option*> OptMap; GetOptionInfo(PositionalOpts, SinkOpts, OptMap); - // Copy Options into a vector so we can sort them as we like. SmallVector<std::pair<const char *, Option*>, 128> Opts; - SmallPtrSet<Option*, 128> OptionSet; // Duplicate option detection. - - for (StringMap<Option*>::iterator I = OptMap.begin(), E = OptMap.end(); - I != E; ++I) { - // Ignore really-hidden options. - if (I->second->getOptionHiddenFlag() == ReallyHidden) - continue; - - // Unless showhidden is set, ignore hidden flags. - if (I->second->getOptionHiddenFlag() == Hidden && !ShowHidden) - continue; - - // If we've already seen this option, don't add it to the list again. - if (!OptionSet.insert(I->second)) - continue; - - Opts.push_back(std::pair<const char *, Option*>(I->getKey().data(), - I->second)); - } - - // Sort the options list alphabetically. - qsort(Opts.data(), Opts.size(), sizeof(Opts[0]), OptNameCompare); + sortOpts(OptMap, Opts, ShowHidden); if (ProgramOverview) outs() << "OVERVIEW: " << ProgramOverview << "\n"; @@ -1197,6 +1289,38 @@ static cl::opt<HelpPrinter, true, parser<bool> > HHOp("help-hidden", cl::desc("Display all available options"), cl::location(HiddenPrinter), cl::Hidden, cl::ValueDisallowed); +static cl::opt<bool> +PrintOptions("print-options", + cl::desc("Print non-default options after command line parsing"), + cl::Hidden, cl::init(false)); + +static cl::opt<bool> +PrintAllOptions("print-all-options", + cl::desc("Print all option values after command line parsing"), + cl::Hidden, cl::init(false)); + +// Print the value of each option. +void cl::PrintOptionValues() { + if (!PrintOptions && !PrintAllOptions) return; + + // Get all the options. + SmallVector<Option*, 4> PositionalOpts; + SmallVector<Option*, 4> SinkOpts; + StringMap<Option*> OptMap; + GetOptionInfo(PositionalOpts, SinkOpts, OptMap); + + SmallVector<std::pair<const char *, Option*>, 128> Opts; + sortOpts(OptMap, Opts, /*ShowHidden*/true); + + // Compute the maximum argument length... + size_t MaxArgLen = 0; + for (size_t i = 0, e = Opts.size(); i != e; ++i) + MaxArgLen = std::max(MaxArgLen, Opts[i].second->getOptionWidth()); + + for (size_t i = 0, e = Opts.size(); i != e; ++i) + Opts[i].second->printOptionValue(MaxArgLen, PrintAllOptions); +} + static void (*OverrideVersionPrinter)() = 0; static int TargetArraySortFn(const void *LHS, const void *RHS) { diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index 0528cc2197..7f5fa3ffe8 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -338,6 +338,9 @@ int main(int argc, char **argv) { return 1; } + // Before executing passes, print the final values of the LLVM options. + cl::PrintOptionValues(); + PM.run(mod); } diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 3f60126b0d..25474c44a6 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -701,6 +701,9 @@ int main(int argc, char **argv) { Passes.add(createBitcodeWriterPass(Out->os())); } + // Before executing passes, print the final values of the LLVM options. + cl::PrintOptionValues(); + // Now that we have all of the passes ready, run them. Passes.run(*M.get()); |