brintos

brintos / llvm-project-archived public Read only

0
0
Text · 97.2 KiB · 5095b29 Raw
2873 lines · cpp
1//===-- CommandLine.cpp - Command line parser implementation --------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This class implements a command line argument processor that is useful when10// creating a tool.  It provides a simple, minimalistic interface that is easily11// extensible and supports nonlocal (library) command line options.12//13// Note that rather than trying to figure out what this code does, you could try14// reading the library documentation located in docs/CommandLine.html15//16//===----------------------------------------------------------------------===//17 18#include "llvm/Support/CommandLine.h"19 20#include "DebugOptions.h"21 22#include "llvm-c/Support.h"23#include "llvm/ADT/ArrayRef.h"24#include "llvm/ADT/STLFunctionalExtras.h"25#include "llvm/ADT/SmallPtrSet.h"26#include "llvm/ADT/SmallString.h"27#include "llvm/ADT/StringExtras.h"28#include "llvm/ADT/StringMap.h"29#include "llvm/ADT/StringRef.h"30#include "llvm/ADT/Twine.h"31#include "llvm/Config/config.h"32#include "llvm/Support/Compiler.h"33#include "llvm/Support/ConvertUTF.h"34#include "llvm/Support/Debug.h"35#include "llvm/Support/Error.h"36#include "llvm/Support/ErrorHandling.h"37#include "llvm/Support/FileSystem.h"38#include "llvm/Support/ManagedStatic.h"39#include "llvm/Support/MemoryBuffer.h"40#include "llvm/Support/Path.h"41#include "llvm/Support/Process.h"42#include "llvm/Support/StringSaver.h"43#include "llvm/Support/VirtualFileSystem.h"44#include "llvm/Support/raw_ostream.h"45#include <cstdlib>46#include <optional>47#include <string>48using namespace llvm;49using namespace cl;50 51#define DEBUG_TYPE "commandline"52 53//===----------------------------------------------------------------------===//54// Template instantiations and anchors.55//56namespace llvm {57namespace cl {58template class LLVM_EXPORT_TEMPLATE basic_parser<bool>;59template class LLVM_EXPORT_TEMPLATE basic_parser<boolOrDefault>;60template class LLVM_EXPORT_TEMPLATE basic_parser<int>;61template class LLVM_EXPORT_TEMPLATE basic_parser<long>;62template class LLVM_EXPORT_TEMPLATE basic_parser<long long>;63template class LLVM_EXPORT_TEMPLATE basic_parser<unsigned>;64template class LLVM_EXPORT_TEMPLATE basic_parser<unsigned long>;65template class LLVM_EXPORT_TEMPLATE basic_parser<unsigned long long>;66template class LLVM_EXPORT_TEMPLATE basic_parser<double>;67template class LLVM_EXPORT_TEMPLATE basic_parser<float>;68template class LLVM_EXPORT_TEMPLATE basic_parser<std::string>;69template class LLVM_EXPORT_TEMPLATE basic_parser<char>;70 71#if !(defined(LLVM_ENABLE_LLVM_EXPORT_ANNOTATIONS) && defined(_MSC_VER))72// Only instantiate opt<std::string> when not building a Windows DLL. When73// exporting opt<std::string>, MSVC implicitly exports symbols for74// std::basic_string through transitive inheritance via std::string. These75// symbols may appear in clients, leading to duplicate symbol conflicts.76template class LLVM_EXPORT_TEMPLATE opt<std::string>;77#endif78 79template class LLVM_EXPORT_TEMPLATE opt<bool>;80template class LLVM_EXPORT_TEMPLATE opt<char>;81template class LLVM_EXPORT_TEMPLATE opt<int>;82template class LLVM_EXPORT_TEMPLATE opt<unsigned>;83 84} // namespace cl85} // namespace llvm86 87// Pin the vtables to this file.88void GenericOptionValue::anchor() {}89void OptionValue<boolOrDefault>::anchor() {}90void OptionValue<std::string>::anchor() {}91void Option::anchor() {}92void basic_parser_impl::anchor() {}93void parser<bool>::anchor() {}94void parser<boolOrDefault>::anchor() {}95void parser<int>::anchor() {}96void parser<long>::anchor() {}97void parser<long long>::anchor() {}98void parser<unsigned>::anchor() {}99void parser<unsigned long>::anchor() {}100void parser<unsigned long long>::anchor() {}101void parser<double>::anchor() {}102void parser<float>::anchor() {}103void parser<std::string>::anchor() {}104void parser<std::optional<std::string>>::anchor() {}105void parser<char>::anchor() {}106 107// These anchor functions instantiate opt<T> and reference its virtual108// destructor to ensure MSVC exports the corresponding vtable and typeinfo when109// building a Windows DLL. Without an explicit reference, MSVC may omit the110// instantiation at link time even if it is marked DLL-export.111void opt_bool_anchor() { opt<bool> anchor{""}; }112void opt_char_anchor() { opt<char> anchor{""}; }113void opt_int_anchor() { opt<int> anchor{""}; }114void opt_unsigned_anchor() { opt<unsigned> anchor{""}; }115 116//===----------------------------------------------------------------------===//117 118const static size_t DefaultPad = 2;119 120static StringRef ArgPrefix = "-";121static StringRef ArgPrefixLong = "--";122static StringRef ArgHelpPrefix = " - ";123 124static size_t argPlusPrefixesSize(StringRef ArgName, size_t Pad = DefaultPad) {125  size_t Len = ArgName.size();126  if (Len == 1)127    return Len + Pad + ArgPrefix.size() + ArgHelpPrefix.size();128  return Len + Pad + ArgPrefixLong.size() + ArgHelpPrefix.size();129}130 131static SmallString<8> argPrefix(StringRef ArgName, size_t Pad = DefaultPad) {132  SmallString<8> Prefix;133  for (size_t I = 0; I < Pad; ++I) {134    Prefix.push_back(' ');135  }136  Prefix.append(ArgName.size() > 1 ? ArgPrefixLong : ArgPrefix);137  return Prefix;138}139 140// Option predicates...141static inline bool isGrouping(const Option *O) {142  return O->getMiscFlags() & cl::Grouping;143}144static inline bool isPrefixedOrGrouping(const Option *O) {145  return isGrouping(O) || O->getFormattingFlag() == cl::Prefix ||146         O->getFormattingFlag() == cl::AlwaysPrefix;147}148 149 150namespace {151 152class PrintArg {153  StringRef ArgName;154  size_t Pad;155public:156  PrintArg(StringRef ArgName, size_t Pad = DefaultPad) : ArgName(ArgName), Pad(Pad) {}157  friend raw_ostream &operator<<(raw_ostream &OS, const PrintArg &);158};159 160raw_ostream &operator<<(raw_ostream &OS, const PrintArg& Arg) {161  OS << argPrefix(Arg.ArgName, Arg.Pad) << Arg.ArgName;162  return OS;163}164 165class CommandLineParser {166public:167  // Globals for name and overview of program.  Program name is not a string to168  // avoid static ctor/dtor issues.169  std::string ProgramName;170  StringRef ProgramOverview;171 172  // This collects additional help to be printed.173  std::vector<StringRef> MoreHelp;174 175  // This collects Options added with the cl::DefaultOption flag. Since they can176  // be overridden, they are not added to the appropriate SubCommands until177  // ParseCommandLineOptions actually runs.178  SmallVector<Option*, 4> DefaultOptions;179 180  // This collects the different option categories that have been registered.181  SmallPtrSet<OptionCategory *, 16> RegisteredOptionCategories;182 183  // This collects the different subcommands that have been registered.184  SmallPtrSet<SubCommand *, 4> RegisteredSubCommands;185 186  CommandLineParser() { registerSubCommand(&SubCommand::getTopLevel()); }187 188  void ResetAllOptionOccurrences();189 190  bool ParseCommandLineOptions(int argc, const char *const *argv,191                               StringRef Overview, raw_ostream *Errs = nullptr,192                               vfs::FileSystem *VFS = nullptr,193                               bool LongOptionsUseDoubleDash = false);194 195  void forEachSubCommand(Option &Opt, function_ref<void(SubCommand &)> Action) {196    if (Opt.Subs.empty()) {197      Action(SubCommand::getTopLevel());198      return;199    }200    if (Opt.Subs.size() == 1 && *Opt.Subs.begin() == &SubCommand::getAll()) {201      for (auto *SC : RegisteredSubCommands)202        Action(*SC);203      Action(SubCommand::getAll());204      return;205    }206    for (auto *SC : Opt.Subs) {207      assert(SC != &SubCommand::getAll() &&208             "SubCommand::getAll() should not be used with other subcommands");209      Action(*SC);210    }211  }212 213  void addLiteralOption(Option &Opt, SubCommand *SC, StringRef Name) {214    if (Opt.hasArgStr())215      return;216    if (!SC->OptionsMap.insert(std::make_pair(Name, &Opt)).second) {217      errs() << ProgramName << ": CommandLine Error: Option '" << Name218             << "' registered more than once!\n";219      report_fatal_error("inconsistency in registered CommandLine options");220    }221  }222 223  void addLiteralOption(Option &Opt, StringRef Name) {224    forEachSubCommand(225        Opt, [&](SubCommand &SC) { addLiteralOption(Opt, &SC, Name); });226  }227 228  void addOption(Option *O, SubCommand *SC) {229    bool HadErrors = false;230    if (O->hasArgStr()) {231      // If it's a DefaultOption, check to make sure it isn't already there.232      if (O->isDefaultOption() && SC->OptionsMap.contains(O->ArgStr))233        return;234 235      // Add argument to the argument map!236      if (!SC->OptionsMap.insert(std::make_pair(O->ArgStr, O)).second) {237        errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr238               << "' registered more than once!\n";239        HadErrors = true;240      }241    }242 243    // Remember information about positional options.244    if (O->getFormattingFlag() == cl::Positional)245      SC->PositionalOpts.push_back(O);246    else if (O->getMiscFlags() & cl::Sink) // Remember sink options247      SC->SinkOpts.push_back(O);248    else if (O->getNumOccurrencesFlag() == cl::ConsumeAfter) {249      if (SC->ConsumeAfterOpt) {250        O->error("Cannot specify more than one option with cl::ConsumeAfter!");251        HadErrors = true;252      }253      SC->ConsumeAfterOpt = O;254    }255 256    // Fail hard if there were errors. These are strictly unrecoverable and257    // indicate serious issues such as conflicting option names or an258    // incorrectly259    // linked LLVM distribution.260    if (HadErrors)261      report_fatal_error("inconsistency in registered CommandLine options");262  }263 264  void addOption(Option *O, bool ProcessDefaultOption = false) {265    if (!ProcessDefaultOption && O->isDefaultOption()) {266      DefaultOptions.push_back(O);267      return;268    }269    forEachSubCommand(*O, [&](SubCommand &SC) { addOption(O, &SC); });270  }271 272  void removeOption(Option *O, SubCommand *SC) {273    SmallVector<StringRef, 16> OptionNames;274    O->getExtraOptionNames(OptionNames);275    if (O->hasArgStr())276      OptionNames.push_back(O->ArgStr);277 278    SubCommand &Sub = *SC;279    auto End = Sub.OptionsMap.end();280    for (auto Name : OptionNames) {281      auto I = Sub.OptionsMap.find(Name);282      if (I != End && I->getValue() == O)283        Sub.OptionsMap.erase(I);284    }285 286    if (O->getFormattingFlag() == cl::Positional)287      for (auto *Opt = Sub.PositionalOpts.begin();288           Opt != Sub.PositionalOpts.end(); ++Opt) {289        if (*Opt == O) {290          Sub.PositionalOpts.erase(Opt);291          break;292        }293      }294    else if (O->getMiscFlags() & cl::Sink)295      for (auto *Opt = Sub.SinkOpts.begin(); Opt != Sub.SinkOpts.end(); ++Opt) {296        if (*Opt == O) {297          Sub.SinkOpts.erase(Opt);298          break;299        }300      }301    else if (O == Sub.ConsumeAfterOpt)302      Sub.ConsumeAfterOpt = nullptr;303  }304 305  void removeOption(Option *O) {306    forEachSubCommand(*O, [&](SubCommand &SC) { removeOption(O, &SC); });307  }308 309  bool hasOptions(const SubCommand &Sub) const {310    return (!Sub.OptionsMap.empty() || !Sub.PositionalOpts.empty() ||311            nullptr != Sub.ConsumeAfterOpt);312  }313 314  bool hasOptions() const {315    for (const auto *S : RegisteredSubCommands) {316      if (hasOptions(*S))317        return true;318    }319    return false;320  }321 322  bool hasNamedSubCommands() const {323    for (const auto *S : RegisteredSubCommands)324      if (!S->getName().empty())325        return true;326    return false;327  }328 329  SubCommand *getActiveSubCommand() { return ActiveSubCommand; }330 331  void updateArgStr(Option *O, StringRef NewName, SubCommand *SC) {332    SubCommand &Sub = *SC;333    if (!Sub.OptionsMap.insert(std::make_pair(NewName, O)).second) {334      errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr335             << "' registered more than once!\n";336      report_fatal_error("inconsistency in registered CommandLine options");337    }338    Sub.OptionsMap.erase(O->ArgStr);339  }340 341  void updateArgStr(Option *O, StringRef NewName) {342    forEachSubCommand(*O,343                      [&](SubCommand &SC) { updateArgStr(O, NewName, &SC); });344  }345 346  void printOptionValues();347 348  void registerCategory(OptionCategory *cat) {349    assert(count_if(RegisteredOptionCategories,350                    [cat](const OptionCategory *Category) {351             return cat->getName() == Category->getName();352           }) == 0 &&353           "Duplicate option categories");354 355    RegisteredOptionCategories.insert(cat);356  }357 358  void registerSubCommand(SubCommand *sub) {359    assert(count_if(RegisteredSubCommands,360                    [sub](const SubCommand *Sub) {361                      return (!sub->getName().empty()) &&362                             (Sub->getName() == sub->getName());363                    }) == 0 &&364           "Duplicate subcommands");365    RegisteredSubCommands.insert(sub);366 367    // For all options that have been registered for all subcommands, add the368    // option to this subcommand now.369    assert(sub != &SubCommand::getAll() &&370           "SubCommand::getAll() should not be registered");371    for (auto &E : SubCommand::getAll().OptionsMap) {372      Option *O = E.second;373      if ((O->isPositional() || O->isSink() || O->isConsumeAfter()) ||374          O->hasArgStr())375        addOption(O, sub);376      else377        addLiteralOption(*O, sub, E.first());378    }379  }380 381  void unregisterSubCommand(SubCommand *sub) {382    RegisteredSubCommands.erase(sub);383  }384 385  iterator_range<SmallPtrSet<SubCommand *, 4>::iterator>386  getRegisteredSubcommands() {387    return make_range(RegisteredSubCommands.begin(),388                      RegisteredSubCommands.end());389  }390 391  void reset() {392    ActiveSubCommand = nullptr;393    ProgramName.clear();394    ProgramOverview = StringRef();395 396    MoreHelp.clear();397    RegisteredOptionCategories.clear();398 399    ResetAllOptionOccurrences();400    RegisteredSubCommands.clear();401 402    SubCommand::getTopLevel().reset();403    SubCommand::getAll().reset();404    registerSubCommand(&SubCommand::getTopLevel());405 406    DefaultOptions.clear();407  }408 409private:410  SubCommand *ActiveSubCommand = nullptr;411 412  Option *LookupOption(SubCommand &Sub, StringRef &Arg, StringRef &Value);413  Option *LookupLongOption(SubCommand &Sub, StringRef &Arg, StringRef &Value,414                           bool LongOptionsUseDoubleDash, bool HaveDoubleDash) {415    Option *Opt = LookupOption(Sub, Arg, Value);416    if (Opt && LongOptionsUseDoubleDash && !HaveDoubleDash && !isGrouping(Opt))417      return nullptr;418    return Opt;419  }420  SubCommand *LookupSubCommand(StringRef Name, std::string &NearestString);421};422 423} // namespace424 425static ManagedStatic<CommandLineParser> GlobalParser;426 427template <typename T, T TrueVal, T FalseVal>428static bool parseBool(Option &O, StringRef ArgName, StringRef Arg, T &Value) {429  if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" ||430      Arg == "1") {431    Value = TrueVal;432    return false;433  }434 435  if (Arg == "false" || Arg == "FALSE" || Arg == "False" || Arg == "0") {436    Value = FalseVal;437    return false;438  }439  return O.error("'" + Arg +440                 "' is invalid value for boolean argument! Try 0 or 1");441}442 443void cl::AddLiteralOption(Option &O, StringRef Name) {444  GlobalParser->addLiteralOption(O, Name);445}446 447extrahelp::extrahelp(StringRef Help) : morehelp(Help) {448  GlobalParser->MoreHelp.push_back(Help);449}450 451void Option::addArgument() {452  GlobalParser->addOption(this);453  FullyInitialized = true;454}455 456void Option::removeArgument() { GlobalParser->removeOption(this); }457 458void Option::setArgStr(StringRef S) {459  if (FullyInitialized)460    GlobalParser->updateArgStr(this, S);461  assert(!S.starts_with("-") && "Option can't start with '-");462  ArgStr = S;463  if (ArgStr.size() == 1)464    setMiscFlag(Grouping);465}466 467void Option::addCategory(OptionCategory &C) {468  assert(!Categories.empty() && "Categories cannot be empty.");469  // Maintain backward compatibility by replacing the default GeneralCategory470  // if it's still set.  Otherwise, just add the new one.  The GeneralCategory471  // must be explicitly added if you want multiple categories that include it.472  if (&C != &getGeneralCategory() && Categories[0] == &getGeneralCategory())473    Categories[0] = &C;474  else if (!is_contained(Categories, &C))475    Categories.push_back(&C);476}477 478void Option::reset() {479  NumOccurrences = 0;480  setDefault();481  if (isDefaultOption())482    removeArgument();483}484 485void OptionCategory::registerCategory() {486  GlobalParser->registerCategory(this);487}488 489// A special subcommand representing no subcommand. It is particularly important490// that this ManagedStatic uses constant initailization and not dynamic491// initialization because it is referenced from cl::opt constructors, which run492// dynamically in an arbitrary order.493LLVM_REQUIRE_CONSTANT_INITIALIZATION494static ManagedStatic<SubCommand> TopLevelSubCommand;495 496// A special subcommand that can be used to put an option into all subcommands.497static ManagedStatic<SubCommand> AllSubCommands;498 499SubCommand &SubCommand::getTopLevel() { return *TopLevelSubCommand; }500 501SubCommand &SubCommand::getAll() { return *AllSubCommands; }502 503void SubCommand::registerSubCommand() {504  GlobalParser->registerSubCommand(this);505}506 507void SubCommand::unregisterSubCommand() {508  GlobalParser->unregisterSubCommand(this);509}510 511void SubCommand::reset() {512  PositionalOpts.clear();513  SinkOpts.clear();514  OptionsMap.clear();515 516  ConsumeAfterOpt = nullptr;517}518 519SubCommand::operator bool() const {520  return (GlobalParser->getActiveSubCommand() == this);521}522 523//===----------------------------------------------------------------------===//524// Basic, shared command line option processing machinery.525//526 527/// LookupOption - Lookup the option specified by the specified option on the528/// command line.  If there is a value specified (after an equal sign) return529/// that as well.  This assumes that leading dashes have already been stripped.530Option *CommandLineParser::LookupOption(SubCommand &Sub, StringRef &Arg,531                                        StringRef &Value) {532  // Reject all dashes.533  if (Arg.empty())534    return nullptr;535  assert(&Sub != &SubCommand::getAll());536 537  size_t EqualPos = Arg.find('=');538 539  // If we have an equals sign, remember the value.540  if (EqualPos == StringRef::npos) {541    // Look up the option.542    return Sub.OptionsMap.lookup(Arg);543  }544 545  // If the argument before the = is a valid option name and the option allows546  // non-prefix form (ie is not AlwaysPrefix), we match.  If not, signal match547  // failure by returning nullptr.548  auto I = Sub.OptionsMap.find(Arg.substr(0, EqualPos));549  if (I == Sub.OptionsMap.end())550    return nullptr;551 552  auto *O = I->second;553  if (O->getFormattingFlag() == cl::AlwaysPrefix)554    return nullptr;555 556  Value = Arg.substr(EqualPos + 1);557  Arg = Arg.substr(0, EqualPos);558  return I->second;559}560 561SubCommand *CommandLineParser::LookupSubCommand(StringRef Name,562                                                std::string &NearestString) {563  if (Name.empty())564    return &SubCommand::getTopLevel();565  // Find a subcommand with the edit distance == 1.566  SubCommand *NearestMatch = nullptr;567  for (auto *S : RegisteredSubCommands) {568    assert(S != &SubCommand::getAll() &&569           "SubCommand::getAll() is not expected in RegisteredSubCommands");570    if (S->getName().empty())571      continue;572 573    if (S->getName() == Name)574      return S;575 576    if (!NearestMatch && S->getName().edit_distance(Name) < 2)577      NearestMatch = S;578  }579 580  if (NearestMatch)581    NearestString = NearestMatch->getName();582 583  return &SubCommand::getTopLevel();584}585 586/// LookupNearestOption - Lookup the closest match to the option specified by587/// the specified option on the command line.  If there is a value specified588/// (after an equal sign) return that as well.  This assumes that leading dashes589/// have already been stripped.590static Option *LookupNearestOption(StringRef Arg,591                                   const StringMap<Option *> &OptionsMap,592                                   std::string &NearestString) {593  // Reject all dashes.594  if (Arg.empty())595    return nullptr;596 597  // Split on any equal sign.598  std::pair<StringRef, StringRef> SplitArg = Arg.split('=');599  StringRef &LHS = SplitArg.first; // LHS == Arg when no '=' is present.600  StringRef &RHS = SplitArg.second;601 602  // Find the closest match.603  Option *Best = nullptr;604  unsigned BestDistance = 0;605  for (const auto &[_, O] : OptionsMap) {606    // Do not suggest really hidden options (not shown in any help).607    if (O->getOptionHiddenFlag() == ReallyHidden)608      continue;609 610    SmallVector<StringRef, 16> OptionNames;611    O->getExtraOptionNames(OptionNames);612    if (O->hasArgStr())613      OptionNames.push_back(O->ArgStr);614 615    bool PermitValue = O->getValueExpectedFlag() != cl::ValueDisallowed;616    StringRef Flag = PermitValue ? LHS : Arg;617    for (const auto &Name : OptionNames) {618      unsigned Distance = StringRef(Name).edit_distance(619          Flag, /*AllowReplacements=*/true, /*MaxEditDistance=*/BestDistance);620      if (!Best || Distance < BestDistance) {621        Best = O;622        BestDistance = Distance;623        if (RHS.empty() || !PermitValue)624          NearestString = std::string(Name);625        else626          NearestString = (Twine(Name) + "=" + RHS).str();627      }628    }629  }630 631  return Best;632}633 634/// CommaSeparateAndAddOccurrence - A wrapper around Handler->addOccurrence()635/// that does special handling of cl::CommaSeparated options.636static bool CommaSeparateAndAddOccurrence(Option *Handler, unsigned pos,637                                          StringRef ArgName, StringRef Value,638                                          bool MultiArg = false) {639  // Check to see if this option accepts a comma separated list of values.  If640  // it does, we have to split up the value into multiple values.641  if (Handler->getMiscFlags() & CommaSeparated) {642    StringRef Val(Value);643    StringRef::size_type Pos = Val.find(',');644 645    while (Pos != StringRef::npos) {646      // Process the portion before the comma.647      if (Handler->addOccurrence(pos, ArgName, Val.substr(0, Pos), MultiArg))648        return true;649      // Erase the portion before the comma, AND the comma.650      Val = Val.substr(Pos + 1);651      // Check for another comma.652      Pos = Val.find(',');653    }654 655    Value = Val;656  }657 658  return Handler->addOccurrence(pos, ArgName, Value, MultiArg);659}660 661/// ProvideOption - For Value, this differentiates between an empty value ("")662/// and a null value (StringRef()).  The later is accepted for arguments that663/// don't allow a value (-foo) the former is rejected (-foo=).664static inline bool ProvideOption(Option *Handler, StringRef ArgName,665                                 StringRef Value, int argc,666                                 const char *const *argv, int &i) {667  // Is this a multi-argument option?668  unsigned NumAdditionalVals = Handler->getNumAdditionalVals();669 670  // Enforce value requirements671  switch (Handler->getValueExpectedFlag()) {672  case ValueRequired:673    if (!Value.data()) { // No value specified?674      // If no other argument or the option only supports prefix form, we675      // cannot look at the next argument.676      if (i + 1 >= argc || Handler->getFormattingFlag() == cl::AlwaysPrefix)677        return Handler->error("requires a value!");678      // Steal the next argument, like for '-o filename'679      assert(argv && "null check");680      Value = StringRef(argv[++i]);681    }682    break;683  case ValueDisallowed:684    if (NumAdditionalVals > 0)685      return Handler->error("multi-valued option specified"686                            " with ValueDisallowed modifier!");687 688    if (Value.data())689      return Handler->error("does not allow a value! '" + Twine(Value) +690                            "' specified.");691    break;692  case ValueOptional:693    break;694  }695 696  // If this isn't a multi-arg option, just run the handler.697  if (NumAdditionalVals == 0)698    return CommaSeparateAndAddOccurrence(Handler, i, ArgName, Value);699 700  // If it is, run the handle several times.701  bool MultiArg = false;702 703  if (Value.data()) {704    if (CommaSeparateAndAddOccurrence(Handler, i, ArgName, Value, MultiArg))705      return true;706    --NumAdditionalVals;707    MultiArg = true;708  }709 710  while (NumAdditionalVals > 0) {711    if (i + 1 >= argc)712      return Handler->error("not enough values!");713    assert(argv && "null check");714    Value = StringRef(argv[++i]);715 716    if (CommaSeparateAndAddOccurrence(Handler, i, ArgName, Value, MultiArg))717      return true;718    MultiArg = true;719    --NumAdditionalVals;720  }721  return false;722}723 724bool llvm::cl::ProvidePositionalOption(Option *Handler, StringRef Arg, int i) {725  int Dummy = i;726  return ProvideOption(Handler, Handler->ArgStr, Arg, 0, nullptr, Dummy);727}728 729// getOptionPred - Check to see if there are any options that satisfy the730// specified predicate with names that are the prefixes in Name.  This is731// checked by progressively stripping characters off of the name, checking to732// see if there options that satisfy the predicate.  If we find one, return it,733// otherwise return null.734//735static Option *getOptionPred(StringRef Name, size_t &Length,736                             bool (*Pred)(const Option *),737                             const StringMap<Option *> &OptionsMap) {738  StringMap<Option *>::const_iterator OMI = OptionsMap.find(Name);739  if (OMI != OptionsMap.end() && !Pred(OMI->getValue()))740    OMI = OptionsMap.end();741 742  // Loop while we haven't found an option and Name still has at least two743  // characters in it (so that the next iteration will not be the empty744  // string.745  while (OMI == OptionsMap.end() && Name.size() > 1) {746    Name = Name.drop_back();747    OMI = OptionsMap.find(Name);748    if (OMI != OptionsMap.end() && !Pred(OMI->getValue()))749      OMI = OptionsMap.end();750  }751 752  if (OMI != OptionsMap.end() && Pred(OMI->second)) {753    Length = Name.size();754    return OMI->second; // Found one!755  }756  return nullptr; // No option found!757}758 759/// HandlePrefixedOrGroupedOption - The specified argument string (which started760/// with at least one '-') does not fully match an available option.  Check to761/// see if this is a prefix or grouped option.  If so, split arg into output an762/// Arg/Value pair and return the Option to parse it with.763static Option *764HandlePrefixedOrGroupedOption(StringRef &Arg, StringRef &Value,765                              bool &ErrorParsing,766                              const StringMap<Option *> &OptionsMap) {767  if (Arg.size() == 1)768    return nullptr;769 770  // Do the lookup!771  size_t Length = 0;772  Option *PGOpt = getOptionPred(Arg, Length, isPrefixedOrGrouping, OptionsMap);773  if (!PGOpt)774    return nullptr;775 776  do {777    StringRef MaybeValue =778        (Length < Arg.size()) ? Arg.substr(Length) : StringRef();779    Arg = Arg.substr(0, Length);780    assert(OptionsMap.count(Arg) && OptionsMap.find(Arg)->second == PGOpt);781 782    // cl::Prefix options do not preserve '=' when used separately.783    // The behavior for them with grouped options should be the same.784    if (MaybeValue.empty() || PGOpt->getFormattingFlag() == cl::AlwaysPrefix ||785        (PGOpt->getFormattingFlag() == cl::Prefix && MaybeValue[0] != '=')) {786      Value = MaybeValue;787      return PGOpt;788    }789 790    if (MaybeValue[0] == '=') {791      Value = MaybeValue.substr(1);792      return PGOpt;793    }794 795    // This must be a grouped option.796    assert(isGrouping(PGOpt) && "Broken getOptionPred!");797 798    // Grouping options inside a group can't have values.799    if (PGOpt->getValueExpectedFlag() == cl::ValueRequired) {800      ErrorParsing |= PGOpt->error("may not occur within a group!");801      return nullptr;802    }803 804    // Because the value for the option is not required, we don't need to pass805    // argc/argv in.806    int Dummy = 0;807    ErrorParsing |= ProvideOption(PGOpt, Arg, StringRef(), 0, nullptr, Dummy);808 809    // Get the next grouping option.810    Arg = MaybeValue;811    PGOpt = getOptionPred(Arg, Length, isGrouping, OptionsMap);812  } while (PGOpt);813 814  // We could not find a grouping option in the remainder of Arg.815  return nullptr;816}817 818static bool RequiresValue(const Option *O) {819  return O->getNumOccurrencesFlag() == cl::Required ||820         O->getNumOccurrencesFlag() == cl::OneOrMore;821}822 823static bool EatsUnboundedNumberOfValues(const Option *O) {824  return O->getNumOccurrencesFlag() == cl::ZeroOrMore ||825         O->getNumOccurrencesFlag() == cl::OneOrMore;826}827 828static bool isWhitespace(char C) {829  return C == ' ' || C == '\t' || C == '\r' || C == '\n';830}831 832static bool isWhitespaceOrNull(char C) {833  return isWhitespace(C) || C == '\0';834}835 836static bool isQuote(char C) { return C == '\"' || C == '\''; }837 838void cl::TokenizeGNUCommandLine(StringRef Src, StringSaver &Saver,839                                SmallVectorImpl<const char *> &NewArgv,840                                bool MarkEOLs) {841  SmallString<128> Token;842  for (size_t I = 0, E = Src.size(); I != E; ++I) {843    // Consume runs of whitespace.844    if (Token.empty()) {845      while (I != E && isWhitespace(Src[I])) {846        // Mark the end of lines in response files.847        if (MarkEOLs && Src[I] == '\n')848          NewArgv.push_back(nullptr);849        ++I;850      }851      if (I == E)852        break;853    }854 855    char C = Src[I];856 857    // Backslash escapes the next character.858    if (I + 1 < E && C == '\\') {859      ++I; // Skip the escape.860      Token.push_back(Src[I]);861      continue;862    }863 864    // Consume a quoted string.865    if (isQuote(C)) {866      ++I;867      while (I != E && Src[I] != C) {868        // Backslash escapes the next character.869        if (Src[I] == '\\' && I + 1 != E)870          ++I;871        Token.push_back(Src[I]);872        ++I;873      }874      if (I == E)875        break;876      continue;877    }878 879    // End the token if this is whitespace.880    if (isWhitespace(C)) {881      if (!Token.empty())882        NewArgv.push_back(Saver.save(Token.str()).data());883      // Mark the end of lines in response files.884      if (MarkEOLs && C == '\n')885        NewArgv.push_back(nullptr);886      Token.clear();887      continue;888    }889 890    // This is a normal character.  Append it.891    Token.push_back(C);892  }893 894  // Append the last token after hitting EOF with no whitespace.895  if (!Token.empty())896    NewArgv.push_back(Saver.save(Token.str()).data());897}898 899/// Backslashes are interpreted in a rather complicated way in the Windows-style900/// command line, because backslashes are used both to separate path and to901/// escape double quote. This method consumes runs of backslashes as well as the902/// following double quote if it's escaped.903///904///  * If an even number of backslashes is followed by a double quote, one905///    backslash is output for every pair of backslashes, and the last double906///    quote remains unconsumed. The double quote will later be interpreted as907///    the start or end of a quoted string in the main loop outside of this908///    function.909///910///  * If an odd number of backslashes is followed by a double quote, one911///    backslash is output for every pair of backslashes, and a double quote is912///    output for the last pair of backslash-double quote. The double quote is913///    consumed in this case.914///915///  * Otherwise, backslashes are interpreted literally.916static size_t parseBackslash(StringRef Src, size_t I, SmallString<128> &Token) {917  size_t E = Src.size();918  int BackslashCount = 0;919  // Skip the backslashes.920  do {921    ++I;922    ++BackslashCount;923  } while (I != E && Src[I] == '\\');924 925  bool FollowedByDoubleQuote = (I != E && Src[I] == '"');926  if (FollowedByDoubleQuote) {927    Token.append(BackslashCount / 2, '\\');928    if (BackslashCount % 2 == 0)929      return I - 1;930    Token.push_back('"');931    return I;932  }933  Token.append(BackslashCount, '\\');934  return I - 1;935}936 937// Windows treats whitespace, double quotes, and backslashes specially, except938// when parsing the first token of a full command line, in which case939// backslashes are not special.940static bool isWindowsSpecialChar(char C) {941  return isWhitespaceOrNull(C) || C == '\\' || C == '\"';942}943static bool isWindowsSpecialCharInCommandName(char C) {944  return isWhitespaceOrNull(C) || C == '\"';945}946 947// Windows tokenization implementation. The implementation is designed to be948// inlined and specialized for the two user entry points.949static inline void tokenizeWindowsCommandLineImpl(950    StringRef Src, StringSaver &Saver, function_ref<void(StringRef)> AddToken,951    bool AlwaysCopy, function_ref<void()> MarkEOL, bool InitialCommandName) {952  SmallString<128> Token;953 954  // Sometimes, this function will be handling a full command line including an955  // executable pathname at the start. In that situation, the initial pathname956  // needs different handling from the following arguments, because when957  // CreateProcess or cmd.exe scans the pathname, it doesn't treat \ as958  // escaping the quote character, whereas when libc scans the rest of the959  // command line, it does.960  bool CommandName = InitialCommandName;961 962  // Try to do as much work inside the state machine as possible.963  enum { INIT, UNQUOTED, QUOTED } State = INIT;964 965  for (size_t I = 0, E = Src.size(); I < E; ++I) {966    switch (State) {967    case INIT: {968      assert(Token.empty() && "token should be empty in initial state");969      // Eat whitespace before a token.970      while (I < E && isWhitespaceOrNull(Src[I])) {971        if (Src[I] == '\n')972          MarkEOL();973        ++I;974      }975      // Stop if this was trailing whitespace.976      if (I >= E)977        break;978      size_t Start = I;979      if (CommandName) {980        while (I < E && !isWindowsSpecialCharInCommandName(Src[I]))981          ++I;982      } else {983        while (I < E && !isWindowsSpecialChar(Src[I]))984          ++I;985      }986      StringRef NormalChars = Src.slice(Start, I);987      if (I >= E || isWhitespaceOrNull(Src[I])) {988        // No special characters: slice out the substring and start the next989        // token. Copy the string if the caller asks us to.990        AddToken(AlwaysCopy ? Saver.save(NormalChars) : NormalChars);991        if (I < E && Src[I] == '\n') {992          MarkEOL();993          CommandName = InitialCommandName;994        } else {995          CommandName = false;996        }997      } else if (Src[I] == '\"') {998        Token += NormalChars;999        State = QUOTED;1000      } else if (Src[I] == '\\') {1001        assert(!CommandName && "or else we'd have treated it as a normal char");1002        Token += NormalChars;1003        I = parseBackslash(Src, I, Token);1004        State = UNQUOTED;1005      } else {1006        llvm_unreachable("unexpected special character");1007      }1008      break;1009    }1010 1011    case UNQUOTED:1012      if (isWhitespaceOrNull(Src[I])) {1013        // Whitespace means the end of the token. If we are in this state, the1014        // token must have contained a special character, so we must copy the1015        // token.1016        AddToken(Saver.save(Token.str()));1017        Token.clear();1018        if (Src[I] == '\n') {1019          CommandName = InitialCommandName;1020          MarkEOL();1021        } else {1022          CommandName = false;1023        }1024        State = INIT;1025      } else if (Src[I] == '\"') {1026        State = QUOTED;1027      } else if (Src[I] == '\\' && !CommandName) {1028        I = parseBackslash(Src, I, Token);1029      } else {1030        Token.push_back(Src[I]);1031      }1032      break;1033 1034    case QUOTED:1035      if (Src[I] == '\"') {1036        if (I < (E - 1) && Src[I + 1] == '"') {1037          // Consecutive double-quotes inside a quoted string implies one1038          // double-quote.1039          Token.push_back('"');1040          ++I;1041        } else {1042          // Otherwise, end the quoted portion and return to the unquoted state.1043          State = UNQUOTED;1044        }1045      } else if (Src[I] == '\\' && !CommandName) {1046        I = parseBackslash(Src, I, Token);1047      } else {1048        Token.push_back(Src[I]);1049      }1050      break;1051    }1052  }1053 1054  if (State != INIT)1055    AddToken(Saver.save(Token.str()));1056}1057 1058void cl::TokenizeWindowsCommandLine(StringRef Src, StringSaver &Saver,1059                                    SmallVectorImpl<const char *> &NewArgv,1060                                    bool MarkEOLs) {1061  auto AddToken = [&](StringRef Tok) { NewArgv.push_back(Tok.data()); };1062  auto OnEOL = [&]() {1063    if (MarkEOLs)1064      NewArgv.push_back(nullptr);1065  };1066  tokenizeWindowsCommandLineImpl(Src, Saver, AddToken,1067                                 /*AlwaysCopy=*/true, OnEOL, false);1068}1069 1070void cl::TokenizeWindowsCommandLineNoCopy(StringRef Src, StringSaver &Saver,1071                                          SmallVectorImpl<StringRef> &NewArgv) {1072  auto AddToken = [&](StringRef Tok) { NewArgv.push_back(Tok); };1073  auto OnEOL = []() {};1074  tokenizeWindowsCommandLineImpl(Src, Saver, AddToken, /*AlwaysCopy=*/false,1075                                 OnEOL, false);1076}1077 1078void cl::TokenizeWindowsCommandLineFull(StringRef Src, StringSaver &Saver,1079                                        SmallVectorImpl<const char *> &NewArgv,1080                                        bool MarkEOLs) {1081  auto AddToken = [&](StringRef Tok) { NewArgv.push_back(Tok.data()); };1082  auto OnEOL = [&]() {1083    if (MarkEOLs)1084      NewArgv.push_back(nullptr);1085  };1086  tokenizeWindowsCommandLineImpl(Src, Saver, AddToken,1087                                 /*AlwaysCopy=*/true, OnEOL, true);1088}1089 1090void cl::tokenizeConfigFile(StringRef Source, StringSaver &Saver,1091                            SmallVectorImpl<const char *> &NewArgv,1092                            bool MarkEOLs) {1093  for (const char *Cur = Source.begin(); Cur != Source.end();) {1094    SmallString<128> Line;1095    // Check for comment line.1096    if (isWhitespace(*Cur)) {1097      while (Cur != Source.end() && isWhitespace(*Cur))1098        ++Cur;1099      continue;1100    }1101    if (*Cur == '#') {1102      while (Cur != Source.end() && *Cur != '\n')1103        ++Cur;1104      continue;1105    }1106    // Find end of the current line.1107    const char *Start = Cur;1108    for (const char *End = Source.end(); Cur != End; ++Cur) {1109      if (*Cur == '\\') {1110        if (Cur + 1 != End) {1111          ++Cur;1112          if (*Cur == '\n' ||1113              (*Cur == '\r' && (Cur + 1 != End) && Cur[1] == '\n')) {1114            Line.append(Start, Cur - 1);1115            if (*Cur == '\r')1116              ++Cur;1117            Start = Cur + 1;1118          }1119        }1120      } else if (*Cur == '\n')1121        break;1122    }1123    // Tokenize line.1124    Line.append(Start, Cur);1125    cl::TokenizeGNUCommandLine(Line, Saver, NewArgv, MarkEOLs);1126  }1127}1128 1129// It is called byte order marker but the UTF-8 BOM is actually not affected1130// by the host system's endianness.1131static bool hasUTF8ByteOrderMark(ArrayRef<char> S) {1132  return (S.size() >= 3 && S[0] == '\xef' && S[1] == '\xbb' && S[2] == '\xbf');1133}1134 1135// Substitute <CFGDIR> with the file's base path.1136static void ExpandBasePaths(StringRef BasePath, StringSaver &Saver,1137                            const char *&Arg) {1138  assert(sys::path::is_absolute(BasePath));1139  constexpr StringLiteral Token("<CFGDIR>");1140  const StringRef ArgString(Arg);1141 1142  SmallString<128> ResponseFile;1143  StringRef::size_type StartPos = 0;1144  for (StringRef::size_type TokenPos = ArgString.find(Token);1145       TokenPos != StringRef::npos;1146       TokenPos = ArgString.find(Token, StartPos)) {1147    // Token may appear more than once per arg (e.g. comma-separated linker1148    // args). Support by using path-append on any subsequent appearances.1149    const StringRef LHS = ArgString.substr(StartPos, TokenPos - StartPos);1150    if (ResponseFile.empty())1151      ResponseFile = LHS;1152    else1153      llvm::sys::path::append(ResponseFile, LHS);1154    ResponseFile.append(BasePath);1155    StartPos = TokenPos + Token.size();1156  }1157 1158  if (!ResponseFile.empty()) {1159    // Path-append the remaining arg substring if at least one token appeared.1160    const StringRef Remaining = ArgString.substr(StartPos);1161    if (!Remaining.empty())1162      llvm::sys::path::append(ResponseFile, Remaining);1163    Arg = Saver.save(ResponseFile.str()).data();1164  }1165}1166 1167// FName must be an absolute path.1168Error ExpansionContext::expandResponseFile(1169    StringRef FName, SmallVectorImpl<const char *> &NewArgv) {1170  assert(sys::path::is_absolute(FName));1171  llvm::ErrorOr<std::unique_ptr<MemoryBuffer>> MemBufOrErr =1172      FS->getBufferForFile(FName);1173  if (!MemBufOrErr) {1174    std::error_code EC = MemBufOrErr.getError();1175    return llvm::createStringError(EC, Twine("cannot not open file '") + FName +1176                                           "': " + EC.message());1177  }1178  MemoryBuffer &MemBuf = *MemBufOrErr.get();1179  StringRef Str(MemBuf.getBufferStart(), MemBuf.getBufferSize());1180 1181  // If we have a UTF-16 byte order mark, convert to UTF-8 for parsing.1182  ArrayRef<char> BufRef(MemBuf.getBufferStart(), MemBuf.getBufferEnd());1183  std::string UTF8Buf;1184  if (hasUTF16ByteOrderMark(BufRef)) {1185    if (!convertUTF16ToUTF8String(BufRef, UTF8Buf))1186      return llvm::createStringError(std::errc::illegal_byte_sequence,1187                                     "Could not convert UTF16 to UTF8");1188    Str = StringRef(UTF8Buf);1189  }1190  // If we see UTF-8 BOM sequence at the beginning of a file, we shall remove1191  // these bytes before parsing.1192  // Reference: http://en.wikipedia.org/wiki/UTF-8#Byte_order_mark1193  else if (hasUTF8ByteOrderMark(BufRef))1194    Str = StringRef(BufRef.data() + 3, BufRef.size() - 3);1195 1196  // Tokenize the contents into NewArgv.1197  Tokenizer(Str, Saver, NewArgv, MarkEOLs);1198 1199  // Expanded file content may require additional transformations, like using1200  // absolute paths instead of relative in '@file' constructs or expanding1201  // macros.1202  if (!RelativeNames && !InConfigFile)1203    return Error::success();1204 1205  StringRef BasePath = llvm::sys::path::parent_path(FName);1206  for (const char *&Arg : NewArgv) {1207    if (!Arg)1208      continue;1209 1210    // Substitute <CFGDIR> with the file's base path.1211    if (InConfigFile)1212      ExpandBasePaths(BasePath, Saver, Arg);1213 1214    // Discover the case, when argument should be transformed into '@file' and1215    // evaluate 'file' for it.1216    StringRef ArgStr(Arg);1217    StringRef FileName;1218    bool ConfigInclusion = false;1219    if (ArgStr.consume_front("@")) {1220      FileName = ArgStr;1221      if (!llvm::sys::path::is_relative(FileName))1222        continue;1223    } else if (ArgStr.consume_front("--config=")) {1224      FileName = ArgStr;1225      ConfigInclusion = true;1226    } else {1227      continue;1228    }1229 1230    // Update expansion construct.1231    SmallString<128> ResponseFile;1232    ResponseFile.push_back('@');1233    if (ConfigInclusion && !llvm::sys::path::has_parent_path(FileName)) {1234      SmallString<128> FilePath;1235      if (!findConfigFile(FileName, FilePath))1236        return createStringError(1237            std::make_error_code(std::errc::no_such_file_or_directory),1238            "cannot not find configuration file: " + FileName);1239      ResponseFile.append(FilePath);1240    } else {1241      ResponseFile.append(BasePath);1242      llvm::sys::path::append(ResponseFile, FileName);1243    }1244    Arg = Saver.save(ResponseFile.str()).data();1245  }1246  return Error::success();1247}1248 1249/// Expand response files on a command line recursively using the given1250/// StringSaver and tokenization strategy.1251Error ExpansionContext::expandResponseFiles(1252    SmallVectorImpl<const char *> &Argv) {1253  struct ResponseFileRecord {1254    std::string File;1255    size_t End;1256  };1257 1258  // To detect recursive response files, we maintain a stack of files and the1259  // position of the last argument in the file. This position is updated1260  // dynamically as we recursively expand files.1261  SmallVector<ResponseFileRecord, 3> FileStack;1262 1263  // Push a dummy entry that represents the initial command line, removing1264  // the need to check for an empty list.1265  FileStack.push_back({"", Argv.size()});1266 1267  // Don't cache Argv.size() because it can change.1268  for (unsigned I = 0; I != Argv.size();) {1269    while (I == FileStack.back().End) {1270      // Passing the end of a file's argument list, so we can remove it from the1271      // stack.1272      FileStack.pop_back();1273    }1274 1275    const char *Arg = Argv[I];1276    // Check if it is an EOL marker1277    if (Arg == nullptr) {1278      ++I;1279      continue;1280    }1281 1282    if (Arg[0] != '@') {1283      ++I;1284      continue;1285    }1286 1287    const char *FName = Arg + 1;1288    // Note that CurrentDir is only used for top-level rsp files, the rest will1289    // always have an absolute path deduced from the containing file.1290    SmallString<128> CurrDir;1291    if (llvm::sys::path::is_relative(FName)) {1292      if (CurrentDir.empty()) {1293        if (auto CWD = FS->getCurrentWorkingDirectory()) {1294          CurrDir = *CWD;1295        } else {1296          return createStringError(1297              CWD.getError(), Twine("cannot get absolute path for: ") + FName);1298        }1299      } else {1300        CurrDir = CurrentDir;1301      }1302      llvm::sys::path::append(CurrDir, FName);1303      FName = CurrDir.c_str();1304    }1305 1306    ErrorOr<llvm::vfs::Status> Res = FS->status(FName);1307    if (!Res || !Res->exists()) {1308      std::error_code EC = Res.getError();1309      if (!InConfigFile) {1310        // If the specified file does not exist, leave '@file' unexpanded, as1311        // libiberty does.1312        if (!EC || EC == llvm::errc::no_such_file_or_directory) {1313          ++I;1314          continue;1315        }1316      }1317      if (!EC)1318        EC = llvm::errc::no_such_file_or_directory;1319      return createStringError(EC, Twine("cannot not open file '") + FName +1320                                       "': " + EC.message());1321    }1322    const llvm::vfs::Status &FileStatus = Res.get();1323 1324    auto IsEquivalent =1325        [FileStatus, this](const ResponseFileRecord &RFile) -> ErrorOr<bool> {1326      ErrorOr<llvm::vfs::Status> RHS = FS->status(RFile.File);1327      if (!RHS)1328        return RHS.getError();1329      return FileStatus.equivalent(*RHS);1330    };1331 1332    // Check for recursive response files.1333    for (const auto &F : drop_begin(FileStack)) {1334      if (ErrorOr<bool> R = IsEquivalent(F)) {1335        if (R.get())1336          return createStringError(1337              R.getError(), Twine("recursive expansion of: '") + F.File + "'");1338      } else {1339        return createStringError(R.getError(),1340                                 Twine("cannot open file: ") + F.File);1341      }1342    }1343 1344    // Replace this response file argument with the tokenization of its1345    // contents.  Nested response files are expanded in subsequent iterations.1346    SmallVector<const char *, 0> ExpandedArgv;1347    if (Error Err = expandResponseFile(FName, ExpandedArgv))1348      return Err;1349 1350    for (ResponseFileRecord &Record : FileStack) {1351      // Increase the end of all active records by the number of newly expanded1352      // arguments, minus the response file itself.1353      Record.End += ExpandedArgv.size() - 1;1354    }1355 1356    FileStack.push_back({FName, I + ExpandedArgv.size()});1357    Argv.erase(Argv.begin() + I);1358    Argv.insert(Argv.begin() + I, ExpandedArgv.begin(), ExpandedArgv.end());1359  }1360 1361  // If successful, the top of the file stack will mark the end of the Argv1362  // stream. A failure here indicates a bug in the stack popping logic above.1363  // Note that FileStack may have more than one element at this point because we1364  // don't have a chance to pop the stack when encountering recursive files at1365  // the end of the stream, so seeing that doesn't indicate a bug.1366  assert(FileStack.size() > 0 && Argv.size() == FileStack.back().End);1367  return Error::success();1368}1369 1370bool cl::expandResponseFiles(int Argc, const char *const *Argv,1371                             const char *EnvVar, StringSaver &Saver,1372                             SmallVectorImpl<const char *> &NewArgv) {1373#ifdef _WIN321374  auto Tokenize = cl::TokenizeWindowsCommandLine;1375#else1376  auto Tokenize = cl::TokenizeGNUCommandLine;1377#endif1378  // The environment variable specifies initial options.1379  if (EnvVar)1380    if (std::optional<std::string> EnvValue = sys::Process::GetEnv(EnvVar))1381      Tokenize(*EnvValue, Saver, NewArgv, /*MarkEOLs=*/false);1382 1383  // Command line options can override the environment variable.1384  NewArgv.append(Argv + 1, Argv + Argc);1385  ExpansionContext ECtx(Saver.getAllocator(), Tokenize);1386  if (Error Err = ECtx.expandResponseFiles(NewArgv)) {1387    errs() << toString(std::move(Err)) << '\n';1388    return false;1389  }1390  return true;1391}1392 1393bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,1394                             SmallVectorImpl<const char *> &Argv) {1395  ExpansionContext ECtx(Saver.getAllocator(), Tokenizer);1396  if (Error Err = ECtx.expandResponseFiles(Argv)) {1397    errs() << toString(std::move(Err)) << '\n';1398    return false;1399  }1400  return true;1401}1402 1403ExpansionContext::ExpansionContext(BumpPtrAllocator &A, TokenizerCallback T,1404                                   vfs::FileSystem *FS)1405    : Saver(A), Tokenizer(T), FS(FS ? FS : vfs::getRealFileSystem().get()) {}1406 1407bool ExpansionContext::findConfigFile(StringRef FileName,1408                                      SmallVectorImpl<char> &FilePath) {1409  SmallString<128> CfgFilePath;1410  const auto FileExists = [this](SmallString<128> Path) -> bool {1411    auto Status = FS->status(Path);1412    return Status &&1413           Status->getType() == llvm::sys::fs::file_type::regular_file;1414  };1415 1416  // If file name contains directory separator, treat it as a path to1417  // configuration file.1418  if (llvm::sys::path::has_parent_path(FileName)) {1419    CfgFilePath = FileName;1420    if (llvm::sys::path::is_relative(FileName) && FS->makeAbsolute(CfgFilePath))1421      return false;1422    if (!FileExists(CfgFilePath))1423      return false;1424    FilePath.assign(CfgFilePath.begin(), CfgFilePath.end());1425    return true;1426  }1427 1428  // Look for the file in search directories.1429  for (const StringRef &Dir : SearchDirs) {1430    if (Dir.empty())1431      continue;1432    CfgFilePath.assign(Dir);1433    llvm::sys::path::append(CfgFilePath, FileName);1434    llvm::sys::path::native(CfgFilePath);1435    if (FileExists(CfgFilePath)) {1436      FilePath.assign(CfgFilePath.begin(), CfgFilePath.end());1437      return true;1438    }1439  }1440 1441  return false;1442}1443 1444Error ExpansionContext::readConfigFile(StringRef CfgFile,1445                                       SmallVectorImpl<const char *> &Argv) {1446  SmallString<128> AbsPath;1447  if (sys::path::is_relative(CfgFile)) {1448    AbsPath.assign(CfgFile);1449    if (std::error_code EC = FS->makeAbsolute(AbsPath))1450      return make_error<StringError>(1451          EC, Twine("cannot get absolute path for " + CfgFile));1452    CfgFile = AbsPath.str();1453  }1454  InConfigFile = true;1455  RelativeNames = true;1456  if (Error Err = expandResponseFile(CfgFile, Argv))1457    return Err;1458  return expandResponseFiles(Argv);1459}1460 1461static void initCommonOptions();1462bool cl::ParseCommandLineOptions(int argc, const char *const *argv,1463                                 StringRef Overview, raw_ostream *Errs,1464                                 vfs::FileSystem *VFS, const char *EnvVar,1465                                 bool LongOptionsUseDoubleDash) {1466  initCommonOptions();1467  SmallVector<const char *, 20> NewArgv;1468  BumpPtrAllocator A;1469  StringSaver Saver(A);1470  NewArgv.push_back(argv[0]);1471 1472  // Parse options from environment variable.1473  if (EnvVar) {1474    if (std::optional<std::string> EnvValue =1475            sys::Process::GetEnv(StringRef(EnvVar)))1476      TokenizeGNUCommandLine(*EnvValue, Saver, NewArgv);1477  }1478 1479  // Append options from command line.1480  for (int I = 1; I < argc; ++I)1481    NewArgv.push_back(argv[I]);1482  int NewArgc = static_cast<int>(NewArgv.size());1483 1484  // Parse all options.1485  return GlobalParser->ParseCommandLineOptions(1486      NewArgc, &NewArgv[0], Overview, Errs, VFS, LongOptionsUseDoubleDash);1487}1488 1489/// Reset all options at least once, so that we can parse different options.1490void CommandLineParser::ResetAllOptionOccurrences() {1491  // Reset all option values to look like they have never been seen before.1492  // Options might be reset twice (they can be reference in both OptionsMap1493  // and one of the other members), but that does not harm.1494  for (auto *SC : RegisteredSubCommands) {1495    for (auto &O : SC->OptionsMap)1496      O.second->reset();1497    for (Option *O : SC->PositionalOpts)1498      O->reset();1499    for (Option *O : SC->SinkOpts)1500      O->reset();1501    if (SC->ConsumeAfterOpt)1502      SC->ConsumeAfterOpt->reset();1503  }1504}1505 1506bool CommandLineParser::ParseCommandLineOptions(1507    int argc, const char *const *argv, StringRef Overview, raw_ostream *Errs,1508    vfs::FileSystem *VFS, bool LongOptionsUseDoubleDash) {1509  assert(hasOptions() && "No options specified!");1510 1511  ProgramOverview = Overview;1512  bool IgnoreErrors = Errs;1513  if (!Errs)1514    Errs = &errs();1515  if (!VFS)1516    VFS = vfs::getRealFileSystem().get();1517  bool ErrorParsing = false;1518 1519  // Expand response files.1520  SmallVector<const char *, 20> newArgv(argv, argv + argc);1521  BumpPtrAllocator A;1522#ifdef _WIN321523  auto Tokenize = cl::TokenizeWindowsCommandLine;1524#else1525  auto Tokenize = cl::TokenizeGNUCommandLine;1526#endif1527  ExpansionContext ECtx(A, Tokenize, VFS);1528  if (Error Err = ECtx.expandResponseFiles(newArgv)) {1529    *Errs << toString(std::move(Err)) << '\n';1530    return false;1531  }1532  argv = &newArgv[0];1533  argc = static_cast<int>(newArgv.size());1534 1535  // Copy the program name into ProgName, making sure not to overflow it.1536  ProgramName = std::string(sys::path::filename(StringRef(argv[0])));1537 1538  // Check out the positional arguments to collect information about them.1539  unsigned NumPositionalRequired = 0;1540 1541  // Determine whether or not there are an unlimited number of positionals1542  bool HasUnlimitedPositionals = false;1543 1544  int FirstArg = 1;1545  SubCommand *ChosenSubCommand = &SubCommand::getTopLevel();1546  std::string NearestSubCommandString;1547  bool MaybeNamedSubCommand =1548      argc >= 2 && argv[FirstArg][0] != '-' && hasNamedSubCommands();1549  if (MaybeNamedSubCommand) {1550    // If the first argument specifies a valid subcommand, start processing1551    // options from the second argument.1552    ChosenSubCommand =1553        LookupSubCommand(StringRef(argv[FirstArg]), NearestSubCommandString);1554    if (ChosenSubCommand != &SubCommand::getTopLevel())1555      FirstArg = 2;1556  }1557  GlobalParser->ActiveSubCommand = ChosenSubCommand;1558 1559  assert(ChosenSubCommand);1560  auto &ConsumeAfterOpt = ChosenSubCommand->ConsumeAfterOpt;1561  auto &PositionalOpts = ChosenSubCommand->PositionalOpts;1562  auto &SinkOpts = ChosenSubCommand->SinkOpts;1563  auto &OptionsMap = ChosenSubCommand->OptionsMap;1564 1565  for (auto *O: DefaultOptions) {1566    addOption(O, true);1567  }1568 1569  if (ConsumeAfterOpt) {1570    assert(PositionalOpts.size() > 0 &&1571           "Cannot specify cl::ConsumeAfter without a positional argument!");1572  }1573  if (!PositionalOpts.empty()) {1574 1575    // Calculate how many positional values are _required_.1576    bool UnboundedFound = false;1577    for (size_t i = 0, e = PositionalOpts.size(); i != e; ++i) {1578      Option *Opt = PositionalOpts[i];1579      if (RequiresValue(Opt))1580        ++NumPositionalRequired;1581      else if (ConsumeAfterOpt) {1582        // ConsumeAfter cannot be combined with "optional" positional options1583        // unless there is only one positional argument...1584        if (PositionalOpts.size() > 1) {1585          if (!IgnoreErrors)1586            Opt->error("error - this positional option will never be matched, "1587                       "because it does not Require a value, and a "1588                       "cl::ConsumeAfter option is active!");1589          ErrorParsing = true;1590        }1591      } else if (UnboundedFound && !Opt->hasArgStr()) {1592        // This option does not "require" a value...  Make sure this option is1593        // not specified after an option that eats all extra arguments, or this1594        // one will never get any!1595        //1596        if (!IgnoreErrors)1597          Opt->error("error - option can never match, because "1598                     "another positional argument will match an "1599                     "unbounded number of values, and this option"1600                     " does not require a value!");1601        *Errs << ProgramName << ": CommandLine Error: Option '" << Opt->ArgStr1602              << "' is all messed up!\n";1603        *Errs << PositionalOpts.size();1604        ErrorParsing = true;1605      }1606      UnboundedFound |= EatsUnboundedNumberOfValues(Opt);1607    }1608    HasUnlimitedPositionals = UnboundedFound || ConsumeAfterOpt;1609  }1610 1611  // PositionalVals - A vector of "positional" arguments we accumulate into1612  // the process at the end.1613  //1614  SmallVector<std::pair<StringRef, unsigned>, 4> PositionalVals;1615 1616  // If the program has named positional arguments, and the name has been run1617  // across, keep track of which positional argument was named.  Otherwise put1618  // the positional args into the PositionalVals list...1619  Option *ActivePositionalArg = nullptr;1620 1621  // Loop over all of the arguments... processing them.1622  bool DashDashFound = false; // Have we read '--'?1623  for (int i = FirstArg; i < argc; ++i) {1624    Option *Handler = nullptr;1625    std::string NearestHandlerString;1626    StringRef Value;1627    StringRef ArgName = "";1628    bool HaveDoubleDash = false;1629 1630    // Check to see if this is a positional argument.  This argument is1631    // considered to be positional if it doesn't start with '-', if it is "-"1632    // itself, or if we have seen "--" already.1633    //1634    if (argv[i][0] != '-' || argv[i][1] == 0 || DashDashFound) {1635      // Positional argument!1636      if (ActivePositionalArg) {1637        ProvidePositionalOption(ActivePositionalArg, StringRef(argv[i]), i);1638        continue; // We are done!1639      }1640 1641      if (!PositionalOpts.empty()) {1642        PositionalVals.push_back(std::make_pair(StringRef(argv[i]), i));1643 1644        // All of the positional arguments have been fulfulled, give the rest to1645        // the consume after option... if it's specified...1646        //1647        if (PositionalVals.size() >= NumPositionalRequired && ConsumeAfterOpt) {1648          for (++i; i < argc; ++i)1649            PositionalVals.push_back(std::make_pair(StringRef(argv[i]), i));1650          break; // Handle outside of the argument processing loop...1651        }1652 1653        // Delay processing positional arguments until the end...1654        continue;1655      }1656    } else if (argv[i][0] == '-' && argv[i][1] == '-' && argv[i][2] == 0 &&1657               !DashDashFound) {1658      DashDashFound = true; // This is the mythical "--"?1659      continue;             // Don't try to process it as an argument itself.1660    } else if (ActivePositionalArg &&1661               (ActivePositionalArg->getMiscFlags() & PositionalEatsArgs)) {1662      // If there is a positional argument eating options, check to see if this1663      // option is another positional argument.  If so, treat it as an argument,1664      // otherwise feed it to the eating positional.1665      ArgName = StringRef(argv[i] + 1);1666      // Eat second dash.1667      if (ArgName.consume_front("-"))1668        HaveDoubleDash = true;1669 1670      Handler = LookupLongOption(*ChosenSubCommand, ArgName, Value,1671                                 LongOptionsUseDoubleDash, HaveDoubleDash);1672      if (!Handler || Handler->getFormattingFlag() != cl::Positional) {1673        ProvidePositionalOption(ActivePositionalArg, StringRef(argv[i]), i);1674        continue; // We are done!1675      }1676    } else { // We start with a '-', must be an argument.1677      ArgName = StringRef(argv[i] + 1);1678      // Eat second dash.1679      if (ArgName.consume_front("-"))1680        HaveDoubleDash = true;1681 1682      Handler = LookupLongOption(*ChosenSubCommand, ArgName, Value,1683                                 LongOptionsUseDoubleDash, HaveDoubleDash);1684 1685      // If Handler is not found in a specialized subcommand, look up handler1686      // in the top-level subcommand.1687      // cl::opt without cl::sub belongs to top-level subcommand.1688      if (!Handler && ChosenSubCommand != &SubCommand::getTopLevel())1689        Handler = LookupLongOption(SubCommand::getTopLevel(), ArgName, Value,1690                                   LongOptionsUseDoubleDash, HaveDoubleDash);1691 1692      // Check to see if this "option" is really a prefixed or grouped argument.1693      if (!Handler && !(LongOptionsUseDoubleDash && HaveDoubleDash))1694        Handler = HandlePrefixedOrGroupedOption(ArgName, Value, ErrorParsing,1695                                                OptionsMap);1696 1697      // Otherwise, look for the closest available option to report to the user1698      // in the upcoming error.1699      if (!Handler && SinkOpts.empty())1700        LookupNearestOption(ArgName, OptionsMap, NearestHandlerString);1701    }1702 1703    if (!Handler) {1704      if (!SinkOpts.empty()) {1705        for (Option *SinkOpt : SinkOpts)1706          SinkOpt->addOccurrence(i, "", StringRef(argv[i]));1707        continue;1708      }1709 1710      auto ReportUnknownArgument = [&](bool IsArg,1711                                       StringRef NearestArgumentName) {1712        *Errs << ProgramName << ": Unknown "1713              << (IsArg ? "command line argument" : "subcommand") << " '"1714              << argv[i] << "'.  Try: '" << argv[0] << " --help'\n";1715 1716        if (NearestArgumentName.empty())1717          return;1718 1719        *Errs << ProgramName << ": Did you mean '";1720        if (IsArg)1721          *Errs << PrintArg(NearestArgumentName, 0);1722        else1723          *Errs << NearestArgumentName;1724        *Errs << "'?\n";1725      };1726 1727      if (i > 1 || !MaybeNamedSubCommand)1728        ReportUnknownArgument(/*IsArg=*/true, NearestHandlerString);1729      else1730        ReportUnknownArgument(/*IsArg=*/false, NearestSubCommandString);1731 1732      ErrorParsing = true;1733      continue;1734    }1735 1736    // If this is a named positional argument, just remember that it is the1737    // active one...1738    if (Handler->getFormattingFlag() == cl::Positional) {1739      if ((Handler->getMiscFlags() & PositionalEatsArgs) && !Value.empty()) {1740        Handler->error("This argument does not take a value.\n"1741                       "\tInstead, it consumes any positional arguments until "1742                       "the next recognized option.", *Errs);1743        ErrorParsing = true;1744      }1745      ActivePositionalArg = Handler;1746    }1747    else1748      ErrorParsing |= ProvideOption(Handler, ArgName, Value, argc, argv, i);1749  }1750 1751  // Check and handle positional arguments now...1752  if (NumPositionalRequired > PositionalVals.size()) {1753      *Errs << ProgramName1754             << ": Not enough positional command line arguments specified!\n"1755             << "Must specify at least " << NumPositionalRequired1756             << " positional argument" << (NumPositionalRequired > 1 ? "s" : "")1757             << ": See: " << argv[0] << " --help\n";1758 1759    ErrorParsing = true;1760  } else if (!HasUnlimitedPositionals &&1761             PositionalVals.size() > PositionalOpts.size()) {1762    *Errs << ProgramName << ": Too many positional arguments specified!\n"1763          << "Can specify at most " << PositionalOpts.size()1764          << " positional arguments: See: " << argv[0] << " --help\n";1765    ErrorParsing = true;1766 1767  } else if (!ConsumeAfterOpt) {1768    // Positional args have already been handled if ConsumeAfter is specified.1769    unsigned ValNo = 0, NumVals = static_cast<unsigned>(PositionalVals.size());1770    for (Option *Opt : PositionalOpts) {1771      if (RequiresValue(Opt)) {1772        ProvidePositionalOption(Opt, PositionalVals[ValNo].first,1773                                PositionalVals[ValNo].second);1774        ValNo++;1775        --NumPositionalRequired; // We fulfilled our duty...1776      }1777 1778      // If we _can_ give this option more arguments, do so now, as long as we1779      // do not give it values that others need.  'Done' controls whether the1780      // option even _WANTS_ any more.1781      //1782      bool Done = Opt->getNumOccurrencesFlag() == cl::Required;1783      while (NumVals - ValNo > NumPositionalRequired && !Done) {1784        switch (Opt->getNumOccurrencesFlag()) {1785        case cl::Optional:1786          Done = true; // Optional arguments want _at most_ one value1787          [[fallthrough]];1788        case cl::ZeroOrMore: // Zero or more will take all they can get...1789        case cl::OneOrMore:  // One or more will take all they can get...1790          ProvidePositionalOption(Opt, PositionalVals[ValNo].first,1791                                  PositionalVals[ValNo].second);1792          ValNo++;1793          break;1794        default:1795          llvm_unreachable("Internal error, unexpected NumOccurrences flag in "1796                           "positional argument processing!");1797        }1798      }1799    }1800  } else {1801    assert(ConsumeAfterOpt && NumPositionalRequired <= PositionalVals.size());1802    unsigned ValNo = 0;1803    for (Option *Opt : PositionalOpts)1804      if (RequiresValue(Opt)) {1805        ErrorParsing |= ProvidePositionalOption(1806            Opt, PositionalVals[ValNo].first, PositionalVals[ValNo].second);1807        ValNo++;1808      }1809 1810    // Handle the case where there is just one positional option, and it's1811    // optional.  In this case, we want to give JUST THE FIRST option to the1812    // positional option and keep the rest for the consume after.  The above1813    // loop would have assigned no values to positional options in this case.1814    //1815    if (PositionalOpts.size() == 1 && ValNo == 0 && !PositionalVals.empty()) {1816      ErrorParsing |= ProvidePositionalOption(PositionalOpts[0],1817                                              PositionalVals[ValNo].first,1818                                              PositionalVals[ValNo].second);1819      ValNo++;1820    }1821 1822    // Handle over all of the rest of the arguments to the1823    // cl::ConsumeAfter command line option...1824    for (; ValNo != PositionalVals.size(); ++ValNo)1825      ErrorParsing |=1826          ProvidePositionalOption(ConsumeAfterOpt, PositionalVals[ValNo].first,1827                                  PositionalVals[ValNo].second);1828  }1829 1830  // Loop over args and make sure all required args are specified!1831  for (const auto &Opt : OptionsMap) {1832    switch (Opt.second->getNumOccurrencesFlag()) {1833    case Required:1834    case OneOrMore:1835      if (Opt.second->getNumOccurrences() == 0) {1836        Opt.second->error("must be specified at least once!");1837        ErrorParsing = true;1838      }1839      [[fallthrough]];1840    default:1841      break;1842    }1843  }1844 1845  // Now that we know if -debug is specified, we can use it.1846  // Note that if ReadResponseFiles == true, this must be done before the1847  // memory allocated for the expanded command line is free()d below.1848  LLVM_DEBUG(dbgs() << "Args: ";1849             for (int i = 0; i < argc; ++i) dbgs() << argv[i] << ' ';1850             dbgs() << '\n';);1851 1852  // Free all of the memory allocated to the map.  Command line options may only1853  // be processed once!1854  MoreHelp.clear();1855 1856  // If we had an error processing our arguments, don't let the program execute1857  if (ErrorParsing) {1858    if (!IgnoreErrors)1859      exit(1);1860    return false;1861  }1862  return true;1863}1864 1865//===----------------------------------------------------------------------===//1866// Option Base class implementation1867//1868 1869bool Option::error(const Twine &Message, StringRef ArgName, raw_ostream &Errs) {1870  if (!ArgName.data())1871    ArgName = ArgStr;1872  if (ArgName.empty())1873    Errs << HelpStr; // Be nice for positional arguments1874  else1875    Errs << GlobalParser->ProgramName << ": for the " << PrintArg(ArgName, 0);1876 1877  Errs << " option: " << Message << "\n";1878  return true;1879}1880 1881bool Option::addOccurrence(unsigned pos, StringRef ArgName, StringRef Value,1882                           bool MultiArg) {1883  if (!MultiArg)1884    NumOccurrences++; // Increment the number of times we have been seen1885 1886  return handleOccurrence(pos, ArgName, Value);1887}1888 1889// getValueStr - Get the value description string, using "DefaultMsg" if nothing1890// has been specified yet.1891//1892static StringRef getValueStr(const Option &O, StringRef DefaultMsg) {1893  if (O.ValueStr.empty())1894    return DefaultMsg;1895  return O.ValueStr;1896}1897 1898//===----------------------------------------------------------------------===//1899// cl::alias class implementation1900//1901 1902// Return the width of the option tag for printing...1903size_t alias::getOptionWidth() const {1904  return argPlusPrefixesSize(ArgStr);1905}1906 1907void Option::printHelpStr(StringRef HelpStr, size_t Indent,1908                          size_t FirstLineIndentedBy) {1909  assert(Indent >= FirstLineIndentedBy);1910  std::pair<StringRef, StringRef> Split = HelpStr.split('\n');1911  outs().indent(Indent - FirstLineIndentedBy)1912      << ArgHelpPrefix << Split.first << "\n";1913  while (!Split.second.empty()) {1914    Split = Split.second.split('\n');1915    outs().indent(Indent) << Split.first << "\n";1916  }1917}1918 1919void Option::printEnumValHelpStr(StringRef HelpStr, size_t BaseIndent,1920                                 size_t FirstLineIndentedBy) {1921  const StringRef ValHelpPrefix = "  ";1922  assert(BaseIndent >= FirstLineIndentedBy);1923  std::pair<StringRef, StringRef> Split = HelpStr.split('\n');1924  outs().indent(BaseIndent - FirstLineIndentedBy)1925      << ArgHelpPrefix << ValHelpPrefix << Split.first << "\n";1926  while (!Split.second.empty()) {1927    Split = Split.second.split('\n');1928    outs().indent(BaseIndent + ValHelpPrefix.size()) << Split.first << "\n";1929  }1930}1931 1932// Print out the option for the alias.1933void alias::printOptionInfo(size_t GlobalWidth) const {1934  outs() << PrintArg(ArgStr);1935  printHelpStr(HelpStr, GlobalWidth, argPlusPrefixesSize(ArgStr));1936}1937 1938//===----------------------------------------------------------------------===//1939// Parser Implementation code...1940//1941 1942// basic_parser implementation1943//1944 1945// Return the width of the option tag for printing...1946size_t basic_parser_impl::getOptionWidth(const Option &O) const {1947  size_t Len = argPlusPrefixesSize(O.ArgStr);1948  auto ValName = getValueName();1949  if (!ValName.empty()) {1950    size_t FormattingLen = 3;1951    if (O.getMiscFlags() & PositionalEatsArgs)1952      FormattingLen = 6;1953    Len += getValueStr(O, ValName).size() + FormattingLen;1954  }1955 1956  return Len;1957}1958 1959// printOptionInfo - Print out information about this option.  The1960// to-be-maintained width is specified.1961//1962void basic_parser_impl::printOptionInfo(const Option &O,1963                                        size_t GlobalWidth) const {1964  outs() << PrintArg(O.ArgStr);1965 1966  auto ValName = getValueName();1967  if (!ValName.empty()) {1968    if (O.getMiscFlags() & PositionalEatsArgs) {1969      outs() << " <" << getValueStr(O, ValName) << ">...";1970    } else if (O.getValueExpectedFlag() == ValueOptional)1971      outs() << "[=<" << getValueStr(O, ValName) << ">]";1972    else {1973      outs() << (O.ArgStr.size() == 1 ? " <" : "=<") << getValueStr(O, ValName)1974             << '>';1975    }1976  }1977 1978  Option::printHelpStr(O.HelpStr, GlobalWidth, getOptionWidth(O));1979}1980 1981void basic_parser_impl::printOptionName(const Option &O,1982                                        size_t GlobalWidth) const {1983  outs() << PrintArg(O.ArgStr);1984  outs().indent(GlobalWidth - O.ArgStr.size());1985}1986 1987// parser<bool> implementation1988//1989bool parser<bool>::parse(Option &O, StringRef ArgName, StringRef Arg,1990                         bool &Value) {1991  return parseBool<bool, true, false>(O, ArgName, Arg, Value);1992}1993 1994// parser<boolOrDefault> implementation1995//1996bool parser<boolOrDefault>::parse(Option &O, StringRef ArgName, StringRef Arg,1997                                  boolOrDefault &Value) {1998  return parseBool<boolOrDefault, BOU_TRUE, BOU_FALSE>(O, ArgName, Arg, Value);1999}2000 2001// parser<int> implementation2002//2003bool parser<int>::parse(Option &O, StringRef ArgName, StringRef Arg,2004                        int &Value) {2005  if (Arg.getAsInteger(0, Value))2006    return O.error("'" + Arg + "' value invalid for integer argument!");2007  return false;2008}2009 2010// parser<long> implementation2011//2012bool parser<long>::parse(Option &O, StringRef ArgName, StringRef Arg,2013                         long &Value) {2014  if (Arg.getAsInteger(0, Value))2015    return O.error("'" + Arg + "' value invalid for long argument!");2016  return false;2017}2018 2019// parser<long long> implementation2020//2021bool parser<long long>::parse(Option &O, StringRef ArgName, StringRef Arg,2022                              long long &Value) {2023  if (Arg.getAsInteger(0, Value))2024    return O.error("'" + Arg + "' value invalid for llong argument!");2025  return false;2026}2027 2028// parser<unsigned> implementation2029//2030bool parser<unsigned>::parse(Option &O, StringRef ArgName, StringRef Arg,2031                             unsigned &Value) {2032 2033  if (Arg.getAsInteger(0, Value))2034    return O.error("'" + Arg + "' value invalid for uint argument!");2035  return false;2036}2037 2038// parser<unsigned long> implementation2039//2040bool parser<unsigned long>::parse(Option &O, StringRef ArgName, StringRef Arg,2041                                  unsigned long &Value) {2042 2043  if (Arg.getAsInteger(0, Value))2044    return O.error("'" + Arg + "' value invalid for ulong argument!");2045  return false;2046}2047 2048// parser<unsigned long long> implementation2049//2050bool parser<unsigned long long>::parse(Option &O, StringRef ArgName,2051                                       StringRef Arg,2052                                       unsigned long long &Value) {2053 2054  if (Arg.getAsInteger(0, Value))2055    return O.error("'" + Arg + "' value invalid for ullong argument!");2056  return false;2057}2058 2059// parser<double>/parser<float> implementation2060//2061static bool parseDouble(Option &O, StringRef Arg, double &Value) {2062  if (to_float(Arg, Value))2063    return false;2064  return O.error("'" + Arg + "' value invalid for floating point argument!");2065}2066 2067bool parser<double>::parse(Option &O, StringRef ArgName, StringRef Arg,2068                           double &Val) {2069  return parseDouble(O, Arg, Val);2070}2071 2072bool parser<float>::parse(Option &O, StringRef ArgName, StringRef Arg,2073                          float &Val) {2074  double dVal;2075  if (parseDouble(O, Arg, dVal))2076    return true;2077  Val = (float)dVal;2078  return false;2079}2080 2081// generic_parser_base implementation2082//2083 2084// findOption - Return the option number corresponding to the specified2085// argument string.  If the option is not found, getNumOptions() is returned.2086//2087unsigned generic_parser_base::findOption(StringRef Name) {2088  unsigned e = getNumOptions();2089 2090  for (unsigned i = 0; i != e; ++i) {2091    if (getOption(i) == Name)2092      return i;2093  }2094  return e;2095}2096 2097static StringRef EqValue = "=<value>";2098static StringRef EmptyOption = "<empty>";2099static StringRef OptionPrefix = "    =";2100static size_t getOptionPrefixesSize() {2101  return OptionPrefix.size() + ArgHelpPrefix.size();2102}2103 2104static bool shouldPrintOption(StringRef Name, StringRef Description,2105                              const Option &O) {2106  return O.getValueExpectedFlag() != ValueOptional || !Name.empty() ||2107         !Description.empty();2108}2109 2110// Return the width of the option tag for printing...2111size_t generic_parser_base::getOptionWidth(const Option &O) const {2112  if (O.hasArgStr()) {2113    size_t Size =2114        argPlusPrefixesSize(O.ArgStr) + EqValue.size();2115    for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {2116      StringRef Name = getOption(i);2117      if (!shouldPrintOption(Name, getDescription(i), O))2118        continue;2119      size_t NameSize = Name.empty() ? EmptyOption.size() : Name.size();2120      Size = std::max(Size, NameSize + getOptionPrefixesSize());2121    }2122    return Size;2123  } else {2124    size_t BaseSize = 0;2125    for (unsigned i = 0, e = getNumOptions(); i != e; ++i)2126      BaseSize = std::max(BaseSize, getOption(i).size() + 8);2127    return BaseSize;2128  }2129}2130 2131// printOptionInfo - Print out information about this option.  The2132// to-be-maintained width is specified.2133//2134void generic_parser_base::printOptionInfo(const Option &O,2135                                          size_t GlobalWidth) const {2136  if (O.hasArgStr()) {2137    // When the value is optional, first print a line just describing the2138    // option without values.2139    if (O.getValueExpectedFlag() == ValueOptional) {2140      for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {2141        if (getOption(i).empty()) {2142          outs() << PrintArg(O.ArgStr);2143          Option::printHelpStr(O.HelpStr, GlobalWidth,2144                               argPlusPrefixesSize(O.ArgStr));2145          break;2146        }2147      }2148    }2149 2150    outs() << PrintArg(O.ArgStr) << EqValue;2151    Option::printHelpStr(O.HelpStr, GlobalWidth,2152                         EqValue.size() +2153                             argPlusPrefixesSize(O.ArgStr));2154    for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {2155      StringRef OptionName = getOption(i);2156      StringRef Description = getDescription(i);2157      if (!shouldPrintOption(OptionName, Description, O))2158        continue;2159      size_t FirstLineIndent = OptionName.size() + getOptionPrefixesSize();2160      outs() << OptionPrefix << OptionName;2161      if (OptionName.empty()) {2162        outs() << EmptyOption;2163        assert(FirstLineIndent >= EmptyOption.size());2164        FirstLineIndent += EmptyOption.size();2165      }2166      if (!Description.empty())2167        Option::printEnumValHelpStr(Description, GlobalWidth, FirstLineIndent);2168      else2169        outs() << '\n';2170    }2171  } else {2172    if (!O.HelpStr.empty())2173      outs() << "  " << O.HelpStr << '\n';2174    for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {2175      StringRef Option = getOption(i);2176      outs() << "    " << PrintArg(Option);2177      Option::printHelpStr(getDescription(i), GlobalWidth, Option.size() + 8);2178    }2179  }2180}2181 2182static const size_t MaxOptWidth = 8; // arbitrary spacing for printOptionDiff2183 2184// printGenericOptionDiff - Print the value of this option and it's default.2185//2186// "Generic" options have each value mapped to a name.2187void generic_parser_base::printGenericOptionDiff(2188    const Option &O, const GenericOptionValue &Value,2189    const GenericOptionValue &Default, size_t GlobalWidth) const {2190  outs() << "  " << PrintArg(O.ArgStr);2191  outs().indent(GlobalWidth - O.ArgStr.size());2192 2193  unsigned NumOpts = getNumOptions();2194  for (unsigned i = 0; i != NumOpts; ++i) {2195    if (!Value.compare(getOptionValue(i)))2196      continue;2197 2198    outs() << "= " << getOption(i);2199    size_t L = getOption(i).size();2200    size_t NumSpaces = MaxOptWidth > L ? MaxOptWidth - L : 0;2201    outs().indent(NumSpaces) << " (default: ";2202    for (unsigned j = 0; j != NumOpts; ++j) {2203      if (!Default.compare(getOptionValue(j)))2204        continue;2205      outs() << getOption(j);2206      break;2207    }2208    outs() << ")\n";2209    return;2210  }2211  outs() << "= *unknown option value*\n";2212}2213 2214// printOptionDiff - Specializations for printing basic value types.2215//2216#define PRINT_OPT_DIFF(T)                                                      \2217  void parser<T>::printOptionDiff(const Option &O, T V, OptionValue<T> D,      \2218                                  size_t GlobalWidth) const {                  \2219    printOptionName(O, GlobalWidth);                                           \2220    std::string Str;                                                           \2221    {                                                                          \2222      raw_string_ostream SS(Str);                                              \2223      SS << V;                                                                 \2224    }                                                                          \2225    outs() << "= " << Str;                                                     \2226    size_t NumSpaces =                                                         \2227        MaxOptWidth > Str.size() ? MaxOptWidth - Str.size() : 0;               \2228    outs().indent(NumSpaces) << " (default: ";                                 \2229    if (D.hasValue())                                                          \2230      outs() << D.getValue();                                                  \2231    else                                                                       \2232      outs() << "*no default*";                                                \2233    outs() << ")\n";                                                           \2234  }2235 2236PRINT_OPT_DIFF(bool)2237PRINT_OPT_DIFF(boolOrDefault)2238PRINT_OPT_DIFF(int)2239PRINT_OPT_DIFF(long)2240PRINT_OPT_DIFF(long long)2241PRINT_OPT_DIFF(unsigned)2242PRINT_OPT_DIFF(unsigned long)2243PRINT_OPT_DIFF(unsigned long long)2244PRINT_OPT_DIFF(double)2245PRINT_OPT_DIFF(float)2246PRINT_OPT_DIFF(char)2247 2248void parser<std::string>::printOptionDiff(const Option &O, StringRef V,2249                                          const OptionValue<std::string> &D,2250                                          size_t GlobalWidth) const {2251  printOptionName(O, GlobalWidth);2252  outs() << "= " << V;2253  size_t NumSpaces = MaxOptWidth > V.size() ? MaxOptWidth - V.size() : 0;2254  outs().indent(NumSpaces) << " (default: ";2255  if (D.hasValue())2256    outs() << D.getValue();2257  else2258    outs() << "*no default*";2259  outs() << ")\n";2260}2261 2262void parser<std::optional<std::string>>::printOptionDiff(2263    const Option &O, std::optional<StringRef> V,2264    const OptionValue<std::optional<std::string>> &D,2265    size_t GlobalWidth) const {2266  printOptionName(O, GlobalWidth);2267  outs() << "= " << V;2268  size_t VSize = V.has_value() ? V.value().size() : 0;2269  size_t NumSpaces = MaxOptWidth > VSize ? MaxOptWidth - VSize : 0;2270  outs().indent(NumSpaces) << " (default: ";2271  if (D.hasValue() && D.getValue().has_value())2272    outs() << D.getValue();2273  else2274    outs() << "*no value*";2275  outs() << ")\n";2276}2277 2278// Print a placeholder for options that don't yet support printOptionDiff().2279void basic_parser_impl::printOptionNoValue(const Option &O,2280                                           size_t GlobalWidth) const {2281  printOptionName(O, GlobalWidth);2282  outs() << "= *cannot print option value*\n";2283}2284 2285//===----------------------------------------------------------------------===//2286// -help and -help-hidden option implementation2287//2288 2289static int OptNameCompare(const std::pair<const char *, Option *> *LHS,2290                          const std::pair<const char *, Option *> *RHS) {2291  return strcmp(LHS->first, RHS->first);2292}2293 2294static int SubNameCompare(const std::pair<const char *, SubCommand *> *LHS,2295                          const std::pair<const char *, SubCommand *> *RHS) {2296  return strcmp(LHS->first, RHS->first);2297}2298 2299// Copy Options into a vector so we can sort them as we like.2300static void sortOpts(StringMap<Option *> &OptMap,2301                     SmallVectorImpl<std::pair<const char *, Option *>> &Opts,2302                     bool ShowHidden) {2303  SmallPtrSet<Option *, 32> OptionSet; // Duplicate option detection.2304 2305  for (StringMap<Option *>::iterator I = OptMap.begin(), E = OptMap.end();2306       I != E; ++I) {2307    // Ignore really-hidden options.2308    if (I->second->getOptionHiddenFlag() == ReallyHidden)2309      continue;2310 2311    // Unless showhidden is set, ignore hidden flags.2312    if (I->second->getOptionHiddenFlag() == Hidden && !ShowHidden)2313      continue;2314 2315    // If we've already seen this option, don't add it to the list again.2316    if (!OptionSet.insert(I->second).second)2317      continue;2318 2319    Opts.push_back(2320        std::pair<const char *, Option *>(I->getKey().data(), I->second));2321  }2322 2323  // Sort the options list alphabetically.2324  array_pod_sort(Opts.begin(), Opts.end(), OptNameCompare);2325}2326 2327static void2328sortSubCommands(const SmallPtrSetImpl<SubCommand *> &SubMap,2329                SmallVectorImpl<std::pair<const char *, SubCommand *>> &Subs) {2330  for (auto *S : SubMap) {2331    if (S->getName().empty())2332      continue;2333    Subs.push_back(std::make_pair(S->getName().data(), S));2334  }2335  array_pod_sort(Subs.begin(), Subs.end(), SubNameCompare);2336}2337 2338namespace {2339 2340class HelpPrinter {2341protected:2342  const bool ShowHidden;2343  using StrOptionPairVector =2344      SmallVector<std::pair<const char *, Option *>, 128>;2345  using StrSubCommandPairVector =2346      SmallVector<std::pair<const char *, SubCommand *>, 128>;2347  // Print the options. Opts is assumed to be alphabetically sorted.2348  virtual void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) {2349    for (const auto &Opt : Opts)2350      Opt.second->printOptionInfo(MaxArgLen);2351  }2352 2353  void printSubCommands(StrSubCommandPairVector &Subs, size_t MaxSubLen) {2354    for (const auto &S : Subs) {2355      outs() << "  " << S.first;2356      if (!S.second->getDescription().empty()) {2357        outs().indent(MaxSubLen - strlen(S.first));2358        outs() << " - " << S.second->getDescription();2359      }2360      outs() << "\n";2361    }2362  }2363 2364public:2365  explicit HelpPrinter(bool showHidden) : ShowHidden(showHidden) {}2366  virtual ~HelpPrinter() = default;2367 2368  // Invoke the printer.2369  void operator=(bool Value) {2370    if (!Value)2371      return;2372    printHelp();2373 2374    // Halt the program since help information was printed2375    exit(0);2376  }2377 2378  void printHelp() {2379    SubCommand *Sub = GlobalParser->getActiveSubCommand();2380    auto &OptionsMap = Sub->OptionsMap;2381    auto &PositionalOpts = Sub->PositionalOpts;2382    auto &ConsumeAfterOpt = Sub->ConsumeAfterOpt;2383 2384    StrOptionPairVector Opts;2385    sortOpts(OptionsMap, Opts, ShowHidden);2386 2387    StrSubCommandPairVector Subs;2388    sortSubCommands(GlobalParser->RegisteredSubCommands, Subs);2389 2390    if (!GlobalParser->ProgramOverview.empty())2391      outs() << "OVERVIEW: " << GlobalParser->ProgramOverview << "\n";2392 2393    if (Sub == &SubCommand::getTopLevel()) {2394      outs() << "USAGE: " << GlobalParser->ProgramName;2395      if (!Subs.empty())2396        outs() << " [subcommand]";2397      outs() << " [options]";2398    } else {2399      if (!Sub->getDescription().empty()) {2400        outs() << "SUBCOMMAND '" << Sub->getName()2401               << "': " << Sub->getDescription() << "\n\n";2402      }2403      outs() << "USAGE: " << GlobalParser->ProgramName << " " << Sub->getName()2404             << " [options]";2405    }2406 2407    for (auto *Opt : PositionalOpts) {2408      if (Opt->hasArgStr())2409        outs() << " --" << Opt->ArgStr;2410      outs() << " " << Opt->HelpStr;2411    }2412 2413    // Print the consume after option info if it exists...2414    if (ConsumeAfterOpt)2415      outs() << " " << ConsumeAfterOpt->HelpStr;2416 2417    if (Sub == &SubCommand::getTopLevel() && !Subs.empty()) {2418      // Compute the maximum subcommand length...2419      size_t MaxSubLen = 0;2420      for (const auto &Sub : Subs)2421        MaxSubLen = std::max(MaxSubLen, strlen(Sub.first));2422 2423      outs() << "\n\n";2424      outs() << "SUBCOMMANDS:\n\n";2425      printSubCommands(Subs, MaxSubLen);2426      outs() << "\n";2427      outs() << "  Type \"" << GlobalParser->ProgramName2428             << " <subcommand> --help\" to get more help on a specific "2429                "subcommand";2430    }2431 2432    outs() << "\n\n";2433 2434    // Compute the maximum argument length...2435    size_t MaxArgLen = 0;2436    for (const auto &Opt : Opts)2437      MaxArgLen = std::max(MaxArgLen, Opt.second->getOptionWidth());2438 2439    outs() << "OPTIONS:\n";2440    printOptions(Opts, MaxArgLen);2441 2442    // Print any extra help the user has declared.2443    for (const auto &I : GlobalParser->MoreHelp)2444      outs() << I;2445    GlobalParser->MoreHelp.clear();2446  }2447};2448 2449class CategorizedHelpPrinter : public HelpPrinter {2450public:2451  explicit CategorizedHelpPrinter(bool showHidden) : HelpPrinter(showHidden) {}2452 2453  // Helper function for printOptions().2454  // It shall return a negative value if A's name should be lexicographically2455  // ordered before B's name. It returns a value greater than zero if B's name2456  // should be ordered before A's name, and it returns 0 otherwise.2457  static int OptionCategoryCompare(OptionCategory *const *A,2458                                   OptionCategory *const *B) {2459    return (*A)->getName().compare((*B)->getName());2460  }2461 2462  // Make sure we inherit our base class's operator=()2463  using HelpPrinter::operator=;2464 2465protected:2466  void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) override {2467    std::vector<OptionCategory *> SortedCategories;2468    DenseMap<OptionCategory *, std::vector<Option *>> CategorizedOptions;2469 2470    // Collect registered option categories into vector in preparation for2471    // sorting.2472    llvm::append_range(SortedCategories,2473                       GlobalParser->RegisteredOptionCategories);2474 2475    // Sort the different option categories alphabetically.2476    assert(SortedCategories.size() > 0 && "No option categories registered!");2477    array_pod_sort(SortedCategories.begin(), SortedCategories.end(),2478                   OptionCategoryCompare);2479 2480    // Walk through pre-sorted options and assign into categories.2481    // Because the options are already alphabetically sorted the2482    // options within categories will also be alphabetically sorted.2483    for (const auto &I : Opts) {2484      Option *Opt = I.second;2485      for (OptionCategory *Cat : Opt->Categories) {2486        assert(llvm::is_contained(SortedCategories, Cat) &&2487               "Option has an unregistered category");2488        CategorizedOptions[Cat].push_back(Opt);2489      }2490    }2491 2492    // Now do printing.2493    for (OptionCategory *Category : SortedCategories) {2494      // Hide empty categories for --help, but show for --help-hidden.2495      const auto &CategoryOptions = CategorizedOptions[Category];2496      if (CategoryOptions.empty())2497        continue;2498 2499      // Print category information.2500      outs() << "\n";2501      outs() << Category->getName() << ":\n";2502 2503      // Check if description is set.2504      if (!Category->getDescription().empty())2505        outs() << Category->getDescription() << "\n\n";2506      else2507        outs() << "\n";2508 2509      // Loop over the options in the category and print.2510      for (const Option *Opt : CategoryOptions)2511        Opt->printOptionInfo(MaxArgLen);2512    }2513  }2514};2515 2516// This wraps the Uncategorizing and Categorizing printers and decides2517// at run time which should be invoked.2518class HelpPrinterWrapper {2519private:2520  HelpPrinter &UncategorizedPrinter;2521  CategorizedHelpPrinter &CategorizedPrinter;2522 2523public:2524  explicit HelpPrinterWrapper(HelpPrinter &UncategorizedPrinter,2525                              CategorizedHelpPrinter &CategorizedPrinter)2526      : UncategorizedPrinter(UncategorizedPrinter),2527        CategorizedPrinter(CategorizedPrinter) {}2528 2529  // Invoke the printer.2530  void operator=(bool Value);2531};2532 2533} // End anonymous namespace2534 2535#if defined(__GNUC__)2536// GCC and GCC-compatible compilers define __OPTIMIZE__ when optimizations are2537// enabled.2538# if defined(__OPTIMIZE__)2539#  define LLVM_IS_DEBUG_BUILD 02540# else2541#  define LLVM_IS_DEBUG_BUILD 12542# endif2543#elif defined(_MSC_VER)2544// MSVC doesn't have a predefined macro indicating if optimizations are enabled.2545// Use _DEBUG instead. This macro actually corresponds to the choice between2546// debug and release CRTs, but it is a reasonable proxy.2547# if defined(_DEBUG)2548#  define LLVM_IS_DEBUG_BUILD 12549# else2550#  define LLVM_IS_DEBUG_BUILD 02551# endif2552#else2553// Otherwise, for an unknown compiler, assume this is an optimized build.2554# define LLVM_IS_DEBUG_BUILD 02555#endif2556 2557namespace {2558class VersionPrinter {2559public:2560  void print(std::vector<VersionPrinterTy> ExtraPrinters = {}) {2561    raw_ostream &OS = outs();2562#ifdef PACKAGE_VENDOR2563    OS << PACKAGE_VENDOR << " ";2564#else2565    OS << "LLVM (http://llvm.org/):\n  ";2566#endif2567    OS << PACKAGE_NAME << " version " << PACKAGE_VERSION << "\n  ";2568#if LLVM_IS_DEBUG_BUILD2569    OS << "DEBUG build";2570#else2571    OS << "Optimized build";2572#endif2573#ifndef NDEBUG2574    OS << " with assertions";2575#endif2576    OS << ".\n";2577 2578    // Iterate over any registered extra printers and call them to add further2579    // information.2580    if (!ExtraPrinters.empty()) {2581      for (const auto &I : ExtraPrinters)2582        I(outs());2583    }2584  }2585  void operator=(bool OptionWasSpecified);2586};2587 2588struct CommandLineCommonOptions {2589  // Declare the four HelpPrinter instances that are used to print out help, or2590  // help-hidden as an uncategorized list or in categories.2591  HelpPrinter UncategorizedNormalPrinter{false};2592  HelpPrinter UncategorizedHiddenPrinter{true};2593  CategorizedHelpPrinter CategorizedNormalPrinter{false};2594  CategorizedHelpPrinter CategorizedHiddenPrinter{true};2595  // Declare HelpPrinter wrappers that will decide whether or not to invoke2596  // a categorizing help printer2597  HelpPrinterWrapper WrappedNormalPrinter{UncategorizedNormalPrinter,2598                                          CategorizedNormalPrinter};2599  HelpPrinterWrapper WrappedHiddenPrinter{UncategorizedHiddenPrinter,2600                                          CategorizedHiddenPrinter};2601  // Define a category for generic options that all tools should have.2602  cl::OptionCategory GenericCategory{"Generic Options"};2603 2604  // Define uncategorized help printers.2605  // --help-list is hidden by default because if Option categories are being2606  // used then --help behaves the same as --help-list.2607  cl::opt<HelpPrinter, true, parser<bool>> HLOp{2608      "help-list",2609      cl::desc(2610          "Display list of available options (--help-list-hidden for more)"),2611      cl::location(UncategorizedNormalPrinter),2612      cl::Hidden,2613      cl::ValueDisallowed,2614      cl::cat(GenericCategory),2615      cl::sub(SubCommand::getAll())};2616 2617  cl::opt<HelpPrinter, true, parser<bool>> HLHOp{2618      "help-list-hidden",2619      cl::desc("Display list of all available options"),2620      cl::location(UncategorizedHiddenPrinter),2621      cl::Hidden,2622      cl::ValueDisallowed,2623      cl::cat(GenericCategory),2624      cl::sub(SubCommand::getAll())};2625 2626  // Define uncategorized/categorized help printers. These printers change their2627  // behaviour at runtime depending on whether one or more Option categories2628  // have been declared.2629  cl::opt<HelpPrinterWrapper, true, parser<bool>> HOp{2630      "help",2631      cl::desc("Display available options (--help-hidden for more)"),2632      cl::location(WrappedNormalPrinter),2633      cl::ValueDisallowed,2634      cl::cat(GenericCategory),2635      cl::sub(SubCommand::getAll())};2636 2637  cl::alias HOpA{"h", cl::desc("Alias for --help"), cl::aliasopt(HOp),2638                 cl::DefaultOption};2639 2640  cl::opt<HelpPrinterWrapper, true, parser<bool>> HHOp{2641      "help-hidden",2642      cl::desc("Display all available options"),2643      cl::location(WrappedHiddenPrinter),2644      cl::Hidden,2645      cl::ValueDisallowed,2646      cl::cat(GenericCategory),2647      cl::sub(SubCommand::getAll())};2648 2649  cl::opt<bool> PrintOptions{2650      "print-options",2651      cl::desc("Print non-default options after command line parsing"),2652      cl::Hidden,2653      cl::init(false),2654      cl::cat(GenericCategory),2655      cl::sub(SubCommand::getAll())};2656 2657  cl::opt<bool> PrintAllOptions{2658      "print-all-options",2659      cl::desc("Print all option values after command line parsing"),2660      cl::Hidden,2661      cl::init(false),2662      cl::cat(GenericCategory),2663      cl::sub(SubCommand::getAll())};2664 2665  VersionPrinterTy OverrideVersionPrinter = nullptr;2666 2667  std::vector<VersionPrinterTy> ExtraVersionPrinters;2668 2669  // Define the --version option that prints out the LLVM version for the tool2670  VersionPrinter VersionPrinterInstance;2671 2672  cl::opt<VersionPrinter, true, parser<bool>> VersOp{2673      "version", cl::desc("Display the version of this program"),2674      cl::location(VersionPrinterInstance), cl::ValueDisallowed,2675      cl::cat(GenericCategory)};2676};2677} // End anonymous namespace2678 2679// Lazy-initialized global instance of options controlling the command-line2680// parser and general handling.2681static ManagedStatic<CommandLineCommonOptions> CommonOptions;2682 2683static void initCommonOptions() {2684  *CommonOptions;2685  initDebugCounterOptions();2686  initGraphWriterOptions();2687  initSignalsOptions();2688  initStatisticOptions();2689  initTimerOptions();2690  initWithColorOptions();2691  initDebugOptions();2692  initRandomSeedOptions();2693}2694 2695OptionCategory &cl::getGeneralCategory() {2696  // Initialise the general option category.2697  static OptionCategory GeneralCategory{"General options"};2698  return GeneralCategory;2699}2700 2701void VersionPrinter::operator=(bool OptionWasSpecified) {2702  if (!OptionWasSpecified)2703    return;2704 2705  if (CommonOptions->OverrideVersionPrinter != nullptr) {2706    CommonOptions->OverrideVersionPrinter(outs());2707    exit(0);2708  }2709  print(CommonOptions->ExtraVersionPrinters);2710 2711  exit(0);2712}2713 2714void HelpPrinterWrapper::operator=(bool Value) {2715  if (!Value)2716    return;2717 2718  // Decide which printer to invoke. If more than one option category is2719  // registered then it is useful to show the categorized help instead of2720  // uncategorized help.2721  if (GlobalParser->RegisteredOptionCategories.size() > 1) {2722    // unhide --help-list option so user can have uncategorized output if they2723    // want it.2724    CommonOptions->HLOp.setHiddenFlag(NotHidden);2725 2726    CategorizedPrinter = true; // Invoke categorized printer2727  } else {2728    UncategorizedPrinter = true; // Invoke uncategorized printer2729  }2730}2731 2732// Print the value of each option.2733void cl::PrintOptionValues() { GlobalParser->printOptionValues(); }2734 2735void CommandLineParser::printOptionValues() {2736  if (!CommonOptions->PrintOptions && !CommonOptions->PrintAllOptions)2737    return;2738 2739  SmallVector<std::pair<const char *, Option *>, 128> Opts;2740  sortOpts(ActiveSubCommand->OptionsMap, Opts, /*ShowHidden*/ true);2741 2742  // Compute the maximum argument length...2743  size_t MaxArgLen = 0;2744  for (const auto &Opt : Opts)2745    MaxArgLen = std::max(MaxArgLen, Opt.second->getOptionWidth());2746 2747  for (const auto &Opt : Opts)2748    Opt.second->printOptionValue(MaxArgLen, CommonOptions->PrintAllOptions);2749}2750 2751// Utility function for printing the help message.2752void cl::PrintHelpMessage(bool Hidden, bool Categorized) {2753  if (!Hidden && !Categorized)2754    CommonOptions->UncategorizedNormalPrinter.printHelp();2755  else if (!Hidden && Categorized)2756    CommonOptions->CategorizedNormalPrinter.printHelp();2757  else if (Hidden && !Categorized)2758    CommonOptions->UncategorizedHiddenPrinter.printHelp();2759  else2760    CommonOptions->CategorizedHiddenPrinter.printHelp();2761}2762 2763ArrayRef<StringRef> cl::getCompilerBuildConfig() {2764  static const StringRef Config[] = {2765      // Placeholder to ensure the array always has elements, since it's an2766      // error to have a zero-sized array. Slice this off before returning.2767      "",2768  // Actual compiler build config feature list:2769#if LLVM_IS_DEBUG_BUILD2770      "+unoptimized",2771#endif2772#ifndef NDEBUG2773      "+assertions",2774#endif2775#ifdef EXPENSIVE_CHECKS2776      "+expensive-checks",2777#endif2778#if __has_feature(address_sanitizer)2779      "+asan",2780#endif2781#if __has_feature(dataflow_sanitizer)2782      "+dfsan",2783#endif2784#if __has_feature(hwaddress_sanitizer)2785      "+hwasan",2786#endif2787#if __has_feature(memory_sanitizer)2788      "+msan",2789#endif2790#if __has_feature(thread_sanitizer)2791      "+tsan",2792#endif2793#if __has_feature(undefined_behavior_sanitizer)2794      "+ubsan",2795#endif2796  };2797  return ArrayRef(Config).drop_front(1);2798}2799 2800// Utility function for printing the build config.2801void cl::printBuildConfig(raw_ostream &OS) {2802#if LLVM_VERSION_PRINTER_SHOW_BUILD_CONFIG2803  OS << "Build config: ";2804  llvm::interleaveComma(cl::getCompilerBuildConfig(), OS);2805  OS << '\n';2806#endif2807}2808 2809/// Utility function for printing version number.2810void cl::PrintVersionMessage() {2811  CommonOptions->VersionPrinterInstance.print(CommonOptions->ExtraVersionPrinters);2812}2813 2814void cl::SetVersionPrinter(VersionPrinterTy func) {2815  CommonOptions->OverrideVersionPrinter = func;2816}2817 2818void cl::AddExtraVersionPrinter(VersionPrinterTy func) {2819  CommonOptions->ExtraVersionPrinters.push_back(func);2820}2821 2822StringMap<Option *> &cl::getRegisteredOptions(SubCommand &Sub) {2823  initCommonOptions();2824  auto &Subs = GlobalParser->RegisteredSubCommands;2825  (void)Subs;2826  assert(Subs.contains(&Sub));2827  return Sub.OptionsMap;2828}2829 2830iterator_range<SmallPtrSet<SubCommand *, 4>::iterator>2831cl::getRegisteredSubcommands() {2832  return GlobalParser->getRegisteredSubcommands();2833}2834 2835void cl::HideUnrelatedOptions(cl::OptionCategory &Category, SubCommand &Sub) {2836  initCommonOptions();2837  for (auto &I : Sub.OptionsMap) {2838    bool Unrelated = true;2839    for (auto &Cat : I.second->Categories) {2840      if (Cat == &Category || Cat == &CommonOptions->GenericCategory)2841        Unrelated = false;2842    }2843    if (Unrelated)2844      I.second->setHiddenFlag(cl::ReallyHidden);2845  }2846}2847 2848void cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *> Categories,2849                              SubCommand &Sub) {2850  initCommonOptions();2851  for (auto &I : Sub.OptionsMap) {2852    bool Unrelated = true;2853    for (auto &Cat : I.second->Categories) {2854      if (is_contained(Categories, Cat) ||2855          Cat == &CommonOptions->GenericCategory)2856        Unrelated = false;2857    }2858    if (Unrelated)2859      I.second->setHiddenFlag(cl::ReallyHidden);2860  }2861}2862 2863void cl::ResetCommandLineParser() { GlobalParser->reset(); }2864void cl::ResetAllOptionOccurrences() {2865  GlobalParser->ResetAllOptionOccurrences();2866}2867 2868void LLVMParseCommandLineOptions(int argc, const char *const *argv,2869                                 const char *Overview) {2870  llvm::cl::ParseCommandLineOptions(argc, argv, StringRef(Overview),2871                                    &llvm::nulls());2872}2873