LLVM 24.0.0git
CommandLine.cpp
Go to the documentation of this file.
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This class implements a command line argument processor that is useful when
10// creating a tool. It provides a simple, minimalistic interface that is easily
11// extensible and supports nonlocal (library) command line options.
12//
13// Note that rather than trying to figure out what this code does, you could try
14// reading the library documentation located in docs/CommandLine.html
15//
16//===----------------------------------------------------------------------===//
17
19
20#include "DebugOptions.h"
21
22#include "llvm-c/Support.h"
23#include "llvm/ADT/ArrayRef.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"
34#include "llvm/Support/Debug.h"
35#include "llvm/Support/Error.h"
40#include "llvm/Support/Path.h"
46#include <cstdlib>
47#include <optional>
48#include <string>
49using namespace llvm;
50using namespace cl;
51
52#define DEBUG_TYPE "commandline"
53
54//===----------------------------------------------------------------------===//
55// Template instantiations and anchors.
56//
57namespace llvm {
58namespace cl {
72
73#if !(defined(LLVM_ENABLE_LLVM_EXPORT_ANNOTATIONS) && defined(_MSC_VER))
74// Only instantiate opt<std::string> when not building a Windows DLL. When
75// exporting opt<std::string>, MSVC implicitly exports symbols for
76// std::basic_string through transitive inheritance via std::string. These
77// symbols may appear in clients, leading to duplicate symbol conflicts.
79#endif
80
85
86} // namespace cl
87} // namespace llvm
88
89// Pin the vtables to this file.
90void GenericOptionValue::anchor() {}
91void OptionValue<boolOrDefault>::anchor() {}
92void OptionValue<std::string>::anchor() {}
93void Option::anchor() {}
97void parser<int>::anchor() {}
104void parser<float>::anchor() {}
106void parser<std::optional<std::string>>::anchor() {}
107void parser<char>::anchor() {}
109
110// These anchor functions instantiate opt<T> and reference its virtual
111// destructor to ensure MSVC exports the corresponding vtable and typeinfo when
112// building a Windows DLL. Without an explicit reference, MSVC may omit the
113// instantiation at link time even if it is marked DLL-export.
114void opt_bool_anchor() { opt<bool> anchor{""}; }
115void opt_char_anchor() { opt<char> anchor{""}; }
116void opt_int_anchor() { opt<int> anchor{""}; }
117void opt_unsigned_anchor() { opt<unsigned> anchor{""}; }
118
119//===----------------------------------------------------------------------===//
120
121const static size_t DefaultPad = 2;
122
123static StringRef ArgPrefix = "-";
126
127static size_t argPlusPrefixesSize(StringRef ArgName, size_t Pad = DefaultPad) {
128 size_t Len = ArgName.size();
129 if (Len == 1)
130 return Len + Pad + ArgPrefix.size() + ArgHelpPrefix.size();
131 return Len + Pad + ArgPrefixLong.size() + ArgHelpPrefix.size();
132}
133
134static SmallString<8> argPrefix(StringRef ArgName, size_t Pad = DefaultPad) {
136 for (size_t I = 0; I < Pad; ++I) {
137 Prefix.push_back(' ');
138 }
139 Prefix.append(ArgName.size() > 1 ? ArgPrefixLong : ArgPrefix);
140 return Prefix;
141}
142
144
145namespace {
146
147class PrintArg {
148 StringRef ArgName;
149 size_t Pad;
150public:
151 PrintArg(StringRef ArgName, size_t Pad = DefaultPad) : ArgName(ArgName), Pad(Pad) {}
152 friend raw_ostream &operator<<(raw_ostream &OS, const PrintArg &);
153};
154
155raw_ostream &operator<<(raw_ostream &OS, const PrintArg& Arg) {
156 OS << argPrefix(Arg.ArgName, Arg.Pad) << Arg.ArgName;
157 return OS;
158}
159
160class CommandLineParser {
161public:
162 // Globals for name and overview of program. Program name is not a string to
163 // avoid static ctor/dtor issues.
164 std::string ProgramName;
165 StringRef ProgramOverview;
166
167 // This collects additional help to be printed.
168 std::vector<StringRef> MoreHelp;
169
170 // This collects the different option categories that have been registered.
171 SmallPtrSet<OptionCategory *, 16> RegisteredOptionCategories;
172
173 // This collects the different subcommands that have been registered.
174 SmallPtrSet<SubCommand *, 4> RegisteredSubCommands;
175
176 CommandLineParser() { registerSubCommand(&SubCommand::getTopLevel()); }
177
179
180 bool ParseCommandLineOptions(int argc, const char *const *argv,
181 StringRef Overview, raw_ostream *Errs = nullptr,
182 vfs::FileSystem *VFS = nullptr);
183
184 void forEachSubCommand(Option &Opt, function_ref<void(SubCommand &)> Action) {
185 if (Opt.Subs.empty()) {
186 Action(SubCommand::getTopLevel());
187 return;
188 }
189 if (Opt.Subs.size() == 1 && *Opt.Subs.begin() == &SubCommand::getAll()) {
190 for (auto *SC : RegisteredSubCommands)
191 Action(*SC);
192 Action(SubCommand::getAll());
193 return;
194 }
195 for (auto *SC : Opt.Subs) {
196 assert(SC != &SubCommand::getAll() &&
197 "SubCommand::getAll() should not be used with other subcommands");
198 Action(*SC);
199 }
200 }
201
202 void addLiteralOption(Option &Opt, SubCommand *SC, StringRef Name) {
203 if (Opt.hasArgStr())
204 return;
205 if (!SC->OptionsMap.insert(std::make_pair(Name, &Opt)).second) {
206 errs() << ProgramName << ": CommandLine Error: Option '" << Name
207 << "' registered more than once!\n";
208 report_fatal_error("inconsistency in registered CommandLine options");
209 }
210 }
211
212 void addLiteralOption(Option &Opt, StringRef Name) {
213 forEachSubCommand(
214 Opt, [&](SubCommand &SC) { addLiteralOption(Opt, &SC, Name); });
215 }
216
217 void addOption(Option *O, SubCommand *SC) {
218 bool HadErrors = false;
219 if (O->hasArgStr()) {
220 // Add argument to the argument map!
221 if (!SC->OptionsMap.insert(std::make_pair(O->ArgStr, O)).second) {
222 errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr
223 << "' registered more than once!\n";
224 HadErrors = true;
225 }
226 }
227
228 // Remember information about positional options.
229 if (O->getFormattingFlag() == cl::Positional)
230 SC->PositionalOpts.push_back(O);
231 else if (O->getNumOccurrencesFlag() == cl::ConsumeAfter) {
232 if (SC->ConsumeAfterOpt) {
233 O->error("Cannot specify more than one option with cl::ConsumeAfter!");
234 HadErrors = true;
235 }
236 SC->ConsumeAfterOpt = O;
237 }
238
239 // Fail hard if there were errors. These are strictly unrecoverable and
240 // indicate serious issues such as conflicting option names or an
241 // incorrectly
242 // linked LLVM distribution.
243 if (HadErrors)
244 report_fatal_error("inconsistency in registered CommandLine options");
245 }
246
247 void addOption(Option *O) {
248 forEachSubCommand(*O, [&](SubCommand &SC) { addOption(O, &SC); });
249 }
250
251 void removeOption(Option *O, SubCommand *SC) {
252 SmallVector<StringRef, 16> OptionNames;
253 O->getExtraOptionNames(OptionNames);
254 if (O->hasArgStr())
255 OptionNames.push_back(O->ArgStr);
256
257 SubCommand &Sub = *SC;
258 for (auto Name : OptionNames) {
259 auto I = Sub.OptionsMap.find(Name);
260 // Re-query end() each iteration: a prior erase invalidates iterators
261 // (including a cached end()) under backward-shift deletion.
262 if (I != Sub.OptionsMap.end() && I->second == O)
263 Sub.OptionsMap.erase(I);
264 }
265
266 if (O->getFormattingFlag() == cl::Positional)
267 for (auto *Opt = Sub.PositionalOpts.begin();
268 Opt != Sub.PositionalOpts.end(); ++Opt) {
269 if (*Opt == O) {
270 Sub.PositionalOpts.erase(Opt);
271 break;
272 }
273 }
274 else if (O == Sub.ConsumeAfterOpt)
275 Sub.ConsumeAfterOpt = nullptr;
276 }
277
278 void removeOption(Option *O) {
279 forEachSubCommand(*O, [&](SubCommand &SC) { removeOption(O, &SC); });
280 }
281
282 bool hasOptions(const SubCommand &Sub) const {
283 return (!Sub.OptionsMap.empty() || !Sub.PositionalOpts.empty() ||
284 nullptr != Sub.ConsumeAfterOpt);
285 }
286
287 bool hasOptions() const {
288 for (const auto *S : RegisteredSubCommands) {
289 if (hasOptions(*S))
290 return true;
291 }
292 return false;
293 }
294
295 bool hasNamedSubCommands() const {
296 for (const auto *S : RegisteredSubCommands)
297 if (!S->getName().empty())
298 return true;
299 return false;
300 }
301
302 SubCommand *getActiveSubCommand() { return ActiveSubCommand; }
303
304 void updateArgStr(Option *O, StringRef NewName, SubCommand *SC) {
305 SubCommand &Sub = *SC;
306 if (!Sub.OptionsMap.insert(std::make_pair(NewName, O)).second) {
307 errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr
308 << "' registered more than once!\n";
309 report_fatal_error("inconsistency in registered CommandLine options");
310 }
311 Sub.OptionsMap.erase(O->ArgStr);
312 }
313
314 void updateArgStr(Option *O, StringRef NewName) {
315 forEachSubCommand(*O,
316 [&](SubCommand &SC) { updateArgStr(O, NewName, &SC); });
317 }
318
319 void printOptionValues();
320
321 void registerCategory(OptionCategory *cat) {
322 assert(count_if(RegisteredOptionCategories,
323 [cat](const OptionCategory *Category) {
324 return cat->getName() == Category->getName();
325 }) == 0 &&
326 "Duplicate option categories");
327
328 RegisteredOptionCategories.insert(cat);
329 }
330
331 void registerSubCommand(SubCommand *sub) {
332 assert(count_if(RegisteredSubCommands,
333 [sub](const SubCommand *Sub) {
334 return (!sub->getName().empty()) &&
335 (Sub->getName() == sub->getName());
336 }) == 0 &&
337 "Duplicate subcommands");
338 RegisteredSubCommands.insert(sub);
339
340 // For all options that have been registered for all subcommands, add the
341 // option to this subcommand now.
343 "SubCommand::getAll() should not be registered");
344 for (auto &E : SubCommand::getAll().OptionsMap) {
345 Option *O = E.second;
346 if (O->isPositional() || O->isConsumeAfter() || O->hasArgStr())
347 addOption(O, sub);
348 else
349 addLiteralOption(*O, sub, E.first);
350 }
351 }
352
353 void unregisterSubCommand(SubCommand *sub) {
354 RegisteredSubCommands.erase(sub);
355 }
356
359 return make_range(RegisteredSubCommands.begin(),
360 RegisteredSubCommands.end());
361 }
362
363 void reset() {
364 ActiveSubCommand = nullptr;
365 ProgramName.clear();
366 ProgramOverview = StringRef();
367
368 MoreHelp.clear();
369 RegisteredOptionCategories.clear();
370
372 RegisteredSubCommands.clear();
373
376 registerSubCommand(&SubCommand::getTopLevel());
377 }
378
379private:
380 SubCommand *ActiveSubCommand = nullptr;
381
382 Option *LookupOption(SubCommand &Sub, StringRef &Arg, StringRef &Value);
383 SubCommand *LookupSubCommand(StringRef Name, std::string &NearestString);
384};
385
386} // namespace
387
388// The global parser is kept as a block-scope static so that option
389// constructors running during dynamic initialization of other translation
390// units never reference a namespace-scope global whose initialization order
391// is unspecified. The ManagedStatic keeps construction lazy and destruction
392// tied to llvm_shutdown().
393static CommandLineParser &globalParser() {
394 static ManagedStatic<CommandLineParser> GlobalParser;
395 return *GlobalParser;
396}
397
398template <typename T, T TrueVal, T FalseVal>
399static bool parseBool(Option &O, StringRef ArgName, StringRef Arg, T &Value) {
400 // ProvideOption passes a null Arg for a bare -flag (treated as true) and an
401 // empty one for -flag= (treated as invalid).
402 if (!Arg.data() || Arg == "true" || Arg == "1") {
403 Value = TrueVal;
404 return false;
405 }
406
407 if (Arg == "false" || Arg == "0") {
408 Value = FalseVal;
409 return false;
410 }
411 return O.error("'" + Arg +
412 "' is invalid value for boolean argument! Try 0 or 1");
413}
414
416 globalParser().addLiteralOption(O, Name);
417}
418
420 globalParser().MoreHelp.push_back(Help);
421}
422
424 : NumOccurrences(0), Occurrences(OccurrencesFlag), Value(0),
425 HiddenFlag(Hidden), Formatting(NormalFormatting), Misc(0),
426 FullyInitialized(false), Position(0) {
427 Categories.push_back(&getGeneralCategory());
428}
429
431 globalParser().addOption(this);
432 FullyInitialized = true;
433}
434
435void Option::removeArgument() { globalParser().removeOption(this); }
436
438 if (FullyInitialized)
439 globalParser().updateArgStr(this, S);
440 assert(!S.starts_with("-") && "Option can't start with '-");
441 ArgStr = S;
442}
443
445 assert(!Categories.empty() && "Categories cannot be empty.");
446 // Maintain backward compatibility by replacing the default GeneralCategory
447 // if it's still set. Otherwise, just add the new one. The GeneralCategory
448 // must be explicitly added if you want multiple categories that include it.
449 if (&C != &getGeneralCategory() && Categories[0] == &getGeneralCategory())
450 Categories[0] = &C;
451 else if (!is_contained(Categories, &C))
452 Categories.push_back(&C);
453}
454
456 NumOccurrences = 0;
457 setDefault();
458}
459
460void OptionCategory::registerCategory() {
461 globalParser().registerCategory(this);
462}
463
464// A special subcommand representing no subcommand. It is kept as a
465// block-scope static because it is referenced from cl::opt constructors,
466// which run dynamically in an arbitrary order across translation units;
467// block-scope statics are initialized on first use and therefore have no
468// initialization-order hazard.
470 static ManagedStatic<SubCommand> TopLevelSubCommand;
471 return *TopLevelSubCommand;
472}
473
474// A special subcommand that can be used to put an option into all subcommands.
476 static ManagedStatic<SubCommand> AllSubCommands;
477 return *AllSubCommands;
478}
479
481 globalParser().registerSubCommand(this);
482}
483
485 globalParser().unregisterSubCommand(this);
486}
487
489 PositionalOpts.clear();
490 OptionsMap.clear();
491
492 ConsumeAfterOpt = nullptr;
493}
494
495SubCommand::operator bool() const {
496 return (globalParser().getActiveSubCommand() == this);
497}
498
499//===----------------------------------------------------------------------===//
500// Basic, shared command line option processing machinery.
501//
502
503/// LookupOption - Lookup the option specified by the specified option on the
504/// command line. If there is a value specified (after an equal sign) return
505/// that as well. This assumes that leading dashes have already been stripped.
506Option *CommandLineParser::LookupOption(SubCommand &Sub, StringRef &Arg,
507 StringRef &Value) {
508 // Reject all dashes.
509 if (Arg.empty())
510 return nullptr;
512
513 size_t EqualPos = Arg.find('=');
514
515 // If we have an equals sign, remember the value.
516 if (EqualPos == StringRef::npos) {
517 // Look up the option.
518 return Sub.OptionsMap.lookup(Arg);
519 }
520
521 // If the argument before the = is a valid option name and the option allows
522 // non-prefix form (ie is not AlwaysPrefix), we match. If not, signal match
523 // failure by returning nullptr.
524 auto I = Sub.OptionsMap.find(Arg.substr(0, EqualPos));
525 if (I == Sub.OptionsMap.end())
526 return nullptr;
527
528 auto *O = I->second;
529 if (O->getFormattingFlag() == cl::AlwaysPrefix)
530 return nullptr;
531
532 Value = Arg.substr(EqualPos + 1);
533 Arg = Arg.substr(0, EqualPos);
534 return I->second;
535}
536
537SubCommand *CommandLineParser::LookupSubCommand(StringRef Name,
538 std::string &NearestString) {
539 if (Name.empty())
540 return &SubCommand::getTopLevel();
541 // Find a subcommand with the edit distance == 1.
542 SubCommand *NearestMatch = nullptr;
543 for (auto *S : RegisteredSubCommands) {
544 assert(S != &SubCommand::getAll() &&
545 "SubCommand::getAll() is not expected in RegisteredSubCommands");
546 if (S->getName().empty())
547 continue;
548
549 if (S->getName() == Name)
550 return S;
551
552 if (!NearestMatch && S->getName().edit_distance(Name) < 2)
553 NearestMatch = S;
554 }
555
556 if (NearestMatch)
557 NearestString = NearestMatch->getName();
558
559 return &SubCommand::getTopLevel();
560}
561
562/// LookupNearestOption - Lookup the closest match to the option specified by
563/// the specified option on the command line. If there is a value specified
564/// (after an equal sign) return that as well. This assumes that leading dashes
565/// have already been stripped.
567 const OptionsMapTy &OptionsMap,
568 std::string &NearestString) {
569 // Reject all dashes.
570 if (Arg.empty())
571 return nullptr;
572
573 // Split on any equal sign.
574 std::pair<StringRef, StringRef> SplitArg = Arg.split('=');
575 StringRef &LHS = SplitArg.first; // LHS == Arg when no '=' is present.
576 StringRef &RHS = SplitArg.second;
577
578 // Find the closest match.
579 Option *Best = nullptr;
580 unsigned BestDistance = 0;
581 for (const auto &[_, O] : OptionsMap) {
582 // Do not suggest really hidden options (not shown in any help).
583 if (O->getOptionHiddenFlag() == ReallyHidden)
584 continue;
585
586 SmallVector<StringRef, 16> OptionNames;
587 O->getExtraOptionNames(OptionNames);
588 if (O->hasArgStr())
589 OptionNames.push_back(O->ArgStr);
590
591 bool PermitValue = O->getValueExpectedFlag() != cl::ValueDisallowed;
592 StringRef Flag = PermitValue ? LHS : Arg;
593 for (const auto &Name : OptionNames) {
594 unsigned Distance = StringRef(Name).edit_distance(
595 Flag, /*AllowReplacements=*/true, /*MaxEditDistance=*/BestDistance);
596 if (!Best || Distance < BestDistance) {
597 Best = O;
598 BestDistance = Distance;
599 if (RHS.empty() || !PermitValue)
600 NearestString = std::string(Name);
601 else
602 NearestString = (Twine(Name) + "=" + RHS).str();
603 }
604 }
605 }
606
607 return Best;
608}
609
610/// CommaSeparateAndAddOccurrence - A wrapper around Handler->addOccurrence()
611/// that does special handling of cl::CommaSeparated options.
612static bool CommaSeparateAndAddOccurrence(Option *Handler, unsigned pos,
613 StringRef ArgName, StringRef Value) {
614 // Check to see if this option accepts a comma separated list of values. If
615 // it does, we have to split up the value into multiple values.
616 if (Handler->getMiscFlags() & CommaSeparated) {
617 StringRef Val(Value);
618 StringRef::size_type Pos = Val.find(',');
619
620 while (Pos != StringRef::npos) {
621 // Process the portion before the comma.
622 if (Handler->addOccurrence(pos, ArgName, Val.substr(0, Pos)))
623 return true;
624 // Erase the portion before the comma, AND the comma.
625 Val = Val.substr(Pos + 1);
626 // Check for another comma.
627 Pos = Val.find(',');
628 }
629
630 Value = Val;
631 }
632
633 return Handler->addOccurrence(pos, ArgName, Value);
634}
635
636/// ProvideOption - For Value, this differentiates between an empty value ("")
637/// and a null value (StringRef()). The later is accepted for arguments that
638/// don't allow a value (-foo) the former is rejected (-foo=).
639static inline bool ProvideOption(Option *Handler, StringRef ArgName,
640 StringRef Value, int argc,
641 const char *const *argv, int &i) {
642 // Enforce value requirements
643 switch (Handler->getValueExpectedFlag()) {
644 case ValueRequired:
645 if (!Value.data()) { // No value specified?
646 // If no other argument or the option only supports prefix form, we
647 // cannot look at the next argument.
648 if (i + 1 >= argc || Handler->getFormattingFlag() == cl::AlwaysPrefix)
649 return Handler->error("requires a value!");
650 // Steal the next argument, like for '-o filename'
651 assert(argv && "null check");
652 Value = StringRef(argv[++i]);
653 }
654 break;
655 case ValueDisallowed:
656 if (Value.data())
657 return Handler->error("does not allow a value! '" + Twine(Value) +
658 "' specified.");
659 break;
660 case ValueOptional:
661 break;
662 }
663
664 return CommaSeparateAndAddOccurrence(Handler, i, ArgName, Value);
665}
666
668 int Dummy = i;
669 return ProvideOption(Handler, Handler->ArgStr, Arg, 0, nullptr, Dummy);
670}
671
672// Find the cl::Prefix or cl::AlwaysPrefix option whose name is the longest
673// prefix of Name.
675 const OptionsMapTy &OptionsMap) {
676 for (; !Name.empty(); Name = Name.drop_back()) {
677 Option *O = OptionsMap.lookup(Name);
678 if (O && (O->getFormattingFlag() == cl::Prefix ||
679 O->getFormattingFlag() == cl::AlwaysPrefix)) {
680 Length = Name.size();
681 return O;
682 }
683 }
684 return nullptr;
685}
686
687/// The specified argument string (which started with at least one '-') does not
688/// fully match an available option. Check to see if this is a prefix option.
689/// If so, split arg into output an Arg/Value pair and return the Option to
690/// parse it with.
692 const OptionsMapTy &OptionsMap) {
693 if (Arg.size() == 1)
694 return nullptr;
695
696 size_t Length = 0;
697 Option *POpt = findPrefixOption(Arg, Length, OptionsMap);
698 if (!POpt)
699 return nullptr;
700
701 StringRef MaybeValue =
702 (Length < Arg.size()) ? Arg.substr(Length) : StringRef();
703 Arg = Arg.substr(0, Length);
704
705 // cl::Prefix options do not preserve '=' when used separately.
706 if (POpt->getFormattingFlag() == cl::Prefix && MaybeValue.starts_with("="))
707 MaybeValue = MaybeValue.drop_front();
708 Value = MaybeValue;
709 return POpt;
710}
711
712static bool RequiresValue(const Option *O) {
713 return O->getNumOccurrencesFlag() == cl::Required ||
714 O->getNumOccurrencesFlag() == cl::OneOrMore;
715}
716
717static bool EatsUnboundedNumberOfValues(const Option *O) {
718 return O->getNumOccurrencesFlag() == cl::ZeroOrMore ||
719 O->getNumOccurrencesFlag() == cl::OneOrMore;
720}
721
722static bool isWhitespace(char C) {
723 return C == ' ' || C == '\t' || C == '\r' || C == '\n';
724}
725
726static bool isWhitespaceOrNull(char C) {
727 return isWhitespace(C) || C == '\0';
728}
729
730static bool isQuote(char C) { return C == '\"' || C == '\''; }
731
734 bool MarkEOLs) {
735 SmallString<128> Token;
736 bool InToken = false;
737 for (size_t I = 0, E = Src.size(); I != E; ++I) {
738 // Consume runs of whitespace.
739 if (!InToken) {
740 while (I != E && isWhitespace(Src[I])) {
741 // Mark the end of lines in response files.
742 if (MarkEOLs && Src[I] == '\n')
743 NewArgv.push_back(nullptr);
744 ++I;
745 }
746 if (I == E)
747 break;
748 InToken = true;
749 }
750
751 char C = Src[I];
752
753 // Backslash escapes the next character.
754 if (I + 1 < E && C == '\\') {
755 ++I; // Skip the escape.
756 Token.push_back(Src[I]);
757 continue;
758 }
759
760 // Consume a quoted string.
761 if (isQuote(C)) {
762 ++I;
763 while (I != E && Src[I] != C) {
764 // Backslash escapes the next character.
765 if (Src[I] == '\\' && I + 1 != E)
766 ++I;
767 Token.push_back(Src[I]);
768 ++I;
769 }
770 if (I == E)
771 break;
772 continue;
773 }
774
775 // End the token if this is whitespace.
776 if (isWhitespace(C)) {
777 NewArgv.push_back(Saver.save(Token.str()).data());
778 // Mark the end of lines in response files.
779 if (MarkEOLs && C == '\n')
780 NewArgv.push_back(nullptr);
781 Token.clear();
782 InToken = false;
783 continue;
784 }
785
786 // This is a normal character. Append it.
787 Token.push_back(C);
788 }
789
790 // Append the last token after hitting EOF with no whitespace.
791 if (InToken)
792 NewArgv.push_back(Saver.save(Token.str()).data());
793}
794
795/// Backslashes are interpreted in a rather complicated way in the Windows-style
796/// command line, because backslashes are used both to separate path and to
797/// escape double quote. This method consumes runs of backslashes as well as the
798/// following double quote if it's escaped.
799///
800/// * If an even number of backslashes is followed by a double quote, one
801/// backslash is output for every pair of backslashes, and the last double
802/// quote remains unconsumed. The double quote will later be interpreted as
803/// the start or end of a quoted string in the main loop outside of this
804/// function.
805///
806/// * If an odd number of backslashes is followed by a double quote, one
807/// backslash is output for every pair of backslashes, and a double quote is
808/// output for the last pair of backslash-double quote. The double quote is
809/// consumed in this case.
810///
811/// * Otherwise, backslashes are interpreted literally.
812static size_t parseBackslash(StringRef Src, size_t I, SmallString<128> &Token) {
813 size_t E = Src.size();
814 int BackslashCount = 0;
815 // Skip the backslashes.
816 do {
817 ++I;
818 ++BackslashCount;
819 } while (I != E && Src[I] == '\\');
820
821 bool FollowedByDoubleQuote = (I != E && Src[I] == '"');
822 if (FollowedByDoubleQuote) {
823 Token.append(BackslashCount / 2, '\\');
824 if (BackslashCount % 2 == 0)
825 return I - 1;
826 Token.push_back('"');
827 return I;
828 }
829 Token.append(BackslashCount, '\\');
830 return I - 1;
831}
832
833// Windows treats whitespace, double quotes, and backslashes specially, except
834// when parsing the first token of a full command line, in which case
835// backslashes are not special.
836static bool isWindowsSpecialChar(char C) {
837 return isWhitespaceOrNull(C) || C == '\\' || C == '\"';
838}
840 return isWhitespaceOrNull(C) || C == '\"';
841}
842
843// Windows tokenization implementation. The implementation is designed to be
844// inlined and specialized for the two user entry points.
846 StringRef Src, StringSaver &Saver, function_ref<void(StringRef)> AddToken,
847 bool AlwaysCopy, function_ref<void()> MarkEOL, bool InitialCommandName) {
848 SmallString<128> Token;
849
850 // Sometimes, this function will be handling a full command line including an
851 // executable pathname at the start. In that situation, the initial pathname
852 // needs different handling from the following arguments, because when
853 // CreateProcess or cmd.exe scans the pathname, it doesn't treat \ as
854 // escaping the quote character, whereas when libc scans the rest of the
855 // command line, it does.
856 bool CommandName = InitialCommandName;
857
858 // Try to do as much work inside the state machine as possible.
859 enum { INIT, UNQUOTED, QUOTED } State = INIT;
860
861 for (size_t I = 0, E = Src.size(); I < E; ++I) {
862 switch (State) {
863 case INIT: {
864 assert(Token.empty() && "token should be empty in initial state");
865 // Eat whitespace before a token.
866 while (I < E && isWhitespaceOrNull(Src[I])) {
867 if (Src[I] == '\n')
868 MarkEOL();
869 ++I;
870 }
871 // Stop if this was trailing whitespace.
872 if (I >= E)
873 break;
874 size_t Start = I;
875 if (CommandName) {
876 while (I < E && !isWindowsSpecialCharInCommandName(Src[I]))
877 ++I;
878 } else {
879 while (I < E && !isWindowsSpecialChar(Src[I]))
880 ++I;
881 }
882 StringRef NormalChars = Src.slice(Start, I);
883 if (I >= E || isWhitespaceOrNull(Src[I])) {
884 // No special characters: slice out the substring and start the next
885 // token. Copy the string if the caller asks us to.
886 AddToken(AlwaysCopy ? Saver.save(NormalChars) : NormalChars);
887 if (I < E && Src[I] == '\n') {
888 MarkEOL();
889 CommandName = InitialCommandName;
890 } else {
891 CommandName = false;
892 }
893 } else if (Src[I] == '\"') {
894 Token += NormalChars;
895 State = QUOTED;
896 } else if (Src[I] == '\\') {
897 assert(!CommandName && "or else we'd have treated it as a normal char");
898 Token += NormalChars;
899 I = parseBackslash(Src, I, Token);
900 State = UNQUOTED;
901 } else {
902 llvm_unreachable("unexpected special character");
903 }
904 break;
905 }
906
907 case UNQUOTED:
908 if (isWhitespaceOrNull(Src[I])) {
909 // Whitespace means the end of the token. If we are in this state, the
910 // token must have contained a special character, so we must copy the
911 // token.
912 AddToken(Saver.save(Token.str()));
913 Token.clear();
914 if (Src[I] == '\n') {
915 CommandName = InitialCommandName;
916 MarkEOL();
917 } else {
918 CommandName = false;
919 }
920 State = INIT;
921 } else if (Src[I] == '\"') {
922 State = QUOTED;
923 } else if (Src[I] == '\\' && !CommandName) {
924 I = parseBackslash(Src, I, Token);
925 } else {
926 Token.push_back(Src[I]);
927 }
928 break;
929
930 case QUOTED:
931 if (Src[I] == '\"') {
932 if (I < (E - 1) && Src[I + 1] == '"') {
933 // Consecutive double-quotes inside a quoted string implies one
934 // double-quote.
935 Token.push_back('"');
936 ++I;
937 } else {
938 // Otherwise, end the quoted portion and return to the unquoted state.
939 State = UNQUOTED;
940 }
941 } else if (Src[I] == '\\' && !CommandName) {
942 I = parseBackslash(Src, I, Token);
943 } else {
944 Token.push_back(Src[I]);
945 }
946 break;
947 }
948 }
949
950 if (State != INIT)
951 AddToken(Saver.save(Token.str()));
952}
953
956 bool MarkEOLs) {
957 auto AddToken = [&](StringRef Tok) { NewArgv.push_back(Tok.data()); };
958 auto OnEOL = [&]() {
959 if (MarkEOLs)
960 NewArgv.push_back(nullptr);
961 };
962 tokenizeWindowsCommandLineImpl(Src, Saver, AddToken,
963 /*AlwaysCopy=*/true, OnEOL, false);
964}
965
968 auto AddToken = [&](StringRef Tok) { NewArgv.push_back(Tok); };
969 auto OnEOL = []() {};
970 tokenizeWindowsCommandLineImpl(Src, Saver, AddToken, /*AlwaysCopy=*/false,
971 OnEOL, false);
972}
973
976 bool MarkEOLs) {
977 auto AddToken = [&](StringRef Tok) { NewArgv.push_back(Tok.data()); };
978 auto OnEOL = [&]() {
979 if (MarkEOLs)
980 NewArgv.push_back(nullptr);
981 };
982 tokenizeWindowsCommandLineImpl(Src, Saver, AddToken,
983 /*AlwaysCopy=*/true, OnEOL, true);
984}
985
988 bool MarkEOLs) {
989 for (const char *Cur = Source.begin(); Cur != Source.end();) {
990 SmallString<128> Line;
991 // Check for comment line.
992 if (isWhitespace(*Cur)) {
993 while (Cur != Source.end() && isWhitespace(*Cur))
994 ++Cur;
995 continue;
996 }
997 if (*Cur == '#') {
998 while (Cur != Source.end() && *Cur != '\n')
999 ++Cur;
1000 continue;
1001 }
1002 // Find end of the current line.
1003 const char *Start = Cur;
1004 for (const char *End = Source.end(); Cur != End; ++Cur) {
1005 if (*Cur == '\\') {
1006 if (Cur + 1 != End) {
1007 ++Cur;
1008 if (*Cur == '\n' ||
1009 (*Cur == '\r' && (Cur + 1 != End) && Cur[1] == '\n')) {
1010 Line.append(Start, Cur - 1);
1011 if (*Cur == '\r')
1012 ++Cur;
1013 Start = Cur + 1;
1014 }
1015 }
1016 } else if (*Cur == '\n')
1017 break;
1018 }
1019 // Tokenize line.
1020 Line.append(Start, Cur);
1021 cl::TokenizeGNUCommandLine(Line, Saver, NewArgv, MarkEOLs);
1022 }
1023}
1024
1025// It is called byte order marker but the UTF-8 BOM is actually not affected
1026// by the host system's endianness.
1028 return (S.size() >= 3 && S[0] == '\xef' && S[1] == '\xbb' && S[2] == '\xbf');
1029}
1030
1031// Substitute <CFGDIR> with the file's base path.
1032static void ExpandBasePaths(StringRef BasePath, StringSaver &Saver,
1033 const char *&Arg) {
1034 assert(sys::path::is_absolute(BasePath));
1035 constexpr StringLiteral Token("<CFGDIR>");
1036 const StringRef ArgString(Arg);
1037
1038 SmallString<128> ResponseFile;
1039 StringRef::size_type StartPos = 0;
1040 for (StringRef::size_type TokenPos = ArgString.find(Token);
1041 TokenPos != StringRef::npos;
1042 TokenPos = ArgString.find(Token, StartPos)) {
1043 // Token may appear more than once per arg (e.g. comma-separated linker
1044 // args). Support by using path-append on any subsequent appearances.
1045 const StringRef LHS = ArgString.substr(StartPos, TokenPos - StartPos);
1046 if (ResponseFile.empty())
1047 ResponseFile = LHS;
1048 else
1049 llvm::sys::path::append(ResponseFile, LHS);
1050 ResponseFile.append(BasePath);
1051 StartPos = TokenPos + Token.size();
1052 }
1053
1054 if (!ResponseFile.empty()) {
1055 // Path-append the remaining arg substring if at least one token appeared.
1056 const StringRef Remaining = ArgString.substr(StartPos);
1057 if (!Remaining.empty())
1058 llvm::sys::path::append(ResponseFile, Remaining);
1059 Arg = Saver.save(ResponseFile.str()).data();
1060 }
1061}
1062
1063// FName must be an absolute path.
1064Error ExpansionContext::expandResponseFile(
1065 StringRef FName, SmallVectorImpl<const char *> &NewArgv) {
1067 llvm::ErrorOr<std::unique_ptr<MemoryBuffer>> MemBufOrErr =
1068 FS->getBufferForFile(FName);
1069 if (!MemBufOrErr) {
1070 std::error_code EC = MemBufOrErr.getError();
1071 return llvm::createStringError(EC, Twine("cannot not open file '") + FName +
1072 "': " + EC.message());
1073 }
1074 MemoryBuffer &MemBuf = *MemBufOrErr.get();
1075 StringRef Str(MemBuf.getBufferStart(), MemBuf.getBufferSize());
1076
1077 // If we have a UTF-16 byte order mark, convert to UTF-8 for parsing.
1078 ArrayRef<char> BufRef(MemBuf.getBufferStart(), MemBuf.getBufferEnd());
1079 std::string UTF8Buf;
1080 if (hasUTF16ByteOrderMark(BufRef)) {
1081 if (!convertUTF16ToUTF8String(BufRef, UTF8Buf))
1082 return llvm::createStringError(std::errc::illegal_byte_sequence,
1083 "Could not convert UTF16 to UTF8");
1084 Str = StringRef(UTF8Buf);
1085 }
1086 // If we see UTF-8 BOM sequence at the beginning of a file, we shall remove
1087 // these bytes before parsing.
1088 // Reference: http://en.wikipedia.org/wiki/UTF-8#Byte_order_mark
1089 else if (hasUTF8ByteOrderMark(BufRef))
1090 Str = StringRef(BufRef.data() + 3, BufRef.size() - 3);
1091
1092 // Tokenize the contents into NewArgv.
1093 Tokenizer(Str, Saver, NewArgv, MarkEOLs);
1094
1095 // Expanded file content may require additional transformations, like using
1096 // absolute paths instead of relative in '@file' constructs or expanding
1097 // macros.
1098 if (!RelativeNames && !InConfigFile)
1099 return Error::success();
1100
1101 StringRef BasePath = llvm::sys::path::parent_path(FName);
1102 for (const char *&Arg : NewArgv) {
1103 if (!Arg)
1104 continue;
1105
1106 // Substitute <CFGDIR> with the file's base path.
1107 if (InConfigFile)
1108 ExpandBasePaths(BasePath, Saver, Arg);
1109
1110 // Discover the case, when argument should be transformed into '@file' and
1111 // evaluate 'file' for it.
1112 StringRef ArgStr(Arg);
1113 StringRef FileName;
1114 bool ConfigInclusion = false;
1115 if (ArgStr.consume_front("@")) {
1116 FileName = ArgStr;
1117 if (!llvm::sys::path::is_relative(FileName))
1118 continue;
1119 } else if (ArgStr.consume_front("--config=")) {
1120 FileName = ArgStr;
1121 ConfigInclusion = true;
1122 } else {
1123 continue;
1124 }
1125
1126 // Update expansion construct.
1127 SmallString<128> ResponseFile;
1128 ResponseFile.push_back('@');
1129 if (ConfigInclusion && !llvm::sys::path::has_parent_path(FileName)) {
1130 SmallString<128> FilePath;
1131 if (!findConfigFile(FileName, FilePath))
1132 return createStringError(
1133 std::make_error_code(std::errc::no_such_file_or_directory),
1134 "cannot not find configuration file: " + FileName);
1135 ResponseFile.append(FilePath);
1136 } else {
1137 ResponseFile.append(BasePath);
1138 llvm::sys::path::append(ResponseFile, FileName);
1139 }
1140 Arg = Saver.save(ResponseFile.str()).data();
1141 }
1142 return Error::success();
1143}
1144
1145/// Expand response files on a command line recursively using the given
1146/// StringSaver and tokenization strategy.
1149 struct ResponseFileRecord {
1150 std::string File;
1151 size_t End;
1152 };
1153
1154 // To detect recursive response files, we maintain a stack of files and the
1155 // position of the last argument in the file. This position is updated
1156 // dynamically as we recursively expand files.
1158
1159 // Push a dummy entry that represents the initial command line, removing
1160 // the need to check for an empty list.
1161 FileStack.push_back({"", Argv.size()});
1162
1163 // Don't cache Argv.size() because it can change.
1164 for (unsigned I = 0; I != Argv.size();) {
1165 while (I == FileStack.back().End) {
1166 // Passing the end of a file's argument list, so we can remove it from the
1167 // stack.
1168 FileStack.pop_back();
1169 }
1170
1171 const char *Arg = Argv[I];
1172 // Check if it is an EOL marker
1173 if (Arg == nullptr) {
1174 ++I;
1175 continue;
1176 }
1177
1178 if (Arg[0] != '@') {
1179 ++I;
1180 continue;
1181 }
1182
1183 const char *FName = Arg + 1;
1184 // Note that CurrentDir is only used for top-level rsp files, the rest will
1185 // always have an absolute path deduced from the containing file.
1186 SmallString<128> CurrDir;
1187 if (llvm::sys::path::is_relative(FName)) {
1188 if (CurrentDir.empty()) {
1189 if (auto CWD = FS->getCurrentWorkingDirectory()) {
1190 CurrDir = *CWD;
1191 } else {
1192 return createStringError(
1193 CWD.getError(), Twine("cannot get absolute path for: ") + FName);
1194 }
1195 } else {
1196 CurrDir = CurrentDir;
1197 }
1198 llvm::sys::path::append(CurrDir, FName);
1199 FName = CurrDir.c_str();
1200 }
1201
1202 ErrorOr<llvm::vfs::Status> Res = FS->status(FName);
1203 if (!Res || !Res->exists()) {
1204 std::error_code EC = Res.getError();
1205 if (!InConfigFile) {
1206 // If the specified file does not exist, leave '@file' unexpanded, as
1207 // libiberty does.
1208 if (!EC || EC == llvm::errc::no_such_file_or_directory) {
1209 ++I;
1210 continue;
1211 }
1212 }
1213 if (!EC)
1215 return createStringError(EC, Twine("cannot not open file '") + FName +
1216 "': " + EC.message());
1217 }
1218 const llvm::vfs::Status &FileStatus = Res.get();
1219
1220 auto IsEquivalent =
1221 [FileStatus, this](const ResponseFileRecord &RFile) -> ErrorOr<bool> {
1222 ErrorOr<llvm::vfs::Status> RHS = FS->status(RFile.File);
1223 if (!RHS)
1224 return RHS.getError();
1225 return FileStatus.equivalent(*RHS);
1226 };
1227
1228 // Check for recursive response files.
1229 for (const auto &F : drop_begin(FileStack)) {
1230 if (ErrorOr<bool> R = IsEquivalent(F)) {
1231 if (R.get())
1232 return createStringError(
1233 R.getError(), Twine("recursive expansion of: '") + F.File + "'");
1234 } else {
1235 return createStringError(R.getError(),
1236 Twine("cannot open file: ") + F.File);
1237 }
1238 }
1239
1240 // Replace this response file argument with the tokenization of its
1241 // contents. Nested response files are expanded in subsequent iterations.
1242 SmallVector<const char *, 0> ExpandedArgv;
1243 if (Error Err = expandResponseFile(FName, ExpandedArgv))
1244 return Err;
1245
1246 for (ResponseFileRecord &Record : FileStack) {
1247 // Increase the end of all active records by the number of newly expanded
1248 // arguments, minus the response file itself.
1249 Record.End += ExpandedArgv.size() - 1;
1250 }
1251
1252 FileStack.push_back({FName, I + ExpandedArgv.size()});
1253 Argv.erase(Argv.begin() + I);
1254 Argv.insert(Argv.begin() + I, ExpandedArgv.begin(), ExpandedArgv.end());
1255 }
1256
1257 // If successful, the top of the file stack will mark the end of the Argv
1258 // stream. A failure here indicates a bug in the stack popping logic above.
1259 // Note that FileStack may have more than one element at this point because we
1260 // don't have a chance to pop the stack when encountering recursive files at
1261 // the end of the stream, so seeing that doesn't indicate a bug.
1262 assert(FileStack.size() > 0 && Argv.size() == FileStack.back().End);
1263 return Error::success();
1264}
1265
1266bool cl::expandResponseFiles(int Argc, const char *const *Argv,
1267 const char *EnvVar, StringSaver &Saver,
1269#ifdef _WIN32
1270 auto Tokenize = cl::TokenizeWindowsCommandLine;
1271#else
1272 auto Tokenize = cl::TokenizeGNUCommandLine;
1273#endif
1274 // The environment variable specifies initial options.
1275 if (EnvVar)
1276 if (std::optional<std::string> EnvValue = sys::Process::GetEnv(EnvVar))
1277 Tokenize(*EnvValue, Saver, NewArgv, /*MarkEOLs=*/false);
1278
1279 // Command line options can override the environment variable.
1280 NewArgv.append(Argv + 1, Argv + Argc);
1281 ExpansionContext ECtx(Saver.getAllocator(), Tokenize);
1282 if (Error Err = ECtx.expandResponseFiles(NewArgv)) {
1283 errs() << toString(std::move(Err)) << '\n';
1284 return false;
1285 }
1286 return true;
1287}
1288
1291 ExpansionContext ECtx(Saver.getAllocator(), Tokenizer);
1292 if (Error Err = ECtx.expandResponseFiles(Argv)) {
1293 errs() << toString(std::move(Err)) << '\n';
1294 return false;
1295 }
1296 return true;
1297}
1298
1300 vfs::FileSystem *FS)
1301 : Saver(A), Tokenizer(T), FS(FS ? FS : vfs::getRealFileSystem().get()) {}
1302
1304 SmallVectorImpl<char> &FilePath) {
1305 SmallString<128> CfgFilePath;
1306 const auto FileExists = [this](SmallString<128> Path) -> bool {
1307 auto Status = FS->status(Path);
1308 return Status &&
1310 };
1311
1312 // If file name contains directory separator, treat it as a path to
1313 // configuration file.
1314 if (llvm::sys::path::has_parent_path(FileName)) {
1315 CfgFilePath = FileName;
1316 if (llvm::sys::path::is_relative(FileName) && FS->makeAbsolute(CfgFilePath))
1317 return false;
1318 if (!FileExists(CfgFilePath))
1319 return false;
1320 FilePath.assign(CfgFilePath.begin(), CfgFilePath.end());
1321 return true;
1322 }
1323
1324 // Look for the file in search directories.
1325 for (const StringRef &Dir : SearchDirs) {
1326 if (Dir.empty())
1327 continue;
1328 CfgFilePath.assign(Dir);
1329 llvm::sys::path::append(CfgFilePath, FileName);
1330 llvm::sys::path::native(CfgFilePath);
1331 if (FileExists(CfgFilePath)) {
1332 FilePath.assign(CfgFilePath.begin(), CfgFilePath.end());
1333 return true;
1334 }
1335 }
1336
1337 return false;
1338}
1339
1342 SmallString<128> AbsPath;
1343 if (sys::path::is_relative(CfgFile)) {
1344 AbsPath.assign(CfgFile);
1345 if (std::error_code EC = FS->makeAbsolute(AbsPath))
1347 EC, Twine("cannot get absolute path for " + CfgFile));
1348 CfgFile = AbsPath.str();
1349 }
1350 InConfigFile = true;
1351 RelativeNames = true;
1352 if (Error Err = expandResponseFile(CfgFile, Argv))
1353 return Err;
1354 return expandResponseFiles(Argv);
1355}
1356
1357static void initCommonOptions();
1358bool cl::ParseCommandLineOptions(int argc, const char *const *argv,
1359 StringRef Overview, raw_ostream *Errs,
1360 vfs::FileSystem *VFS, const char *EnvVar) {
1364 StringSaver Saver(A);
1365 NewArgv.push_back(argv[0]);
1366
1367 // Parse options from environment variable.
1368 if (EnvVar) {
1369 if (std::optional<std::string> EnvValue =
1371 TokenizeGNUCommandLine(*EnvValue, Saver, NewArgv);
1372 }
1373
1374 // Append options from command line.
1375 for (int I = 1; I < argc; ++I)
1376 NewArgv.push_back(argv[I]);
1377 int NewArgc = static_cast<int>(NewArgv.size());
1378
1379 // Parse all options.
1380 return globalParser().ParseCommandLineOptions(NewArgc, &NewArgv[0], Overview,
1381 Errs, VFS);
1382}
1383
1384/// Reset all options at least once, so that we can parse different options.
1385void CommandLineParser::ResetAllOptionOccurrences() {
1386 // Reset all option values to look like they have never been seen before.
1387 // Options might be reset twice (they can be reference in both OptionsMap
1388 // and one of the other members), but that does not harm.
1389 for (auto *SC : RegisteredSubCommands) {
1390 // reset() removes default options from OptionsMap (via removeArgument), so
1391 // collect the options first to avoid invalidating the map iterator.
1393 Opts.reserve(SC->OptionsMap.size());
1394 for (auto &O : SC->OptionsMap)
1395 Opts.push_back(O.second);
1396 for (Option *O : Opts)
1397 O->reset();
1398 for (Option *O : SC->PositionalOpts)
1399 O->reset();
1400 if (SC->ConsumeAfterOpt)
1401 SC->ConsumeAfterOpt->reset();
1402 }
1403}
1404
1405bool CommandLineParser::ParseCommandLineOptions(int argc,
1406 const char *const *argv,
1407 StringRef Overview,
1408 raw_ostream *Errs,
1409 vfs::FileSystem *VFS) {
1410 assert(hasOptions() && "No options specified!");
1411
1412 ProgramOverview = Overview;
1413 bool IgnoreErrors = Errs;
1414 if (!Errs)
1415 Errs = &errs();
1416 if (!VFS)
1417 VFS = vfs::getRealFileSystem().get();
1418 bool ErrorParsing = false;
1419
1420 // Expand response files.
1421 SmallVector<const char *, 20> newArgv(argv, argv + argc);
1423#ifdef _WIN32
1424 auto Tokenize = cl::TokenizeWindowsCommandLine;
1425#else
1426 auto Tokenize = cl::TokenizeGNUCommandLine;
1427#endif
1428 ExpansionContext ECtx(A, Tokenize, VFS);
1429 if (Error Err = ECtx.expandResponseFiles(newArgv)) {
1430 *Errs << toString(std::move(Err)) << '\n';
1431 return false;
1432 }
1433 argv = &newArgv[0];
1434 argc = static_cast<int>(newArgv.size());
1435
1436 // Copy the program name into ProgName, making sure not to overflow it.
1437 ProgramName = std::string(sys::path::filename(StringRef(argv[0])));
1438
1439 // Check out the positional arguments to collect information about them.
1440 unsigned NumPositionalRequired = 0;
1441
1442 // Determine whether or not there are an unlimited number of positionals
1443 bool HasUnlimitedPositionals = false;
1444
1445 int FirstArg = 1;
1446 SubCommand *ChosenSubCommand = &SubCommand::getTopLevel();
1447 std::string NearestSubCommandString;
1448 bool MaybeNamedSubCommand =
1449 argc >= 2 && argv[FirstArg][0] != '-' && hasNamedSubCommands();
1450 if (MaybeNamedSubCommand) {
1451 // If the first argument specifies a valid subcommand, start processing
1452 // options from the second argument.
1453 ChosenSubCommand =
1454 LookupSubCommand(StringRef(argv[FirstArg]), NearestSubCommandString);
1455 if (ChosenSubCommand != &SubCommand::getTopLevel())
1456 FirstArg = 2;
1457 }
1458 globalParser().ActiveSubCommand = ChosenSubCommand;
1459
1460 assert(ChosenSubCommand);
1461 auto &ConsumeAfterOpt = ChosenSubCommand->ConsumeAfterOpt;
1462 auto &PositionalOpts = ChosenSubCommand->PositionalOpts;
1463 auto &OptionsMap = ChosenSubCommand->OptionsMap;
1464
1465 if (ConsumeAfterOpt) {
1466 assert(PositionalOpts.size() > 0 &&
1467 "Cannot specify cl::ConsumeAfter without a positional argument!");
1468 }
1469 if (!PositionalOpts.empty()) {
1470
1471 // Calculate how many positional values are _required_.
1472 bool UnboundedFound = false;
1473 for (size_t i = 0, e = PositionalOpts.size(); i != e; ++i) {
1474 Option *Opt = PositionalOpts[i];
1475 if (RequiresValue(Opt))
1476 ++NumPositionalRequired;
1477 else if (ConsumeAfterOpt) {
1478 // ConsumeAfter cannot be combined with "optional" positional options
1479 // unless there is only one positional argument...
1480 if (PositionalOpts.size() > 1) {
1481 if (!IgnoreErrors)
1482 Opt->error("error - this positional option will never be matched, "
1483 "because it does not Require a value, and a "
1484 "cl::ConsumeAfter option is active!");
1485 ErrorParsing = true;
1486 }
1487 } else if (UnboundedFound && !Opt->hasArgStr()) {
1488 // This option does not "require" a value... Make sure this option is
1489 // not specified after an option that eats all extra arguments, or this
1490 // one will never get any!
1491 //
1492 if (!IgnoreErrors)
1493 Opt->error("error - option can never match, because "
1494 "another positional argument will match an "
1495 "unbounded number of values, and this option"
1496 " does not require a value!");
1497 *Errs << ProgramName << ": CommandLine Error: Option '" << Opt->ArgStr
1498 << "' is all messed up!\n";
1499 *Errs << PositionalOpts.size();
1500 ErrorParsing = true;
1501 }
1502 UnboundedFound |= EatsUnboundedNumberOfValues(Opt);
1503 }
1504 HasUnlimitedPositionals = UnboundedFound || ConsumeAfterOpt;
1505 }
1506
1507 // PositionalVals - A vector of "positional" arguments we accumulate into
1508 // the process at the end.
1509 //
1511
1512 // If the program has named positional arguments, and the name has been run
1513 // across, keep track of which positional argument was named. Otherwise put
1514 // the positional args into the PositionalVals list...
1515 Option *ActivePositionalArg = nullptr;
1516
1517 // Loop over all of the arguments... processing them.
1518 bool DashDashFound = false; // Have we read '--'?
1519 for (int i = FirstArg; i < argc; ++i) {
1520 Option *Handler = nullptr;
1521 std::string NearestHandlerString;
1522 StringRef Value;
1523 StringRef ArgName = "";
1524
1525 // Check to see if this is a positional argument. This argument is
1526 // considered to be positional if it doesn't start with '-', if it is "-"
1527 // itself, or if we have seen "--" already.
1528 //
1529 if (argv[i][0] != '-' || argv[i][1] == 0 || DashDashFound) {
1530 // Positional argument!
1531 if (ActivePositionalArg) {
1532 ProvidePositionalOption(ActivePositionalArg, StringRef(argv[i]), i);
1533 continue; // We are done!
1534 }
1535
1536 if (!PositionalOpts.empty()) {
1537 PositionalVals.push_back(std::make_pair(StringRef(argv[i]), i));
1538
1539 // All of the positional arguments have been fulfulled, give the rest to
1540 // the consume after option... if it's specified...
1541 //
1542 if (PositionalVals.size() >= NumPositionalRequired && ConsumeAfterOpt) {
1543 for (++i; i < argc; ++i)
1544 PositionalVals.push_back(std::make_pair(StringRef(argv[i]), i));
1545 break; // Handle outside of the argument processing loop...
1546 }
1547
1548 // Delay processing positional arguments until the end...
1549 continue;
1550 }
1551 } else if (argv[i][0] == '-' && argv[i][1] == '-' && argv[i][2] == 0 &&
1552 !DashDashFound) {
1553 DashDashFound = true; // This is the mythical "--"?
1554 continue; // Don't try to process it as an argument itself.
1555 } else if (ActivePositionalArg &&
1556 (ActivePositionalArg->getMiscFlags() & PositionalEatsArgs)) {
1557 // If there is a positional argument eating options, check to see if this
1558 // option is another positional argument. If so, treat it as an argument,
1559 // otherwise feed it to the eating positional.
1560 ArgName = StringRef(argv[i] + 1);
1561 // Eat second dash.
1562 ArgName.consume_front("-");
1563
1564 Handler = LookupOption(*ChosenSubCommand, ArgName, Value);
1565 if (!Handler || Handler->getFormattingFlag() != cl::Positional) {
1566 ProvidePositionalOption(ActivePositionalArg, StringRef(argv[i]), i);
1567 continue; // We are done!
1568 }
1569 } else { // We start with a '-', must be an argument.
1570 ArgName = StringRef(argv[i] + 1);
1571 // Eat second dash.
1572 ArgName.consume_front("-");
1573
1574 Handler = LookupOption(*ChosenSubCommand, ArgName, Value);
1575
1576 // If Handler is not found in a specialized subcommand, look up handler
1577 // in the top-level subcommand.
1578 // cl::opt without cl::sub belongs to top-level subcommand.
1579 if (!Handler && ChosenSubCommand != &SubCommand::getTopLevel())
1580 Handler = LookupOption(SubCommand::getTopLevel(), ArgName, Value);
1581
1582 // Check to see if this "option" is really a prefixed argument.
1583 if (!Handler)
1584 Handler = HandlePrefixedOption(ArgName, Value, OptionsMap);
1585
1586 // Otherwise, look for the closest available option to report to the user
1587 // in the upcoming error.
1588 if (!Handler)
1589 LookupNearestOption(ArgName, OptionsMap, NearestHandlerString);
1590 }
1591
1592 if (!Handler) {
1593 auto ReportUnknownArgument = [&](bool IsArg,
1594 StringRef NearestArgumentName) {
1595 *Errs << ProgramName << ": Unknown "
1596 << (IsArg ? "command line argument" : "subcommand") << " '"
1597 << argv[i] << "'. Try: '" << argv[0] << " --help'\n";
1598
1599 if (NearestArgumentName.empty())
1600 return;
1601
1602 *Errs << ProgramName << ": Did you mean '";
1603 if (IsArg)
1604 *Errs << PrintArg(NearestArgumentName, 0);
1605 else
1606 *Errs << NearestArgumentName;
1607 *Errs << "'?\n";
1608 };
1609
1610 if (i > 1 || !MaybeNamedSubCommand)
1611 ReportUnknownArgument(/*IsArg=*/true, NearestHandlerString);
1612 else
1613 ReportUnknownArgument(/*IsArg=*/false, NearestSubCommandString);
1614
1615 ErrorParsing = true;
1616 continue;
1617 }
1618
1619 // If this is a named positional argument, just remember that it is the
1620 // active one...
1621 if (Handler->getFormattingFlag() == cl::Positional) {
1622 if ((Handler->getMiscFlags() & PositionalEatsArgs) && !Value.empty()) {
1623 Handler->error("This argument does not take a value.\n"
1624 "\tInstead, it consumes any positional arguments until "
1625 "the next recognized option.", *Errs);
1626 ErrorParsing = true;
1627 }
1628 ActivePositionalArg = Handler;
1629 }
1630 else
1631 ErrorParsing |= ProvideOption(Handler, ArgName, Value, argc, argv, i);
1632 }
1633
1634 // Check and handle positional arguments now...
1635 if (NumPositionalRequired > PositionalVals.size()) {
1636 *Errs << ProgramName
1637 << ": Not enough positional command line arguments specified!\n"
1638 << "Must specify at least " << NumPositionalRequired
1639 << " positional argument" << (NumPositionalRequired > 1 ? "s" : "")
1640 << ": See: " << argv[0] << " --help\n";
1641
1642 ErrorParsing = true;
1643 } else if (!HasUnlimitedPositionals &&
1644 PositionalVals.size() > PositionalOpts.size()) {
1645 *Errs << ProgramName << ": Too many positional arguments specified!\n"
1646 << "Can specify at most " << PositionalOpts.size()
1647 << " positional arguments: See: " << argv[0] << " --help\n";
1648 ErrorParsing = true;
1649
1650 } else if (!ConsumeAfterOpt) {
1651 // Positional args have already been handled if ConsumeAfter is specified.
1652 unsigned ValNo = 0, NumVals = static_cast<unsigned>(PositionalVals.size());
1653 for (Option *Opt : PositionalOpts) {
1654 if (RequiresValue(Opt)) {
1655 ProvidePositionalOption(Opt, PositionalVals[ValNo].first,
1656 PositionalVals[ValNo].second);
1657 ValNo++;
1658 --NumPositionalRequired; // We fulfilled our duty...
1659 }
1660
1661 // If we _can_ give this option more arguments, do so now, as long as we
1662 // do not give it values that others need. 'Done' controls whether the
1663 // option even _WANTS_ any more.
1664 //
1665 bool Done = Opt->getNumOccurrencesFlag() == cl::Required;
1666 while (NumVals - ValNo > NumPositionalRequired && !Done) {
1667 switch (Opt->getNumOccurrencesFlag()) {
1668 case cl::Optional:
1669 Done = true; // Optional arguments want _at most_ one value
1670 [[fallthrough]];
1671 case cl::ZeroOrMore: // Zero or more will take all they can get...
1672 case cl::OneOrMore: // One or more will take all they can get...
1673 ProvidePositionalOption(Opt, PositionalVals[ValNo].first,
1674 PositionalVals[ValNo].second);
1675 ValNo++;
1676 break;
1677 default:
1678 llvm_unreachable("Internal error, unexpected NumOccurrences flag in "
1679 "positional argument processing!");
1680 }
1681 }
1682 }
1683 } else {
1684 assert(ConsumeAfterOpt && NumPositionalRequired <= PositionalVals.size());
1685 unsigned ValNo = 0;
1686 for (Option *Opt : PositionalOpts)
1687 if (RequiresValue(Opt)) {
1688 ErrorParsing |= ProvidePositionalOption(
1689 Opt, PositionalVals[ValNo].first, PositionalVals[ValNo].second);
1690 ValNo++;
1691 }
1692
1693 // Handle the case where there is just one positional option, and it's
1694 // optional. In this case, we want to give JUST THE FIRST option to the
1695 // positional option and keep the rest for the consume after. The above
1696 // loop would have assigned no values to positional options in this case.
1697 //
1698 if (PositionalOpts.size() == 1 && ValNo == 0 && !PositionalVals.empty()) {
1699 ErrorParsing |= ProvidePositionalOption(PositionalOpts[0],
1700 PositionalVals[ValNo].first,
1701 PositionalVals[ValNo].second);
1702 ValNo++;
1703 }
1704
1705 // Handle over all of the rest of the arguments to the
1706 // cl::ConsumeAfter command line option...
1707 for (; ValNo != PositionalVals.size(); ++ValNo)
1708 ErrorParsing |=
1709 ProvidePositionalOption(ConsumeAfterOpt, PositionalVals[ValNo].first,
1710 PositionalVals[ValNo].second);
1711 }
1712
1713 // Loop over args and make sure all required args are specified!
1714 for (const auto &Opt : OptionsMap) {
1715 switch (Opt.second->getNumOccurrencesFlag()) {
1716 case Required:
1717 case OneOrMore:
1718 if (Opt.second->getNumOccurrences() == 0) {
1719 Opt.second->error("must be specified at least once!");
1720 ErrorParsing = true;
1721 }
1722 [[fallthrough]];
1723 default:
1724 break;
1725 }
1726 }
1727
1728 // Now that we know if -debug is specified, we can use it.
1729 // Note that if ReadResponseFiles == true, this must be done before the
1730 // memory allocated for the expanded command line is free()d below.
1731 LLVM_DEBUG(dbgs() << "Args: ";
1732 for (int i = 0; i < argc; ++i) dbgs() << argv[i] << ' ';
1733 dbgs() << '\n';);
1734
1735 // Free all of the memory allocated to the map. Command line options may only
1736 // be processed once!
1737 MoreHelp.clear();
1738
1739 // If we had an error processing our arguments, don't let the program execute
1740 if (ErrorParsing) {
1741 if (!IgnoreErrors)
1742 exit(1);
1743 return false;
1744 }
1745 return true;
1746}
1747
1748//===----------------------------------------------------------------------===//
1749// Option Base class implementation
1750//
1751
1752bool Option::error(const Twine &Message, StringRef ArgName, raw_ostream &Errs) {
1753 if (!ArgName.data())
1754 ArgName = ArgStr;
1755 if (ArgName.empty())
1756 Errs << HelpStr; // Be nice for positional arguments
1757 else
1758 Errs << globalParser().ProgramName << ": for the " << PrintArg(ArgName, 0);
1759
1760 Errs << " option: " << Message << "\n";
1761 return true;
1762}
1763
1764bool Option::addOccurrence(unsigned pos, StringRef ArgName, StringRef Value) {
1765 ++NumOccurrences;
1766 return handleOccurrence(pos, ArgName, Value);
1767}
1768
1769// getValueStr - Get the value description string, using "DefaultMsg" if nothing
1770// has been specified yet.
1771//
1772static StringRef getValueStr(const Option &O, StringRef DefaultMsg) {
1773 if (O.ValueStr.empty())
1774 return DefaultMsg;
1775 return O.ValueStr;
1776}
1777
1778//===----------------------------------------------------------------------===//
1779// cl::alias class implementation
1780//
1781
1782// Return the width of the option tag for printing...
1783size_t alias::getOptionWidth() const {
1785}
1786
1788 size_t FirstLineIndentedBy) {
1789 assert(Indent >= FirstLineIndentedBy);
1790 std::pair<StringRef, StringRef> Split = HelpStr.split('\n');
1791 outs().indent(Indent - FirstLineIndentedBy)
1792 << ArgHelpPrefix << Split.first << "\n";
1793 while (!Split.second.empty()) {
1794 Split = Split.second.split('\n');
1795 outs().indent(Indent) << Split.first << "\n";
1796 }
1797}
1798
1800 size_t FirstLineIndentedBy) {
1801 const StringRef ValHelpPrefix = " ";
1802 assert(BaseIndent >= FirstLineIndentedBy);
1803 std::pair<StringRef, StringRef> Split = HelpStr.split('\n');
1804 outs().indent(BaseIndent - FirstLineIndentedBy)
1805 << ArgHelpPrefix << ValHelpPrefix << Split.first << "\n";
1806 while (!Split.second.empty()) {
1807 Split = Split.second.split('\n');
1808 outs().indent(BaseIndent + ValHelpPrefix.size()) << Split.first << "\n";
1809 }
1810}
1811
1812// Print out the option for the alias.
1813void alias::printOptionInfo(size_t GlobalWidth) const {
1814 outs() << PrintArg(ArgStr);
1816}
1817
1818//===----------------------------------------------------------------------===//
1819// Parser Implementation code...
1820//
1821
1822// basic_parser implementation
1823//
1824
1825// Return the width of the option tag for printing...
1827 size_t Len = argPlusPrefixesSize(O.ArgStr);
1828 auto ValName = getValueName();
1829 if (!ValName.empty()) {
1830 size_t FormattingLen = 3;
1831 if (O.getMiscFlags() & PositionalEatsArgs)
1832 FormattingLen = 6;
1833 Len += getValueStr(O, ValName).size() + FormattingLen;
1834 }
1835
1836 return Len;
1837}
1838
1839// printOptionInfo - Print out information about this option. The
1840// to-be-maintained width is specified.
1841//
1843 size_t GlobalWidth) const {
1844 outs() << PrintArg(O.ArgStr);
1845
1846 auto ValName = getValueName();
1847 if (!ValName.empty()) {
1848 if (O.getMiscFlags() & PositionalEatsArgs) {
1849 outs() << " <" << getValueStr(O, ValName) << ">...";
1850 } else if (O.getValueExpectedFlag() == ValueOptional)
1851 outs() << "[=<" << getValueStr(O, ValName) << ">]";
1852 else {
1853 outs() << (O.ArgStr.size() == 1 ? " <" : "=<") << getValueStr(O, ValName)
1854 << '>';
1855 }
1856 }
1857
1858 Option::printHelpStr(O.HelpStr, GlobalWidth, getOptionWidth(O));
1859}
1860
1862 size_t GlobalWidth) const {
1863 outs() << PrintArg(O.ArgStr);
1864 outs().indent(GlobalWidth - O.ArgStr.size());
1865}
1866
1867// parser<bool> implementation
1868//
1869bool parser<bool>::parse(Option &O, StringRef ArgName, StringRef Arg,
1870 bool &Value) {
1871 return parseBool<bool, true, false>(O, ArgName, Arg, Value);
1872}
1873
1874// parser<boolOrDefault> implementation
1875//
1879 boolOrDefault::BOU_FALSE>(O, ArgName, Arg, Value);
1880}
1881
1882// parser<FixedOrScalableQuantity> implementation
1883//
1884template <typename FixedOrScalableQuantityT>
1886 StringRef ValueKind,
1887 FixedOrScalableQuantityT &Value) {
1888 using ScalarTy = typename FixedOrScalableQuantityT::ScalarTy;
1889
1890 Arg = Arg.trim();
1891
1892 ScalarTy MinValue;
1893 if (!Arg.getAsInteger(0, MinValue)) {
1894 Value = FixedOrScalableQuantityT::getFixed(MinValue);
1895 return false;
1896 }
1897
1898 StringRef Remainder = Arg;
1899 if (!Remainder.consume_front("vscale"))
1900 return O.error("'" + Arg + "' value invalid for " + ValueKind +
1901 " argument!");
1902
1903 Remainder = Remainder.ltrim();
1904 if (!Remainder.consume_front('x'))
1905 return O.error("'" + Arg + "' value invalid for " + ValueKind +
1906 " argument!");
1907
1908 Remainder = Remainder.ltrim();
1909 if (Remainder.getAsInteger(0, MinValue))
1910 return O.error("'" + Arg + "' value invalid for " + ValueKind +
1911 " argument!");
1912
1913 Value = FixedOrScalableQuantityT::getScalable(MinValue);
1914 return false;
1915}
1916
1917// parser<int> implementation
1918//
1919bool parser<int>::parse(Option &O, StringRef ArgName, StringRef Arg,
1920 int &Value) {
1921 if (Arg.getAsInteger(0, Value))
1922 return O.error("'" + Arg + "' value invalid for integer argument!");
1923 return false;
1924}
1925
1926// parser<long> implementation
1927//
1928bool parser<long>::parse(Option &O, StringRef ArgName, StringRef Arg,
1929 long &Value) {
1930 if (Arg.getAsInteger(0, Value))
1931 return O.error("'" + Arg + "' value invalid for long argument!");
1932 return false;
1933}
1934
1935// parser<long long> implementation
1936//
1937bool parser<long long>::parse(Option &O, StringRef ArgName, StringRef Arg,
1938 long long &Value) {
1939 if (Arg.getAsInteger(0, Value))
1940 return O.error("'" + Arg + "' value invalid for llong argument!");
1941 return false;
1942}
1943
1944// parser<unsigned> implementation
1945//
1946bool parser<unsigned>::parse(Option &O, StringRef ArgName, StringRef Arg,
1947 unsigned &Value) {
1948
1949 if (Arg.getAsInteger(0, Value))
1950 return O.error("'" + Arg + "' value invalid for uint argument!");
1951 return false;
1952}
1953
1954// parser<unsigned long> implementation
1955//
1956bool parser<unsigned long>::parse(Option &O, StringRef ArgName, StringRef Arg,
1957 unsigned long &Value) {
1958
1959 if (Arg.getAsInteger(0, Value))
1960 return O.error("'" + Arg + "' value invalid for ulong argument!");
1961 return false;
1962}
1963
1964// parser<unsigned long long> implementation
1965//
1966bool parser<unsigned long long>::parse(Option &O, StringRef ArgName,
1967 StringRef Arg,
1968 unsigned long long &Value) {
1969
1970 if (Arg.getAsInteger(0, Value))
1971 return O.error("'" + Arg + "' value invalid for ullong argument!");
1972 return false;
1973}
1974
1975// parser<ElementCount> implementation
1976//
1977bool parser<ElementCount>::parse(Option &O, StringRef ArgName, StringRef Arg,
1978 ElementCount &Value) {
1979 return parseFixedOrScalableQuantity(O, Arg, getValueName(), Value);
1980}
1981
1982// parser<double>/parser<float> implementation
1983//
1984static bool parseDouble(Option &O, StringRef Arg, double &Value) {
1985 if (to_float(Arg, Value))
1986 return false;
1987 return O.error("'" + Arg + "' value invalid for floating point argument!");
1988}
1989
1990bool parser<double>::parse(Option &O, StringRef ArgName, StringRef Arg,
1991 double &Val) {
1992 return parseDouble(O, Arg, Val);
1993}
1994
1995bool parser<float>::parse(Option &O, StringRef ArgName, StringRef Arg,
1996 float &Val) {
1997 double dVal;
1998 if (parseDouble(O, Arg, dVal))
1999 return true;
2000 Val = (float)dVal;
2001 return false;
2002}
2003
2004// generic_parser_base implementation
2005//
2006
2007// findOption - Return the option number corresponding to the specified
2008// argument string. If the option is not found, getNumOptions() is returned.
2009//
2011 unsigned e = getNumOptions();
2012
2013 for (unsigned i = 0; i != e; ++i) {
2014 if (getOption(i) == Name)
2015 return i;
2016 }
2017 return e;
2018}
2019
2020static StringRef EqValue = "=<value>";
2021static StringRef EmptyOption = "<empty>";
2023static size_t getOptionPrefixesSize() {
2024 return OptionPrefix.size() + ArgHelpPrefix.size();
2025}
2026
2027static bool shouldPrintOption(StringRef Name, StringRef Description,
2028 const Option &O) {
2029 return O.getValueExpectedFlag() != ValueOptional || !Name.empty() ||
2030 !Description.empty();
2031}
2032
2033// Return the width of the option tag for printing...
2035 if (O.hasArgStr()) {
2036 size_t Size =
2037 argPlusPrefixesSize(O.ArgStr) + EqValue.size();
2038 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
2039 StringRef Name = getOption(i);
2040 if (!shouldPrintOption(Name, getDescription(i), O))
2041 continue;
2042 size_t NameSize = Name.empty() ? EmptyOption.size() : Name.size();
2043 Size = std::max(Size, NameSize + getOptionPrefixesSize());
2044 }
2045 return Size;
2046 } else {
2047 size_t BaseSize = 0;
2048 for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
2049 BaseSize = std::max(BaseSize, getOption(i).size() + 8);
2050 return BaseSize;
2051 }
2052}
2053
2054// printOptionInfo - Print out information about this option. The
2055// to-be-maintained width is specified.
2056//
2058 size_t GlobalWidth) const {
2059 if (O.hasArgStr()) {
2060 // When the value is optional, first print a line just describing the
2061 // option without values.
2062 if (O.getValueExpectedFlag() == ValueOptional) {
2063 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
2064 if (getOption(i).empty()) {
2065 outs() << PrintArg(O.ArgStr);
2066 Option::printHelpStr(O.HelpStr, GlobalWidth,
2067 argPlusPrefixesSize(O.ArgStr));
2068 break;
2069 }
2070 }
2071 }
2072
2073 outs() << PrintArg(O.ArgStr) << EqValue;
2074 Option::printHelpStr(O.HelpStr, GlobalWidth,
2075 EqValue.size() +
2076 argPlusPrefixesSize(O.ArgStr));
2077 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
2078 StringRef OptionName = getOption(i);
2079 StringRef Description = getDescription(i);
2080 if (!shouldPrintOption(OptionName, Description, O))
2081 continue;
2082 size_t FirstLineIndent = OptionName.size() + getOptionPrefixesSize();
2083 outs() << OptionPrefix << OptionName;
2084 if (OptionName.empty()) {
2085 outs() << EmptyOption;
2086 assert(FirstLineIndent >= EmptyOption.size());
2087 FirstLineIndent += EmptyOption.size();
2088 }
2089 if (!Description.empty())
2090 Option::printEnumValHelpStr(Description, GlobalWidth, FirstLineIndent);
2091 else
2092 outs() << '\n';
2093 }
2094 } else {
2095 if (!O.HelpStr.empty())
2096 outs() << " " << O.HelpStr << '\n';
2097 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
2099 outs() << " " << PrintArg(Option);
2100 Option::printHelpStr(getDescription(i), GlobalWidth, Option.size() + 8);
2101 }
2102 }
2103}
2104
2105static const size_t MaxOptWidth = 8; // arbitrary spacing for printOptionDiff
2106
2107// printGenericOptionDiff - Print the value of this option and it's default.
2108//
2109// "Generic" options have each value mapped to a name.
2111 const Option &O, const GenericOptionValue &Value,
2112 const GenericOptionValue &Default, size_t GlobalWidth) const {
2113 outs() << " " << PrintArg(O.ArgStr);
2114 outs().indent(GlobalWidth - O.ArgStr.size());
2115
2116 unsigned NumOpts = getNumOptions();
2117 for (unsigned i = 0; i != NumOpts; ++i) {
2118 if (!Value.compare(getOptionValue(i)))
2119 continue;
2120
2121 outs() << "= " << getOption(i);
2122 size_t L = getOption(i).size();
2123 size_t NumSpaces = MaxOptWidth > L ? MaxOptWidth - L : 0;
2124 outs().indent(NumSpaces) << " (default: ";
2125 for (unsigned j = 0; j != NumOpts; ++j) {
2126 if (!Default.compare(getOptionValue(j)))
2127 continue;
2128 outs() << getOption(j);
2129 break;
2130 }
2131 outs() << ")\n";
2132 return;
2133 }
2134 outs() << "= *unknown option value*\n";
2135}
2136
2137// printOptionDiff - Specializations for printing basic value types.
2138//
2139namespace llvm {
2140namespace cl {
2142 return OS << static_cast<int>(V);
2143}
2144} // namespace cl
2145} // namespace llvm
2146
2147#define PRINT_OPT_DIFF(T) \
2148 void parser<T>::printOptionDiff(const Option &O, T V, OptionValue<T> D, \
2149 size_t GlobalWidth) const { \
2150 printOptionName(O, GlobalWidth); \
2151 std::string Str; \
2152 { \
2153 raw_string_ostream SS(Str); \
2154 SS << V; \
2155 } \
2156 outs() << "= " << Str; \
2157 size_t NumSpaces = \
2158 MaxOptWidth > Str.size() ? MaxOptWidth - Str.size() : 0; \
2159 outs().indent(NumSpaces) << " (default: "; \
2160 if (D.hasValue()) \
2161 outs() << D.getValue(); \
2162 else \
2163 outs() << "*no default*"; \
2164 outs() << ")\n"; \
2165 }
2166
2167PRINT_OPT_DIFF(bool)
2169PRINT_OPT_DIFF(int)
2170PRINT_OPT_DIFF(long)
2171PRINT_OPT_DIFF(long long)
2172PRINT_OPT_DIFF(unsigned)
2173PRINT_OPT_DIFF(unsigned long)
2174PRINT_OPT_DIFF(unsigned long long)
2175PRINT_OPT_DIFF(double)
2176PRINT_OPT_DIFF(float)
2177PRINT_OPT_DIFF(char)
2179
2182 size_t GlobalWidth) const {
2183 printOptionName(O, GlobalWidth);
2184 outs() << "= " << V;
2185 size_t NumSpaces = MaxOptWidth > V.size() ? MaxOptWidth - V.size() : 0;
2186 outs().indent(NumSpaces) << " (default: ";
2187 if (D.hasValue())
2188 outs() << D.getValue();
2189 else
2190 outs() << "*no default*";
2191 outs() << ")\n";
2192}
2193
2194void parser<std::optional<std::string>>::printOptionDiff(
2195 const Option &O, std::optional<StringRef> V,
2196 const OptionValue<std::optional<std::string>> &D,
2197 size_t GlobalWidth) const {
2198 printOptionName(O, GlobalWidth);
2199 outs() << "= " << V;
2200 size_t VSize = V.has_value() ? V.value().size() : 0;
2201 size_t NumSpaces = MaxOptWidth > VSize ? MaxOptWidth - VSize : 0;
2202 outs().indent(NumSpaces) << " (default: ";
2203 if (D.hasValue() && D.getValue().has_value())
2204 outs() << D.getValue();
2205 else
2206 outs() << "*no value*";
2207 outs() << ")\n";
2208}
2209
2210// Print a placeholder for options that don't yet support printOptionDiff().
2212 size_t GlobalWidth) const {
2213 printOptionName(O, GlobalWidth);
2214 outs() << "= *cannot print option value*\n";
2215}
2216
2217//===----------------------------------------------------------------------===//
2218// -help and -help-hidden option implementation
2219//
2220
2221static int OptNameCompare(const std::pair<const char *, Option *> *LHS,
2222 const std::pair<const char *, Option *> *RHS) {
2223 return strcmp(LHS->first, RHS->first);
2224}
2225
2226static int SubNameCompare(const std::pair<const char *, SubCommand *> *LHS,
2227 const std::pair<const char *, SubCommand *> *RHS) {
2228 return strcmp(LHS->first, RHS->first);
2229}
2230
2231// Copy Options into a vector so we can sort them as we like.
2232static void sortOpts(OptionsMapTy &OptMap,
2233 SmallVectorImpl<std::pair<const char *, Option *>> &Opts,
2234 bool ShowHidden) {
2235 SmallPtrSet<Option *, 32> OptionSet; // Duplicate option detection.
2236
2237 for (auto I = OptMap.begin(), E = OptMap.end(); I != E; ++I) {
2238 // Ignore really-hidden options.
2239 if (I->second->getOptionHiddenFlag() == ReallyHidden)
2240 continue;
2241
2242 // Unless showhidden is set, ignore hidden flags.
2243 if (I->second->getOptionHiddenFlag() == Hidden && !ShowHidden)
2244 continue;
2245
2246 // If we've already seen this option, don't add it to the list again.
2247 if (!OptionSet.insert(I->second).second)
2248 continue;
2249
2250 Opts.push_back(
2251 std::pair<const char *, Option *>(I->first.data(), I->second));
2252 }
2253
2254 // Sort the options list alphabetically.
2255 array_pod_sort(Opts.begin(), Opts.end(), OptNameCompare);
2256}
2257
2258static void
2260 SmallVectorImpl<std::pair<const char *, SubCommand *>> &Subs) {
2261 for (auto *S : SubMap) {
2262 if (S->getName().empty())
2263 continue;
2264 Subs.push_back(std::make_pair(S->getName().data(), S));
2265 }
2266 array_pod_sort(Subs.begin(), Subs.end(), SubNameCompare);
2267}
2268
2269namespace {
2270
2271class HelpPrinter {
2272protected:
2273 const bool ShowHidden;
2274 using StrOptionPairVector =
2276 using StrSubCommandPairVector =
2278 // Print the options. Opts is assumed to be alphabetically sorted.
2279 virtual void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) {
2280 for (const auto &Opt : Opts)
2281 Opt.second->printOptionInfo(MaxArgLen);
2282 }
2283
2284 void printSubCommands(StrSubCommandPairVector &Subs, size_t MaxSubLen) {
2285 for (const auto &S : Subs) {
2286 outs() << " " << S.first;
2287 if (!S.second->getDescription().empty()) {
2288 outs().indent(MaxSubLen - strlen(S.first));
2289 outs() << " - " << S.second->getDescription();
2290 }
2291 outs() << "\n";
2292 }
2293 }
2294
2295public:
2296 explicit HelpPrinter(bool showHidden) : ShowHidden(showHidden) {}
2297 virtual ~HelpPrinter() = default;
2298
2299 // Invoke the printer.
2300 void operator=(bool Value) {
2301 if (!Value)
2302 return;
2303 printHelp();
2304
2305 // Halt the program since help information was printed
2306 exit(0);
2307 }
2308
2309 void printHelp() {
2310 SubCommand *Sub = globalParser().getActiveSubCommand();
2311 auto &OptionsMap = Sub->OptionsMap;
2312 auto &PositionalOpts = Sub->PositionalOpts;
2313 auto &ConsumeAfterOpt = Sub->ConsumeAfterOpt;
2314
2315 StrOptionPairVector Opts;
2316 sortOpts(OptionsMap, Opts, ShowHidden);
2317
2318 StrSubCommandPairVector Subs;
2319 sortSubCommands(globalParser().RegisteredSubCommands, Subs);
2320
2321 if (!globalParser().ProgramOverview.empty())
2322 outs() << "OVERVIEW: " << globalParser().ProgramOverview << "\n";
2323
2324 if (Sub == &SubCommand::getTopLevel()) {
2325 outs() << "USAGE: " << globalParser().ProgramName;
2326 if (!Subs.empty())
2327 outs() << " [subcommand]";
2328 outs() << " [options]";
2329 } else {
2330 if (!Sub->getDescription().empty()) {
2331 outs() << "SUBCOMMAND '" << Sub->getName()
2332 << "': " << Sub->getDescription() << "\n\n";
2333 }
2334 outs() << "USAGE: " << globalParser().ProgramName << " " << Sub->getName()
2335 << " [options]";
2336 }
2337
2338 for (auto *Opt : PositionalOpts) {
2339 if (Opt->hasArgStr())
2340 outs() << " --" << Opt->ArgStr;
2341 outs() << " " << Opt->HelpStr;
2342 }
2343
2344 // Print the consume after option info if it exists...
2345 if (ConsumeAfterOpt)
2346 outs() << " " << ConsumeAfterOpt->HelpStr;
2347
2348 if (Sub == &SubCommand::getTopLevel() && !Subs.empty()) {
2349 // Compute the maximum subcommand length...
2350 size_t MaxSubLen = 0;
2351 for (const auto &Sub : Subs)
2352 MaxSubLen = std::max(MaxSubLen, strlen(Sub.first));
2353
2354 outs() << "\n\n";
2355 outs() << "SUBCOMMANDS:\n\n";
2356 printSubCommands(Subs, MaxSubLen);
2357 outs() << "\n";
2358 outs() << " Type \"" << globalParser().ProgramName
2359 << " <subcommand> --help\" to get more help on a specific "
2360 "subcommand";
2361 }
2362
2363 outs() << "\n\n";
2364
2365 // Compute the maximum argument length...
2366 size_t MaxArgLen = 0;
2367 for (const auto &Opt : Opts)
2368 MaxArgLen = std::max(MaxArgLen, Opt.second->getOptionWidth());
2369
2370 outs() << "OPTIONS:\n";
2371 printOptions(Opts, MaxArgLen);
2372
2373 // Print any extra help the user has declared.
2374 for (const auto &I : globalParser().MoreHelp)
2375 outs() << I;
2376 globalParser().MoreHelp.clear();
2377 }
2378};
2379
2380class CategorizedHelpPrinter : public HelpPrinter {
2381public:
2382 explicit CategorizedHelpPrinter(bool showHidden) : HelpPrinter(showHidden) {}
2383
2384 // Helper function for printOptions().
2385 // It shall return a negative value if A's name should be lexicographically
2386 // ordered before B's name. It returns a value greater than zero if B's name
2387 // should be ordered before A's name, and it returns 0 otherwise.
2388 static int OptionCategoryCompare(OptionCategory *const *A,
2389 OptionCategory *const *B) {
2390 return (*A)->getName().compare((*B)->getName());
2391 }
2392
2393 // Make sure we inherit our base class's operator=()
2394 using HelpPrinter::operator=;
2395
2396protected:
2397 void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) override {
2398 std::vector<OptionCategory *> SortedCategories;
2399 DenseMap<OptionCategory *, std::vector<Option *>> CategorizedOptions;
2400
2401 // Collect registered option categories into vector in preparation for
2402 // sorting.
2403 llvm::append_range(SortedCategories,
2404 globalParser().RegisteredOptionCategories);
2405
2406 // Sort the different option categories alphabetically.
2407 assert(SortedCategories.size() > 0 && "No option categories registered!");
2408 array_pod_sort(SortedCategories.begin(), SortedCategories.end(),
2409 OptionCategoryCompare);
2410
2411 // Walk through pre-sorted options and assign into categories.
2412 // Because the options are already alphabetically sorted the
2413 // options within categories will also be alphabetically sorted.
2414 for (const auto &I : Opts) {
2415 Option *Opt = I.second;
2416 for (OptionCategory *Cat : Opt->Categories) {
2417 assert(llvm::is_contained(SortedCategories, Cat) &&
2418 "Option has an unregistered category");
2419 CategorizedOptions[Cat].push_back(Opt);
2420 }
2421 }
2422
2423 // Now do printing.
2424 for (OptionCategory *Category : SortedCategories) {
2425 // Hide empty categories for --help, but show for --help-hidden.
2426 const auto &CategoryOptions = CategorizedOptions[Category];
2427 if (CategoryOptions.empty())
2428 continue;
2429
2430 // Print category information.
2431 outs() << "\n";
2432 outs() << Category->getName() << ":\n";
2433
2434 // Check if description is set.
2435 if (!Category->getDescription().empty())
2436 outs() << Category->getDescription() << "\n\n";
2437 else
2438 outs() << "\n";
2439
2440 // Loop over the options in the category and print.
2441 for (const Option *Opt : CategoryOptions)
2442 Opt->printOptionInfo(MaxArgLen);
2443 }
2444 }
2445};
2446
2447// This wraps the Uncategorizing and Categorizing printers and decides
2448// at run time which should be invoked.
2449class HelpPrinterWrapper {
2450private:
2451 HelpPrinter &UncategorizedPrinter;
2452 CategorizedHelpPrinter &CategorizedPrinter;
2453
2454public:
2455 explicit HelpPrinterWrapper(HelpPrinter &UncategorizedPrinter,
2456 CategorizedHelpPrinter &CategorizedPrinter)
2457 : UncategorizedPrinter(UncategorizedPrinter),
2458 CategorizedPrinter(CategorizedPrinter) {}
2459
2460 // Invoke the printer.
2461 void operator=(bool Value);
2462};
2463
2464} // End anonymous namespace
2465
2466#if defined(__GNUC__)
2467// GCC and GCC-compatible compilers define __OPTIMIZE__ when optimizations are
2468// enabled.
2469# if defined(__OPTIMIZE__)
2470# define LLVM_IS_DEBUG_BUILD 0
2471# else
2472# define LLVM_IS_DEBUG_BUILD 1
2473# endif
2474#elif defined(_MSC_VER)
2475// MSVC doesn't have a predefined macro indicating if optimizations are enabled.
2476// Use _DEBUG instead. This macro actually corresponds to the choice between
2477// debug and release CRTs, but it is a reasonable proxy.
2478# if defined(_DEBUG)
2479# define LLVM_IS_DEBUG_BUILD 1
2480# else
2481# define LLVM_IS_DEBUG_BUILD 0
2482# endif
2483#else
2484// Otherwise, for an unknown compiler, assume this is an optimized build.
2485# define LLVM_IS_DEBUG_BUILD 0
2486#endif
2487
2488namespace {
2489class VersionPrinter {
2490public:
2491 void print(const std::vector<VersionPrinterTy> &ExtraPrinters) {
2492 raw_ostream &OS = outs();
2493#ifdef PACKAGE_VENDOR
2494 OS << PACKAGE_VENDOR << " ";
2495#else
2496 OS << "LLVM (http://llvm.org/):\n ";
2497#endif
2498 OS << PACKAGE_NAME << " version " << PACKAGE_VERSION << "\n ";
2499#if LLVM_IS_DEBUG_BUILD
2500 OS << "DEBUG build";
2501#else
2502 OS << "Optimized build";
2503#endif
2504#ifndef NDEBUG
2505 OS << " with assertions";
2506#endif
2507 OS << ".\n";
2508
2509 // Iterate over any registered extra printers and call them to add further
2510 // information.
2511 if (!ExtraPrinters.empty()) {
2512 for (const auto &I : ExtraPrinters)
2513 I(outs());
2514 }
2515 }
2516 void operator=(bool OptionWasSpecified);
2517};
2518
2519struct CommandLineCommonOptions {
2520 // Declare the four HelpPrinter instances that are used to print out help, or
2521 // help-hidden as an uncategorized list or in categories.
2522 HelpPrinter UncategorizedNormalPrinter{false};
2523 HelpPrinter UncategorizedHiddenPrinter{true};
2524 CategorizedHelpPrinter CategorizedNormalPrinter{false};
2525 CategorizedHelpPrinter CategorizedHiddenPrinter{true};
2526 // Declare HelpPrinter wrappers that will decide whether or not to invoke
2527 // a categorizing help printer
2528 HelpPrinterWrapper WrappedNormalPrinter{UncategorizedNormalPrinter,
2529 CategorizedNormalPrinter};
2530 HelpPrinterWrapper WrappedHiddenPrinter{UncategorizedHiddenPrinter,
2531 CategorizedHiddenPrinter};
2532 // Define a category for generic options that all tools should have.
2533 cl::OptionCategory GenericCategory{"Generic Options"};
2534
2535 // Define uncategorized help printers.
2536 // --help-list is hidden by default because if Option categories are being
2537 // used then --help behaves the same as --help-list.
2539 "help-list",
2540 cl::desc(
2541 "Display list of available options (--help-list-hidden for more)"),
2542 cl::location(UncategorizedNormalPrinter),
2543 cl::Hidden,
2545 cl::cat(GenericCategory),
2547
2549 "help-list-hidden",
2550 cl::desc("Display list of all available options"),
2551 cl::location(UncategorizedHiddenPrinter),
2552 cl::Hidden,
2554 cl::cat(GenericCategory),
2556
2557 // Define uncategorized/categorized help printers. These printers change their
2558 // behaviour at runtime depending on whether one or more Option categories
2559 // have been declared.
2561 "help",
2562 cl::desc("Display available options (--help-hidden for more)"),
2563 cl::location(WrappedNormalPrinter),
2565 cl::cat(GenericCategory),
2567
2568 cl::alias HOpA{"h", cl::desc("Alias for --help"), cl::aliasopt(HOp)};
2569
2571 "help-hidden",
2572 cl::desc("Display all available options"),
2573 cl::location(WrappedHiddenPrinter),
2574 cl::Hidden,
2576 cl::cat(GenericCategory),
2578
2579 cl::opt<bool> PrintOptions{
2580 "print-options",
2581 cl::desc("Print non-default options after command line parsing"),
2582 cl::Hidden,
2583 cl::init(false),
2584 cl::cat(GenericCategory),
2586
2587 cl::opt<bool> PrintAllOptions{
2588 "print-all-options",
2589 cl::desc("Print all option values after command line parsing"),
2590 cl::Hidden,
2591 cl::init(false),
2592 cl::cat(GenericCategory),
2594
2595 VersionPrinterTy OverrideVersionPrinter = nullptr;
2596
2597 std::vector<VersionPrinterTy> ExtraVersionPrinters;
2598
2599 // Define the --version option that prints out the LLVM version for the tool
2600 VersionPrinter VersionPrinterInstance;
2601
2603 "version", cl::desc("Display the version of this program"),
2604 cl::location(VersionPrinterInstance), cl::ValueDisallowed,
2605 cl::cat(GenericCategory)};
2606};
2607} // End anonymous namespace
2608
2609// Lazy-initialized global instance of options controlling the command-line
2610// parser and general handling.
2612
2624
2626 // Initialise the general option category.
2627 static OptionCategory GeneralCategory{"General options"};
2628 return GeneralCategory;
2629}
2630
2631void VersionPrinter::operator=(bool OptionWasSpecified) {
2632 if (!OptionWasSpecified)
2633 return;
2634
2635 if (CommonOptions->OverrideVersionPrinter != nullptr) {
2636 CommonOptions->OverrideVersionPrinter(outs());
2637 exit(0);
2638 }
2639 print(CommonOptions->ExtraVersionPrinters);
2640
2641 exit(0);
2642}
2643
2644void HelpPrinterWrapper::operator=(bool Value) {
2645 if (!Value)
2646 return;
2647
2648 // Decide which printer to invoke. If more than one option category is
2649 // registered then it is useful to show the categorized help instead of
2650 // uncategorized help.
2651 if (globalParser().RegisteredOptionCategories.size() > 1) {
2652 // unhide --help-list option so user can have uncategorized output if they
2653 // want it.
2654 CommonOptions->HLOp.setHiddenFlag(NotHidden);
2655
2656 CategorizedPrinter = true; // Invoke categorized printer
2657 } else {
2658 UncategorizedPrinter = true; // Invoke uncategorized printer
2659 }
2660}
2661
2662// Print the value of each option.
2663void cl::PrintOptionValues() { globalParser().printOptionValues(); }
2664
2665void CommandLineParser::printOptionValues() {
2666 if (!CommonOptions->PrintOptions && !CommonOptions->PrintAllOptions)
2667 return;
2668
2670 sortOpts(ActiveSubCommand->OptionsMap, Opts, /*ShowHidden*/ true);
2671
2672 // Compute the maximum argument length...
2673 size_t MaxArgLen = 0;
2674 for (const auto &Opt : Opts)
2675 MaxArgLen = std::max(MaxArgLen, Opt.second->getOptionWidth());
2676
2677 for (const auto &Opt : Opts)
2678 Opt.second->printOptionValue(MaxArgLen, CommonOptions->PrintAllOptions);
2679}
2680
2681// Utility function for printing the help message.
2682void cl::PrintHelpMessage(bool Hidden, bool Categorized) {
2683 if (!Hidden && !Categorized)
2684 CommonOptions->UncategorizedNormalPrinter.printHelp();
2685 else if (!Hidden && Categorized)
2686 CommonOptions->CategorizedNormalPrinter.printHelp();
2687 else if (Hidden && !Categorized)
2688 CommonOptions->UncategorizedHiddenPrinter.printHelp();
2689 else
2690 CommonOptions->CategorizedHiddenPrinter.printHelp();
2691}
2692
2694 static const StringRef Config[] = {
2695 // Placeholder to ensure the array always has elements, since it's an
2696 // error to have a zero-sized array. Slice this off before returning.
2697 "",
2698 // Actual compiler build config feature list:
2699#if LLVM_IS_DEBUG_BUILD
2700 "+unoptimized",
2701#endif
2702#ifndef NDEBUG
2703 "+assertions",
2704#endif
2705#ifdef EXPENSIVE_CHECKS
2706 "+expensive-checks",
2707#endif
2708#if __has_feature(address_sanitizer)
2709 "+asan",
2710#endif
2711#if __has_feature(dataflow_sanitizer)
2712 "+dfsan",
2713#endif
2714#if __has_feature(hwaddress_sanitizer)
2715 "+hwasan",
2716#endif
2717#if __has_feature(memory_sanitizer)
2718 "+msan",
2719#endif
2720#if __has_feature(thread_sanitizer)
2721 "+tsan",
2722#endif
2723#if __has_feature(undefined_behavior_sanitizer)
2724 "+ubsan",
2725#endif
2726#ifdef LLVM_INTEGRATED_CRT_ALLOC
2727 "+alloc:" LLVM_INTEGRATED_CRT_ALLOC,
2728#endif
2729 };
2730 return ArrayRef(Config).drop_front(1);
2731}
2732
2733// Utility function for printing the build config.
2735#if LLVM_VERSION_PRINTER_SHOW_BUILD_CONFIG
2736 OS << "Build config: ";
2738 OS << '\n';
2739#endif
2740}
2741
2742/// Utility function for printing version number.
2744 CommonOptions->VersionPrinterInstance.print(CommonOptions->ExtraVersionPrinters);
2745}
2746
2748 CommonOptions->OverrideVersionPrinter = func;
2749}
2750
2752 CommonOptions->ExtraVersionPrinters.push_back(func);
2753}
2754
2757 auto &Subs = globalParser().RegisteredSubCommands;
2758 (void)Subs;
2759 assert(Subs.contains(&Sub));
2760 return Sub.OptionsMap;
2761}
2762
2765 return globalParser().getRegisteredSubcommands();
2766}
2767
2770 for (auto &I : Sub.OptionsMap) {
2771 bool Unrelated = true;
2772 for (auto &Cat : I.second->Categories) {
2773 if (Cat == &Category || Cat == &CommonOptions->GenericCategory)
2774 Unrelated = false;
2775 }
2776 if (Unrelated)
2777 I.second->setHiddenFlag(cl::ReallyHidden);
2778 }
2779}
2780
2782 SubCommand &Sub) {
2784 for (auto &I : Sub.OptionsMap) {
2785 bool Unrelated = true;
2786 for (auto &Cat : I.second->Categories) {
2787 if (is_contained(Categories, Cat) ||
2788 Cat == &CommonOptions->GenericCategory)
2789 Unrelated = false;
2790 }
2791 if (Unrelated)
2792 I.second->setHiddenFlag(cl::ReallyHidden);
2793 }
2794}
2795
2798 globalParser().ResetAllOptionOccurrences();
2799}
2800
2801void LLVMParseCommandLineOptions(int argc, const char *const *argv,
2802 const char *Overview) {
2803 llvm::cl::ParseCommandLineOptions(argc, argv, StringRef(Overview),
2804 &llvm::nulls());
2805}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
void opt_bool_anchor()
static StringRef OptionPrefix
static bool RequiresValue(const Option *O)
static int SubNameCompare(const std::pair< const char *, SubCommand * > *LHS, const std::pair< const char *, SubCommand * > *RHS)
static size_t argPlusPrefixesSize(StringRef ArgName, size_t Pad=DefaultPad)
static bool shouldPrintOption(StringRef Name, StringRef Description, const Option &O)
static bool parseDouble(Option &O, StringRef Arg, double &Value)
static CommandLineParser & globalParser()
static bool parseBool(Option &O, StringRef ArgName, StringRef Arg, T &Value)
static const size_t DefaultPad
static StringRef EmptyOption
static bool hasUTF8ByteOrderMark(ArrayRef< char > S)
static void ExpandBasePaths(StringRef BasePath, StringSaver &Saver, const char *&Arg)
static SmallString< 8 > argPrefix(StringRef ArgName, size_t Pad=DefaultPad)
static StringRef ArgHelpPrefix
void opt_unsigned_anchor()
static bool isWindowsSpecialCharInCommandName(char C)
static StringRef getValueStr(const Option &O, StringRef DefaultMsg)
static Option * HandlePrefixedOption(StringRef &Arg, StringRef &Value, const OptionsMapTy &OptionsMap)
The specified argument string (which started with at least one '-') does not fully match an available...
static size_t getOptionPrefixesSize()
static bool ProvideOption(Option *Handler, StringRef ArgName, StringRef Value, int argc, const char *const *argv, int &i)
ProvideOption - For Value, this differentiates between an empty value ("") and a null value (StringRe...
static bool isQuote(char C)
static ManagedStatic< CommandLineCommonOptions > CommonOptions
static void initCommonOptions()
void opt_char_anchor()
static void sortOpts(OptionsMapTy &OptMap, SmallVectorImpl< std::pair< const char *, Option * > > &Opts, bool ShowHidden)
DenseMap< StringRef, Option * > OptionsMapTy
static void tokenizeWindowsCommandLineImpl(StringRef Src, StringSaver &Saver, function_ref< void(StringRef)> AddToken, bool AlwaysCopy, function_ref< void()> MarkEOL, bool InitialCommandName)
static Option * findPrefixOption(StringRef Name, size_t &Length, const OptionsMapTy &OptionsMap)
static bool isWhitespace(char C)
static bool parseFixedOrScalableQuantity(Option &O, StringRef Arg, StringRef ValueKind, FixedOrScalableQuantityT &Value)
static size_t parseBackslash(StringRef Src, size_t I, SmallString< 128 > &Token)
Backslashes are interpreted in a rather complicated way in the Windows-style command line,...
static StringRef ArgPrefixLong
static void sortSubCommands(const SmallPtrSetImpl< SubCommand * > &SubMap, SmallVectorImpl< std::pair< const char *, SubCommand * > > &Subs)
#define PRINT_OPT_DIFF(T)
static bool isWhitespaceOrNull(char C)
static StringRef EqValue
static const size_t MaxOptWidth
static bool EatsUnboundedNumberOfValues(const Option *O)
static int OptNameCompare(const std::pair< const char *, Option * > *LHS, const std::pair< const char *, Option * > *RHS)
static Option * LookupNearestOption(StringRef Arg, const OptionsMapTy &OptionsMap, std::string &NearestString)
LookupNearestOption - Lookup the closest match to the option specified by the specified option on the...
void opt_int_anchor()
static StringRef ArgPrefix
static bool isWindowsSpecialChar(char C)
static bool CommaSeparateAndAddOccurrence(Option *Handler, unsigned pos, StringRef ArgName, StringRef Value)
CommaSeparateAndAddOccurrence - A wrapper around Handler->addOccurrence() that does special handling ...
#define LLVM_EXPORT_TEMPLATE
Definition Compiler.h:217
#define _
static void Help(StringTable CPUNames, ArrayRef< SubtargetFeatureKV > FeatTable)
Display help for feature and mcpu choices.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define T
Provides a library for accessing information about this process and other processes on the operating ...
This file defines the SmallPtrSet class.
This file defines the SmallString class.
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition Debug.h:119
Defines the virtual file system interface vfs::FileSystem.
Value * RHS
Value * LHS
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
iterator end()
Definition DenseMap.h:702
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
Definition DenseMap.h:809
iterator begin()
Definition DenseMap.h:698
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:843
Represents either an error or a value T.
Definition ErrorOr.h:56
reference get()
Definition ErrorOr.h:149
std::error_code getError() const
Definition ErrorOr.h:152
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...
size_t getBufferSize() const
const char * getBufferEnd() const
const char * getBufferStart() const
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool erase(PtrType Ptr)
Remove pointer from the set.
iterator end() const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
iterator begin() const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
void assign(StringRef RHS)
Assign from a StringRef.
Definition SmallString.h:51
void append(StringRef RHS)
Append from a StringRef.
Definition SmallString.h:68
const char * c_str()
StringRef str() const
Explicit conversion to StringRef.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
void reserve(size_type N)
iterator erase(const_iterator CI)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition StringRef.h:888
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition StringRef.h:736
static constexpr size_t npos
Definition StringRef.h:58
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition StringRef.h:490
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition StringRef.h:597
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:258
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition StringRef.h:635
LLVM_ABI unsigned edit_distance(StringRef Other, bool AllowReplacements=true, unsigned MaxEditDistance=0) const
Determine the edit distance between this string and another string.
Definition StringRef.cpp:88
size_t size_type
Definition StringRef.h:62
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition StringRef.h:720
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Definition StringRef.h:138
StringRef ltrim(char Char) const
Return string with consecutive Char characters starting from the the left removed.
Definition StringRef.h:826
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition StringRef.h:290
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
Definition StringRef.h:850
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Definition StringRef.h:661
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
Definition StringSaver.h:22
BumpPtrAllocator & getAllocator() const
Definition StringSaver.h:28
StringRef save(const char *S)
Definition StringSaver.h:31
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
LLVM Value Representation.
Definition Value.h:75
Contains options that control response file expansion.
LLVM_ABI ExpansionContext(BumpPtrAllocator &A, TokenizerCallback T, vfs::FileSystem *FS=nullptr)
LLVM_ABI bool findConfigFile(StringRef FileName, SmallVectorImpl< char > &FilePath)
Looks for the specified configuration file.
LLVM_ABI Error expandResponseFiles(SmallVectorImpl< const char * > &Argv)
Expands constructs "@file" in the provided array of arguments recursively.
LLVM_ABI Error readConfigFile(StringRef CfgFile, SmallVectorImpl< const char * > &Argv)
Reads command line options from the given configuration file.
StringRef getName() const
SmallPtrSet< SubCommand *, 1 > Subs
int getNumOccurrences() const
enum ValueExpected getValueExpectedFlag() const
void addCategory(OptionCategory &C)
enum FormattingFlags getFormattingFlag() const
virtual void printOptionInfo(size_t GlobalWidth) const =0
enum NumOccurrencesFlag getNumOccurrencesFlag() const
virtual bool addOccurrence(unsigned pos, StringRef ArgName, StringRef Value)
SmallVector< OptionCategory *, 1 > Categories
bool error(const Twine &Message, StringRef ArgName=StringRef(), raw_ostream &Errs=llvm::errs())
void setArgStr(StringRef S)
bool hasArgStr() const
unsigned getMiscFlags() const
virtual void setDefault()=0
virtual void printOptionValue(size_t GlobalWidth, bool Force) const =0
static void printEnumValHelpStr(StringRef HelpStr, size_t Indent, size_t FirstLineIndentedBy)
void removeArgument()
Unregisters this option from the CommandLine system.
static void printHelpStr(StringRef HelpStr, size_t Indent, size_t FirstLineIndentedBy)
virtual size_t getOptionWidth() const =0
StringRef HelpStr
Option(enum NumOccurrencesFlag OccurrencesFlag, enum OptionHidden Hidden)
StringRef getName() const
SubCommand(StringRef Name, StringRef Description="")
static LLVM_ABI SubCommand & getTopLevel()
LLVM_ABI void unregisterSubCommand()
static LLVM_ABI SubCommand & getAll()
LLVM_ABI void reset()
DenseMap< StringRef, Option * > OptionsMap
LLVM_ABI void registerSubCommand()
SmallVector< Option *, 4 > PositionalOpts
void printOptionInfo(const Option &O, size_t GlobalWidth) const
virtual StringRef getValueName() const
void printOptionNoValue(const Option &O, size_t GlobalWidth) const
size_t getOptionWidth(const Option &O) const
void printOptionName(const Option &O, size_t GlobalWidth) const
virtual size_t getOptionWidth(const Option &O) const
virtual StringRef getDescription(unsigned N) const =0
virtual const GenericOptionValue & getOptionValue(unsigned N) const =0
virtual unsigned getNumOptions() const =0
virtual StringRef getOption(unsigned N) const =0
void printGenericOptionDiff(const Option &O, const GenericOptionValue &V, const GenericOptionValue &Default, size_t GlobalWidth) const
virtual void printOptionInfo(const Option &O, size_t GlobalWidth) const
unsigned findOption(StringRef Name)
bool parse(Option &O, StringRef ArgName, StringRef Arg, DataType &V)
An efficient, type-erasing, non-owning reference to a callable.
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
static LLVM_ABI std::optional< std::string > GetEnv(StringRef name)
The virtual file system interface.
The result of a status operation.
LLVM_ABI bool equivalent(const Status &Other) const
LLVM_C_ABI void LLVMParseCommandLineOptions(int argc, const char *const *argv, const char *Overview)
This function parses the given arguments using the LLVM command line parser.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr size_t NameSize
Definition XCOFF.h:30
This namespace contains all of the command line option processing machinery.
Definition MCSchedule.h:35
LLVM_ABI iterator_range< SmallPtrSet< SubCommand *, 4 >::iterator > getRegisteredSubcommands()
Use this to get all registered SubCommands from the provided parser.
LLVM_ABI void PrintVersionMessage()
Utility function for printing version number.
LLVM_ABI bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, SmallVectorImpl< const char * > &Argv)
A convenience helper which supports the typical use case of expansion function call.
LLVM_ABI void TokenizeWindowsCommandLine(StringRef Source, StringSaver &Saver, SmallVectorImpl< const char * > &NewArgv, bool MarkEOLs=false)
Tokenizes a string of Windows command line arguments, which may contain quotes and escaped quotes.
LLVM_ABI OptionCategory & getGeneralCategory()
@ ValueDisallowed
LLVM_ABI void ResetAllOptionOccurrences()
Reset all command line options to a state that looks as if they have never appeared on the command li...
LLVM_ABI void SetVersionPrinter(VersionPrinterTy func)
===------------------------------------------------------------------—===// Override the default (LLV...
LLVM_ABI void tokenizeConfigFile(StringRef Source, StringSaver &Saver, SmallVectorImpl< const char * > &NewArgv, bool MarkEOLs=false)
Tokenizes content of configuration file.
LLVM_ABI DenseMap< StringRef, Option * > & getRegisteredOptions(SubCommand &Sub=SubCommand::getTopLevel())
Use this to get a map of all registered named options (e.g.
LLVM_ABI bool expandResponseFiles(int Argc, const char *const *Argv, const char *EnvVar, StringSaver &Saver, SmallVectorImpl< const char * > &NewArgv)
A convenience helper which concatenates the options specified by the environment variable EnvVar and ...
LLVM_ABI void ResetCommandLineParser()
Reset the command line parser back to its initial state.
LLVM_ABI void PrintOptionValues()
LLVM_ABI void AddLiteralOption(Option &O, StringRef Name)
Adds a new option for parsing and provides the option it refers to.
void printOptionDiff(const Option &O, const generic_parser_base &P, const DT &V, const OptionValue< DT > &Default, size_t GlobalWidth)
LLVM_ABI void TokenizeWindowsCommandLineNoCopy(StringRef Source, StringSaver &Saver, SmallVectorImpl< StringRef > &NewArgv)
Tokenizes a Windows command line while attempting to avoid copies.
LLVM_ABI void printBuildConfig(raw_ostream &OS)
Prints the compiler build configuration.
void(*)(StringRef Source, StringSaver &Saver, SmallVectorImpl< const char * > &NewArgv, bool MarkEOLs) TokenizerCallback
String tokenization function type.
LLVM_ABI bool ProvidePositionalOption(Option *Handler, StringRef Arg, int i)
Parses Arg into the option handler Handler.
static raw_ostream & operator<<(raw_ostream &OS, boolOrDefault V)
initializer< Ty > init(const Ty &Val)
std::function< void(raw_ostream &)> VersionPrinterTy
Definition CommandLine.h:73
@ PositionalEatsArgs
LLVM_ABI ArrayRef< StringRef > getCompilerBuildConfig()
An array of optional enabled settings in the LLVM build configuration, which may be of interest to co...
LocationClass< Ty > location(Ty &L)
LLVM_ABI bool ParseCommandLineOptions(int argc, const char *const *argv, StringRef Overview="", raw_ostream *Errs=nullptr, vfs::FileSystem *VFS=nullptr, const char *EnvVar=nullptr)
LLVM_ABI void HideUnrelatedOptions(cl::OptionCategory &Category, SubCommand &Sub=SubCommand::getTopLevel())
Mark all options not part of this category as cl::ReallyHidden.
LLVM_ABI void AddExtraVersionPrinter(VersionPrinterTy func)
===------------------------------------------------------------------—===// Add an extra printer to u...
LLVM_ABI void PrintHelpMessage(bool Hidden=false, bool Categorized=false)
This function just prints the help message, exactly the same way as if the -help or -help-hidden opti...
LLVM_ABI void TokenizeWindowsCommandLineFull(StringRef Source, StringSaver &Saver, SmallVectorImpl< const char * > &NewArgv, bool MarkEOLs=false)
Tokenizes a Windows full command line, including command name at the start.
@ NormalFormatting
LLVM_ABI void TokenizeGNUCommandLine(StringRef Source, StringSaver &Saver, SmallVectorImpl< const char * > &NewArgv, bool MarkEOLs=false)
Tokenizes a command line that can contain escapes and quotes.
LLVM_ABI StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
Definition Path.cpp:478
LLVM_ABI bool has_parent_path(const Twine &path, Style style=Style::native)
Has parent path?
Definition Path.cpp:667
LLVM_ABI bool is_relative(const Twine &path, Style style=Style::native)
Is path relative?
Definition Path.cpp:716
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
Definition Path.cpp:594
LLVM_ABI bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
Definition Path.cpp:688
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition Path.cpp:467
LLVM_ABI IntrusiveRefCntPtr< FileSystem > getRealFileSystem()
Gets an vfs::FileSystem for the 'real' file system, as seen by the operating system.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:316
@ Length
Definition DWP.cpp:577
void initWithColorOptions()
Definition WithColor.cpp:34
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1685
@ Done
Definition Threading.h:60
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void initDebugOptions()
Definition Debug.cpp:189
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2224
void interleaveComma(const Container &c, StreamT &os, UnaryFunctor each_fn)
Definition STLExtras.h:2329
LLVM_ABI bool hasUTF16ByteOrderMark(ArrayRef< char > SrcBytes)
Returns true if a blob of text starts with a UTF-16 big or little endian byte order mark.
void initDebugCounterOptions()
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
bool to_float(const Twine &T, float &Num)
@ no_such_file_or_directory
Definition Errc.h:65
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
LLVM_ABI bool convertUTF16ToUTF8String(ArrayRef< char > SrcBytes, std::string &Out)
Converts a stream of raw bytes assumed to be UTF16 into a UTF8 std::string.
void initSignalsOptions()
Definition Signals.cpp:64
void initStatisticOptions()
Definition Statistic.cpp:49
LLVM_ABI raw_ostream & nulls()
This returns a reference to a raw_ostream which simply discards output.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
void initTimerOptions()
Definition Timer.cpp:569
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void initRandomSeedOptions()
@ Sub
Subtraction of integers.
void initGraphWriterOptions()
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
ArrayRef(const T &OneElt) -> ArrayRef< T >
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
Definition STLExtras.h:2035
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
Definition STLExtras.h:1612
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:390
@ Default
The result value is uniform if and only if all operands are uniform.
Definition Uniformity.h:20
#define INIT(o, n)
Definition regexec.c:71
LLVM_ABI extrahelp(StringRef help)