Index: include/llvm/Option/OptTable.h =================================================================== --- include/llvm/Option/OptTable.h +++ include/llvm/Option/OptTable.h @@ -191,12 +191,13 @@ /// \param FlagsToInclude - If non-zero, only include options with any /// of these flags set. /// \param FlagsToExclude - Exclude options with any of these flags set. - void PrintHelp(raw_ostream &OS, const char *Name, - const char *Title, unsigned FlagsToInclude, - unsigned FlagsToExclude) const; + /// \param ShowAliases - If true, then options aliases are rendered. + void PrintHelp(raw_ostream &OS, const char *Name, const char *Title, + unsigned FlagsToInclude, unsigned FlagsToExclude, + bool ShowAliases) const; - void PrintHelp(raw_ostream &OS, const char *Name, - const char *Title, bool ShowHidden = false) const; + void PrintHelp(raw_ostream &OS, const char *Name, const char *Title, + bool ShowHidden = false, bool ShowAliases = false) const; }; } // end namespace opt Index: lib/Option/OptTable.cpp =================================================================== --- lib/Option/OptTable.cpp +++ lib/Option/OptTable.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" @@ -390,37 +391,41 @@ return Name; } +namespace { +struct OptionInfo { + StringRef HelpText; + std::string Name; +}; +} // namespace + static void PrintHelpOptionList(raw_ostream &OS, StringRef Title, - std::vector> &OptionHelp) { + std::map &Options) { OS << Title << ":\n"; // Find the maximum option length. unsigned OptionFieldWidth = 0; - for (unsigned i = 0, e = OptionHelp.size(); i != e; ++i) { - // Skip titles. - if (!OptionHelp[i].second) - continue; - + for (auto &P : Options) { // Limit the amount of padding we are willing to give up for alignment. - unsigned Length = OptionHelp[i].first.size(); + unsigned Length = P.second.Name.size(); if (Length <= 23) OptionFieldWidth = std::max(OptionFieldWidth, Length); } const unsigned InitialPad = 2; - for (unsigned i = 0, e = OptionHelp.size(); i != e; ++i) { - const std::string &Option = OptionHelp[i].first; - int Pad = OptionFieldWidth - int(Option.size()); - OS.indent(InitialPad) << Option; + for (auto &P : Options) { + OptionInfo &Opt = P.second; + OS.indent(InitialPad) << Opt.Name; // Break on long option names. + int Pad = OptionFieldWidth - int(Opt.Name.size()); if (Pad < 0) { OS << "\n"; Pad = OptionFieldWidth + InitialPad; } - OS.indent(Pad + 1) << OptionHelp[i].second << '\n'; + OS.indent(Pad + 1) << Opt.HelpText << '\n'; } + + OS << "\n"; } static const char *getOptionHelpGroup(const OptTable &Opts, OptSpecifier Id) { @@ -442,26 +447,20 @@ } void OptTable::PrintHelp(raw_ostream &OS, const char *Name, const char *Title, - bool ShowHidden) const { + bool ShowHidden, bool ShowAliases) const { PrintHelp(OS, Name, Title, /*Include*/ 0, /*Exclude*/ - (ShowHidden ? 0 : HelpHidden)); + (ShowHidden ? 0 : HelpHidden), ShowAliases); } - void OptTable::PrintHelp(raw_ostream &OS, const char *Name, const char *Title, - unsigned FlagsToInclude, - unsigned FlagsToExclude) const { + unsigned FlagsToInclude, unsigned FlagsToExclude, + bool ShowAliases) const { OS << "OVERVIEW: " << Title << "\n"; OS << '\n'; OS << "USAGE: " << Name << " [options] \n"; OS << '\n'; - // Render help text into a map of group-name to a list of (option, help) - // pairs. - using helpmap_ty = - std::map>>; - helpmap_ty GroupedOptionHelp; - + std::map> Groups; for (unsigned i = 0, e = getNumOptions(); i != e; ++i) { unsigned Id = i + 1; @@ -475,19 +474,24 @@ if (Flags & FlagsToExclude) continue; + const char *HelpGroup = getOptionHelpGroup(*this, Id); if (const char *Text = getOptionHelpText(Id)) { - const char *HelpGroup = getOptionHelpGroup(*this, Id); - const std::string &OptName = getOptionHelpName(*this, Id); - GroupedOptionHelp[HelpGroup].push_back(std::make_pair(OptName, Text)); + OptionInfo &Opt = Groups[HelpGroup][Id]; + Opt.HelpText = Text; + Opt.Name = getOptionHelpName(*this, Id) + Opt.Name; + continue; } - } - for (helpmap_ty::iterator it = GroupedOptionHelp .begin(), - ie = GroupedOptionHelp.end(); it != ie; ++it) { - if (it != GroupedOptionHelp .begin()) - OS << "\n"; - PrintHelpOptionList(OS, it->first, it->second); + const Option Alias = getOption(Id).getAlias(); + if (!ShowAliases || !Alias.isValid() || !getOptionHelpText(Alias.getID())) + continue; + + OptionInfo &Opt = Groups[HelpGroup][Alias.getID()]; + Opt.Name += ", " + getOptionHelpName(*this, Id); } + for (auto &G : Groups) + PrintHelpOptionList(OS, G.first, G.second); + OS.flush(); }