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