diff options
Diffstat (limited to 'contrib/llvm/lib/Support/CommandLine.cpp')
-rw-r--r-- | contrib/llvm/lib/Support/CommandLine.cpp | 213 |
1 files changed, 123 insertions, 90 deletions
diff --git a/contrib/llvm/lib/Support/CommandLine.cpp b/contrib/llvm/lib/Support/CommandLine.cpp index a5d2ba2..3889902 100644 --- a/contrib/llvm/lib/Support/CommandLine.cpp +++ b/contrib/llvm/lib/Support/CommandLine.cpp @@ -20,6 +20,7 @@ #include "llvm-c/Support.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" @@ -29,10 +30,12 @@ #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/Host.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" +#include "llvm/Support/Process.h" #include "llvm/Support/StringSaver.h" #include "llvm/Support/raw_ostream.h" #include <cstdlib> @@ -42,6 +45,17 @@ using namespace cl; #define DEBUG_TYPE "commandline" +#if LLVM_ENABLE_ABI_BREAKING_CHECKS +namespace llvm { +// If LLVM_ENABLE_ABI_BREAKING_CHECKS is set the flag -mllvm -reverse-iterate +// can be used to toggle forward/reverse iteration of unordered containers. +// This will help uncover differences in codegen caused due to undefined +// iteration order. +static cl::opt<bool, true> ReverseIteration("reverse-iterate", + cl::location(ReverseIterate<bool>::value)); +} +#endif + //===----------------------------------------------------------------------===// // Template instantiations and anchors. // @@ -90,10 +104,10 @@ public: // Globals for name and overview of program. Program name is not a string to // avoid static ctor/dtor issues. std::string ProgramName; - const char *ProgramOverview; + StringRef ProgramOverview; // This collects additional help to be printed. - std::vector<const char *> MoreHelp; + std::vector<StringRef> MoreHelp; // This collects the different option categories that have been registered. SmallPtrSet<OptionCategory *, 16> RegisteredOptionCategories; @@ -101,7 +115,7 @@ public: // This collects the different subcommands that have been registered. SmallPtrSet<SubCommand *, 4> RegisteredSubCommands; - CommandLineParser() : ProgramOverview(nullptr), ActiveSubCommand(nullptr) { + CommandLineParser() : ActiveSubCommand(nullptr) { registerSubCommand(&*TopLevelSubCommand); registerSubCommand(&*AllSubCommands); } @@ -109,9 +123,9 @@ public: void ResetAllOptionOccurrences(); bool ParseCommandLineOptions(int argc, const char *const *argv, - const char *Overview, bool IgnoreErrors); + StringRef Overview, bool IgnoreErrors); - void addLiteralOption(Option &Opt, SubCommand *SC, const char *Name) { + void addLiteralOption(Option &Opt, SubCommand *SC, StringRef Name) { if (Opt.hasArgStr()) return; if (!SC->OptionsMap.insert(std::make_pair(Name, &Opt)).second) { @@ -131,7 +145,7 @@ public: } } - void addLiteralOption(Option &Opt, const char *Name) { + void addLiteralOption(Option &Opt, StringRef Name) { if (Opt.Subs.empty()) addLiteralOption(Opt, &*TopLevelSubCommand, Name); else { @@ -283,7 +297,7 @@ public: void registerSubCommand(SubCommand *sub) { assert(count_if(RegisteredSubCommands, [sub](const SubCommand *Sub) { - return (sub->getName() != nullptr) && + return (!sub->getName().empty()) && (Sub->getName() == sub->getName()); }) == 0 && "Duplicate subcommands"); @@ -298,7 +312,7 @@ public: O->hasArgStr()) addOption(O, sub); else - addLiteralOption(*O, sub, E.first().str().c_str()); + addLiteralOption(*O, sub, E.first()); } } } @@ -307,10 +321,16 @@ public: RegisteredSubCommands.erase(sub); } + iterator_range<typename SmallPtrSet<SubCommand *, 4>::iterator> + getRegisteredSubcommands() { + return make_range(RegisteredSubCommands.begin(), + RegisteredSubCommands.end()); + } + void reset() { ActiveSubCommand = nullptr; ProgramName.clear(); - ProgramOverview = nullptr; + ProgramOverview = StringRef(); MoreHelp.clear(); RegisteredOptionCategories.clear(); @@ -328,18 +348,18 @@ private: SubCommand *ActiveSubCommand; Option *LookupOption(SubCommand &Sub, StringRef &Arg, StringRef &Value); - SubCommand *LookupSubCommand(const char *Name); + SubCommand *LookupSubCommand(StringRef Name); }; } // namespace static ManagedStatic<CommandLineParser> GlobalParser; -void cl::AddLiteralOption(Option &O, const char *Name) { +void cl::AddLiteralOption(Option &O, StringRef Name) { GlobalParser->addLiteralOption(O, Name); } -extrahelp::extrahelp(const char *Help) : morehelp(Help) { +extrahelp::extrahelp(StringRef Help) : morehelp(Help) { GlobalParser->MoreHelp.push_back(Help); } @@ -353,6 +373,7 @@ void Option::removeArgument() { GlobalParser->removeOption(this); } void Option::setArgStr(StringRef S) { if (FullyInitialized) GlobalParser->updateArgStr(this, S); + assert((S.empty() || S[0] != '-') && "Option can't start with '-"); ArgStr = S; } @@ -426,13 +447,13 @@ Option *CommandLineParser::LookupOption(SubCommand &Sub, StringRef &Arg, return I->second; } -SubCommand *CommandLineParser::LookupSubCommand(const char *Name) { - if (Name == nullptr) +SubCommand *CommandLineParser::LookupSubCommand(StringRef Name) { + if (Name.empty()) return &*TopLevelSubCommand; for (auto S : RegisteredSubCommands) { if (S == &*AllSubCommands) continue; - if (S->getName() == nullptr) + if (S->getName().empty()) continue; if (StringRef(S->getName()) == StringRef(Name)) @@ -505,7 +526,6 @@ static bool CommaSeparateAndAddOccurrence(Option *Handler, unsigned pos, return true; // Erase the portion before the comma, AND the comma. Val = Val.substr(Pos + 1); - Value.substr(Pos + 1); // Increment the original value pointer as well. // Check for another comma. Pos = Val.find(','); } @@ -533,7 +553,7 @@ static inline bool ProvideOption(Option *Handler, StringRef ArgName, return Handler->error("requires a value!"); // Steal the next argument, like for '-o filename' assert(argv && "null check"); - Value = argv[++i]; + Value = StringRef(argv[++i]); } break; case ValueDisallowed: @@ -567,7 +587,7 @@ static inline bool ProvideOption(Option *Handler, StringRef ArgName, if (i + 1 >= argc) return Handler->error("not enough values!"); assert(argv && "null check"); - Value = argv[++i]; + Value = StringRef(argv[++i]); if (CommaSeparateAndAddOccurrence(Handler, i, ArgName, Value, MultiArg)) return true; @@ -725,7 +745,7 @@ void cl::TokenizeGNUCommandLine(StringRef Src, StringSaver &Saver, // End the token if this is whitespace. if (isWhitespace(Src[I])) { if (!Token.empty()) - NewArgv.push_back(Saver.save(Token.c_str())); + NewArgv.push_back(Saver.save(StringRef(Token)).data()); Token.clear(); continue; } @@ -736,7 +756,7 @@ void cl::TokenizeGNUCommandLine(StringRef Src, StringSaver &Saver, // Append the last token after hitting EOF with no whitespace. if (!Token.empty()) - NewArgv.push_back(Saver.save(Token.c_str())); + NewArgv.push_back(Saver.save(StringRef(Token)).data()); // Mark the end of response files if (MarkEOLs) NewArgv.push_back(nullptr); @@ -817,7 +837,7 @@ void cl::TokenizeWindowsCommandLine(StringRef Src, StringSaver &Saver, if (State == UNQUOTED) { // Whitespace means the end of the token. if (isWhitespace(Src[I])) { - NewArgv.push_back(Saver.save(Token.c_str())); + NewArgv.push_back(Saver.save(StringRef(Token)).data()); Token.clear(); State = INIT; // Mark the end of lines in response files @@ -852,7 +872,7 @@ void cl::TokenizeWindowsCommandLine(StringRef Src, StringSaver &Saver, } // Append the last token after hitting EOF with no whitespace. if (!Token.empty()) - NewArgv.push_back(Saver.save(Token.c_str())); + NewArgv.push_back(Saver.save(StringRef(Token)).data()); // Mark the end of response files if (MarkEOLs) NewArgv.push_back(nullptr); @@ -864,10 +884,10 @@ static bool hasUTF8ByteOrderMark(ArrayRef<char> S) { return (S.size() >= 3 && S[0] == '\xef' && S[1] == '\xbb' && S[2] == '\xbf'); } -static bool ExpandResponseFile(const char *FName, StringSaver &Saver, +static bool ExpandResponseFile(StringRef FName, StringSaver &Saver, TokenizerCallback Tokenizer, SmallVectorImpl<const char *> &NewArgv, - bool MarkEOLs = false) { + bool MarkEOLs, bool RelativeNames) { ErrorOr<std::unique_ptr<MemoryBuffer>> MemBufOrErr = MemoryBuffer::getFile(FName); if (!MemBufOrErr) @@ -892,6 +912,30 @@ static bool ExpandResponseFile(const char *FName, StringSaver &Saver, // Tokenize the contents into NewArgv. Tokenizer(Str, Saver, NewArgv, MarkEOLs); + // If names of nested response files should be resolved relative to including + // file, replace the included response file names with their full paths + // obtained by required resolution. + if (RelativeNames) + for (unsigned I = 0; I < NewArgv.size(); ++I) + if (NewArgv[I]) { + StringRef Arg = NewArgv[I]; + if (Arg.front() == '@') { + StringRef FileName = Arg.drop_front(); + if (llvm::sys::path::is_relative(FileName)) { + SmallString<128> ResponseFile; + ResponseFile.append(1, '@'); + if (llvm::sys::path::is_relative(FName)) { + SmallString<128> curr_dir; + llvm::sys::fs::current_path(curr_dir); + ResponseFile.append(curr_dir.str()); + } + llvm::sys::path::append( + ResponseFile, llvm::sys::path::parent_path(FName), FileName); + NewArgv[I] = Saver.save(ResponseFile.c_str()).data(); + } + } + } + return true; } @@ -899,7 +943,7 @@ static bool ExpandResponseFile(const char *FName, StringSaver &Saver, /// StringSaver and tokenization strategy. bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, SmallVectorImpl<const char *> &Argv, - bool MarkEOLs) { + bool MarkEOLs, bool RelativeNames) { unsigned RspFiles = 0; bool AllExpanded = true; @@ -923,11 +967,9 @@ bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, // Replace this response file argument with the tokenization of its // contents. Nested response files are expanded in subsequent iterations. - // FIXME: If a nested response file uses a relative path, is it relative to - // the cwd of the process or the response file? SmallVector<const char *, 0> ExpandedArgv; if (!ExpandResponseFile(Arg + 1, Saver, Tokenizer, ExpandedArgv, - MarkEOLs)) { + MarkEOLs, RelativeNames)) { // We couldn't read this file, so we leave it in the argument stream and // move on. AllExpanded = false; @@ -952,45 +994,26 @@ void cl::ParseEnvironmentOptions(const char *progName, const char *envVar, assert(envVar && "Environment variable name missing"); // Get the environment variable they want us to parse options out of. -#ifdef _WIN32 - std::wstring wenvVar; - if (!llvm::ConvertUTF8toWide(envVar, wenvVar)) { - assert(false && - "Unicode conversion of environment variable name failed"); - return; - } - const wchar_t *wenvValue = _wgetenv(wenvVar.c_str()); - if (!wenvValue) - return; - std::string envValueBuffer; - if (!llvm::convertWideToUTF8(wenvValue, envValueBuffer)) { - assert(false && - "Unicode conversion of environment variable value failed"); - return; - } - const char *envValue = envValueBuffer.c_str(); -#else - const char *envValue = getenv(envVar); + llvm::Optional<std::string> envValue = sys::Process::GetEnv(StringRef(envVar)); if (!envValue) return; -#endif // Get program's "name", which we wouldn't know without the caller // telling us. SmallVector<const char *, 20> newArgv; BumpPtrAllocator A; StringSaver Saver(A); - newArgv.push_back(Saver.save(progName)); + newArgv.push_back(Saver.save(progName).data()); // Parse the value of the environment variable into a "command line" // and hand it off to ParseCommandLineOptions(). - TokenizeGNUCommandLine(envValue, Saver, newArgv); + TokenizeGNUCommandLine(*envValue, Saver, newArgv); int newArgc = static_cast<int>(newArgv.size()); - ParseCommandLineOptions(newArgc, &newArgv[0], Overview); + ParseCommandLineOptions(newArgc, &newArgv[0], StringRef(Overview)); } bool cl::ParseCommandLineOptions(int argc, const char *const *argv, - const char *Overview, bool IgnoreErrors) { + StringRef Overview, bool IgnoreErrors) { return GlobalParser->ParseCommandLineOptions(argc, argv, Overview, IgnoreErrors); } @@ -1006,7 +1029,7 @@ void CommandLineParser::ResetAllOptionOccurrences() { bool CommandLineParser::ParseCommandLineOptions(int argc, const char *const *argv, - const char *Overview, + StringRef Overview, bool IgnoreErrors) { assert(hasOptions() && "No options specified!"); @@ -1019,7 +1042,7 @@ bool CommandLineParser::ParseCommandLineOptions(int argc, argc = static_cast<int>(newArgv.size()); // Copy the program name into ProgName, making sure not to overflow it. - ProgramName = sys::path::filename(argv[0]); + ProgramName = sys::path::filename(StringRef(argv[0])); ProgramOverview = Overview; bool ErrorParsing = false; @@ -1035,7 +1058,7 @@ bool CommandLineParser::ParseCommandLineOptions(int argc, if (argc >= 2 && argv[FirstArg][0] != '-') { // If the first argument specifies a valid subcommand, start processing // options from the second argument. - ChosenSubCommand = LookupSubCommand(argv[FirstArg]); + ChosenSubCommand = LookupSubCommand(StringRef(argv[FirstArg])); if (ChosenSubCommand != &*TopLevelSubCommand) FirstArg = 2; } @@ -1116,19 +1139,19 @@ bool CommandLineParser::ParseCommandLineOptions(int argc, if (argv[i][0] != '-' || argv[i][1] == 0 || DashDashFound) { // Positional argument! if (ActivePositionalArg) { - ProvidePositionalOption(ActivePositionalArg, argv[i], i); + ProvidePositionalOption(ActivePositionalArg, StringRef(argv[i]), i); continue; // We are done! } if (!PositionalOpts.empty()) { - PositionalVals.push_back(std::make_pair(argv[i], i)); + PositionalVals.push_back(std::make_pair(StringRef(argv[i]), i)); // All of the positional arguments have been fulfulled, give the rest to // the consume after option... if it's specified... // if (PositionalVals.size() >= NumPositionalRequired && ConsumeAfterOpt) { for (++i; i < argc; ++i) - PositionalVals.push_back(std::make_pair(argv[i], i)); + PositionalVals.push_back(std::make_pair(StringRef(argv[i]), i)); break; // Handle outside of the argument processing loop... } @@ -1144,19 +1167,19 @@ bool CommandLineParser::ParseCommandLineOptions(int argc, // If there is a positional argument eating options, check to see if this // option is another positional argument. If so, treat it as an argument, // otherwise feed it to the eating positional. - ArgName = argv[i] + 1; + ArgName = StringRef(argv[i] + 1); // Eat leading dashes. while (!ArgName.empty() && ArgName[0] == '-') ArgName = ArgName.substr(1); Handler = LookupOption(*ChosenSubCommand, ArgName, Value); if (!Handler || Handler->getFormattingFlag() != cl::Positional) { - ProvidePositionalOption(ActivePositionalArg, argv[i], i); + ProvidePositionalOption(ActivePositionalArg, StringRef(argv[i]), i); continue; // We are done! } } else { // We start with a '-', must be an argument. - ArgName = argv[i] + 1; + ArgName = StringRef(argv[i] + 1); // Eat leading dashes. while (!ArgName.empty() && ArgName[0] == '-') ArgName = ArgName.substr(1); @@ -1193,7 +1216,7 @@ bool CommandLineParser::ParseCommandLineOptions(int argc, for (SmallVectorImpl<Option *>::iterator I = SinkOpts.begin(), E = SinkOpts.end(); I != E; ++I) - (*I)->addOccurrence(i, "", argv[i]); + (*I)->addOccurrence(i, "", StringRef(argv[i])); } continue; } @@ -1212,7 +1235,8 @@ bool CommandLineParser::ParseCommandLineOptions(int argc, errs() << ProgramName << ": Not enough positional command line arguments specified!\n" << "Must specify at least " << NumPositionalRequired - << " positional arguments: See: " << argv[0] << " -help\n"; + << " positional argument" << (NumPositionalRequired > 1 ? "s" : "") + << ": See: " << argv[0] << " - help\n"; } ErrorParsing = true; @@ -1245,7 +1269,7 @@ bool CommandLineParser::ParseCommandLineOptions(int argc, switch (PositionalOpts[i]->getNumOccurrencesFlag()) { case cl::Optional: Done = true; // Optional arguments want _at most_ one value - // FALL THROUGH + LLVM_FALLTHROUGH; case cl::ZeroOrMore: // Zero or more will take all they can get... case cl::OneOrMore: // One or more will take all they can get... ProvidePositionalOption(PositionalOpts[i], @@ -1299,7 +1323,7 @@ bool CommandLineParser::ParseCommandLineOptions(int argc, Opt.second->error("must be specified at least once!"); ErrorParsing = true; } - // Fall through + LLVM_FALLTHROUGH; default: break; } @@ -1354,7 +1378,7 @@ bool Option::addOccurrence(unsigned pos, StringRef ArgName, StringRef Value, case Required: if (NumOccurrences > 1) return error("must occur exactly one time!", ArgName); - // Fall through + LLVM_FALLTHROUGH; case OneOrMore: case ZeroOrMore: case ConsumeAfter: @@ -1406,7 +1430,8 @@ void alias::printOptionInfo(size_t GlobalWidth) const { // Return the width of the option tag for printing... size_t basic_parser_impl::getOptionWidth(const Option &O) const { size_t Len = O.ArgStr.size(); - if (const char *ValName = getValueName()) + auto ValName = getValueName(); + if (!ValName.empty()) Len += getValueStr(O, ValName).size() + 3; return Len + 6; @@ -1419,7 +1444,8 @@ void basic_parser_impl::printOptionInfo(const Option &O, size_t GlobalWidth) const { outs() << " -" << O.ArgStr; - if (const char *ValName = getValueName()) + auto ValName = getValueName(); + if (!ValName.empty()) outs() << "=<" << getValueStr(O, ValName) << '>'; printHelpStr(O.HelpStr, GlobalWidth, getOptionWidth(O)); @@ -1529,11 +1555,11 @@ bool parser<float>::parse(Option &O, StringRef ArgName, StringRef Arg, // findOption - Return the option number corresponding to the specified // argument string. If the option is not found, getNumOptions() is returned. // -unsigned generic_parser_base::findOption(const char *Name) { +unsigned generic_parser_base::findOption(StringRef Name) { unsigned e = getNumOptions(); for (unsigned i = 0; i != e; ++i) { - if (strcmp(getOption(i), Name) == 0) + if (getOption(i) == Name) return i; } return e; @@ -1544,12 +1570,12 @@ size_t generic_parser_base::getOptionWidth(const Option &O) const { if (O.hasArgStr()) { size_t Size = O.ArgStr.size() + 6; for (unsigned i = 0, e = getNumOptions(); i != e; ++i) - Size = std::max(Size, std::strlen(getOption(i)) + 8); + Size = std::max(Size, getOption(i).size() + 8); return Size; } else { size_t BaseSize = 0; for (unsigned i = 0, e = getNumOptions(); i != e; ++i) - BaseSize = std::max(BaseSize, std::strlen(getOption(i)) + 8); + BaseSize = std::max(BaseSize, getOption(i).size() + 8); return BaseSize; } } @@ -1564,7 +1590,7 @@ void generic_parser_base::printOptionInfo(const Option &O, printHelpStr(O.HelpStr, GlobalWidth, O.ArgStr.size() + 6); for (unsigned i = 0, e = getNumOptions(); i != e; ++i) { - size_t NumSpaces = GlobalWidth - strlen(getOption(i)) - 8; + size_t NumSpaces = GlobalWidth - getOption(i).size() - 8; outs() << " =" << getOption(i); outs().indent(NumSpaces) << " - " << getDescription(i) << '\n'; } @@ -1572,9 +1598,9 @@ void generic_parser_base::printOptionInfo(const Option &O, if (!O.HelpStr.empty()) outs() << " " << O.HelpStr << '\n'; for (unsigned i = 0, e = getNumOptions(); i != e; ++i) { - const char *Option = getOption(i); + auto Option = getOption(i); outs() << " -" << Option; - printHelpStr(getDescription(i), GlobalWidth, std::strlen(Option) + 8); + printHelpStr(getDescription(i), GlobalWidth, Option.size() + 8); } } } @@ -1596,7 +1622,7 @@ void generic_parser_base::printGenericOptionDiff( continue; outs() << "= " << getOption(i); - size_t L = std::strlen(getOption(i)); + size_t L = getOption(i).size(); size_t NumSpaces = MaxOptWidth > L ? MaxOptWidth - L : 0; outs().indent(NumSpaces) << " (default: "; for (unsigned j = 0; j != NumOpts; ++j) { @@ -1709,9 +1735,9 @@ static void sortSubCommands(const SmallPtrSetImpl<SubCommand *> &SubMap, SmallVectorImpl<std::pair<const char *, SubCommand *>> &Subs) { for (const auto &S : SubMap) { - if (S->getName() == nullptr) + if (S->getName().empty()) continue; - Subs.push_back(std::make_pair(S->getName(), S)); + Subs.push_back(std::make_pair(S->getName().data(), S)); } array_pod_sort(Subs.begin(), Subs.end(), SubNameCompare); } @@ -1734,7 +1760,7 @@ protected: void printSubCommands(StrSubCommandPairVector &Subs, size_t MaxSubLen) { for (const auto &S : Subs) { outs() << " " << S.first; - if (S.second->getDescription()) { + if (!S.second->getDescription().empty()) { outs().indent(MaxSubLen - strlen(S.first)); outs() << " - " << S.second->getDescription(); } @@ -1762,14 +1788,16 @@ public: StrSubCommandPairVector Subs; sortSubCommands(GlobalParser->RegisteredSubCommands, Subs); - if (GlobalParser->ProgramOverview) + if (!GlobalParser->ProgramOverview.empty()) outs() << "OVERVIEW: " << GlobalParser->ProgramOverview << "\n"; - if (Sub == &*TopLevelSubCommand) - outs() << "USAGE: " << GlobalParser->ProgramName - << " [subcommand] [options]"; - else { - if (Sub->getDescription() != nullptr) { + if (Sub == &*TopLevelSubCommand) { + outs() << "USAGE: " << GlobalParser->ProgramName; + if (Subs.size() > 2) + outs() << " [subcommand]"; + outs() << " [options]"; + } else { + if (!Sub->getDescription().empty()) { outs() << "SUBCOMMAND '" << Sub->getName() << "': " << Sub->getDescription() << "\n\n"; } @@ -1787,7 +1815,7 @@ public: if (ConsumeAfterOpt) outs() << " " << ConsumeAfterOpt->HelpStr; - if (Sub == &*TopLevelSubCommand && Subs.size() > 2) { + if (Sub == &*TopLevelSubCommand && !Subs.empty()) { // Compute the maximum subcommand length... size_t MaxSubLen = 0; for (size_t i = 0, e = Subs.size(); i != e; ++i) @@ -1831,7 +1859,7 @@ public: // ordered before B's name. It returns a value greater equal zero otherwise. static int OptionCategoryCompare(OptionCategory *const *A, OptionCategory *const *B) { - return strcmp((*A)->getName(), (*B)->getName()); + return (*A)->getName() == (*B)->getName(); } // Make sure we inherit our base class's operator=() @@ -1888,7 +1916,7 @@ protected: outs() << (*Category)->getName() << ":\n"; // Check if description is set. - if ((*Category)->getDescription() != nullptr) + if (!(*Category)->getDescription().empty()) outs() << (*Category)->getDescription() << "\n\n"; else outs() << "\n"; @@ -2118,10 +2146,15 @@ void cl::AddExtraVersionPrinter(void (*func)()) { StringMap<Option *> &cl::getRegisteredOptions(SubCommand &Sub) { auto &Subs = GlobalParser->RegisteredSubCommands; (void)Subs; - assert(std::find(Subs.begin(), Subs.end(), &Sub) != Subs.end()); + assert(is_contained(Subs, &Sub)); return Sub.OptionsMap; } +iterator_range<typename SmallPtrSet<SubCommand *, 4>::iterator> +cl::getRegisteredSubcommands() { + return GlobalParser->getRegisteredSubcommands(); +} + void cl::HideUnrelatedOptions(cl::OptionCategory &Category, SubCommand &Sub) { for (auto &I : Sub.OptionsMap) { if (I.second->Category != &Category && @@ -2149,5 +2182,5 @@ void cl::ResetAllOptionOccurrences() { void LLVMParseCommandLineOptions(int argc, const char *const *argv, const char *Overview) { - llvm::cl::ParseCommandLineOptions(argc, argv, Overview, true); + llvm::cl::ParseCommandLineOptions(argc, argv, StringRef(Overview), true); } |