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