Path: blob/main/contrib/llvm-project/llvm/lib/Support/CommandLine.cpp
35232 views
//===-- CommandLine.cpp - Command line parser implementation --------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This class implements a command line argument processor that is useful when9// creating a tool. It provides a simple, minimalistic interface that is easily10// extensible and supports nonlocal (library) command line options.11//12// Note that rather than trying to figure out what this code does, you could try13// reading the library documentation located in docs/CommandLine.html14//15//===----------------------------------------------------------------------===//1617#include "llvm/Support/CommandLine.h"1819#include "DebugOptions.h"2021#include "llvm-c/Support.h"22#include "llvm/ADT/ArrayRef.h"23#include "llvm/ADT/STLFunctionalExtras.h"24#include "llvm/ADT/SmallPtrSet.h"25#include "llvm/ADT/SmallString.h"26#include "llvm/ADT/StringExtras.h"27#include "llvm/ADT/StringMap.h"28#include "llvm/ADT/StringRef.h"29#include "llvm/ADT/Twine.h"30#include "llvm/Config/config.h"31#include "llvm/Support/ConvertUTF.h"32#include "llvm/Support/Debug.h"33#include "llvm/Support/Error.h"34#include "llvm/Support/ErrorHandling.h"35#include "llvm/Support/FileSystem.h"36#include "llvm/Support/ManagedStatic.h"37#include "llvm/Support/MemoryBuffer.h"38#include "llvm/Support/Path.h"39#include "llvm/Support/Process.h"40#include "llvm/Support/StringSaver.h"41#include "llvm/Support/VirtualFileSystem.h"42#include "llvm/Support/raw_ostream.h"43#include <cstdlib>44#include <optional>45#include <string>46using namespace llvm;47using namespace cl;4849#define DEBUG_TYPE "commandline"5051//===----------------------------------------------------------------------===//52// Template instantiations and anchors.53//54namespace llvm {55namespace cl {56template class basic_parser<bool>;57template class basic_parser<boolOrDefault>;58template class basic_parser<int>;59template class basic_parser<long>;60template class basic_parser<long long>;61template class basic_parser<unsigned>;62template class basic_parser<unsigned long>;63template class basic_parser<unsigned long long>;64template class basic_parser<double>;65template class basic_parser<float>;66template class basic_parser<std::string>;67template class basic_parser<char>;6869template class opt<unsigned>;70template class opt<int>;71template class opt<std::string>;72template class opt<char>;73template class opt<bool>;74} // namespace cl75} // namespace llvm7677// Pin the vtables to this file.78void GenericOptionValue::anchor() {}79void OptionValue<boolOrDefault>::anchor() {}80void OptionValue<std::string>::anchor() {}81void Option::anchor() {}82void basic_parser_impl::anchor() {}83void parser<bool>::anchor() {}84void parser<boolOrDefault>::anchor() {}85void parser<int>::anchor() {}86void parser<long>::anchor() {}87void parser<long long>::anchor() {}88void parser<unsigned>::anchor() {}89void parser<unsigned long>::anchor() {}90void parser<unsigned long long>::anchor() {}91void parser<double>::anchor() {}92void parser<float>::anchor() {}93void parser<std::string>::anchor() {}94void parser<char>::anchor() {}9596//===----------------------------------------------------------------------===//9798const static size_t DefaultPad = 2;99100static StringRef ArgPrefix = "-";101static StringRef ArgPrefixLong = "--";102static StringRef ArgHelpPrefix = " - ";103104static size_t argPlusPrefixesSize(StringRef ArgName, size_t Pad = DefaultPad) {105size_t Len = ArgName.size();106if (Len == 1)107return Len + Pad + ArgPrefix.size() + ArgHelpPrefix.size();108return Len + Pad + ArgPrefixLong.size() + ArgHelpPrefix.size();109}110111static SmallString<8> argPrefix(StringRef ArgName, size_t Pad = DefaultPad) {112SmallString<8> Prefix;113for (size_t I = 0; I < Pad; ++I) {114Prefix.push_back(' ');115}116Prefix.append(ArgName.size() > 1 ? ArgPrefixLong : ArgPrefix);117return Prefix;118}119120// Option predicates...121static inline bool isGrouping(const Option *O) {122return O->getMiscFlags() & cl::Grouping;123}124static inline bool isPrefixedOrGrouping(const Option *O) {125return isGrouping(O) || O->getFormattingFlag() == cl::Prefix ||126O->getFormattingFlag() == cl::AlwaysPrefix;127}128129130namespace {131132class PrintArg {133StringRef ArgName;134size_t Pad;135public:136PrintArg(StringRef ArgName, size_t Pad = DefaultPad) : ArgName(ArgName), Pad(Pad) {}137friend raw_ostream &operator<<(raw_ostream &OS, const PrintArg &);138};139140raw_ostream &operator<<(raw_ostream &OS, const PrintArg& Arg) {141OS << argPrefix(Arg.ArgName, Arg.Pad) << Arg.ArgName;142return OS;143}144145class CommandLineParser {146public:147// Globals for name and overview of program. Program name is not a string to148// avoid static ctor/dtor issues.149std::string ProgramName;150StringRef ProgramOverview;151152// This collects additional help to be printed.153std::vector<StringRef> MoreHelp;154155// This collects Options added with the cl::DefaultOption flag. Since they can156// be overridden, they are not added to the appropriate SubCommands until157// ParseCommandLineOptions actually runs.158SmallVector<Option*, 4> DefaultOptions;159160// This collects the different option categories that have been registered.161SmallPtrSet<OptionCategory *, 16> RegisteredOptionCategories;162163// This collects the different subcommands that have been registered.164SmallPtrSet<SubCommand *, 4> RegisteredSubCommands;165166CommandLineParser() { registerSubCommand(&SubCommand::getTopLevel()); }167168void ResetAllOptionOccurrences();169170bool ParseCommandLineOptions(int argc, const char *const *argv,171StringRef Overview, raw_ostream *Errs = nullptr,172bool LongOptionsUseDoubleDash = false);173174void forEachSubCommand(Option &Opt, function_ref<void(SubCommand &)> Action) {175if (Opt.Subs.empty()) {176Action(SubCommand::getTopLevel());177return;178}179if (Opt.Subs.size() == 1 && *Opt.Subs.begin() == &SubCommand::getAll()) {180for (auto *SC : RegisteredSubCommands)181Action(*SC);182Action(SubCommand::getAll());183return;184}185for (auto *SC : Opt.Subs) {186assert(SC != &SubCommand::getAll() &&187"SubCommand::getAll() should not be used with other subcommands");188Action(*SC);189}190}191192void addLiteralOption(Option &Opt, SubCommand *SC, StringRef Name) {193if (Opt.hasArgStr())194return;195if (!SC->OptionsMap.insert(std::make_pair(Name, &Opt)).second) {196errs() << ProgramName << ": CommandLine Error: Option '" << Name197<< "' registered more than once!\n";198report_fatal_error("inconsistency in registered CommandLine options");199}200}201202void addLiteralOption(Option &Opt, StringRef Name) {203forEachSubCommand(204Opt, [&](SubCommand &SC) { addLiteralOption(Opt, &SC, Name); });205}206207void addOption(Option *O, SubCommand *SC) {208bool HadErrors = false;209if (O->hasArgStr()) {210// If it's a DefaultOption, check to make sure it isn't already there.211if (O->isDefaultOption() && SC->OptionsMap.contains(O->ArgStr))212return;213214// Add argument to the argument map!215if (!SC->OptionsMap.insert(std::make_pair(O->ArgStr, O)).second) {216errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr217<< "' registered more than once!\n";218HadErrors = true;219}220}221222// Remember information about positional options.223if (O->getFormattingFlag() == cl::Positional)224SC->PositionalOpts.push_back(O);225else if (O->getMiscFlags() & cl::Sink) // Remember sink options226SC->SinkOpts.push_back(O);227else if (O->getNumOccurrencesFlag() == cl::ConsumeAfter) {228if (SC->ConsumeAfterOpt) {229O->error("Cannot specify more than one option with cl::ConsumeAfter!");230HadErrors = true;231}232SC->ConsumeAfterOpt = O;233}234235// Fail hard if there were errors. These are strictly unrecoverable and236// indicate serious issues such as conflicting option names or an237// incorrectly238// linked LLVM distribution.239if (HadErrors)240report_fatal_error("inconsistency in registered CommandLine options");241}242243void addOption(Option *O, bool ProcessDefaultOption = false) {244if (!ProcessDefaultOption && O->isDefaultOption()) {245DefaultOptions.push_back(O);246return;247}248forEachSubCommand(*O, [&](SubCommand &SC) { addOption(O, &SC); });249}250251void removeOption(Option *O, SubCommand *SC) {252SmallVector<StringRef, 16> OptionNames;253O->getExtraOptionNames(OptionNames);254if (O->hasArgStr())255OptionNames.push_back(O->ArgStr);256257SubCommand &Sub = *SC;258auto End = Sub.OptionsMap.end();259for (auto Name : OptionNames) {260auto I = Sub.OptionsMap.find(Name);261if (I != End && I->getValue() == O)262Sub.OptionsMap.erase(I);263}264265if (O->getFormattingFlag() == cl::Positional)266for (auto *Opt = Sub.PositionalOpts.begin();267Opt != Sub.PositionalOpts.end(); ++Opt) {268if (*Opt == O) {269Sub.PositionalOpts.erase(Opt);270break;271}272}273else if (O->getMiscFlags() & cl::Sink)274for (auto *Opt = Sub.SinkOpts.begin(); Opt != Sub.SinkOpts.end(); ++Opt) {275if (*Opt == O) {276Sub.SinkOpts.erase(Opt);277break;278}279}280else if (O == Sub.ConsumeAfterOpt)281Sub.ConsumeAfterOpt = nullptr;282}283284void removeOption(Option *O) {285forEachSubCommand(*O, [&](SubCommand &SC) { removeOption(O, &SC); });286}287288bool hasOptions(const SubCommand &Sub) const {289return (!Sub.OptionsMap.empty() || !Sub.PositionalOpts.empty() ||290nullptr != Sub.ConsumeAfterOpt);291}292293bool hasOptions() const {294for (const auto *S : RegisteredSubCommands) {295if (hasOptions(*S))296return true;297}298return false;299}300301bool hasNamedSubCommands() const {302for (const auto *S : RegisteredSubCommands)303if (!S->getName().empty())304return true;305return false;306}307308SubCommand *getActiveSubCommand() { return ActiveSubCommand; }309310void updateArgStr(Option *O, StringRef NewName, SubCommand *SC) {311SubCommand &Sub = *SC;312if (!Sub.OptionsMap.insert(std::make_pair(NewName, O)).second) {313errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr314<< "' registered more than once!\n";315report_fatal_error("inconsistency in registered CommandLine options");316}317Sub.OptionsMap.erase(O->ArgStr);318}319320void updateArgStr(Option *O, StringRef NewName) {321forEachSubCommand(*O,322[&](SubCommand &SC) { updateArgStr(O, NewName, &SC); });323}324325void printOptionValues();326327void registerCategory(OptionCategory *cat) {328assert(count_if(RegisteredOptionCategories,329[cat](const OptionCategory *Category) {330return cat->getName() == Category->getName();331}) == 0 &&332"Duplicate option categories");333334RegisteredOptionCategories.insert(cat);335}336337void registerSubCommand(SubCommand *sub) {338assert(count_if(RegisteredSubCommands,339[sub](const SubCommand *Sub) {340return (!sub->getName().empty()) &&341(Sub->getName() == sub->getName());342}) == 0 &&343"Duplicate subcommands");344RegisteredSubCommands.insert(sub);345346// For all options that have been registered for all subcommands, add the347// option to this subcommand now.348assert(sub != &SubCommand::getAll() &&349"SubCommand::getAll() should not be registered");350for (auto &E : SubCommand::getAll().OptionsMap) {351Option *O = E.second;352if ((O->isPositional() || O->isSink() || O->isConsumeAfter()) ||353O->hasArgStr())354addOption(O, sub);355else356addLiteralOption(*O, sub, E.first());357}358}359360void unregisterSubCommand(SubCommand *sub) {361RegisteredSubCommands.erase(sub);362}363364iterator_range<typename SmallPtrSet<SubCommand *, 4>::iterator>365getRegisteredSubcommands() {366return make_range(RegisteredSubCommands.begin(),367RegisteredSubCommands.end());368}369370void reset() {371ActiveSubCommand = nullptr;372ProgramName.clear();373ProgramOverview = StringRef();374375MoreHelp.clear();376RegisteredOptionCategories.clear();377378ResetAllOptionOccurrences();379RegisteredSubCommands.clear();380381SubCommand::getTopLevel().reset();382SubCommand::getAll().reset();383registerSubCommand(&SubCommand::getTopLevel());384385DefaultOptions.clear();386}387388private:389SubCommand *ActiveSubCommand = nullptr;390391Option *LookupOption(SubCommand &Sub, StringRef &Arg, StringRef &Value);392Option *LookupLongOption(SubCommand &Sub, StringRef &Arg, StringRef &Value,393bool LongOptionsUseDoubleDash, bool HaveDoubleDash) {394Option *Opt = LookupOption(Sub, Arg, Value);395if (Opt && LongOptionsUseDoubleDash && !HaveDoubleDash && !isGrouping(Opt))396return nullptr;397return Opt;398}399SubCommand *LookupSubCommand(StringRef Name, std::string &NearestString);400};401402} // namespace403404static ManagedStatic<CommandLineParser> GlobalParser;405406void cl::AddLiteralOption(Option &O, StringRef Name) {407GlobalParser->addLiteralOption(O, Name);408}409410extrahelp::extrahelp(StringRef Help) : morehelp(Help) {411GlobalParser->MoreHelp.push_back(Help);412}413414void Option::addArgument() {415GlobalParser->addOption(this);416FullyInitialized = true;417}418419void Option::removeArgument() { GlobalParser->removeOption(this); }420421void Option::setArgStr(StringRef S) {422if (FullyInitialized)423GlobalParser->updateArgStr(this, S);424assert(!S.starts_with("-") && "Option can't start with '-");425ArgStr = S;426if (ArgStr.size() == 1)427setMiscFlag(Grouping);428}429430void Option::addCategory(OptionCategory &C) {431assert(!Categories.empty() && "Categories cannot be empty.");432// Maintain backward compatibility by replacing the default GeneralCategory433// if it's still set. Otherwise, just add the new one. The GeneralCategory434// must be explicitly added if you want multiple categories that include it.435if (&C != &getGeneralCategory() && Categories[0] == &getGeneralCategory())436Categories[0] = &C;437else if (!is_contained(Categories, &C))438Categories.push_back(&C);439}440441void Option::reset() {442NumOccurrences = 0;443setDefault();444if (isDefaultOption())445removeArgument();446}447448void OptionCategory::registerCategory() {449GlobalParser->registerCategory(this);450}451452// A special subcommand representing no subcommand. It is particularly important453// that this ManagedStatic uses constant initailization and not dynamic454// initialization because it is referenced from cl::opt constructors, which run455// dynamically in an arbitrary order.456LLVM_REQUIRE_CONSTANT_INITIALIZATION457static ManagedStatic<SubCommand> TopLevelSubCommand;458459// A special subcommand that can be used to put an option into all subcommands.460static ManagedStatic<SubCommand> AllSubCommands;461462SubCommand &SubCommand::getTopLevel() { return *TopLevelSubCommand; }463464SubCommand &SubCommand::getAll() { return *AllSubCommands; }465466void SubCommand::registerSubCommand() {467GlobalParser->registerSubCommand(this);468}469470void SubCommand::unregisterSubCommand() {471GlobalParser->unregisterSubCommand(this);472}473474void SubCommand::reset() {475PositionalOpts.clear();476SinkOpts.clear();477OptionsMap.clear();478479ConsumeAfterOpt = nullptr;480}481482SubCommand::operator bool() const {483return (GlobalParser->getActiveSubCommand() == this);484}485486//===----------------------------------------------------------------------===//487// Basic, shared command line option processing machinery.488//489490/// LookupOption - Lookup the option specified by the specified option on the491/// command line. If there is a value specified (after an equal sign) return492/// that as well. This assumes that leading dashes have already been stripped.493Option *CommandLineParser::LookupOption(SubCommand &Sub, StringRef &Arg,494StringRef &Value) {495// Reject all dashes.496if (Arg.empty())497return nullptr;498assert(&Sub != &SubCommand::getAll());499500size_t EqualPos = Arg.find('=');501502// If we have an equals sign, remember the value.503if (EqualPos == StringRef::npos) {504// Look up the option.505return Sub.OptionsMap.lookup(Arg);506}507508// If the argument before the = is a valid option name and the option allows509// non-prefix form (ie is not AlwaysPrefix), we match. If not, signal match510// failure by returning nullptr.511auto I = Sub.OptionsMap.find(Arg.substr(0, EqualPos));512if (I == Sub.OptionsMap.end())513return nullptr;514515auto *O = I->second;516if (O->getFormattingFlag() == cl::AlwaysPrefix)517return nullptr;518519Value = Arg.substr(EqualPos + 1);520Arg = Arg.substr(0, EqualPos);521return I->second;522}523524SubCommand *CommandLineParser::LookupSubCommand(StringRef Name,525std::string &NearestString) {526if (Name.empty())527return &SubCommand::getTopLevel();528// Find a subcommand with the edit distance == 1.529SubCommand *NearestMatch = nullptr;530for (auto *S : RegisteredSubCommands) {531assert(S != &SubCommand::getAll() &&532"SubCommand::getAll() is not expected in RegisteredSubCommands");533if (S->getName().empty())534continue;535536if (S->getName() == Name)537return S;538539if (!NearestMatch && S->getName().edit_distance(Name) < 2)540NearestMatch = S;541}542543if (NearestMatch)544NearestString = NearestMatch->getName();545546return &SubCommand::getTopLevel();547}548549/// LookupNearestOption - Lookup the closest match to the option specified by550/// the specified option on the command line. If there is a value specified551/// (after an equal sign) return that as well. This assumes that leading dashes552/// have already been stripped.553static Option *LookupNearestOption(StringRef Arg,554const StringMap<Option *> &OptionsMap,555std::string &NearestString) {556// Reject all dashes.557if (Arg.empty())558return nullptr;559560// Split on any equal sign.561std::pair<StringRef, StringRef> SplitArg = Arg.split('=');562StringRef &LHS = SplitArg.first; // LHS == Arg when no '=' is present.563StringRef &RHS = SplitArg.second;564565// Find the closest match.566Option *Best = nullptr;567unsigned BestDistance = 0;568for (StringMap<Option *>::const_iterator it = OptionsMap.begin(),569ie = OptionsMap.end();570it != ie; ++it) {571Option *O = it->second;572// Do not suggest really hidden options (not shown in any help).573if (O->getOptionHiddenFlag() == ReallyHidden)574continue;575576SmallVector<StringRef, 16> OptionNames;577O->getExtraOptionNames(OptionNames);578if (O->hasArgStr())579OptionNames.push_back(O->ArgStr);580581bool PermitValue = O->getValueExpectedFlag() != cl::ValueDisallowed;582StringRef Flag = PermitValue ? LHS : Arg;583for (const auto &Name : OptionNames) {584unsigned Distance = StringRef(Name).edit_distance(585Flag, /*AllowReplacements=*/true, /*MaxEditDistance=*/BestDistance);586if (!Best || Distance < BestDistance) {587Best = O;588BestDistance = Distance;589if (RHS.empty() || !PermitValue)590NearestString = std::string(Name);591else592NearestString = (Twine(Name) + "=" + RHS).str();593}594}595}596597return Best;598}599600/// CommaSeparateAndAddOccurrence - A wrapper around Handler->addOccurrence()601/// that does special handling of cl::CommaSeparated options.602static bool CommaSeparateAndAddOccurrence(Option *Handler, unsigned pos,603StringRef ArgName, StringRef Value,604bool MultiArg = false) {605// Check to see if this option accepts a comma separated list of values. If606// it does, we have to split up the value into multiple values.607if (Handler->getMiscFlags() & CommaSeparated) {608StringRef Val(Value);609StringRef::size_type Pos = Val.find(',');610611while (Pos != StringRef::npos) {612// Process the portion before the comma.613if (Handler->addOccurrence(pos, ArgName, Val.substr(0, Pos), MultiArg))614return true;615// Erase the portion before the comma, AND the comma.616Val = Val.substr(Pos + 1);617// Check for another comma.618Pos = Val.find(',');619}620621Value = Val;622}623624return Handler->addOccurrence(pos, ArgName, Value, MultiArg);625}626627/// ProvideOption - For Value, this differentiates between an empty value ("")628/// and a null value (StringRef()). The later is accepted for arguments that629/// don't allow a value (-foo) the former is rejected (-foo=).630static inline bool ProvideOption(Option *Handler, StringRef ArgName,631StringRef Value, int argc,632const char *const *argv, int &i) {633// Is this a multi-argument option?634unsigned NumAdditionalVals = Handler->getNumAdditionalVals();635636// Enforce value requirements637switch (Handler->getValueExpectedFlag()) {638case ValueRequired:639if (!Value.data()) { // No value specified?640// If no other argument or the option only supports prefix form, we641// cannot look at the next argument.642if (i + 1 >= argc || Handler->getFormattingFlag() == cl::AlwaysPrefix)643return Handler->error("requires a value!");644// Steal the next argument, like for '-o filename'645assert(argv && "null check");646Value = StringRef(argv[++i]);647}648break;649case ValueDisallowed:650if (NumAdditionalVals > 0)651return Handler->error("multi-valued option specified"652" with ValueDisallowed modifier!");653654if (Value.data())655return Handler->error("does not allow a value! '" + Twine(Value) +656"' specified.");657break;658case ValueOptional:659break;660}661662// If this isn't a multi-arg option, just run the handler.663if (NumAdditionalVals == 0)664return CommaSeparateAndAddOccurrence(Handler, i, ArgName, Value);665666// If it is, run the handle several times.667bool MultiArg = false;668669if (Value.data()) {670if (CommaSeparateAndAddOccurrence(Handler, i, ArgName, Value, MultiArg))671return true;672--NumAdditionalVals;673MultiArg = true;674}675676while (NumAdditionalVals > 0) {677if (i + 1 >= argc)678return Handler->error("not enough values!");679assert(argv && "null check");680Value = StringRef(argv[++i]);681682if (CommaSeparateAndAddOccurrence(Handler, i, ArgName, Value, MultiArg))683return true;684MultiArg = true;685--NumAdditionalVals;686}687return false;688}689690bool llvm::cl::ProvidePositionalOption(Option *Handler, StringRef Arg, int i) {691int Dummy = i;692return ProvideOption(Handler, Handler->ArgStr, Arg, 0, nullptr, Dummy);693}694695// getOptionPred - Check to see if there are any options that satisfy the696// specified predicate with names that are the prefixes in Name. This is697// checked by progressively stripping characters off of the name, checking to698// see if there options that satisfy the predicate. If we find one, return it,699// otherwise return null.700//701static Option *getOptionPred(StringRef Name, size_t &Length,702bool (*Pred)(const Option *),703const StringMap<Option *> &OptionsMap) {704StringMap<Option *>::const_iterator OMI = OptionsMap.find(Name);705if (OMI != OptionsMap.end() && !Pred(OMI->getValue()))706OMI = OptionsMap.end();707708// Loop while we haven't found an option and Name still has at least two709// characters in it (so that the next iteration will not be the empty710// string.711while (OMI == OptionsMap.end() && Name.size() > 1) {712Name = Name.substr(0, Name.size() - 1); // Chop off the last character.713OMI = OptionsMap.find(Name);714if (OMI != OptionsMap.end() && !Pred(OMI->getValue()))715OMI = OptionsMap.end();716}717718if (OMI != OptionsMap.end() && Pred(OMI->second)) {719Length = Name.size();720return OMI->second; // Found one!721}722return nullptr; // No option found!723}724725/// HandlePrefixedOrGroupedOption - The specified argument string (which started726/// with at least one '-') does not fully match an available option. Check to727/// see if this is a prefix or grouped option. If so, split arg into output an728/// Arg/Value pair and return the Option to parse it with.729static Option *730HandlePrefixedOrGroupedOption(StringRef &Arg, StringRef &Value,731bool &ErrorParsing,732const StringMap<Option *> &OptionsMap) {733if (Arg.size() == 1)734return nullptr;735736// Do the lookup!737size_t Length = 0;738Option *PGOpt = getOptionPred(Arg, Length, isPrefixedOrGrouping, OptionsMap);739if (!PGOpt)740return nullptr;741742do {743StringRef MaybeValue =744(Length < Arg.size()) ? Arg.substr(Length) : StringRef();745Arg = Arg.substr(0, Length);746assert(OptionsMap.count(Arg) && OptionsMap.find(Arg)->second == PGOpt);747748// cl::Prefix options do not preserve '=' when used separately.749// The behavior for them with grouped options should be the same.750if (MaybeValue.empty() || PGOpt->getFormattingFlag() == cl::AlwaysPrefix ||751(PGOpt->getFormattingFlag() == cl::Prefix && MaybeValue[0] != '=')) {752Value = MaybeValue;753return PGOpt;754}755756if (MaybeValue[0] == '=') {757Value = MaybeValue.substr(1);758return PGOpt;759}760761// This must be a grouped option.762assert(isGrouping(PGOpt) && "Broken getOptionPred!");763764// Grouping options inside a group can't have values.765if (PGOpt->getValueExpectedFlag() == cl::ValueRequired) {766ErrorParsing |= PGOpt->error("may not occur within a group!");767return nullptr;768}769770// Because the value for the option is not required, we don't need to pass771// argc/argv in.772int Dummy = 0;773ErrorParsing |= ProvideOption(PGOpt, Arg, StringRef(), 0, nullptr, Dummy);774775// Get the next grouping option.776Arg = MaybeValue;777PGOpt = getOptionPred(Arg, Length, isGrouping, OptionsMap);778} while (PGOpt);779780// We could not find a grouping option in the remainder of Arg.781return nullptr;782}783784static bool RequiresValue(const Option *O) {785return O->getNumOccurrencesFlag() == cl::Required ||786O->getNumOccurrencesFlag() == cl::OneOrMore;787}788789static bool EatsUnboundedNumberOfValues(const Option *O) {790return O->getNumOccurrencesFlag() == cl::ZeroOrMore ||791O->getNumOccurrencesFlag() == cl::OneOrMore;792}793794static bool isWhitespace(char C) {795return C == ' ' || C == '\t' || C == '\r' || C == '\n';796}797798static bool isWhitespaceOrNull(char C) {799return isWhitespace(C) || C == '\0';800}801802static bool isQuote(char C) { return C == '\"' || C == '\''; }803804void cl::TokenizeGNUCommandLine(StringRef Src, StringSaver &Saver,805SmallVectorImpl<const char *> &NewArgv,806bool MarkEOLs) {807SmallString<128> Token;808for (size_t I = 0, E = Src.size(); I != E; ++I) {809// Consume runs of whitespace.810if (Token.empty()) {811while (I != E && isWhitespace(Src[I])) {812// Mark the end of lines in response files.813if (MarkEOLs && Src[I] == '\n')814NewArgv.push_back(nullptr);815++I;816}817if (I == E)818break;819}820821char C = Src[I];822823// Backslash escapes the next character.824if (I + 1 < E && C == '\\') {825++I; // Skip the escape.826Token.push_back(Src[I]);827continue;828}829830// Consume a quoted string.831if (isQuote(C)) {832++I;833while (I != E && Src[I] != C) {834// Backslash escapes the next character.835if (Src[I] == '\\' && I + 1 != E)836++I;837Token.push_back(Src[I]);838++I;839}840if (I == E)841break;842continue;843}844845// End the token if this is whitespace.846if (isWhitespace(C)) {847if (!Token.empty())848NewArgv.push_back(Saver.save(Token.str()).data());849// Mark the end of lines in response files.850if (MarkEOLs && C == '\n')851NewArgv.push_back(nullptr);852Token.clear();853continue;854}855856// This is a normal character. Append it.857Token.push_back(C);858}859860// Append the last token after hitting EOF with no whitespace.861if (!Token.empty())862NewArgv.push_back(Saver.save(Token.str()).data());863}864865/// Backslashes are interpreted in a rather complicated way in the Windows-style866/// command line, because backslashes are used both to separate path and to867/// escape double quote. This method consumes runs of backslashes as well as the868/// following double quote if it's escaped.869///870/// * If an even number of backslashes is followed by a double quote, one871/// backslash is output for every pair of backslashes, and the last double872/// quote remains unconsumed. The double quote will later be interpreted as873/// the start or end of a quoted string in the main loop outside of this874/// function.875///876/// * If an odd number of backslashes is followed by a double quote, one877/// backslash is output for every pair of backslashes, and a double quote is878/// output for the last pair of backslash-double quote. The double quote is879/// consumed in this case.880///881/// * Otherwise, backslashes are interpreted literally.882static size_t parseBackslash(StringRef Src, size_t I, SmallString<128> &Token) {883size_t E = Src.size();884int BackslashCount = 0;885// Skip the backslashes.886do {887++I;888++BackslashCount;889} while (I != E && Src[I] == '\\');890891bool FollowedByDoubleQuote = (I != E && Src[I] == '"');892if (FollowedByDoubleQuote) {893Token.append(BackslashCount / 2, '\\');894if (BackslashCount % 2 == 0)895return I - 1;896Token.push_back('"');897return I;898}899Token.append(BackslashCount, '\\');900return I - 1;901}902903// Windows treats whitespace, double quotes, and backslashes specially, except904// when parsing the first token of a full command line, in which case905// backslashes are not special.906static bool isWindowsSpecialChar(char C) {907return isWhitespaceOrNull(C) || C == '\\' || C == '\"';908}909static bool isWindowsSpecialCharInCommandName(char C) {910return isWhitespaceOrNull(C) || C == '\"';911}912913// Windows tokenization implementation. The implementation is designed to be914// inlined and specialized for the two user entry points.915static inline void tokenizeWindowsCommandLineImpl(916StringRef Src, StringSaver &Saver, function_ref<void(StringRef)> AddToken,917bool AlwaysCopy, function_ref<void()> MarkEOL, bool InitialCommandName) {918SmallString<128> Token;919920// Sometimes, this function will be handling a full command line including an921// executable pathname at the start. In that situation, the initial pathname922// needs different handling from the following arguments, because when923// CreateProcess or cmd.exe scans the pathname, it doesn't treat \ as924// escaping the quote character, whereas when libc scans the rest of the925// command line, it does.926bool CommandName = InitialCommandName;927928// Try to do as much work inside the state machine as possible.929enum { INIT, UNQUOTED, QUOTED } State = INIT;930931for (size_t I = 0, E = Src.size(); I < E; ++I) {932switch (State) {933case INIT: {934assert(Token.empty() && "token should be empty in initial state");935// Eat whitespace before a token.936while (I < E && isWhitespaceOrNull(Src[I])) {937if (Src[I] == '\n')938MarkEOL();939++I;940}941// Stop if this was trailing whitespace.942if (I >= E)943break;944size_t Start = I;945if (CommandName) {946while (I < E && !isWindowsSpecialCharInCommandName(Src[I]))947++I;948} else {949while (I < E && !isWindowsSpecialChar(Src[I]))950++I;951}952StringRef NormalChars = Src.slice(Start, I);953if (I >= E || isWhitespaceOrNull(Src[I])) {954// No special characters: slice out the substring and start the next955// token. Copy the string if the caller asks us to.956AddToken(AlwaysCopy ? Saver.save(NormalChars) : NormalChars);957if (I < E && Src[I] == '\n') {958MarkEOL();959CommandName = InitialCommandName;960} else {961CommandName = false;962}963} else if (Src[I] == '\"') {964Token += NormalChars;965State = QUOTED;966} else if (Src[I] == '\\') {967assert(!CommandName && "or else we'd have treated it as a normal char");968Token += NormalChars;969I = parseBackslash(Src, I, Token);970State = UNQUOTED;971} else {972llvm_unreachable("unexpected special character");973}974break;975}976977case UNQUOTED:978if (isWhitespaceOrNull(Src[I])) {979// Whitespace means the end of the token. If we are in this state, the980// token must have contained a special character, so we must copy the981// token.982AddToken(Saver.save(Token.str()));983Token.clear();984if (Src[I] == '\n') {985CommandName = InitialCommandName;986MarkEOL();987} else {988CommandName = false;989}990State = INIT;991} else if (Src[I] == '\"') {992State = QUOTED;993} else if (Src[I] == '\\' && !CommandName) {994I = parseBackslash(Src, I, Token);995} else {996Token.push_back(Src[I]);997}998break;9991000case QUOTED:1001if (Src[I] == '\"') {1002if (I < (E - 1) && Src[I + 1] == '"') {1003// Consecutive double-quotes inside a quoted string implies one1004// double-quote.1005Token.push_back('"');1006++I;1007} else {1008// Otherwise, end the quoted portion and return to the unquoted state.1009State = UNQUOTED;1010}1011} else if (Src[I] == '\\' && !CommandName) {1012I = parseBackslash(Src, I, Token);1013} else {1014Token.push_back(Src[I]);1015}1016break;1017}1018}10191020if (State != INIT)1021AddToken(Saver.save(Token.str()));1022}10231024void cl::TokenizeWindowsCommandLine(StringRef Src, StringSaver &Saver,1025SmallVectorImpl<const char *> &NewArgv,1026bool MarkEOLs) {1027auto AddToken = [&](StringRef Tok) { NewArgv.push_back(Tok.data()); };1028auto OnEOL = [&]() {1029if (MarkEOLs)1030NewArgv.push_back(nullptr);1031};1032tokenizeWindowsCommandLineImpl(Src, Saver, AddToken,1033/*AlwaysCopy=*/true, OnEOL, false);1034}10351036void cl::TokenizeWindowsCommandLineNoCopy(StringRef Src, StringSaver &Saver,1037SmallVectorImpl<StringRef> &NewArgv) {1038auto AddToken = [&](StringRef Tok) { NewArgv.push_back(Tok); };1039auto OnEOL = []() {};1040tokenizeWindowsCommandLineImpl(Src, Saver, AddToken, /*AlwaysCopy=*/false,1041OnEOL, false);1042}10431044void cl::TokenizeWindowsCommandLineFull(StringRef Src, StringSaver &Saver,1045SmallVectorImpl<const char *> &NewArgv,1046bool MarkEOLs) {1047auto AddToken = [&](StringRef Tok) { NewArgv.push_back(Tok.data()); };1048auto OnEOL = [&]() {1049if (MarkEOLs)1050NewArgv.push_back(nullptr);1051};1052tokenizeWindowsCommandLineImpl(Src, Saver, AddToken,1053/*AlwaysCopy=*/true, OnEOL, true);1054}10551056void cl::tokenizeConfigFile(StringRef Source, StringSaver &Saver,1057SmallVectorImpl<const char *> &NewArgv,1058bool MarkEOLs) {1059for (const char *Cur = Source.begin(); Cur != Source.end();) {1060SmallString<128> Line;1061// Check for comment line.1062if (isWhitespace(*Cur)) {1063while (Cur != Source.end() && isWhitespace(*Cur))1064++Cur;1065continue;1066}1067if (*Cur == '#') {1068while (Cur != Source.end() && *Cur != '\n')1069++Cur;1070continue;1071}1072// Find end of the current line.1073const char *Start = Cur;1074for (const char *End = Source.end(); Cur != End; ++Cur) {1075if (*Cur == '\\') {1076if (Cur + 1 != End) {1077++Cur;1078if (*Cur == '\n' ||1079(*Cur == '\r' && (Cur + 1 != End) && Cur[1] == '\n')) {1080Line.append(Start, Cur - 1);1081if (*Cur == '\r')1082++Cur;1083Start = Cur + 1;1084}1085}1086} else if (*Cur == '\n')1087break;1088}1089// Tokenize line.1090Line.append(Start, Cur);1091cl::TokenizeGNUCommandLine(Line, Saver, NewArgv, MarkEOLs);1092}1093}10941095// It is called byte order marker but the UTF-8 BOM is actually not affected1096// by the host system's endianness.1097static bool hasUTF8ByteOrderMark(ArrayRef<char> S) {1098return (S.size() >= 3 && S[0] == '\xef' && S[1] == '\xbb' && S[2] == '\xbf');1099}11001101// Substitute <CFGDIR> with the file's base path.1102static void ExpandBasePaths(StringRef BasePath, StringSaver &Saver,1103const char *&Arg) {1104assert(sys::path::is_absolute(BasePath));1105constexpr StringLiteral Token("<CFGDIR>");1106const StringRef ArgString(Arg);11071108SmallString<128> ResponseFile;1109StringRef::size_type StartPos = 0;1110for (StringRef::size_type TokenPos = ArgString.find(Token);1111TokenPos != StringRef::npos;1112TokenPos = ArgString.find(Token, StartPos)) {1113// Token may appear more than once per arg (e.g. comma-separated linker1114// args). Support by using path-append on any subsequent appearances.1115const StringRef LHS = ArgString.substr(StartPos, TokenPos - StartPos);1116if (ResponseFile.empty())1117ResponseFile = LHS;1118else1119llvm::sys::path::append(ResponseFile, LHS);1120ResponseFile.append(BasePath);1121StartPos = TokenPos + Token.size();1122}11231124if (!ResponseFile.empty()) {1125// Path-append the remaining arg substring if at least one token appeared.1126const StringRef Remaining = ArgString.substr(StartPos);1127if (!Remaining.empty())1128llvm::sys::path::append(ResponseFile, Remaining);1129Arg = Saver.save(ResponseFile.str()).data();1130}1131}11321133// FName must be an absolute path.1134Error ExpansionContext::expandResponseFile(1135StringRef FName, SmallVectorImpl<const char *> &NewArgv) {1136assert(sys::path::is_absolute(FName));1137llvm::ErrorOr<std::unique_ptr<MemoryBuffer>> MemBufOrErr =1138FS->getBufferForFile(FName);1139if (!MemBufOrErr) {1140std::error_code EC = MemBufOrErr.getError();1141return llvm::createStringError(EC, Twine("cannot not open file '") + FName +1142"': " + EC.message());1143}1144MemoryBuffer &MemBuf = *MemBufOrErr.get();1145StringRef Str(MemBuf.getBufferStart(), MemBuf.getBufferSize());11461147// If we have a UTF-16 byte order mark, convert to UTF-8 for parsing.1148ArrayRef<char> BufRef(MemBuf.getBufferStart(), MemBuf.getBufferEnd());1149std::string UTF8Buf;1150if (hasUTF16ByteOrderMark(BufRef)) {1151if (!convertUTF16ToUTF8String(BufRef, UTF8Buf))1152return llvm::createStringError(std::errc::illegal_byte_sequence,1153"Could not convert UTF16 to UTF8");1154Str = StringRef(UTF8Buf);1155}1156// If we see UTF-8 BOM sequence at the beginning of a file, we shall remove1157// these bytes before parsing.1158// Reference: http://en.wikipedia.org/wiki/UTF-8#Byte_order_mark1159else if (hasUTF8ByteOrderMark(BufRef))1160Str = StringRef(BufRef.data() + 3, BufRef.size() - 3);11611162// Tokenize the contents into NewArgv.1163Tokenizer(Str, Saver, NewArgv, MarkEOLs);11641165// Expanded file content may require additional transformations, like using1166// absolute paths instead of relative in '@file' constructs or expanding1167// macros.1168if (!RelativeNames && !InConfigFile)1169return Error::success();11701171StringRef BasePath = llvm::sys::path::parent_path(FName);1172for (const char *&Arg : NewArgv) {1173if (!Arg)1174continue;11751176// Substitute <CFGDIR> with the file's base path.1177if (InConfigFile)1178ExpandBasePaths(BasePath, Saver, Arg);11791180// Discover the case, when argument should be transformed into '@file' and1181// evaluate 'file' for it.1182StringRef ArgStr(Arg);1183StringRef FileName;1184bool ConfigInclusion = false;1185if (ArgStr.consume_front("@")) {1186FileName = ArgStr;1187if (!llvm::sys::path::is_relative(FileName))1188continue;1189} else if (ArgStr.consume_front("--config=")) {1190FileName = ArgStr;1191ConfigInclusion = true;1192} else {1193continue;1194}11951196// Update expansion construct.1197SmallString<128> ResponseFile;1198ResponseFile.push_back('@');1199if (ConfigInclusion && !llvm::sys::path::has_parent_path(FileName)) {1200SmallString<128> FilePath;1201if (!findConfigFile(FileName, FilePath))1202return createStringError(1203std::make_error_code(std::errc::no_such_file_or_directory),1204"cannot not find configuration file: " + FileName);1205ResponseFile.append(FilePath);1206} else {1207ResponseFile.append(BasePath);1208llvm::sys::path::append(ResponseFile, FileName);1209}1210Arg = Saver.save(ResponseFile.str()).data();1211}1212return Error::success();1213}12141215/// Expand response files on a command line recursively using the given1216/// StringSaver and tokenization strategy.1217Error ExpansionContext::expandResponseFiles(1218SmallVectorImpl<const char *> &Argv) {1219struct ResponseFileRecord {1220std::string File;1221size_t End;1222};12231224// To detect recursive response files, we maintain a stack of files and the1225// position of the last argument in the file. This position is updated1226// dynamically as we recursively expand files.1227SmallVector<ResponseFileRecord, 3> FileStack;12281229// Push a dummy entry that represents the initial command line, removing1230// the need to check for an empty list.1231FileStack.push_back({"", Argv.size()});12321233// Don't cache Argv.size() because it can change.1234for (unsigned I = 0; I != Argv.size();) {1235while (I == FileStack.back().End) {1236// Passing the end of a file's argument list, so we can remove it from the1237// stack.1238FileStack.pop_back();1239}12401241const char *Arg = Argv[I];1242// Check if it is an EOL marker1243if (Arg == nullptr) {1244++I;1245continue;1246}12471248if (Arg[0] != '@') {1249++I;1250continue;1251}12521253const char *FName = Arg + 1;1254// Note that CurrentDir is only used for top-level rsp files, the rest will1255// always have an absolute path deduced from the containing file.1256SmallString<128> CurrDir;1257if (llvm::sys::path::is_relative(FName)) {1258if (CurrentDir.empty()) {1259if (auto CWD = FS->getCurrentWorkingDirectory()) {1260CurrDir = *CWD;1261} else {1262return createStringError(1263CWD.getError(), Twine("cannot get absolute path for: ") + FName);1264}1265} else {1266CurrDir = CurrentDir;1267}1268llvm::sys::path::append(CurrDir, FName);1269FName = CurrDir.c_str();1270}12711272ErrorOr<llvm::vfs::Status> Res = FS->status(FName);1273if (!Res || !Res->exists()) {1274std::error_code EC = Res.getError();1275if (!InConfigFile) {1276// If the specified file does not exist, leave '@file' unexpanded, as1277// libiberty does.1278if (!EC || EC == llvm::errc::no_such_file_or_directory) {1279++I;1280continue;1281}1282}1283if (!EC)1284EC = llvm::errc::no_such_file_or_directory;1285return createStringError(EC, Twine("cannot not open file '") + FName +1286"': " + EC.message());1287}1288const llvm::vfs::Status &FileStatus = Res.get();12891290auto IsEquivalent =1291[FileStatus, this](const ResponseFileRecord &RFile) -> ErrorOr<bool> {1292ErrorOr<llvm::vfs::Status> RHS = FS->status(RFile.File);1293if (!RHS)1294return RHS.getError();1295return FileStatus.equivalent(*RHS);1296};12971298// Check for recursive response files.1299for (const auto &F : drop_begin(FileStack)) {1300if (ErrorOr<bool> R = IsEquivalent(F)) {1301if (R.get())1302return createStringError(1303R.getError(), Twine("recursive expansion of: '") + F.File + "'");1304} else {1305return createStringError(R.getError(),1306Twine("cannot open file: ") + F.File);1307}1308}13091310// Replace this response file argument with the tokenization of its1311// contents. Nested response files are expanded in subsequent iterations.1312SmallVector<const char *, 0> ExpandedArgv;1313if (Error Err = expandResponseFile(FName, ExpandedArgv))1314return Err;13151316for (ResponseFileRecord &Record : FileStack) {1317// Increase the end of all active records by the number of newly expanded1318// arguments, minus the response file itself.1319Record.End += ExpandedArgv.size() - 1;1320}13211322FileStack.push_back({FName, I + ExpandedArgv.size()});1323Argv.erase(Argv.begin() + I);1324Argv.insert(Argv.begin() + I, ExpandedArgv.begin(), ExpandedArgv.end());1325}13261327// If successful, the top of the file stack will mark the end of the Argv1328// stream. A failure here indicates a bug in the stack popping logic above.1329// Note that FileStack may have more than one element at this point because we1330// don't have a chance to pop the stack when encountering recursive files at1331// the end of the stream, so seeing that doesn't indicate a bug.1332assert(FileStack.size() > 0 && Argv.size() == FileStack.back().End);1333return Error::success();1334}13351336bool cl::expandResponseFiles(int Argc, const char *const *Argv,1337const char *EnvVar, StringSaver &Saver,1338SmallVectorImpl<const char *> &NewArgv) {1339#ifdef _WIN321340auto Tokenize = cl::TokenizeWindowsCommandLine;1341#else1342auto Tokenize = cl::TokenizeGNUCommandLine;1343#endif1344// The environment variable specifies initial options.1345if (EnvVar)1346if (std::optional<std::string> EnvValue = sys::Process::GetEnv(EnvVar))1347Tokenize(*EnvValue, Saver, NewArgv, /*MarkEOLs=*/false);13481349// Command line options can override the environment variable.1350NewArgv.append(Argv + 1, Argv + Argc);1351ExpansionContext ECtx(Saver.getAllocator(), Tokenize);1352if (Error Err = ECtx.expandResponseFiles(NewArgv)) {1353errs() << toString(std::move(Err)) << '\n';1354return false;1355}1356return true;1357}13581359bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,1360SmallVectorImpl<const char *> &Argv) {1361ExpansionContext ECtx(Saver.getAllocator(), Tokenizer);1362if (Error Err = ECtx.expandResponseFiles(Argv)) {1363errs() << toString(std::move(Err)) << '\n';1364return false;1365}1366return true;1367}13681369ExpansionContext::ExpansionContext(BumpPtrAllocator &A, TokenizerCallback T)1370: Saver(A), Tokenizer(T), FS(vfs::getRealFileSystem().get()) {}13711372bool ExpansionContext::findConfigFile(StringRef FileName,1373SmallVectorImpl<char> &FilePath) {1374SmallString<128> CfgFilePath;1375const auto FileExists = [this](SmallString<128> Path) -> bool {1376auto Status = FS->status(Path);1377return Status &&1378Status->getType() == llvm::sys::fs::file_type::regular_file;1379};13801381// If file name contains directory separator, treat it as a path to1382// configuration file.1383if (llvm::sys::path::has_parent_path(FileName)) {1384CfgFilePath = FileName;1385if (llvm::sys::path::is_relative(FileName) && FS->makeAbsolute(CfgFilePath))1386return false;1387if (!FileExists(CfgFilePath))1388return false;1389FilePath.assign(CfgFilePath.begin(), CfgFilePath.end());1390return true;1391}13921393// Look for the file in search directories.1394for (const StringRef &Dir : SearchDirs) {1395if (Dir.empty())1396continue;1397CfgFilePath.assign(Dir);1398llvm::sys::path::append(CfgFilePath, FileName);1399llvm::sys::path::native(CfgFilePath);1400if (FileExists(CfgFilePath)) {1401FilePath.assign(CfgFilePath.begin(), CfgFilePath.end());1402return true;1403}1404}14051406return false;1407}14081409Error ExpansionContext::readConfigFile(StringRef CfgFile,1410SmallVectorImpl<const char *> &Argv) {1411SmallString<128> AbsPath;1412if (sys::path::is_relative(CfgFile)) {1413AbsPath.assign(CfgFile);1414if (std::error_code EC = FS->makeAbsolute(AbsPath))1415return make_error<StringError>(1416EC, Twine("cannot get absolute path for " + CfgFile));1417CfgFile = AbsPath.str();1418}1419InConfigFile = true;1420RelativeNames = true;1421if (Error Err = expandResponseFile(CfgFile, Argv))1422return Err;1423return expandResponseFiles(Argv);1424}14251426static void initCommonOptions();1427bool cl::ParseCommandLineOptions(int argc, const char *const *argv,1428StringRef Overview, raw_ostream *Errs,1429const char *EnvVar,1430bool LongOptionsUseDoubleDash) {1431initCommonOptions();1432SmallVector<const char *, 20> NewArgv;1433BumpPtrAllocator A;1434StringSaver Saver(A);1435NewArgv.push_back(argv[0]);14361437// Parse options from environment variable.1438if (EnvVar) {1439if (std::optional<std::string> EnvValue =1440sys::Process::GetEnv(StringRef(EnvVar)))1441TokenizeGNUCommandLine(*EnvValue, Saver, NewArgv);1442}14431444// Append options from command line.1445for (int I = 1; I < argc; ++I)1446NewArgv.push_back(argv[I]);1447int NewArgc = static_cast<int>(NewArgv.size());14481449// Parse all options.1450return GlobalParser->ParseCommandLineOptions(NewArgc, &NewArgv[0], Overview,1451Errs, LongOptionsUseDoubleDash);1452}14531454/// Reset all options at least once, so that we can parse different options.1455void CommandLineParser::ResetAllOptionOccurrences() {1456// Reset all option values to look like they have never been seen before.1457// Options might be reset twice (they can be reference in both OptionsMap1458// and one of the other members), but that does not harm.1459for (auto *SC : RegisteredSubCommands) {1460for (auto &O : SC->OptionsMap)1461O.second->reset();1462for (Option *O : SC->PositionalOpts)1463O->reset();1464for (Option *O : SC->SinkOpts)1465O->reset();1466if (SC->ConsumeAfterOpt)1467SC->ConsumeAfterOpt->reset();1468}1469}14701471bool CommandLineParser::ParseCommandLineOptions(int argc,1472const char *const *argv,1473StringRef Overview,1474raw_ostream *Errs,1475bool LongOptionsUseDoubleDash) {1476assert(hasOptions() && "No options specified!");14771478ProgramOverview = Overview;1479bool IgnoreErrors = Errs;1480if (!Errs)1481Errs = &errs();1482bool ErrorParsing = false;14831484// Expand response files.1485SmallVector<const char *, 20> newArgv(argv, argv + argc);1486BumpPtrAllocator A;1487#ifdef _WIN321488auto Tokenize = cl::TokenizeWindowsCommandLine;1489#else1490auto Tokenize = cl::TokenizeGNUCommandLine;1491#endif1492ExpansionContext ECtx(A, Tokenize);1493if (Error Err = ECtx.expandResponseFiles(newArgv)) {1494*Errs << toString(std::move(Err)) << '\n';1495return false;1496}1497argv = &newArgv[0];1498argc = static_cast<int>(newArgv.size());14991500// Copy the program name into ProgName, making sure not to overflow it.1501ProgramName = std::string(sys::path::filename(StringRef(argv[0])));15021503// Check out the positional arguments to collect information about them.1504unsigned NumPositionalRequired = 0;15051506// Determine whether or not there are an unlimited number of positionals1507bool HasUnlimitedPositionals = false;15081509int FirstArg = 1;1510SubCommand *ChosenSubCommand = &SubCommand::getTopLevel();1511std::string NearestSubCommandString;1512bool MaybeNamedSubCommand =1513argc >= 2 && argv[FirstArg][0] != '-' && hasNamedSubCommands();1514if (MaybeNamedSubCommand) {1515// If the first argument specifies a valid subcommand, start processing1516// options from the second argument.1517ChosenSubCommand =1518LookupSubCommand(StringRef(argv[FirstArg]), NearestSubCommandString);1519if (ChosenSubCommand != &SubCommand::getTopLevel())1520FirstArg = 2;1521}1522GlobalParser->ActiveSubCommand = ChosenSubCommand;15231524assert(ChosenSubCommand);1525auto &ConsumeAfterOpt = ChosenSubCommand->ConsumeAfterOpt;1526auto &PositionalOpts = ChosenSubCommand->PositionalOpts;1527auto &SinkOpts = ChosenSubCommand->SinkOpts;1528auto &OptionsMap = ChosenSubCommand->OptionsMap;15291530for (auto *O: DefaultOptions) {1531addOption(O, true);1532}15331534if (ConsumeAfterOpt) {1535assert(PositionalOpts.size() > 0 &&1536"Cannot specify cl::ConsumeAfter without a positional argument!");1537}1538if (!PositionalOpts.empty()) {15391540// Calculate how many positional values are _required_.1541bool UnboundedFound = false;1542for (size_t i = 0, e = PositionalOpts.size(); i != e; ++i) {1543Option *Opt = PositionalOpts[i];1544if (RequiresValue(Opt))1545++NumPositionalRequired;1546else if (ConsumeAfterOpt) {1547// ConsumeAfter cannot be combined with "optional" positional options1548// unless there is only one positional argument...1549if (PositionalOpts.size() > 1) {1550if (!IgnoreErrors)1551Opt->error("error - this positional option will never be matched, "1552"because it does not Require a value, and a "1553"cl::ConsumeAfter option is active!");1554ErrorParsing = true;1555}1556} else if (UnboundedFound && !Opt->hasArgStr()) {1557// This option does not "require" a value... Make sure this option is1558// not specified after an option that eats all extra arguments, or this1559// one will never get any!1560//1561if (!IgnoreErrors)1562Opt->error("error - option can never match, because "1563"another positional argument will match an "1564"unbounded number of values, and this option"1565" does not require a value!");1566*Errs << ProgramName << ": CommandLine Error: Option '" << Opt->ArgStr1567<< "' is all messed up!\n";1568*Errs << PositionalOpts.size();1569ErrorParsing = true;1570}1571UnboundedFound |= EatsUnboundedNumberOfValues(Opt);1572}1573HasUnlimitedPositionals = UnboundedFound || ConsumeAfterOpt;1574}15751576// PositionalVals - A vector of "positional" arguments we accumulate into1577// the process at the end.1578//1579SmallVector<std::pair<StringRef, unsigned>, 4> PositionalVals;15801581// If the program has named positional arguments, and the name has been run1582// across, keep track of which positional argument was named. Otherwise put1583// the positional args into the PositionalVals list...1584Option *ActivePositionalArg = nullptr;15851586// Loop over all of the arguments... processing them.1587bool DashDashFound = false; // Have we read '--'?1588for (int i = FirstArg; i < argc; ++i) {1589Option *Handler = nullptr;1590std::string NearestHandlerString;1591StringRef Value;1592StringRef ArgName = "";1593bool HaveDoubleDash = false;15941595// Check to see if this is a positional argument. This argument is1596// considered to be positional if it doesn't start with '-', if it is "-"1597// itself, or if we have seen "--" already.1598//1599if (argv[i][0] != '-' || argv[i][1] == 0 || DashDashFound) {1600// Positional argument!1601if (ActivePositionalArg) {1602ProvidePositionalOption(ActivePositionalArg, StringRef(argv[i]), i);1603continue; // We are done!1604}16051606if (!PositionalOpts.empty()) {1607PositionalVals.push_back(std::make_pair(StringRef(argv[i]), i));16081609// All of the positional arguments have been fulfulled, give the rest to1610// the consume after option... if it's specified...1611//1612if (PositionalVals.size() >= NumPositionalRequired && ConsumeAfterOpt) {1613for (++i; i < argc; ++i)1614PositionalVals.push_back(std::make_pair(StringRef(argv[i]), i));1615break; // Handle outside of the argument processing loop...1616}16171618// Delay processing positional arguments until the end...1619continue;1620}1621} else if (argv[i][0] == '-' && argv[i][1] == '-' && argv[i][2] == 0 &&1622!DashDashFound) {1623DashDashFound = true; // This is the mythical "--"?1624continue; // Don't try to process it as an argument itself.1625} else if (ActivePositionalArg &&1626(ActivePositionalArg->getMiscFlags() & PositionalEatsArgs)) {1627// If there is a positional argument eating options, check to see if this1628// option is another positional argument. If so, treat it as an argument,1629// otherwise feed it to the eating positional.1630ArgName = StringRef(argv[i] + 1);1631// Eat second dash.1632if (ArgName.consume_front("-"))1633HaveDoubleDash = true;16341635Handler = LookupLongOption(*ChosenSubCommand, ArgName, Value,1636LongOptionsUseDoubleDash, HaveDoubleDash);1637if (!Handler || Handler->getFormattingFlag() != cl::Positional) {1638ProvidePositionalOption(ActivePositionalArg, StringRef(argv[i]), i);1639continue; // We are done!1640}1641} else { // We start with a '-', must be an argument.1642ArgName = StringRef(argv[i] + 1);1643// Eat second dash.1644if (ArgName.consume_front("-"))1645HaveDoubleDash = true;16461647Handler = LookupLongOption(*ChosenSubCommand, ArgName, Value,1648LongOptionsUseDoubleDash, HaveDoubleDash);16491650// If Handler is not found in a specialized subcommand, look up handler1651// in the top-level subcommand.1652// cl::opt without cl::sub belongs to top-level subcommand.1653if (!Handler && ChosenSubCommand != &SubCommand::getTopLevel())1654Handler = LookupLongOption(SubCommand::getTopLevel(), ArgName, Value,1655LongOptionsUseDoubleDash, HaveDoubleDash);16561657// Check to see if this "option" is really a prefixed or grouped argument.1658if (!Handler && !(LongOptionsUseDoubleDash && HaveDoubleDash))1659Handler = HandlePrefixedOrGroupedOption(ArgName, Value, ErrorParsing,1660OptionsMap);16611662// Otherwise, look for the closest available option to report to the user1663// in the upcoming error.1664if (!Handler && SinkOpts.empty())1665LookupNearestOption(ArgName, OptionsMap, NearestHandlerString);1666}16671668if (!Handler) {1669if (!SinkOpts.empty()) {1670for (Option *SinkOpt : SinkOpts)1671SinkOpt->addOccurrence(i, "", StringRef(argv[i]));1672continue;1673}16741675auto ReportUnknownArgument = [&](bool IsArg,1676StringRef NearestArgumentName) {1677*Errs << ProgramName << ": Unknown "1678<< (IsArg ? "command line argument" : "subcommand") << " '"1679<< argv[i] << "'. Try: '" << argv[0] << " --help'\n";16801681if (NearestArgumentName.empty())1682return;16831684*Errs << ProgramName << ": Did you mean '";1685if (IsArg)1686*Errs << PrintArg(NearestArgumentName, 0);1687else1688*Errs << NearestArgumentName;1689*Errs << "'?\n";1690};16911692if (i > 1 || !MaybeNamedSubCommand)1693ReportUnknownArgument(/*IsArg=*/true, NearestHandlerString);1694else1695ReportUnknownArgument(/*IsArg=*/false, NearestSubCommandString);16961697ErrorParsing = true;1698continue;1699}17001701// If this is a named positional argument, just remember that it is the1702// active one...1703if (Handler->getFormattingFlag() == cl::Positional) {1704if ((Handler->getMiscFlags() & PositionalEatsArgs) && !Value.empty()) {1705Handler->error("This argument does not take a value.\n"1706"\tInstead, it consumes any positional arguments until "1707"the next recognized option.", *Errs);1708ErrorParsing = true;1709}1710ActivePositionalArg = Handler;1711}1712else1713ErrorParsing |= ProvideOption(Handler, ArgName, Value, argc, argv, i);1714}17151716// Check and handle positional arguments now...1717if (NumPositionalRequired > PositionalVals.size()) {1718*Errs << ProgramName1719<< ": Not enough positional command line arguments specified!\n"1720<< "Must specify at least " << NumPositionalRequired1721<< " positional argument" << (NumPositionalRequired > 1 ? "s" : "")1722<< ": See: " << argv[0] << " --help\n";17231724ErrorParsing = true;1725} else if (!HasUnlimitedPositionals &&1726PositionalVals.size() > PositionalOpts.size()) {1727*Errs << ProgramName << ": Too many positional arguments specified!\n"1728<< "Can specify at most " << PositionalOpts.size()1729<< " positional arguments: See: " << argv[0] << " --help\n";1730ErrorParsing = true;17311732} else if (!ConsumeAfterOpt) {1733// Positional args have already been handled if ConsumeAfter is specified.1734unsigned ValNo = 0, NumVals = static_cast<unsigned>(PositionalVals.size());1735for (Option *Opt : PositionalOpts) {1736if (RequiresValue(Opt)) {1737ProvidePositionalOption(Opt, PositionalVals[ValNo].first,1738PositionalVals[ValNo].second);1739ValNo++;1740--NumPositionalRequired; // We fulfilled our duty...1741}17421743// If we _can_ give this option more arguments, do so now, as long as we1744// do not give it values that others need. 'Done' controls whether the1745// option even _WANTS_ any more.1746//1747bool Done = Opt->getNumOccurrencesFlag() == cl::Required;1748while (NumVals - ValNo > NumPositionalRequired && !Done) {1749switch (Opt->getNumOccurrencesFlag()) {1750case cl::Optional:1751Done = true; // Optional arguments want _at most_ one value1752[[fallthrough]];1753case cl::ZeroOrMore: // Zero or more will take all they can get...1754case cl::OneOrMore: // One or more will take all they can get...1755ProvidePositionalOption(Opt, PositionalVals[ValNo].first,1756PositionalVals[ValNo].second);1757ValNo++;1758break;1759default:1760llvm_unreachable("Internal error, unexpected NumOccurrences flag in "1761"positional argument processing!");1762}1763}1764}1765} else {1766assert(ConsumeAfterOpt && NumPositionalRequired <= PositionalVals.size());1767unsigned ValNo = 0;1768for (Option *Opt : PositionalOpts)1769if (RequiresValue(Opt)) {1770ErrorParsing |= ProvidePositionalOption(1771Opt, PositionalVals[ValNo].first, PositionalVals[ValNo].second);1772ValNo++;1773}17741775// Handle the case where there is just one positional option, and it's1776// optional. In this case, we want to give JUST THE FIRST option to the1777// positional option and keep the rest for the consume after. The above1778// loop would have assigned no values to positional options in this case.1779//1780if (PositionalOpts.size() == 1 && ValNo == 0 && !PositionalVals.empty()) {1781ErrorParsing |= ProvidePositionalOption(PositionalOpts[0],1782PositionalVals[ValNo].first,1783PositionalVals[ValNo].second);1784ValNo++;1785}17861787// Handle over all of the rest of the arguments to the1788// cl::ConsumeAfter command line option...1789for (; ValNo != PositionalVals.size(); ++ValNo)1790ErrorParsing |=1791ProvidePositionalOption(ConsumeAfterOpt, PositionalVals[ValNo].first,1792PositionalVals[ValNo].second);1793}17941795// Loop over args and make sure all required args are specified!1796for (const auto &Opt : OptionsMap) {1797switch (Opt.second->getNumOccurrencesFlag()) {1798case Required:1799case OneOrMore:1800if (Opt.second->getNumOccurrences() == 0) {1801Opt.second->error("must be specified at least once!");1802ErrorParsing = true;1803}1804[[fallthrough]];1805default:1806break;1807}1808}18091810// Now that we know if -debug is specified, we can use it.1811// Note that if ReadResponseFiles == true, this must be done before the1812// memory allocated for the expanded command line is free()d below.1813LLVM_DEBUG(dbgs() << "Args: ";1814for (int i = 0; i < argc; ++i) dbgs() << argv[i] << ' ';1815dbgs() << '\n';);18161817// Free all of the memory allocated to the map. Command line options may only1818// be processed once!1819MoreHelp.clear();18201821// If we had an error processing our arguments, don't let the program execute1822if (ErrorParsing) {1823if (!IgnoreErrors)1824exit(1);1825return false;1826}1827return true;1828}18291830//===----------------------------------------------------------------------===//1831// Option Base class implementation1832//18331834bool Option::error(const Twine &Message, StringRef ArgName, raw_ostream &Errs) {1835if (!ArgName.data())1836ArgName = ArgStr;1837if (ArgName.empty())1838Errs << HelpStr; // Be nice for positional arguments1839else1840Errs << GlobalParser->ProgramName << ": for the " << PrintArg(ArgName, 0);18411842Errs << " option: " << Message << "\n";1843return true;1844}18451846bool Option::addOccurrence(unsigned pos, StringRef ArgName, StringRef Value,1847bool MultiArg) {1848if (!MultiArg)1849NumOccurrences++; // Increment the number of times we have been seen18501851return handleOccurrence(pos, ArgName, Value);1852}18531854// getValueStr - Get the value description string, using "DefaultMsg" if nothing1855// has been specified yet.1856//1857static StringRef getValueStr(const Option &O, StringRef DefaultMsg) {1858if (O.ValueStr.empty())1859return DefaultMsg;1860return O.ValueStr;1861}18621863//===----------------------------------------------------------------------===//1864// cl::alias class implementation1865//18661867// Return the width of the option tag for printing...1868size_t alias::getOptionWidth() const {1869return argPlusPrefixesSize(ArgStr);1870}18711872void Option::printHelpStr(StringRef HelpStr, size_t Indent,1873size_t FirstLineIndentedBy) {1874assert(Indent >= FirstLineIndentedBy);1875std::pair<StringRef, StringRef> Split = HelpStr.split('\n');1876outs().indent(Indent - FirstLineIndentedBy)1877<< ArgHelpPrefix << Split.first << "\n";1878while (!Split.second.empty()) {1879Split = Split.second.split('\n');1880outs().indent(Indent) << Split.first << "\n";1881}1882}18831884void Option::printEnumValHelpStr(StringRef HelpStr, size_t BaseIndent,1885size_t FirstLineIndentedBy) {1886const StringRef ValHelpPrefix = " ";1887assert(BaseIndent >= FirstLineIndentedBy);1888std::pair<StringRef, StringRef> Split = HelpStr.split('\n');1889outs().indent(BaseIndent - FirstLineIndentedBy)1890<< ArgHelpPrefix << ValHelpPrefix << Split.first << "\n";1891while (!Split.second.empty()) {1892Split = Split.second.split('\n');1893outs().indent(BaseIndent + ValHelpPrefix.size()) << Split.first << "\n";1894}1895}18961897// Print out the option for the alias.1898void alias::printOptionInfo(size_t GlobalWidth) const {1899outs() << PrintArg(ArgStr);1900printHelpStr(HelpStr, GlobalWidth, argPlusPrefixesSize(ArgStr));1901}19021903//===----------------------------------------------------------------------===//1904// Parser Implementation code...1905//19061907// basic_parser implementation1908//19091910// Return the width of the option tag for printing...1911size_t basic_parser_impl::getOptionWidth(const Option &O) const {1912size_t Len = argPlusPrefixesSize(O.ArgStr);1913auto ValName = getValueName();1914if (!ValName.empty()) {1915size_t FormattingLen = 3;1916if (O.getMiscFlags() & PositionalEatsArgs)1917FormattingLen = 6;1918Len += getValueStr(O, ValName).size() + FormattingLen;1919}19201921return Len;1922}19231924// printOptionInfo - Print out information about this option. The1925// to-be-maintained width is specified.1926//1927void basic_parser_impl::printOptionInfo(const Option &O,1928size_t GlobalWidth) const {1929outs() << PrintArg(O.ArgStr);19301931auto ValName = getValueName();1932if (!ValName.empty()) {1933if (O.getMiscFlags() & PositionalEatsArgs) {1934outs() << " <" << getValueStr(O, ValName) << ">...";1935} else if (O.getValueExpectedFlag() == ValueOptional)1936outs() << "[=<" << getValueStr(O, ValName) << ">]";1937else {1938outs() << (O.ArgStr.size() == 1 ? " <" : "=<") << getValueStr(O, ValName)1939<< '>';1940}1941}19421943Option::printHelpStr(O.HelpStr, GlobalWidth, getOptionWidth(O));1944}19451946void basic_parser_impl::printOptionName(const Option &O,1947size_t GlobalWidth) const {1948outs() << PrintArg(O.ArgStr);1949outs().indent(GlobalWidth - O.ArgStr.size());1950}19511952// parser<bool> implementation1953//1954bool parser<bool>::parse(Option &O, StringRef ArgName, StringRef Arg,1955bool &Value) {1956if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" ||1957Arg == "1") {1958Value = true;1959return false;1960}19611962if (Arg == "false" || Arg == "FALSE" || Arg == "False" || Arg == "0") {1963Value = false;1964return false;1965}1966return O.error("'" + Arg +1967"' is invalid value for boolean argument! Try 0 or 1");1968}19691970// parser<boolOrDefault> implementation1971//1972bool parser<boolOrDefault>::parse(Option &O, StringRef ArgName, StringRef Arg,1973boolOrDefault &Value) {1974if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" ||1975Arg == "1") {1976Value = BOU_TRUE;1977return false;1978}1979if (Arg == "false" || Arg == "FALSE" || Arg == "False" || Arg == "0") {1980Value = BOU_FALSE;1981return false;1982}19831984return O.error("'" + Arg +1985"' is invalid value for boolean argument! Try 0 or 1");1986}19871988// parser<int> implementation1989//1990bool parser<int>::parse(Option &O, StringRef ArgName, StringRef Arg,1991int &Value) {1992if (Arg.getAsInteger(0, Value))1993return O.error("'" + Arg + "' value invalid for integer argument!");1994return false;1995}19961997// parser<long> implementation1998//1999bool parser<long>::parse(Option &O, StringRef ArgName, StringRef Arg,2000long &Value) {2001if (Arg.getAsInteger(0, Value))2002return O.error("'" + Arg + "' value invalid for long argument!");2003return false;2004}20052006// parser<long long> implementation2007//2008bool parser<long long>::parse(Option &O, StringRef ArgName, StringRef Arg,2009long long &Value) {2010if (Arg.getAsInteger(0, Value))2011return O.error("'" + Arg + "' value invalid for llong argument!");2012return false;2013}20142015// parser<unsigned> implementation2016//2017bool parser<unsigned>::parse(Option &O, StringRef ArgName, StringRef Arg,2018unsigned &Value) {20192020if (Arg.getAsInteger(0, Value))2021return O.error("'" + Arg + "' value invalid for uint argument!");2022return false;2023}20242025// parser<unsigned long> implementation2026//2027bool parser<unsigned long>::parse(Option &O, StringRef ArgName, StringRef Arg,2028unsigned long &Value) {20292030if (Arg.getAsInteger(0, Value))2031return O.error("'" + Arg + "' value invalid for ulong argument!");2032return false;2033}20342035// parser<unsigned long long> implementation2036//2037bool parser<unsigned long long>::parse(Option &O, StringRef ArgName,2038StringRef Arg,2039unsigned long long &Value) {20402041if (Arg.getAsInteger(0, Value))2042return O.error("'" + Arg + "' value invalid for ullong argument!");2043return false;2044}20452046// parser<double>/parser<float> implementation2047//2048static bool parseDouble(Option &O, StringRef Arg, double &Value) {2049if (to_float(Arg, Value))2050return false;2051return O.error("'" + Arg + "' value invalid for floating point argument!");2052}20532054bool parser<double>::parse(Option &O, StringRef ArgName, StringRef Arg,2055double &Val) {2056return parseDouble(O, Arg, Val);2057}20582059bool parser<float>::parse(Option &O, StringRef ArgName, StringRef Arg,2060float &Val) {2061double dVal;2062if (parseDouble(O, Arg, dVal))2063return true;2064Val = (float)dVal;2065return false;2066}20672068// generic_parser_base implementation2069//20702071// findOption - Return the option number corresponding to the specified2072// argument string. If the option is not found, getNumOptions() is returned.2073//2074unsigned generic_parser_base::findOption(StringRef Name) {2075unsigned e = getNumOptions();20762077for (unsigned i = 0; i != e; ++i) {2078if (getOption(i) == Name)2079return i;2080}2081return e;2082}20832084static StringRef EqValue = "=<value>";2085static StringRef EmptyOption = "<empty>";2086static StringRef OptionPrefix = " =";2087static size_t getOptionPrefixesSize() {2088return OptionPrefix.size() + ArgHelpPrefix.size();2089}20902091static bool shouldPrintOption(StringRef Name, StringRef Description,2092const Option &O) {2093return O.getValueExpectedFlag() != ValueOptional || !Name.empty() ||2094!Description.empty();2095}20962097// Return the width of the option tag for printing...2098size_t generic_parser_base::getOptionWidth(const Option &O) const {2099if (O.hasArgStr()) {2100size_t Size =2101argPlusPrefixesSize(O.ArgStr) + EqValue.size();2102for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {2103StringRef Name = getOption(i);2104if (!shouldPrintOption(Name, getDescription(i), O))2105continue;2106size_t NameSize = Name.empty() ? EmptyOption.size() : Name.size();2107Size = std::max(Size, NameSize + getOptionPrefixesSize());2108}2109return Size;2110} else {2111size_t BaseSize = 0;2112for (unsigned i = 0, e = getNumOptions(); i != e; ++i)2113BaseSize = std::max(BaseSize, getOption(i).size() + 8);2114return BaseSize;2115}2116}21172118// printOptionInfo - Print out information about this option. The2119// to-be-maintained width is specified.2120//2121void generic_parser_base::printOptionInfo(const Option &O,2122size_t GlobalWidth) const {2123if (O.hasArgStr()) {2124// When the value is optional, first print a line just describing the2125// option without values.2126if (O.getValueExpectedFlag() == ValueOptional) {2127for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {2128if (getOption(i).empty()) {2129outs() << PrintArg(O.ArgStr);2130Option::printHelpStr(O.HelpStr, GlobalWidth,2131argPlusPrefixesSize(O.ArgStr));2132break;2133}2134}2135}21362137outs() << PrintArg(O.ArgStr) << EqValue;2138Option::printHelpStr(O.HelpStr, GlobalWidth,2139EqValue.size() +2140argPlusPrefixesSize(O.ArgStr));2141for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {2142StringRef OptionName = getOption(i);2143StringRef Description = getDescription(i);2144if (!shouldPrintOption(OptionName, Description, O))2145continue;2146size_t FirstLineIndent = OptionName.size() + getOptionPrefixesSize();2147outs() << OptionPrefix << OptionName;2148if (OptionName.empty()) {2149outs() << EmptyOption;2150assert(FirstLineIndent >= EmptyOption.size());2151FirstLineIndent += EmptyOption.size();2152}2153if (!Description.empty())2154Option::printEnumValHelpStr(Description, GlobalWidth, FirstLineIndent);2155else2156outs() << '\n';2157}2158} else {2159if (!O.HelpStr.empty())2160outs() << " " << O.HelpStr << '\n';2161for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {2162StringRef Option = getOption(i);2163outs() << " " << PrintArg(Option);2164Option::printHelpStr(getDescription(i), GlobalWidth, Option.size() + 8);2165}2166}2167}21682169static const size_t MaxOptWidth = 8; // arbitrary spacing for printOptionDiff21702171// printGenericOptionDiff - Print the value of this option and it's default.2172//2173// "Generic" options have each value mapped to a name.2174void generic_parser_base::printGenericOptionDiff(2175const Option &O, const GenericOptionValue &Value,2176const GenericOptionValue &Default, size_t GlobalWidth) const {2177outs() << " " << PrintArg(O.ArgStr);2178outs().indent(GlobalWidth - O.ArgStr.size());21792180unsigned NumOpts = getNumOptions();2181for (unsigned i = 0; i != NumOpts; ++i) {2182if (!Value.compare(getOptionValue(i)))2183continue;21842185outs() << "= " << getOption(i);2186size_t L = getOption(i).size();2187size_t NumSpaces = MaxOptWidth > L ? MaxOptWidth - L : 0;2188outs().indent(NumSpaces) << " (default: ";2189for (unsigned j = 0; j != NumOpts; ++j) {2190if (!Default.compare(getOptionValue(j)))2191continue;2192outs() << getOption(j);2193break;2194}2195outs() << ")\n";2196return;2197}2198outs() << "= *unknown option value*\n";2199}22002201// printOptionDiff - Specializations for printing basic value types.2202//2203#define PRINT_OPT_DIFF(T) \2204void parser<T>::printOptionDiff(const Option &O, T V, OptionValue<T> D, \2205size_t GlobalWidth) const { \2206printOptionName(O, GlobalWidth); \2207std::string Str; \2208{ \2209raw_string_ostream SS(Str); \2210SS << V; \2211} \2212outs() << "= " << Str; \2213size_t NumSpaces = \2214MaxOptWidth > Str.size() ? MaxOptWidth - Str.size() : 0; \2215outs().indent(NumSpaces) << " (default: "; \2216if (D.hasValue()) \2217outs() << D.getValue(); \2218else \2219outs() << "*no default*"; \2220outs() << ")\n"; \2221}22222223PRINT_OPT_DIFF(bool)2224PRINT_OPT_DIFF(boolOrDefault)2225PRINT_OPT_DIFF(int)2226PRINT_OPT_DIFF(long)2227PRINT_OPT_DIFF(long long)2228PRINT_OPT_DIFF(unsigned)2229PRINT_OPT_DIFF(unsigned long)2230PRINT_OPT_DIFF(unsigned long long)2231PRINT_OPT_DIFF(double)2232PRINT_OPT_DIFF(float)2233PRINT_OPT_DIFF(char)22342235void parser<std::string>::printOptionDiff(const Option &O, StringRef V,2236const OptionValue<std::string> &D,2237size_t GlobalWidth) const {2238printOptionName(O, GlobalWidth);2239outs() << "= " << V;2240size_t NumSpaces = MaxOptWidth > V.size() ? MaxOptWidth - V.size() : 0;2241outs().indent(NumSpaces) << " (default: ";2242if (D.hasValue())2243outs() << D.getValue();2244else2245outs() << "*no default*";2246outs() << ")\n";2247}22482249// Print a placeholder for options that don't yet support printOptionDiff().2250void basic_parser_impl::printOptionNoValue(const Option &O,2251size_t GlobalWidth) const {2252printOptionName(O, GlobalWidth);2253outs() << "= *cannot print option value*\n";2254}22552256//===----------------------------------------------------------------------===//2257// -help and -help-hidden option implementation2258//22592260static int OptNameCompare(const std::pair<const char *, Option *> *LHS,2261const std::pair<const char *, Option *> *RHS) {2262return strcmp(LHS->first, RHS->first);2263}22642265static int SubNameCompare(const std::pair<const char *, SubCommand *> *LHS,2266const std::pair<const char *, SubCommand *> *RHS) {2267return strcmp(LHS->first, RHS->first);2268}22692270// Copy Options into a vector so we can sort them as we like.2271static void sortOpts(StringMap<Option *> &OptMap,2272SmallVectorImpl<std::pair<const char *, Option *>> &Opts,2273bool ShowHidden) {2274SmallPtrSet<Option *, 32> OptionSet; // Duplicate option detection.22752276for (StringMap<Option *>::iterator I = OptMap.begin(), E = OptMap.end();2277I != E; ++I) {2278// Ignore really-hidden options.2279if (I->second->getOptionHiddenFlag() == ReallyHidden)2280continue;22812282// Unless showhidden is set, ignore hidden flags.2283if (I->second->getOptionHiddenFlag() == Hidden && !ShowHidden)2284continue;22852286// If we've already seen this option, don't add it to the list again.2287if (!OptionSet.insert(I->second).second)2288continue;22892290Opts.push_back(2291std::pair<const char *, Option *>(I->getKey().data(), I->second));2292}22932294// Sort the options list alphabetically.2295array_pod_sort(Opts.begin(), Opts.end(), OptNameCompare);2296}22972298static void2299sortSubCommands(const SmallPtrSetImpl<SubCommand *> &SubMap,2300SmallVectorImpl<std::pair<const char *, SubCommand *>> &Subs) {2301for (auto *S : SubMap) {2302if (S->getName().empty())2303continue;2304Subs.push_back(std::make_pair(S->getName().data(), S));2305}2306array_pod_sort(Subs.begin(), Subs.end(), SubNameCompare);2307}23082309namespace {23102311class HelpPrinter {2312protected:2313const bool ShowHidden;2314typedef SmallVector<std::pair<const char *, Option *>, 128>2315StrOptionPairVector;2316typedef SmallVector<std::pair<const char *, SubCommand *>, 128>2317StrSubCommandPairVector;2318// Print the options. Opts is assumed to be alphabetically sorted.2319virtual void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) {2320for (size_t i = 0, e = Opts.size(); i != e; ++i)2321Opts[i].second->printOptionInfo(MaxArgLen);2322}23232324void printSubCommands(StrSubCommandPairVector &Subs, size_t MaxSubLen) {2325for (const auto &S : Subs) {2326outs() << " " << S.first;2327if (!S.second->getDescription().empty()) {2328outs().indent(MaxSubLen - strlen(S.first));2329outs() << " - " << S.second->getDescription();2330}2331outs() << "\n";2332}2333}23342335public:2336explicit HelpPrinter(bool showHidden) : ShowHidden(showHidden) {}2337virtual ~HelpPrinter() = default;23382339// Invoke the printer.2340void operator=(bool Value) {2341if (!Value)2342return;2343printHelp();23442345// Halt the program since help information was printed2346exit(0);2347}23482349void printHelp() {2350SubCommand *Sub = GlobalParser->getActiveSubCommand();2351auto &OptionsMap = Sub->OptionsMap;2352auto &PositionalOpts = Sub->PositionalOpts;2353auto &ConsumeAfterOpt = Sub->ConsumeAfterOpt;23542355StrOptionPairVector Opts;2356sortOpts(OptionsMap, Opts, ShowHidden);23572358StrSubCommandPairVector Subs;2359sortSubCommands(GlobalParser->RegisteredSubCommands, Subs);23602361if (!GlobalParser->ProgramOverview.empty())2362outs() << "OVERVIEW: " << GlobalParser->ProgramOverview << "\n";23632364if (Sub == &SubCommand::getTopLevel()) {2365outs() << "USAGE: " << GlobalParser->ProgramName;2366if (!Subs.empty())2367outs() << " [subcommand]";2368outs() << " [options]";2369} else {2370if (!Sub->getDescription().empty()) {2371outs() << "SUBCOMMAND '" << Sub->getName()2372<< "': " << Sub->getDescription() << "\n\n";2373}2374outs() << "USAGE: " << GlobalParser->ProgramName << " " << Sub->getName()2375<< " [options]";2376}23772378for (auto *Opt : PositionalOpts) {2379if (Opt->hasArgStr())2380outs() << " --" << Opt->ArgStr;2381outs() << " " << Opt->HelpStr;2382}23832384// Print the consume after option info if it exists...2385if (ConsumeAfterOpt)2386outs() << " " << ConsumeAfterOpt->HelpStr;23872388if (Sub == &SubCommand::getTopLevel() && !Subs.empty()) {2389// Compute the maximum subcommand length...2390size_t MaxSubLen = 0;2391for (size_t i = 0, e = Subs.size(); i != e; ++i)2392MaxSubLen = std::max(MaxSubLen, strlen(Subs[i].first));23932394outs() << "\n\n";2395outs() << "SUBCOMMANDS:\n\n";2396printSubCommands(Subs, MaxSubLen);2397outs() << "\n";2398outs() << " Type \"" << GlobalParser->ProgramName2399<< " <subcommand> --help\" to get more help on a specific "2400"subcommand";2401}24022403outs() << "\n\n";24042405// Compute the maximum argument length...2406size_t MaxArgLen = 0;2407for (size_t i = 0, e = Opts.size(); i != e; ++i)2408MaxArgLen = std::max(MaxArgLen, Opts[i].second->getOptionWidth());24092410outs() << "OPTIONS:\n";2411printOptions(Opts, MaxArgLen);24122413// Print any extra help the user has declared.2414for (const auto &I : GlobalParser->MoreHelp)2415outs() << I;2416GlobalParser->MoreHelp.clear();2417}2418};24192420class CategorizedHelpPrinter : public HelpPrinter {2421public:2422explicit CategorizedHelpPrinter(bool showHidden) : HelpPrinter(showHidden) {}24232424// Helper function for printOptions().2425// It shall return a negative value if A's name should be lexicographically2426// ordered before B's name. It returns a value greater than zero if B's name2427// should be ordered before A's name, and it returns 0 otherwise.2428static int OptionCategoryCompare(OptionCategory *const *A,2429OptionCategory *const *B) {2430return (*A)->getName().compare((*B)->getName());2431}24322433// Make sure we inherit our base class's operator=()2434using HelpPrinter::operator=;24352436protected:2437void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) override {2438std::vector<OptionCategory *> SortedCategories;2439DenseMap<OptionCategory *, std::vector<Option *>> CategorizedOptions;24402441// Collect registered option categories into vector in preparation for2442// sorting.2443for (OptionCategory *Category : GlobalParser->RegisteredOptionCategories)2444SortedCategories.push_back(Category);24452446// Sort the different option categories alphabetically.2447assert(SortedCategories.size() > 0 && "No option categories registered!");2448array_pod_sort(SortedCategories.begin(), SortedCategories.end(),2449OptionCategoryCompare);24502451// Walk through pre-sorted options and assign into categories.2452// Because the options are already alphabetically sorted the2453// options within categories will also be alphabetically sorted.2454for (size_t I = 0, E = Opts.size(); I != E; ++I) {2455Option *Opt = Opts[I].second;2456for (auto &Cat : Opt->Categories) {2457assert(llvm::is_contained(SortedCategories, Cat) &&2458"Option has an unregistered category");2459CategorizedOptions[Cat].push_back(Opt);2460}2461}24622463// Now do printing.2464for (OptionCategory *Category : SortedCategories) {2465// Hide empty categories for --help, but show for --help-hidden.2466const auto &CategoryOptions = CategorizedOptions[Category];2467if (CategoryOptions.empty())2468continue;24692470// Print category information.2471outs() << "\n";2472outs() << Category->getName() << ":\n";24732474// Check if description is set.2475if (!Category->getDescription().empty())2476outs() << Category->getDescription() << "\n\n";2477else2478outs() << "\n";24792480// Loop over the options in the category and print.2481for (const Option *Opt : CategoryOptions)2482Opt->printOptionInfo(MaxArgLen);2483}2484}2485};24862487// This wraps the Uncategorizing and Categorizing printers and decides2488// at run time which should be invoked.2489class HelpPrinterWrapper {2490private:2491HelpPrinter &UncategorizedPrinter;2492CategorizedHelpPrinter &CategorizedPrinter;24932494public:2495explicit HelpPrinterWrapper(HelpPrinter &UncategorizedPrinter,2496CategorizedHelpPrinter &CategorizedPrinter)2497: UncategorizedPrinter(UncategorizedPrinter),2498CategorizedPrinter(CategorizedPrinter) {}24992500// Invoke the printer.2501void operator=(bool Value);2502};25032504} // End anonymous namespace25052506#if defined(__GNUC__)2507// GCC and GCC-compatible compilers define __OPTIMIZE__ when optimizations are2508// enabled.2509# if defined(__OPTIMIZE__)2510# define LLVM_IS_DEBUG_BUILD 02511# else2512# define LLVM_IS_DEBUG_BUILD 12513# endif2514#elif defined(_MSC_VER)2515// MSVC doesn't have a predefined macro indicating if optimizations are enabled.2516// Use _DEBUG instead. This macro actually corresponds to the choice between2517// debug and release CRTs, but it is a reasonable proxy.2518# if defined(_DEBUG)2519# define LLVM_IS_DEBUG_BUILD 12520# else2521# define LLVM_IS_DEBUG_BUILD 02522# endif2523#else2524// Otherwise, for an unknown compiler, assume this is an optimized build.2525# define LLVM_IS_DEBUG_BUILD 02526#endif25272528namespace {2529class VersionPrinter {2530public:2531void print(std::vector<VersionPrinterTy> ExtraPrinters = {}) {2532raw_ostream &OS = outs();2533#ifdef PACKAGE_VENDOR2534OS << PACKAGE_VENDOR << " ";2535#else2536OS << "LLVM (http://llvm.org/):\n ";2537#endif2538OS << PACKAGE_NAME << " version " << PACKAGE_VERSION << "\n ";2539#if LLVM_IS_DEBUG_BUILD2540OS << "DEBUG build";2541#else2542OS << "Optimized build";2543#endif2544#ifndef NDEBUG2545OS << " with assertions";2546#endif2547OS << ".\n";25482549// Iterate over any registered extra printers and call them to add further2550// information.2551if (!ExtraPrinters.empty()) {2552for (const auto &I : ExtraPrinters)2553I(outs());2554}2555}2556void operator=(bool OptionWasSpecified);2557};25582559struct CommandLineCommonOptions {2560// Declare the four HelpPrinter instances that are used to print out help, or2561// help-hidden as an uncategorized list or in categories.2562HelpPrinter UncategorizedNormalPrinter{false};2563HelpPrinter UncategorizedHiddenPrinter{true};2564CategorizedHelpPrinter CategorizedNormalPrinter{false};2565CategorizedHelpPrinter CategorizedHiddenPrinter{true};2566// Declare HelpPrinter wrappers that will decide whether or not to invoke2567// a categorizing help printer2568HelpPrinterWrapper WrappedNormalPrinter{UncategorizedNormalPrinter,2569CategorizedNormalPrinter};2570HelpPrinterWrapper WrappedHiddenPrinter{UncategorizedHiddenPrinter,2571CategorizedHiddenPrinter};2572// Define a category for generic options that all tools should have.2573cl::OptionCategory GenericCategory{"Generic Options"};25742575// Define uncategorized help printers.2576// --help-list is hidden by default because if Option categories are being2577// used then --help behaves the same as --help-list.2578cl::opt<HelpPrinter, true, parser<bool>> HLOp{2579"help-list",2580cl::desc(2581"Display list of available options (--help-list-hidden for more)"),2582cl::location(UncategorizedNormalPrinter),2583cl::Hidden,2584cl::ValueDisallowed,2585cl::cat(GenericCategory),2586cl::sub(SubCommand::getAll())};25872588cl::opt<HelpPrinter, true, parser<bool>> HLHOp{2589"help-list-hidden",2590cl::desc("Display list of all available options"),2591cl::location(UncategorizedHiddenPrinter),2592cl::Hidden,2593cl::ValueDisallowed,2594cl::cat(GenericCategory),2595cl::sub(SubCommand::getAll())};25962597// Define uncategorized/categorized help printers. These printers change their2598// behaviour at runtime depending on whether one or more Option categories2599// have been declared.2600cl::opt<HelpPrinterWrapper, true, parser<bool>> HOp{2601"help",2602cl::desc("Display available options (--help-hidden for more)"),2603cl::location(WrappedNormalPrinter),2604cl::ValueDisallowed,2605cl::cat(GenericCategory),2606cl::sub(SubCommand::getAll())};26072608cl::alias HOpA{"h", cl::desc("Alias for --help"), cl::aliasopt(HOp),2609cl::DefaultOption};26102611cl::opt<HelpPrinterWrapper, true, parser<bool>> HHOp{2612"help-hidden",2613cl::desc("Display all available options"),2614cl::location(WrappedHiddenPrinter),2615cl::Hidden,2616cl::ValueDisallowed,2617cl::cat(GenericCategory),2618cl::sub(SubCommand::getAll())};26192620cl::opt<bool> PrintOptions{2621"print-options",2622cl::desc("Print non-default options after command line parsing"),2623cl::Hidden,2624cl::init(false),2625cl::cat(GenericCategory),2626cl::sub(SubCommand::getAll())};26272628cl::opt<bool> PrintAllOptions{2629"print-all-options",2630cl::desc("Print all option values after command line parsing"),2631cl::Hidden,2632cl::init(false),2633cl::cat(GenericCategory),2634cl::sub(SubCommand::getAll())};26352636VersionPrinterTy OverrideVersionPrinter = nullptr;26372638std::vector<VersionPrinterTy> ExtraVersionPrinters;26392640// Define the --version option that prints out the LLVM version for the tool2641VersionPrinter VersionPrinterInstance;26422643cl::opt<VersionPrinter, true, parser<bool>> VersOp{2644"version", cl::desc("Display the version of this program"),2645cl::location(VersionPrinterInstance), cl::ValueDisallowed,2646cl::cat(GenericCategory)};2647};2648} // End anonymous namespace26492650// Lazy-initialized global instance of options controlling the command-line2651// parser and general handling.2652static ManagedStatic<CommandLineCommonOptions> CommonOptions;26532654static void initCommonOptions() {2655*CommonOptions;2656initDebugCounterOptions();2657initGraphWriterOptions();2658initSignalsOptions();2659initStatisticOptions();2660initTimerOptions();2661initTypeSizeOptions();2662initWithColorOptions();2663initDebugOptions();2664initRandomSeedOptions();2665}26662667OptionCategory &cl::getGeneralCategory() {2668// Initialise the general option category.2669static OptionCategory GeneralCategory{"General options"};2670return GeneralCategory;2671}26722673void VersionPrinter::operator=(bool OptionWasSpecified) {2674if (!OptionWasSpecified)2675return;26762677if (CommonOptions->OverrideVersionPrinter != nullptr) {2678CommonOptions->OverrideVersionPrinter(outs());2679exit(0);2680}2681print(CommonOptions->ExtraVersionPrinters);26822683exit(0);2684}26852686void HelpPrinterWrapper::operator=(bool Value) {2687if (!Value)2688return;26892690// Decide which printer to invoke. If more than one option category is2691// registered then it is useful to show the categorized help instead of2692// uncategorized help.2693if (GlobalParser->RegisteredOptionCategories.size() > 1) {2694// unhide --help-list option so user can have uncategorized output if they2695// want it.2696CommonOptions->HLOp.setHiddenFlag(NotHidden);26972698CategorizedPrinter = true; // Invoke categorized printer2699} else2700UncategorizedPrinter = true; // Invoke uncategorized printer2701}27022703// Print the value of each option.2704void cl::PrintOptionValues() { GlobalParser->printOptionValues(); }27052706void CommandLineParser::printOptionValues() {2707if (!CommonOptions->PrintOptions && !CommonOptions->PrintAllOptions)2708return;27092710SmallVector<std::pair<const char *, Option *>, 128> Opts;2711sortOpts(ActiveSubCommand->OptionsMap, Opts, /*ShowHidden*/ true);27122713// Compute the maximum argument length...2714size_t MaxArgLen = 0;2715for (size_t i = 0, e = Opts.size(); i != e; ++i)2716MaxArgLen = std::max(MaxArgLen, Opts[i].second->getOptionWidth());27172718for (size_t i = 0, e = Opts.size(); i != e; ++i)2719Opts[i].second->printOptionValue(MaxArgLen, CommonOptions->PrintAllOptions);2720}27212722// Utility function for printing the help message.2723void cl::PrintHelpMessage(bool Hidden, bool Categorized) {2724if (!Hidden && !Categorized)2725CommonOptions->UncategorizedNormalPrinter.printHelp();2726else if (!Hidden && Categorized)2727CommonOptions->CategorizedNormalPrinter.printHelp();2728else if (Hidden && !Categorized)2729CommonOptions->UncategorizedHiddenPrinter.printHelp();2730else2731CommonOptions->CategorizedHiddenPrinter.printHelp();2732}27332734ArrayRef<StringRef> cl::getCompilerBuildConfig() {2735static const StringRef Config[] = {2736// Placeholder to ensure the array always has elements, since it's an2737// error to have a zero-sized array. Slice this off before returning.2738"",2739// Actual compiler build config feature list:2740#if LLVM_IS_DEBUG_BUILD2741"+unoptimized",2742#endif2743#ifndef NDEBUG2744"+assertions",2745#endif2746#ifdef EXPENSIVE_CHECKS2747"+expensive-checks",2748#endif2749#if __has_feature(address_sanitizer)2750"+asan",2751#endif2752#if __has_feature(dataflow_sanitizer)2753"+dfsan",2754#endif2755#if __has_feature(hwaddress_sanitizer)2756"+hwasan",2757#endif2758#if __has_feature(memory_sanitizer)2759"+msan",2760#endif2761#if __has_feature(thread_sanitizer)2762"+tsan",2763#endif2764#if __has_feature(undefined_behavior_sanitizer)2765"+ubsan",2766#endif2767};2768return ArrayRef(Config).drop_front(1);2769}27702771// Utility function for printing the build config.2772void cl::printBuildConfig(raw_ostream &OS) {2773#if LLVM_VERSION_PRINTER_SHOW_BUILD_CONFIG2774OS << "Build config: ";2775llvm::interleaveComma(cl::getCompilerBuildConfig(), OS);2776OS << '\n';2777#endif2778}27792780/// Utility function for printing version number.2781void cl::PrintVersionMessage() {2782CommonOptions->VersionPrinterInstance.print(CommonOptions->ExtraVersionPrinters);2783}27842785void cl::SetVersionPrinter(VersionPrinterTy func) {2786CommonOptions->OverrideVersionPrinter = func;2787}27882789void cl::AddExtraVersionPrinter(VersionPrinterTy func) {2790CommonOptions->ExtraVersionPrinters.push_back(func);2791}27922793StringMap<Option *> &cl::getRegisteredOptions(SubCommand &Sub) {2794initCommonOptions();2795auto &Subs = GlobalParser->RegisteredSubCommands;2796(void)Subs;2797assert(Subs.contains(&Sub));2798return Sub.OptionsMap;2799}28002801iterator_range<typename SmallPtrSet<SubCommand *, 4>::iterator>2802cl::getRegisteredSubcommands() {2803return GlobalParser->getRegisteredSubcommands();2804}28052806void cl::HideUnrelatedOptions(cl::OptionCategory &Category, SubCommand &Sub) {2807initCommonOptions();2808for (auto &I : Sub.OptionsMap) {2809bool Unrelated = true;2810for (auto &Cat : I.second->Categories) {2811if (Cat == &Category || Cat == &CommonOptions->GenericCategory)2812Unrelated = false;2813}2814if (Unrelated)2815I.second->setHiddenFlag(cl::ReallyHidden);2816}2817}28182819void cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *> Categories,2820SubCommand &Sub) {2821initCommonOptions();2822for (auto &I : Sub.OptionsMap) {2823bool Unrelated = true;2824for (auto &Cat : I.second->Categories) {2825if (is_contained(Categories, Cat) ||2826Cat == &CommonOptions->GenericCategory)2827Unrelated = false;2828}2829if (Unrelated)2830I.second->setHiddenFlag(cl::ReallyHidden);2831}2832}28332834void cl::ResetCommandLineParser() { GlobalParser->reset(); }2835void cl::ResetAllOptionOccurrences() {2836GlobalParser->ResetAllOptionOccurrences();2837}28382839void LLVMParseCommandLineOptions(int argc, const char *const *argv,2840const char *Overview) {2841llvm::cl::ParseCommandLineOptions(argc, argv, StringRef(Overview),2842&llvm::nulls());2843}284428452846