Index: include/llvm/Option/OptTable.h =================================================================== --- include/llvm/Option/OptTable.h +++ include/llvm/Option/OptTable.h @@ -166,9 +166,10 @@ /// \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 PrintUndocumented - Print options that don't have any help. + void PrintHelp(raw_ostream &OS, const char *Name, const char *Title, + unsigned FlagsToInclude, unsigned FlagsToExclude, + bool PrintUndocumented = false) const; void PrintHelp(raw_ostream &OS, const char *Name, const char *Title, bool ShowHidden = false) const; Index: lib/Option/OptTable.cpp =================================================================== --- lib/Option/OptTable.cpp +++ lib/Option/OptTable.cpp @@ -295,6 +295,27 @@ return Args; } +static std::string getOptionAlias(const OptTable &Opts, OptSpecifier Id) { + const Option O = Opts.getOption(Id); + std::string Name; + + if (O.getAlias().isValid()) { + Name += O.getAlias().getPrefixedName(); + if (O.getAliasArgs()) { + const char *Val = O.getAliasArgs(); + const char *ArgSeparator = ""; + while (*Val != '\0') { + Name += ArgSeparator; + Name += Val; + // Move past the '\0' to the next argument. + Val += strlen(Val) + 1; + ArgSeparator = " "; + } + } + } + return Name; +} + static std::string getOptionHelpName(const OptTable &Opts, OptSpecifier Id) { const Option O = Opts.getOption(Id); std::string Name = O.getPrefixedName(); @@ -319,6 +340,12 @@ break; case Option::FlagClass: + if (O.getAlias().isValid()) { + const std::string Alias = getOptionAlias(Opts, Id); + assert(!Alias.empty() && "Valid but empty alias."); + Name += " | "; + Name += Alias; + } break; case Option::SeparateClass: case Option::JoinedOrSeparateClass: @@ -361,9 +388,11 @@ int Pad = OptionFieldWidth - int(Option.size()); OS.indent(InitialPad) << Option; - // Break on long option names. + // Break on long option names if there's a help string to print. if (Pad < 0) { - OS << "\n"; + if (strlen(OptionHelp[i].second) > 0) { + OS << "\n"; + } Pad = OptionFieldWidth + InitialPad; } OS.indent(Pad + 1) << OptionHelp[i].second << '\n'; @@ -394,10 +423,9 @@ (ShowHidden ? 0 : HelpHidden)); } - void OptTable::PrintHelp(raw_ostream &OS, const char *Name, const char *Title, - unsigned FlagsToInclude, - unsigned FlagsToExclude) const { + unsigned FlagsToInclude, unsigned FlagsToExclude, + bool PrintUndocumented) const { OS << "OVERVIEW: " << Title << "\n"; OS << '\n'; OS << "USAGE: " << Name << " [options] \n"; @@ -422,10 +450,25 @@ if (Flags & FlagsToExclude) continue; - if (const char *Text = getOptionHelpText(Id)) { + const char *HelpText = getOptionHelpText(Id); + + if (!HelpText && PrintUndocumented) { + switch (getOptionKind(Id)) { + case Option::GroupClass: + case Option::InputClass: + case Option::UnknownClass: + // These option kinds are not supposed to be printed even now. + break; + default: + // For other options without help, fake an empty help string. + HelpText = ""; + } + } + + if (HelpText) { const char *HelpGroup = getOptionHelpGroup(*this, Id); const std::string &OptName = getOptionHelpName(*this, Id); - GroupedOptionHelp[HelpGroup].push_back(std::make_pair(OptName, Text)); + GroupedOptionHelp[HelpGroup].push_back(std::make_pair(OptName, HelpText)); } }