LLVM: lib/Support/CommandLine.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

19

21

31#include "llvm/Config/config.h"

44#include

45#include

46#include

47using namespace llvm;

48using namespace cl;

49

50#define DEBUG_TYPE "commandline"

51

52

53

54

55namespace llvm {

56namespace cl {

69

75}

76}

77

78

79void GenericOptionValue::anchor() {}

82void Option::anchor() {}

96

97

98

100

104

106 size_t Len = ArgName.size();

107 if (Len == 1)

110}

111

114 for (size_t I = 0; I < Pad; ++I) {

115 Prefix.push_back(' ');

116 }

119}

120

121

124}

128}

129

130

131namespace {

132

133class PrintArg {

135 size_t Pad;

136public:

137 PrintArg(StringRef ArgName, size_t Pad = DefaultPad) : ArgName(ArgName), Pad(Pad) {}

139};

140

142 OS << argPrefix(Arg.ArgName, Arg.Pad) << Arg.ArgName;

143 return OS;

144}

145

146class CommandLineParser {

147public:

148

149

150 std::string ProgramName;

152

153

154 std::vector MoreHelp;

155

156

157

158

160

161

163

164

166

168

170

173 bool LongOptionsUseDoubleDash = false);

174

176 if (Opt.Subs.empty()) {

178 return;

179 }

181 for (auto *SC : RegisteredSubCommands)

182 Action(*SC);

184 return;

185 }

186 for (auto *SC : Opt.Subs) {

188 "SubCommand::getAll() should not be used with other subcommands");

189 Action(*SC);

190 }

191 }

192

195 return;

196 if (SC->OptionsMap.insert(std::make_pair(Name, &Opt)).second) {

197 errs() << ProgramName << ": CommandLine Error: Option '" << Name

198 << "' registered more than once!\n";

199 report_fatal_error("inconsistency in registered CommandLine options");

200 }

201 }

202

204 forEachSubCommand(

205 Opt, [&](SubCommand &SC) { addLiteralOption(Opt, &SC, Name); });

206 }

207

209 bool HadErrors = false;

210 if (O->hasArgStr()) {

211

212 if (O->isDefaultOption() && SC->OptionsMap.contains(O->ArgStr))

213 return;

214

215

216 if (SC->OptionsMap.insert(std::make_pair(O->ArgStr, O)).second) {

217 errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr

218 << "' registered more than once!\n";

219 HadErrors = true;

220 }

221 }

222

223

225 SC->PositionalOpts.push_back(O);

226 else if (O->getMiscFlags() & cl::Sink)

227 SC->SinkOpts.push_back(O);

229 if (SC->ConsumeAfterOpt) {

230 O->error("Cannot specify more than one option with cl::ConsumeAfter!");

231 HadErrors = true;

232 }

233 SC->ConsumeAfterOpt = O;

234 }

235

236

237

238

239

240 if (HadErrors)

241 report_fatal_error("inconsistency in registered CommandLine options");

242 }

243

244 void addOption(Option *O, bool ProcessDefaultOption = false) {

245 if (!ProcessDefaultOption && O->isDefaultOption()) {

247 return;

248 }

249 forEachSubCommand(*O, [&](SubCommand &SC) { addOption(O, &SC); });

250 }

251

254 O->getExtraOptionNames(OptionNames);

255 if (O->hasArgStr())

257

260 for (auto Name : OptionNames) {

262 if (I != End && I->getValue() == O)

264 }

265

269 if (*Opt == O) {

271 break;

272 }

273 }

274 else if (O->getMiscFlags() & cl::Sink)

275 for (auto *Opt = Sub.SinkOpts.begin(); Opt != Sub.SinkOpts.end(); ++Opt) {

276 if (*Opt == O) {

278 break;

279 }

280 }

283 }

284

285 void removeOption(Option *O) {

286 forEachSubCommand(*O, [&](SubCommand &SC) { removeOption(O, &SC); });

287 }

288

289 bool hasOptions(const SubCommand &Sub) const {

292 }

293

294 bool hasOptions() const {

295 for (const auto *S : RegisteredSubCommands) {

296 if (hasOptions(*S))

297 return true;

298 }

299 return false;

300 }

301

302 bool hasNamedSubCommands() const {

303 for (const auto *S : RegisteredSubCommands)

304 if (!S->getName().empty())

305 return true;

306 return false;

307 }

308

309 SubCommand *getActiveSubCommand() { return ActiveSubCommand; }

310

313 if (!Sub.OptionsMap.insert(std::make_pair(NewName, O)).second) {

314 errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr

315 << "' registered more than once!\n";

316 report_fatal_error("inconsistency in registered CommandLine options");

317 }

319 }

320

322 forEachSubCommand(*O,

323 [&](SubCommand &SC) { updateArgStr(O, NewName, &SC); });

324 }

325

326 void printOptionValues();

327

331 return cat->getName() == Category->getName();

332 }) == 0 &&

333 "Duplicate option categories");

334

335 RegisteredOptionCategories.insert(cat);

336 }

337

341 return (sub->getName().empty()) &&

343 }) == 0 &&

344 "Duplicate subcommands");

345 RegisteredSubCommands.insert(sub);

346

347

348

350 "SubCommand::getAll() should not be registered");

353 if ((O->isPositional() || O->isSink() || O->isConsumeAfter()) ||

354 O->hasArgStr())

355 addOption(O, sub);

356 else

357 addLiteralOption(*O, sub, E.first());

358 }

359 }

360

362 RegisteredSubCommands.erase(sub);

363 }

364

367 return make_range(RegisteredSubCommands.begin(),

368 RegisteredSubCommands.end());

369 }

370

371 void reset() {

372 ActiveSubCommand = nullptr;

373 ProgramName.clear();

375

376 MoreHelp.clear();

377 RegisteredOptionCategories.clear();

378

380 RegisteredSubCommands.clear();

381

385

386 DefaultOptions.clear();

387 }

388

389private:

390 SubCommand *ActiveSubCommand = nullptr;

391

394 bool LongOptionsUseDoubleDash, bool HaveDoubleDash) {

395 Option *Opt = LookupOption(Sub, Arg, Value);

396 if (Opt && LongOptionsUseDoubleDash && !HaveDoubleDash && isGrouping(Opt))

397 return nullptr;

398 return Opt;

399 }

401};

402

403}

404

406

407template <typename T, T TrueVal, T FalseVal>

409 if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" ||

410 Arg == "1") {

412 return false;

413 }

414

415 if (Arg == "false" || Arg == "FALSE" || Arg == "False" || Arg == "0") {

416 Value = FalseVal;

417 return false;

418 }

419 return O.error("'" + Arg +

420 "' is invalid value for boolean argument! Try 0 or 1");

421}

422

425}

426

429}

430

433 FullyInitialized = true;

434}

435

437

439 if (FullyInitialized)

445}

446

448 assert(Categories.empty() && "Categories cannot be empty.");

449

450

451

456}

457

459 NumOccurrences = 0;

463}

464

465void OptionCategory::registerCategory() {

467}

468

469

470

471

472

475

476

478

480

482

485}

486

489}

490

495

497}

498

499SubCommand::operator bool() const {

500 return (GlobalParser->getActiveSubCommand() == this);

501}

502

503

504

505

506

507

508

509

512

514 return nullptr;

516

517 size_t EqualPos = Arg.find('=');

518

519

521

523 }

524

525

526

527

530 return nullptr;

531

532 auto *O = I->second;

534 return nullptr;

535

537 Arg = Arg.substr(0, EqualPos);

538 return I->second;

539}

540

542 std::string &NearestString) {

543 if (Name.empty())

545

547 for (auto *S : RegisteredSubCommands) {

549 "SubCommand::getAll() is not expected in RegisteredSubCommands");

550 if (S->getName().empty())

551 continue;

552

553 if (S->getName() == Name)

554 return S;

555

556 if (!NearestMatch && S->getName().edit_distance(Name) < 2)

557 NearestMatch = S;

558 }

559

560 if (NearestMatch)

561 NearestString = NearestMatch->getName();

562

564}

565

566

567

568

569

572 std::string &NearestString) {

573

575 return nullptr;

576

577

578 std::pair<StringRef, StringRef> SplitArg = Arg.split('=');

579 StringRef &LHS = SplitArg.first;

581

582

583 Option *Best = nullptr;

584 unsigned BestDistance = 0;

586 ie = OptionsMap.end();

587 it != ie; ++it) {

588 Option *O = it->second;

589

590 if (O->getOptionHiddenFlag() == ReallyHidden)

591 continue;

592

594 O->getExtraOptionNames(OptionNames);

595 if (O->hasArgStr())

596 OptionNames.push_back(O->ArgStr);

597

600 for (const auto &Name : OptionNames) {

602 Flag, true, BestDistance);

603 if (!Best || Distance < BestDistance) {

604 Best = O;

605 BestDistance = Distance;

606 if (RHS.empty() || !PermitValue)

607 NearestString = std::string(Name);

608 else

609 NearestString = (Twine(Name) + "=" + RHS).str();

610 }

611 }

612 }

613

614 return Best;

615}

616

617

618

621 bool MultiArg = false) {

622

623

627

629

631 return true;

632

633 Val = Val.substr(Pos + 1);

634

635 Pos = Val.find(',');

636 }

637

639 }

640

642}

643

644

645

646

649 const char *const *argv, int &i) {

650

652

653

656 if (Value.data()) {

657

658

660 return Handler->error("requires a value!");

661

662 assert(argv && "null check");

664 }

665 break;

667 if (NumAdditionalVals > 0)

668 return Handler->error("multi-valued option specified"

669 " with ValueDisallowed modifier!");

670

671 if (Value.data())

672 return Handler->error("does not allow a value! '" + Twine(Value) +

673 "' specified.");

674 break;

676 break;

677 }

678

679

680 if (NumAdditionalVals == 0)

682

683

684 bool MultiArg = false;

685

686 if (Value.data()) {

688 return true;

689 --NumAdditionalVals;

690 MultiArg = true;

691 }

692

693 while (NumAdditionalVals > 0) {

694 if (i + 1 >= argc)

695 return Handler->error("not enough values!");

696 assert(argv && "null check");

698

700 return true;

701 MultiArg = true;

702 --NumAdditionalVals;

703 }

704 return false;

705}

706

708 int Dummy = i;

710}

711

712

713

714

715

716

717

719 bool (*Pred)(const Option *),

722 if (OMI != OptionsMap.end() && !Pred(OMI->getValue()))

723 OMI = OptionsMap.end();

724

725

726

727

728 while (OMI == OptionsMap.end() && Name.size() > 1) {

729 Name = Name.substr(0, Name.size() - 1);

731 if (OMI != OptionsMap.end() && !Pred(OMI->getValue()))

732 OMI = OptionsMap.end();

733 }

734

735 if (OMI != OptionsMap.end() && Pred(OMI->second)) {

737 return OMI->second;

738 }

739 return nullptr;

740}

741

742

743

744

745

748 bool &ErrorParsing,

750 if (Arg.size() == 1)

751 return nullptr;

752

753

756 if (!PGOpt)

757 return nullptr;

758

759 do {

763 assert(OptionsMap.count(Arg) && OptionsMap.find(Arg)->second == PGOpt);

764

765

766

769 Value = MaybeValue;

770 return PGOpt;

771 }

772

773 if (MaybeValue[0] == '=') {

775 return PGOpt;

776 }

777

778

780

781

783 ErrorParsing |= PGOpt->error("may not occur within a group!");

784 return nullptr;

785 }

786

787

788

789 int Dummy = 0;

791

792

793 Arg = MaybeValue;

795 } while (PGOpt);

796

797

798 return nullptr;

799}

800

802 return O->getNumOccurrencesFlag() == cl::Required ||

804}

805

807 return O->getNumOccurrencesFlag() == cl::ZeroOrMore ||

809}

810

812 return C == ' ' || C == '\t' || C == '\r' || C == '\n';

813}

814

817}

818

819static bool isQuote(char C) { return C == '\"' || C == '\''; }

820

823 bool MarkEOLs) {

825 for (size_t I = 0, E = Src.size(); I != E; ++I) {

826

827 if (Token.empty()) {

829

830 if (MarkEOLs && Src[I] == '\n')

832 ++I;

833 }

834 if (I == E)

835 break;

836 }

837

838 char C = Src[I];

839

840

841 if (I + 1 < E && C == '\\') {

842 ++I;

844 continue;

845 }

846

847

849 ++I;

850 while (I != E && Src[I] != C) {

851

852 if (Src[I] == '\\' && I + 1 != E)

853 ++I;

855 ++I;

856 }

857 if (I == E)

858 break;

859 continue;

860 }

861

862

864 if (!Token.empty())

866

867 if (MarkEOLs && C == '\n')

870 continue;

871 }

872

873

875 }

876

877

878 if (!Token.empty())

880}

881

882

883

884

885

886

887

888

889

890

891

892

893

894

895

896

897

898

900 size_t E = Src.size();

901 int BackslashCount = 0;

902

903 do {

904 ++I;

905 ++BackslashCount;

906 } while (I != E && Src[I] == '\\');

907

908 bool FollowedByDoubleQuote = (I != E && Src[I] == '"');

909 if (FollowedByDoubleQuote) {

910 Token.append(BackslashCount / 2, '\\');

911 if (BackslashCount % 2 == 0)

912 return I - 1;

914 return I;

915 }

916 Token.append(BackslashCount, '\\');

917 return I - 1;

918}

919

920

921

922

925}

928}

929

930

931

934 bool AlwaysCopy, function_ref<void()> MarkEOL, bool InitialCommandName) {

936

937

938

939

940

941

942

943 bool CommandName = InitialCommandName;

944

945

946 enum { INIT, UNQUOTED, QUOTED } State = INIT;

947

948 for (size_t I = 0, E = Src.size(); I < E; ++I) {

949 switch (State) {

951 assert(Token.empty() && "token should be empty in initial state");

952

954 if (Src[I] == '\n')

955 MarkEOL();

956 ++I;

957 }

958

959 if (I >= E)

960 break;

961 size_t Start = I;

962 if (CommandName) {

964 ++I;

965 } else {

967 ++I;

968 }

969 StringRef NormalChars = Src.slice(Start, I);

971

972

973 AddToken(AlwaysCopy ? Saver.save(NormalChars) : NormalChars);

974 if (I < E && Src[I] == '\n') {

975 MarkEOL();

976 CommandName = InitialCommandName;

977 } else {

978 CommandName = false;

979 }

980 } else if (Src[I] == '\"') {

981 Token += NormalChars;

982 State = QUOTED;

983 } else if (Src[I] == '\\') {

984 assert(!CommandName && "or else we'd have treated it as a normal char");

985 Token += NormalChars;

987 State = UNQUOTED;

988 } else {

990 }

991 break;

992 }

993

994 case UNQUOTED:

996

997

998

999 AddToken(Saver.save(Token.str()));

1001 if (Src[I] == '\n') {

1002 CommandName = InitialCommandName;

1003 MarkEOL();

1004 } else {

1005 CommandName = false;

1006 }

1007 State = INIT;

1008 } else if (Src[I] == '\"') {

1009 State = QUOTED;

1010 } else if (Src[I] == '\\' && !CommandName) {

1012 } else {

1014 }

1015 break;

1016

1017 case QUOTED:

1018 if (Src[I] == '\"') {

1019 if (I < (E - 1) && Src[I + 1] == '"') {

1020

1021

1023 ++I;

1024 } else {

1025

1026 State = UNQUOTED;

1027 }

1028 } else if (Src[I] == '\\' && !CommandName) {

1030 } else {

1032 }

1033 break;

1034 }

1035 }

1036

1037 if (State != INIT)

1038 AddToken(Saver.save(Token.str()));

1039}

1040

1043 bool MarkEOLs) {

1044 auto AddToken = [&](StringRef Tok) { NewArgv.push_back(Tok.data()); };

1045 auto OnEOL = [&]() {

1046 if (MarkEOLs)

1048 };

1050 true, OnEOL, false);

1051}

1052

1056 auto OnEOL = []() {};

1058 OnEOL, false);

1059}

1060

1063 bool MarkEOLs) {

1064 auto AddToken = [&](StringRef Tok) { NewArgv.push_back(Tok.data()); };

1065 auto OnEOL = [&]() {

1066 if (MarkEOLs)

1068 };

1070 true, OnEOL, true);

1071}

1072

1075 bool MarkEOLs) {

1076 for (const char *Cur = Source.begin(); Cur != Source.end();) {

1078

1080 while (Cur != Source.end() && isWhitespace(*Cur))

1081 ++Cur;

1082 continue;

1083 }

1084 if (*Cur == '#') {

1085 while (Cur != Source.end() && *Cur != '\n')

1086 ++Cur;

1087 continue;

1088 }

1089

1090 const char *Start = Cur;

1091 for (const char *End = Source.end(); Cur != End; ++Cur) {

1092 if (*Cur == '\\') {

1093 if (Cur + 1 != End) {

1094 ++Cur;

1095 if (*Cur == '\n' ||

1096 (*Cur == '\r' && (Cur + 1 != End) && Cur[1] == '\n')) {

1097 Line.append(Start, Cur - 1);

1098 if (*Cur == '\r')

1099 ++Cur;

1100 Start = Cur + 1;

1101 }

1102 }

1103 } else if (*Cur == '\n')

1104 break;

1105 }

1106

1107 Line.append(Start, Cur);

1109 }

1110}

1111

1112

1113

1115 return (S.size() >= 3 && S[0] == '\xef' && S[1] == '\xbb' && S[2] == '\xbf');

1116}

1117

1118

1120 const char *&Arg) {

1124

1129 TokenPos = ArgString.find(Token, StartPos)) {

1130

1131

1132 const StringRef LHS = ArgString.substr(StartPos, TokenPos - StartPos);

1133 if (ResponseFile.empty())

1134 ResponseFile = LHS;

1135 else

1137 ResponseFile.append(BasePath);

1138 StartPos = TokenPos + Token.size();

1139 }

1140

1141 if (!ResponseFile.empty()) {

1142

1144 if (!Remaining.empty())

1146 Arg = Saver.save(ResponseFile.str()).data();

1147 }

1148}

1149

1150

1151Error ExpansionContext::expandResponseFile(

1156 if (!MemBufOrErr) {

1157 std::error_code EC = MemBufOrErr.getError();

1159 "': " + EC.message());

1160 }

1163

1164

1166 std::string UTF8Buf;

1170 "Could not convert UTF16 to UTF8");

1172 }

1173

1174

1175

1177 Str = StringRef(BufRef.data() + 3, BufRef.size() - 3);

1178

1179

1180 Tokenizer(Str, Saver, NewArgv, MarkEOLs);

1181

1182

1183

1184

1185 if (!RelativeNames && !InConfigFile)

1187

1189 for (const char *&Arg : NewArgv) {

1190 if (!Arg)

1191 continue;

1192

1193

1194 if (InConfigFile)

1196

1197

1198

1201 bool ConfigInclusion = false;

1202 if (ArgStr.consume_front("@")) {

1203 FileName = ArgStr;

1205 continue;

1206 } else if (ArgStr.consume_front("--config=")) {

1207 FileName = ArgStr;

1208 ConfigInclusion = true;

1209 } else {

1210 continue;

1211 }

1212

1213

1220 std::make_error_code(std::errc::no_such_file_or_directory),

1221 "cannot not find configuration file: " + FileName);

1222 ResponseFile.append(FilePath);

1223 } else {

1224 ResponseFile.append(BasePath);

1226 }

1227 Arg = Saver.save(ResponseFile.str()).data();

1228 }

1230}

1231

1232

1233

1236 struct ResponseFileRecord {

1237 std::string File;

1238 size_t End;

1239 };

1240

1241

1242

1243

1245

1246

1247

1249

1250

1251 for (unsigned I = 0; I != Argv.size();) {

1252 while (I == FileStack.back().End) {

1253

1254

1256 }

1257

1258 const char *Arg = Argv[I];

1259

1260 if (Arg == nullptr) {

1261 ++I;

1262 continue;

1263 }

1264

1265 if (Arg[0] != '@') {

1266 ++I;

1267 continue;

1268 }

1269

1270 const char *FName = Arg + 1;

1271

1272

1275 if (CurrentDir.empty()) {

1277 CurrDir = *CWD;

1278 } else {

1280 CWD.getError(), Twine("cannot get absolute path for: ") + FName);

1281 }

1282 } else {

1283 CurrDir = CurrentDir;

1284 }

1286 FName = CurrDir.c_str();

1287 }

1288

1290 if (!Res || !Res->exists()) {

1291 std::error_code EC = Res.getError();

1292 if (!InConfigFile) {

1293

1294

1296 ++I;

1297 continue;

1298 }

1299 }

1300 if (!EC)

1303 "': " + EC.message());

1304 }

1306

1307 auto IsEquivalent =

1308 [FileStatus, this](const ResponseFileRecord &RFile) -> ErrorOr {

1310 if (RHS)

1311 return RHS.getError();

1313 };

1314

1315

1316 for (const auto &F : drop_begin(FileStack)) {

1318 if (R.get())

1320 R.getError(), Twine("recursive expansion of: '") + F.File + "'");

1321 } else {

1323 Twine("cannot open file: ") + F.File);

1324 }

1325 }

1326

1327

1328

1330 if (Error Err = expandResponseFile(FName, ExpandedArgv))

1331 return Err;

1332

1333 for (ResponseFileRecord &Record : FileStack) {

1334

1335

1336 Record.End += ExpandedArgv.size() - 1;

1337 }

1338

1339 FileStack.push_back({FName, I + ExpandedArgv.size()});

1342 }

1343

1344

1345

1346

1347

1348

1349 assert(FileStack.size() > 0 && Argv.size() == FileStack.back().End);

1351}

1352

1356#ifdef _WIN32

1358#else

1360#endif

1361

1362 if (EnvVar)

1364 Tokenize(*EnvValue, Saver, NewArgv, false);

1365

1366

1367 NewArgv.append(Argv + 1, Argv + Argc);

1371 return false;

1372 }

1373 return true;

1374}

1375

1381 return false;

1382 }

1383 return true;

1384}

1385

1387 : Saver(A), Tokenizer(T), FS(vfs::getRealFileSystem().get()) {}

1388

1392 const auto FileExists = [this](SmallString<128> Path) -> bool {

1396 };

1397

1398

1399

1401 CfgFilePath = FileName;

1403 return false;

1404 if (!FileExists(CfgFilePath))

1405 return false;

1406 FilePath.assign(CfgFilePath.begin(), CfgFilePath.end());

1407 return true;

1408 }

1409

1410

1411 for (const StringRef &Dir : SearchDirs) {

1412 if (Dir.empty())

1413 continue;

1414 CfgFilePath.assign(Dir);

1417 if (FileExists(CfgFilePath)) {

1418 FilePath.assign(CfgFilePath.begin(), CfgFilePath.end());

1419 return true;

1420 }

1421 }

1422

1423 return false;

1424}

1425

1430 AbsPath.assign(CfgFile);

1431 if (std::error_code EC = FS->makeAbsolute(AbsPath))

1432 return make_error(

1433 EC, Twine("cannot get absolute path for " + CfgFile));

1434 CfgFile = AbsPath.str();

1435 }

1436 InConfigFile = true;

1437 RelativeNames = true;

1438 if (Error Err = expandResponseFile(CfgFile, Argv))

1439 return Err;

1441}

1442

1446 const char *EnvVar,

1447 bool LongOptionsUseDoubleDash) {

1453

1454

1455 if (EnvVar) {

1456 if (std::optionalstd::string EnvValue =

1459 }

1460

1461

1462 for (int I = 1; I < argc; ++I)

1464 int NewArgc = static_cast<int>(NewArgv.size());

1465

1466

1467 return GlobalParser->ParseCommandLineOptions(NewArgc, &NewArgv[0], Overview,

1468 Errs, LongOptionsUseDoubleDash);

1469}

1470

1471

1472void CommandLineParser::ResetAllOptionOccurrences() {

1473

1474

1475

1476 for (auto *SC : RegisteredSubCommands) {

1477 for (auto &O : SC->OptionsMap)

1478 O.second->reset();

1479 for (Option *O : SC->PositionalOpts)

1480 O->reset();

1481 for (Option *O : SC->SinkOpts)

1482 O->reset();

1483 if (SC->ConsumeAfterOpt)

1484 SC->ConsumeAfterOpt->reset();

1485 }

1486}

1487

1488bool CommandLineParser::ParseCommandLineOptions(int argc,

1489 const char *const *argv,

1492 bool LongOptionsUseDoubleDash) {

1493 assert(hasOptions() && "No options specified!");

1494

1495 ProgramOverview = Overview;

1496 bool IgnoreErrors = Errs;

1497 if (!Errs)

1498 Errs = &errs();

1499 bool ErrorParsing = false;

1500

1501

1504#ifdef _WIN32

1506#else

1508#endif

1510 if (Error Err = ECtx.expandResponseFiles(newArgv)) {

1511 *Errs << toString(std::move(Err)) << '\n';

1512 return false;

1513 }

1514 argv = &newArgv[0];

1515 argc = static_cast<int>(newArgv.size());

1516

1517

1519

1520

1521 unsigned NumPositionalRequired = 0;

1522

1523

1524 bool HasUnlimitedPositionals = false;

1525

1526 int FirstArg = 1;

1528 std::string NearestSubCommandString;

1529 bool MaybeNamedSubCommand =

1530 argc >= 2 && argv[FirstArg][0] != '-' && hasNamedSubCommands();

1531 if (MaybeNamedSubCommand) {

1532

1533

1534 ChosenSubCommand =

1535 LookupSubCommand(StringRef(argv[FirstArg]), NearestSubCommandString);

1537 FirstArg = 2;

1538 }

1539 GlobalParser->ActiveSubCommand = ChosenSubCommand;

1540

1541 assert(ChosenSubCommand);

1542 auto &ConsumeAfterOpt = ChosenSubCommand->ConsumeAfterOpt;

1543 auto &PositionalOpts = ChosenSubCommand->PositionalOpts;

1544 auto &SinkOpts = ChosenSubCommand->SinkOpts;

1545 auto &OptionsMap = ChosenSubCommand->OptionsMap;

1546

1547 for (auto *O: DefaultOptions) {

1548 addOption(O, true);

1549 }

1550

1551 if (ConsumeAfterOpt) {

1552 assert(PositionalOpts.size() > 0 &&

1553 "Cannot specify cl::ConsumeAfter without a positional argument!");

1554 }

1555 if (!PositionalOpts.empty()) {

1556

1557

1558 bool UnboundedFound = false;

1559 for (size_t i = 0, e = PositionalOpts.size(); i != e; ++i) {

1560 Option *Opt = PositionalOpts[i];

1562 ++NumPositionalRequired;

1563 else if (ConsumeAfterOpt) {

1564

1565

1566 if (PositionalOpts.size() > 1) {

1567 if (!IgnoreErrors)

1568 Opt->error("error - this positional option will never be matched, "

1569 "because it does not Require a value, and a "

1570 "cl::ConsumeAfter option is active!");

1571 ErrorParsing = true;

1572 }

1573 } else if (UnboundedFound && !Opt->hasArgStr()) {

1574

1575

1576

1577

1578 if (!IgnoreErrors)

1579 Opt->error("error - option can never match, because "

1580 "another positional argument will match an "

1581 "unbounded number of values, and this option"

1582 " does not require a value!");

1583 *Errs << ProgramName << ": CommandLine Error: Option '" << Opt->ArgStr

1584 << "' is all messed up!\n";

1585 *Errs << PositionalOpts.size();

1586 ErrorParsing = true;

1587 }

1589 }

1590 HasUnlimitedPositionals = UnboundedFound || ConsumeAfterOpt;

1591 }

1592

1593

1594

1595

1597

1598

1599

1600

1601 Option *ActivePositionalArg = nullptr;

1602

1603

1604 bool DashDashFound = false;

1605 for (int i = FirstArg; i < argc; ++i) {

1606 Option *Handler = nullptr;

1607 std::string NearestHandlerString;

1610 bool HaveDoubleDash = false;

1611

1612

1613

1614

1615

1616 if (argv[i][0] != '-' || argv[i][1] == 0 || DashDashFound) {

1617

1618 if (ActivePositionalArg) {

1620 continue;

1621 }

1622

1623 if (!PositionalOpts.empty()) {

1625

1626

1627

1628

1629 if (PositionalVals.size() >= NumPositionalRequired && ConsumeAfterOpt) {

1630 for (++i; i < argc; ++i)

1632 break;

1633 }

1634

1635

1636 continue;

1637 }

1638 } else if (argv[i][0] == '-' && argv[i][1] == '-' && argv[i][2] == 0 &&

1639 !DashDashFound) {

1640 DashDashFound = true;

1641 continue;

1642 } else if (ActivePositionalArg &&

1644

1645

1646

1647 ArgName = StringRef(argv[i] + 1);

1648

1650 HaveDoubleDash = true;

1651

1652 Handler = LookupLongOption(*ChosenSubCommand, ArgName, Value,

1653 LongOptionsUseDoubleDash, HaveDoubleDash);

1656 continue;

1657 }

1658 } else {

1659 ArgName = StringRef(argv[i] + 1);

1660

1662 HaveDoubleDash = true;

1663

1664 Handler = LookupLongOption(*ChosenSubCommand, ArgName, Value,

1665 LongOptionsUseDoubleDash, HaveDoubleDash);

1666

1667

1668

1669

1672 LongOptionsUseDoubleDash, HaveDoubleDash);

1673

1674

1675 if (!Handler && !(LongOptionsUseDoubleDash && HaveDoubleDash))

1677 OptionsMap);

1678

1679

1680

1681 if (!Handler && SinkOpts.empty())

1683 }

1684

1685 if (!Handler) {

1686 if (!SinkOpts.empty()) {

1687 for (Option *SinkOpt : SinkOpts)

1688 SinkOpt->addOccurrence(i, "", StringRef(argv[i]));

1689 continue;

1690 }

1691

1692 auto ReportUnknownArgument = [&](bool IsArg,

1693 StringRef NearestArgumentName) {

1694 *Errs << ProgramName << ": Unknown "

1695 << (IsArg ? "command line argument" : "subcommand") << " '"

1696 << argv[i] << "'. Try: '" << argv[0] << " --help'\n";

1697

1698 if (NearestArgumentName.empty())

1699 return;

1700

1701 *Errs << ProgramName << ": Did you mean '";

1702 if (IsArg)

1703 *Errs << PrintArg(NearestArgumentName, 0);

1704 else

1705 *Errs << NearestArgumentName;

1706 *Errs << "'?\n";

1707 };

1708

1709 if (i > 1 || !MaybeNamedSubCommand)

1710 ReportUnknownArgument(true, NearestHandlerString);

1711 else

1712 ReportUnknownArgument(false, NearestSubCommandString);

1713

1714 ErrorParsing = true;

1715 continue;

1716 }

1717

1718

1719

1722 Handler->error("This argument does not take a value.\n"

1723 "\tInstead, it consumes any positional arguments until "

1724 "the next recognized option.", *Errs);

1725 ErrorParsing = true;

1726 }

1727 ActivePositionalArg = Handler;

1728 }

1729 else

1730 ErrorParsing |= ProvideOption(Handler, ArgName, Value, argc, argv, i);

1731 }

1732

1733

1734 if (NumPositionalRequired > PositionalVals.size()) {

1735 *Errs << ProgramName

1736 << ": Not enough positional command line arguments specified!\n"

1737 << "Must specify at least " << NumPositionalRequired

1738 << " positional argument" << (NumPositionalRequired > 1 ? "s" : "")

1739 << ": See: " << argv[0] << " --help\n";

1740

1741 ErrorParsing = true;

1742 } else if (!HasUnlimitedPositionals &&

1743 PositionalVals.size() > PositionalOpts.size()) {

1744 *Errs << ProgramName << ": Too many positional arguments specified!\n"

1745 << "Can specify at most " << PositionalOpts.size()

1746 << " positional arguments: See: " << argv[0] << " --help\n";

1747 ErrorParsing = true;

1748

1749 } else if (!ConsumeAfterOpt) {

1750

1751 unsigned ValNo = 0, NumVals = static_cast<unsigned>(PositionalVals.size());

1752 for (Option *Opt : PositionalOpts) {

1755 PositionalVals[ValNo].second);

1756 ValNo++;

1757 --NumPositionalRequired;

1758 }

1759

1760

1761

1762

1763

1765 while (NumVals - ValNo > NumPositionalRequired && Done) {

1768 Done = true;

1769 [[fallthrough]];

1770 case cl::ZeroOrMore:

1771 case cl::OneOrMore:

1773 PositionalVals[ValNo].second);

1774 ValNo++;

1775 break;

1776 default:

1777 llvm_unreachable("Internal error, unexpected NumOccurrences flag in "

1778 "positional argument processing!");

1779 }

1780 }

1781 }

1782 } else {

1783 assert(ConsumeAfterOpt && NumPositionalRequired <= PositionalVals.size());

1784 unsigned ValNo = 0;

1785 for (Option *Opt : PositionalOpts)

1788 Opt, PositionalVals[ValNo].first, PositionalVals[ValNo].second);

1789 ValNo++;

1790 }

1791

1792

1793

1794

1795

1796

1797 if (PositionalOpts.size() == 1 && ValNo == 0 && !PositionalVals.empty()) {

1799 PositionalVals[ValNo].first,

1800 PositionalVals[ValNo].second);

1801 ValNo++;

1802 }

1803

1804

1805

1806 for (; ValNo != PositionalVals.size(); ++ValNo)

1807 ErrorParsing |=

1809 PositionalVals[ValNo].second);

1810 }

1811

1812

1813 for (const auto &Opt : OptionsMap) {

1818 Opt.second->error("must be specified at least once!");

1819 ErrorParsing = true;

1820 }

1821 [[fallthrough]];

1822 default:

1823 break;

1824 }

1825 }

1826

1827

1828

1829

1831 for (int i = 0; i < argc; ++i) dbgs() << argv[i] << ' ';

1832 dbgs() << '\n';);

1833

1834

1835

1836 MoreHelp.clear();

1837

1838

1839 if (ErrorParsing) {

1840 if (!IgnoreErrors)

1841 exit(1);

1842 return false;

1843 }

1844 return true;

1845}

1846

1847

1848

1849

1850

1852 if (!ArgName.data())

1854 if (ArgName.empty())

1855 Errs << HelpStr;

1856 else

1857 Errs << GlobalParser->ProgramName << ": for the " << PrintArg(ArgName, 0);

1858

1859 Errs << " option: " << Message << "\n";

1860 return true;

1861}

1862

1864 bool MultiArg) {

1865 if (!MultiArg)

1866 NumOccurrences++;

1867

1868 return handleOccurrence(pos, ArgName, Value);

1869}

1870

1871

1872

1873

1875 if (O.ValueStr.empty())

1876 return DefaultMsg;

1877 return O.ValueStr;

1878}

1879

1880

1881

1882

1883

1884

1885size_t alias::getOptionWidth() const {

1887}

1888

1890 size_t FirstLineIndentedBy) {

1891 assert(Indent >= FirstLineIndentedBy);

1892 std::pair<StringRef, StringRef> Split = HelpStr.split('\n');

1893 outs().indent(Indent - FirstLineIndentedBy)

1895 while (!Split.second.empty()) {

1896 Split = Split.second.split('\n');

1897 outs().indent(Indent) << Split.first << "\n";

1898 }

1899}

1900

1902 size_t FirstLineIndentedBy) {

1903 const StringRef ValHelpPrefix = " ";

1904 assert(BaseIndent >= FirstLineIndentedBy);

1905 std::pair<StringRef, StringRef> Split = HelpStr.split('\n');

1906 outs().indent(BaseIndent - FirstLineIndentedBy)

1907 << ArgHelpPrefix << ValHelpPrefix << Split.first << "\n";

1908 while (!Split.second.empty()) {

1909 Split = Split.second.split('\n');

1910 outs().indent(BaseIndent + ValHelpPrefix.size()) << Split.first << "\n";

1911 }

1912}

1913

1914

1915void alias::printOptionInfo(size_t GlobalWidth) const {

1918}

1919

1920

1921

1922

1923

1924

1925

1926

1927

1931 if (!ValName.empty()) {

1932 size_t FormattingLen = 3;

1934 FormattingLen = 6;

1936 }

1937

1938 return Len;

1939}

1940

1941

1942

1943

1945 size_t GlobalWidth) const {

1946 outs() << PrintArg(O.ArgStr);

1947

1949 if (!ValName.empty()) {

1952 } else if (O.getValueExpectedFlag() == ValueOptional)

1954 else {

1955 outs() << (O.ArgStr.size() == 1 ? " <" : "=<") << getValueStr(O, ValName)

1956 << '>';

1957 }

1958 }

1959

1961}

1962

1964 size_t GlobalWidth) const {

1965 outs() << PrintArg(O.ArgStr);

1966 outs().indent(GlobalWidth - O.ArgStr.size());

1967}

1968

1969

1970

1973 return parseBool<bool, true, false>(O, ArgName, Arg, Value);

1974}

1975

1976

1977

1980 return parseBool<boolOrDefault, BOU_TRUE, BOU_FALSE>(O, ArgName, Arg, Value);

1981}

1982

1983

1984

1988 return O.error("'" + Arg + "' value invalid for integer argument!");

1989 return false;

1990}

1991

1992

1993

1997 return O.error("'" + Arg + "' value invalid for long argument!");

1998 return false;

1999}

2000

2001

2002

2004 long long &Value) {

2006 return O.error("'" + Arg + "' value invalid for llong argument!");

2007 return false;

2008}

2009

2010

2011

2013 unsigned &Value) {

2014

2016 return O.error("'" + Arg + "' value invalid for uint argument!");

2017 return false;

2018}

2019

2020

2021

2023 unsigned long &Value) {

2024

2026 return O.error("'" + Arg + "' value invalid for ulong argument!");

2027 return false;

2028}

2029

2030

2031

2034 unsigned long long &Value) {

2035

2037 return O.error("'" + Arg + "' value invalid for ullong argument!");

2038 return false;

2039}

2040

2041

2042

2044 if (to_float(Arg, Value))

2045 return false;

2046 return O.error("'" + Arg + "' value invalid for floating point argument!");

2047}

2048

2050 double &Val) {

2052}

2053

2055 float &Val) {

2056 double dVal;

2058 return true;

2059 Val = (float)dVal;

2060 return false;

2061}

2062

2063

2064

2065

2066

2067

2068

2071

2072 for (unsigned i = 0; i != e; ++i) {

2074 return i;

2075 }

2076 return e;

2077}

2078

2084}

2085

2088 return O.getValueExpectedFlag() != ValueOptional || Name.empty() ||

2089 !Description.empty();

2090}

2091

2092

2094 if (O.hasArgStr()) {

2095 size_t Size =

2097 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {

2100 continue;

2103 }

2104 return Size;

2105 } else {

2106 size_t BaseSize = 0;

2107 for (unsigned i = 0, e = getNumOptions(); i != e; ++i)

2108 BaseSize = std::max(BaseSize, getOption(i).size() + 8);

2109 return BaseSize;

2110 }

2111}

2112

2113

2114

2115

2117 size_t GlobalWidth) const {

2118 if (O.hasArgStr()) {

2119

2120

2121 if (O.getValueExpectedFlag() == ValueOptional) {

2122 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {

2124 outs() << PrintArg(O.ArgStr);

2127 break;

2128 }

2129 }

2130 }

2131

2132 outs() << PrintArg(O.ArgStr) << EqValue;

2136 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {

2140 continue;

2143 if (OptionName.empty()) {

2147 }

2148 if (!Description.empty())

2150 else

2151 outs() << '\n';

2152 }

2153 } else {

2154 if (!O.HelpStr.empty())

2155 outs() << " " << O.HelpStr << '\n';

2156 for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {

2160 }

2161 }

2162}

2163

2164static const size_t MaxOptWidth = 8;

2165

2166

2167

2168

2172 outs() << " " << PrintArg(O.ArgStr);

2173 outs().indent(GlobalWidth - O.ArgStr.size());

2174

2176 for (unsigned i = 0; i != NumOpts; ++i) {

2178 continue;

2179

2183 outs().indent(NumSpaces) << " (default: ";

2184 for (unsigned j = 0; j != NumOpts; ++j) {

2186 continue;

2188 break;

2189 }

2190 outs() << ")\n";

2191 return;

2192 }

2193 outs() << "= *unknown option value*\n";

2194}

2195

2196

2197

2198#define PRINT_OPT_DIFF(T) \

2199 void parser::printOptionDiff(const Option &O, T V, OptionValue D, \

2200 size_t GlobalWidth) const { \

2201 printOptionName(O, GlobalWidth); \

2202 std::string Str; \

2203 { \

2204 raw_string_ostream SS(Str); \

2205 SS << V; \

2206 } \

2207 outs() << "= " << Str; \

2208 size_t NumSpaces = \

2209 MaxOptWidth > Str.size() ? MaxOptWidth - Str.size() : 0; \

2210 outs().indent(NumSpaces) << " (default: "; \

2211 if (D.hasValue()) \

2212 outs() << D.getValue(); \

2213 else \

2214 outs() << "*no default*"; \

2215 outs() << ")\n"; \

2216 }

2217

2229

2232 size_t GlobalWidth) const {

2233 printOptionName(O, GlobalWidth);

2234 outs() << "= " << V;

2236 outs().indent(NumSpaces) << " (default: ";

2237 if (D.hasValue())

2238 outs() << D.getValue();

2239 else

2240 outs() << "*no default*";

2241 outs() << ")\n";

2242}

2243

2244

2246 size_t GlobalWidth) const {

2248 outs() << "= *cannot print option value*\n";

2249}

2250

2251

2252

2253

2254

2255static int OptNameCompare(const std::pair<const char *, Option *> *LHS,

2256 const std::pair<const char *, Option *> *RHS) {

2257 return strcmp(LHS->first, RHS->first);

2258}

2259

2260static int SubNameCompare(const std::pair<const char *, SubCommand *> *LHS,

2261 const std::pair<const char *, SubCommand *> *RHS) {

2262 return strcmp(LHS->first, RHS->first);

2263}

2264

2265

2267 SmallVectorImpl<std::pair<const char *, Option *>> &Opts,

2268 bool ShowHidden) {

2270

2272 I != E; ++I) {

2273

2274 if (I->second->getOptionHiddenFlag() == ReallyHidden)

2275 continue;

2276

2277

2278 if (I->second->getOptionHiddenFlag() == Hidden && !ShowHidden)

2279 continue;

2280

2281

2282 if (!OptionSet.insert(I->second).second)

2283 continue;

2284

2285 Opts.push_back(

2286 std::pair<const char *, Option *>(I->getKey().data(), I->second));

2287 }

2288

2289

2291}

2292

2293static void

2295 SmallVectorImpl<std::pair<const char *, SubCommand *>> &Subs) {

2296 for (auto *S : SubMap) {

2297 if (S->getName().empty())

2298 continue;

2299 Subs.push_back(std::make_pair(S->getName().data(), S));

2300 }

2302}

2303

2304namespace {

2305

2306class HelpPrinter {

2307protected:

2308 const bool ShowHidden;

2310 StrOptionPairVector;

2312 StrSubCommandPairVector;

2313

2314 virtual void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) {

2315 for (size_t i = 0, e = Opts.size(); i != e; ++i)

2316 Opts[i].second->printOptionInfo(MaxArgLen);

2317 }

2318

2319 void printSubCommands(StrSubCommandPairVector &Subs, size_t MaxSubLen) {

2320 for (const auto &S : Subs) {

2321 outs() << " " << S.first;

2322 if (!S.second->getDescription().empty()) {

2323 outs().indent(MaxSubLen - strlen(S.first));

2324 outs() << " - " << S.second->getDescription();

2325 }

2326 outs() << "\n";

2327 }

2328 }

2329

2330public:

2331 explicit HelpPrinter(bool showHidden) : ShowHidden(showHidden) {}

2332 virtual ~HelpPrinter() = default;

2333

2334

2335 void operator=(bool Value) {

2337 return;

2338 printHelp();

2339

2340

2341 exit(0);

2342 }

2343

2344 void printHelp() {

2349

2350 StrOptionPairVector Opts;

2351 sortOpts(OptionsMap, Opts, ShowHidden);

2352

2353 StrSubCommandPairVector Subs;

2355

2357 outs() << "OVERVIEW: " << GlobalParser->ProgramOverview << "\n";

2358

2361 if (!Subs.empty())

2362 outs() << " [subcommand]";

2363 outs() << " [options]";

2364 } else {

2366 outs() << "SUBCOMMAND '" << Sub->getName()

2368 }

2370 << " [options]";

2371 }

2372

2373 for (auto *Opt : PositionalOpts) {

2377 }

2378

2379

2380 if (ConsumeAfterOpt)

2381 outs() << " " << ConsumeAfterOpt->HelpStr;

2382

2384

2385 size_t MaxSubLen = 0;

2386 for (size_t i = 0, e = Subs.size(); i != e; ++i)

2387 MaxSubLen = std::max(MaxSubLen, strlen(Subs[i].first));

2388

2389 outs() << "\n\n";

2390 outs() << "SUBCOMMANDS:\n\n";

2391 printSubCommands(Subs, MaxSubLen);

2392 outs() << "\n";

2394 << " --help\" to get more help on a specific "

2395 "subcommand";

2396 }

2397

2398 outs() << "\n\n";

2399

2400

2401 size_t MaxArgLen = 0;

2402 for (size_t i = 0, e = Opts.size(); i != e; ++i)

2403 MaxArgLen = std::max(MaxArgLen, Opts[i].second->getOptionWidth());

2404

2405 outs() << "OPTIONS:\n";

2406 printOptions(Opts, MaxArgLen);

2407

2408

2412 }

2413};

2414

2415class CategorizedHelpPrinter : public HelpPrinter {

2416public:

2417 explicit CategorizedHelpPrinter(bool showHidden) : HelpPrinter(showHidden) {}

2418

2419

2420

2421

2422

2423 static int OptionCategoryCompare(OptionCategory *const *A,

2425 return (*A)->getName().compare((*B)->getName());

2426 }

2427

2428

2429 using HelpPrinter::operator=;

2430

2431protected:

2432 void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) override {

2433 std::vector<OptionCategory *> SortedCategories;

2435

2436

2437

2439 SortedCategories.push_back(Category);

2440

2441

2442 assert(SortedCategories.size() > 0 && "No option categories registered!");

2443 array_pod_sort(SortedCategories.begin(), SortedCategories.end(),

2444 OptionCategoryCompare);

2445

2446

2447

2448

2449 for (size_t I = 0, E = Opts.size(); I != E; ++I) {

2450 Option *Opt = Opts[I].second;

2453 "Option has an unregistered category");

2454 CategorizedOptions[Cat].push_back(Opt);

2455 }

2456 }

2457

2458

2460

2461 const auto &CategoryOptions = CategorizedOptions[Category];

2462 if (CategoryOptions.empty())

2463 continue;

2464

2465

2466 outs() << "\n";

2468

2469

2472 else

2473 outs() << "\n";

2474

2475

2476 for (const Option *Opt : CategoryOptions)

2478 }

2479 }

2480};

2481

2482

2483

2484class HelpPrinterWrapper {

2485private:

2486 HelpPrinter &UncategorizedPrinter;

2487 CategorizedHelpPrinter &CategorizedPrinter;

2488

2489public:

2490 explicit HelpPrinterWrapper(HelpPrinter &UncategorizedPrinter,

2491 CategorizedHelpPrinter &CategorizedPrinter)

2492 : UncategorizedPrinter(UncategorizedPrinter),

2493 CategorizedPrinter(CategorizedPrinter) {}

2494

2495

2496 void operator=(bool Value);

2497};

2498

2499}

2500

2501#if defined(__GNUC__)

2502

2503

2504# if defined(__OPTIMIZE__)

2505# define LLVM_IS_DEBUG_BUILD 0

2506# else

2507# define LLVM_IS_DEBUG_BUILD 1

2508# endif

2509#elif defined(_MSC_VER)

2510

2511

2512

2513# if defined(_DEBUG)

2514# define LLVM_IS_DEBUG_BUILD 1

2515# else

2516# define LLVM_IS_DEBUG_BUILD 0

2517# endif

2518#else

2519

2520# define LLVM_IS_DEBUG_BUILD 0

2521#endif

2522

2523namespace {

2524class VersionPrinter {

2525public:

2526 void print(std::vector ExtraPrinters = {}) {

2528#ifdef PACKAGE_VENDOR

2529 OS << PACKAGE_VENDOR << " ";

2530#else

2531 OS << "LLVM (http://llvm.org/):\\n ";

2532#endif

2533 OS << PACKAGE_NAME << " version " << PACKAGE_VERSION << "\n ";

2534#if LLVM_IS_DEBUG_BUILD

2535 OS << "DEBUG build";

2536#else

2537 OS << "Optimized build";

2538#endif

2539#ifndef NDEBUG

2540 OS << " with assertions";

2541#endif

2542 OS << ".\n";

2543

2544

2545

2546 if (!ExtraPrinters.empty()) {

2547 for (const auto &I : ExtraPrinters)

2549 }

2550 }

2551 void operator=(bool OptionWasSpecified);

2552};

2553

2554struct CommandLineCommonOptions {

2555

2556

2557 HelpPrinter UncategorizedNormalPrinter{false};

2558 HelpPrinter UncategorizedHiddenPrinter{true};

2559 CategorizedHelpPrinter CategorizedNormalPrinter{false};

2560 CategorizedHelpPrinter CategorizedHiddenPrinter{true};

2561

2562

2563 HelpPrinterWrapper WrappedNormalPrinter{UncategorizedNormalPrinter,

2564 CategorizedNormalPrinter};

2565 HelpPrinterWrapper WrappedHiddenPrinter{UncategorizedHiddenPrinter,

2566 CategorizedHiddenPrinter};

2567

2569

2570

2571

2572

2574 "help-list",

2576 "Display list of available options (--help-list-hidden for more)"),

2580 cl::cat(GenericCategory),

2582

2584 "help-list-hidden",

2585 cl::desc("Display list of all available options"),

2589 cl::cat(GenericCategory),

2591

2592

2593

2594

2596 "help",

2597 cl::desc("Display available options (--help-hidden for more)"),

2600 cl::cat(GenericCategory),

2602

2605

2607 "help-hidden",

2608 cl::desc("Display all available options"),

2612 cl::cat(GenericCategory),

2614

2616 "print-options",

2617 cl::desc("Print non-default options after command line parsing"),

2620 cl::cat(GenericCategory),

2622

2624 "print-all-options",

2625 cl::desc("Print all option values after command line parsing"),

2628 cl::cat(GenericCategory),

2630

2632

2633 std::vector ExtraVersionPrinters;

2634

2635

2636 VersionPrinter VersionPrinterInstance;

2637

2639 "version", cl::desc("Display the version of this program"),

2641 cl::cat(GenericCategory)};

2642};

2643}

2644

2645

2646

2648

2660}

2661

2663

2664 static OptionCategory GeneralCategory{"General options"};

2665 return GeneralCategory;

2666}

2667

2668void VersionPrinter::operator=(bool OptionWasSpecified) {

2669 if (!OptionWasSpecified)

2670 return;

2671

2672 if (CommonOptions->OverrideVersionPrinter != nullptr) {

2674 exit(0);

2675 }

2677

2678 exit(0);

2679}

2680

2681void HelpPrinterWrapper::operator=(bool Value) {

2683 return;

2684

2685

2686

2687

2688 if (GlobalParser->RegisteredOptionCategories.size() > 1) {

2689

2690

2692

2693 CategorizedPrinter = true;

2694 } else

2695 UncategorizedPrinter = true;

2696}

2697

2698

2700

2701void CommandLineParser::printOptionValues() {

2703 return;

2704

2707

2708

2709 size_t MaxArgLen = 0;

2710 for (size_t i = 0, e = Opts.size(); i != e; ++i)

2711 MaxArgLen = std::max(MaxArgLen, Opts[i].second->getOptionWidth());

2712

2713 for (size_t i = 0, e = Opts.size(); i != e; ++i)

2714 Opts[i].second->printOptionValue(MaxArgLen, CommonOptions->PrintAllOptions);

2715}

2716

2717

2719 if (Hidden && !Categorized)

2720 CommonOptions->UncategorizedNormalPrinter.printHelp();

2721 else if (Hidden && Categorized)

2722 CommonOptions->CategorizedNormalPrinter.printHelp();

2723 else if (Hidden && !Categorized)

2724 CommonOptions->UncategorizedHiddenPrinter.printHelp();

2725 else

2726 CommonOptions->CategorizedHiddenPrinter.printHelp();

2727}

2728

2731

2732

2733 "",

2734

2735#if LLVM_IS_DEBUG_BUILD

2736 "+unoptimized",

2737#endif

2738#ifndef NDEBUG

2739 "+assertions",

2740#endif

2741#ifdef EXPENSIVE_CHECKS

2742 "+expensive-checks",

2743#endif

2744#if __has_feature(address_sanitizer)

2745 "+asan",

2746#endif

2747#if __has_feature(dataflow_sanitizer)

2748 "+dfsan",

2749#endif

2750#if __has_feature(hwaddress_sanitizer)

2751 "+hwasan",

2752#endif

2753#if __has_feature(memory_sanitizer)

2754 "+msan",

2755#endif

2756#if __has_feature(thread_sanitizer)

2757 "+tsan",

2758#endif

2759#if __has_feature(undefined_behavior_sanitizer)

2760 "+ubsan",

2761#endif

2762 };

2764}

2765

2766

2768#if LLVM_VERSION_PRINTER_SHOW_BUILD_CONFIG

2769 OS << "Build config: ";

2771 OS << '\n';

2772#endif

2773}

2774

2775

2778}

2779

2782}

2783

2786}

2787

2790 auto &Subs = GlobalParser->RegisteredSubCommands;

2791 (void)Subs;

2792 assert(Subs.contains(&Sub));

2794}

2795

2798 return GlobalParser->getRegisteredSubcommands();

2799}

2800

2804 bool Unrelated = true;

2805 for (auto &Cat : I.second->Categories) {

2806 if (Cat == &Category || Cat == &CommonOptions->GenericCategory)

2807 Unrelated = false;

2808 }

2809 if (Unrelated)

2811 }

2812}

2813

2818 bool Unrelated = true;

2819 for (auto &Cat : I.second->Categories) {

2822 Unrelated = false;

2823 }

2824 if (Unrelated)

2826 }

2827}

2828

2832}

2833

2835 const char *Overview) {

2838}

This file defines the StringMap class.

static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static bool CommaSeparateAndAddOccurrence(Option *Handler, unsigned pos, StringRef ArgName, StringRef Value, bool MultiArg=false)

CommaSeparateAndAddOccurrence - A wrapper around Handler->addOccurrence() that does special handling ...

static StringRef OptionPrefix

static bool RequiresValue(const Option *O)

static int SubNameCompare(const std::pair< const char *, SubCommand * > *LHS, const std::pair< const char *, SubCommand * > *RHS)

static size_t argPlusPrefixesSize(StringRef ArgName, size_t Pad=DefaultPad)

static bool isPrefixedOrGrouping(const Option *O)

static bool shouldPrintOption(StringRef Name, StringRef Description, const Option &O)

static ManagedStatic< SubCommand > AllSubCommands

static Option * HandlePrefixedOrGroupedOption(StringRef &Arg, StringRef &Value, bool &ErrorParsing, const StringMap< Option * > &OptionsMap)

HandlePrefixedOrGroupedOption - The specified argument string (which started with at least one '-') d...

static bool parseDouble(Option &O, StringRef Arg, double &Value)

static bool parseBool(Option &O, StringRef ArgName, StringRef Arg, T &Value)

static const size_t DefaultPad

static StringRef EmptyOption

static bool hasUTF8ByteOrderMark(ArrayRef< char > S)

static ManagedStatic< CommandLineParser > GlobalParser

static void ExpandBasePaths(StringRef BasePath, StringSaver &Saver, const char *&Arg)

static SmallString< 8 > argPrefix(StringRef ArgName, size_t Pad=DefaultPad)

static StringRef ArgHelpPrefix

static bool isWindowsSpecialCharInCommandName(char C)

static Option * getOptionPred(StringRef Name, size_t &Length, bool(*Pred)(const Option *), const StringMap< Option * > &OptionsMap)

static StringRef getValueStr(const Option &O, StringRef DefaultMsg)

static size_t getOptionPrefixesSize()

static bool ProvideOption(Option *Handler, StringRef ArgName, StringRef Value, int argc, const char *const *argv, int &i)

ProvideOption - For Value, this differentiates between an empty value ("") and a null value (StringRe...

static bool isQuote(char C)

static ManagedStatic< CommandLineCommonOptions > CommonOptions

static void initCommonOptions()

static void tokenizeWindowsCommandLineImpl(StringRef Src, StringSaver &Saver, function_ref< void(StringRef)> AddToken, bool AlwaysCopy, function_ref< void()> MarkEOL, bool InitialCommandName)

static bool isWhitespace(char C)

static LLVM_REQUIRE_CONSTANT_INITIALIZATION ManagedStatic< SubCommand > TopLevelSubCommand

static size_t parseBackslash(StringRef Src, size_t I, SmallString< 128 > &Token)

Backslashes are interpreted in a rather complicated way in the Windows-style command line,...

static StringRef ArgPrefixLong

static void sortSubCommands(const SmallPtrSetImpl< SubCommand * > &SubMap, SmallVectorImpl< std::pair< const char *, SubCommand * > > &Subs)

#define PRINT_OPT_DIFF(T)

static bool isWhitespaceOrNull(char C)

static const size_t MaxOptWidth

static Option * LookupNearestOption(StringRef Arg, const StringMap< Option * > &OptionsMap, std::string &NearestString)

LookupNearestOption - Lookup the closest match to the option specified by the specified option on the...

static bool EatsUnboundedNumberOfValues(const Option *O)

static int OptNameCompare(const std::pair< const char *, Option * > *LHS, const std::pair< const char *, Option * > *RHS)

static void sortOpts(StringMap< Option * > &OptMap, SmallVectorImpl< std::pair< const char *, Option * > > &Opts, bool ShowHidden)

static StringRef ArgPrefix

static bool isWindowsSpecialChar(char C)

static bool isGrouping(const Option *O)

#define LLVM_REQUIRE_CONSTANT_INITIALIZATION

LLVM_REQUIRE_CONSTANT_INITIALIZATION - Apply this to globals to ensure that they are constant initial...

static void Help(ArrayRef< StringRef > CPUNames, ArrayRef< SubtargetFeatureKV > FeatTable)

Display help for feature and mcpu choices.

Provides a library for accessing information about this process and other processes on the operating ...

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

This file defines the SmallPtrSet class.

This file defines the SmallString class.

Defines the virtual file system interface vfs::FileSystem.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

ArrayRef< T > drop_front(size_t N=1) const

Drop the first N elements of the array.

size_t size() const

size - Get the array size.

Allocate memory in an ever growing pool, as if by bump-pointer.

Represents either an error or a value T.

std::error_code getError() const

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...

This interface provides simple read-only access to a block of memory, and provides simple methods for...

size_t getBufferSize() const

const char * getBufferEnd() const

const char * getBufferStart() const

A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...

std::pair< iterator, bool > insert(PtrType Ptr)

Inserts Ptr if and only if there is no element in the container equal to Ptr.

SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

void assign(StringRef RHS)

Assign from a StringRef.

void append(StringRef RHS)

Append from a StringRef.

StringRef str() const

Explicit conversion to StringRef.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void assign(size_type NumElts, ValueParamT Elt)

iterator erase(const_iterator CI)

void append(ItTy in_start, ItTy in_end)

Add the specified range to the end of the SmallVector.

iterator insert(iterator I, T &&Elt)

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...

StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...

iterator find(StringRef Key)

size_type count(StringRef Key) const

count - Return 1 if the element is in the map, 0 otherwise.

StringRef - Represent a constant reference to a string, i.e.

std::pair< StringRef, StringRef > split(char Separator) const

Split into two substrings around the first occurrence of a separator character.

bool getAsInteger(unsigned Radix, T &Result) const

Parse the current string as an integer of the specified radix.

constexpr StringRef substr(size_t Start, size_t N=npos) const

Return a reference to the substring from [Start, Start + N).

bool starts_with(StringRef Prefix) const

Check if this string starts with the given Prefix.

constexpr bool empty() const

empty - Check if the string is empty.

unsigned edit_distance(StringRef Other, bool AllowReplacements=true, unsigned MaxEditDistance=0) const

Determine the edit distance between this string and another string.

constexpr size_t size() const

size - Get the string size.

constexpr const char * data() const

data - Get a pointer to the start of the string (which may not be null terminated).

bool consume_front(StringRef Prefix)

Returns true if this StringRef has the given prefix and removes that prefix.

size_t find(char C, size_t From=0) const

Search for the first character C in the string.

static constexpr size_t npos

Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.

BumpPtrAllocator & getAllocator() const

StringRef save(const char *S)

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

LLVM Value Representation.

Contains options that control response file expansion.

bool findConfigFile(StringRef FileName, SmallVectorImpl< char > &FilePath)

Looks for the specified configuration file.

ExpansionContext(BumpPtrAllocator &A, TokenizerCallback T)

Error expandResponseFiles(SmallVectorImpl< const char * > &Argv)

Expands constructs "@file" in the provided array of arguments recursively.

Error readConfigFile(StringRef CfgFile, SmallVectorImpl< const char * > &Argv)

Reads command line options from the given configuration file.

StringRef getDescription() const

StringRef getName() const

SmallPtrSet< SubCommand *, 1 > Subs

int getNumOccurrences() const

enum ValueExpected getValueExpectedFlag() const

void addCategory(OptionCategory &C)

virtual bool addOccurrence(unsigned pos, StringRef ArgName, StringRef Value, bool MultiArg=false)

void setMiscFlag(enum MiscFlags M)

enum FormattingFlags getFormattingFlag() const

virtual void printOptionInfo(size_t GlobalWidth) const =0

enum NumOccurrencesFlag getNumOccurrencesFlag() const

SmallVector< OptionCategory *, 1 > Categories

bool error(const Twine &Message, StringRef ArgName=StringRef(), raw_ostream &Errs=llvm::errs())

void setArgStr(StringRef S)

bool isDefaultOption() const

unsigned getMiscFlags() const

virtual void setDefault()=0

static void printEnumValHelpStr(StringRef HelpStr, size_t Indent, size_t FirstLineIndentedBy)

unsigned getNumAdditionalVals() const

void removeArgument()

Unregisters this option from the CommandLine system.

static void printHelpStr(StringRef HelpStr, size_t Indent, size_t FirstLineIndentedBy)

StringRef getName() const

SmallVector< Option *, 4 > SinkOpts

static SubCommand & getTopLevel()

void unregisterSubCommand()

static SubCommand & getAll()

void registerSubCommand()

SmallVector< Option *, 4 > PositionalOpts

StringMap< Option * > OptionsMap

StringRef getDescription() const

void printOptionInfo(const Option &O, size_t GlobalWidth) const

virtual StringRef getValueName() const

void printOptionNoValue(const Option &O, size_t GlobalWidth) const

size_t getOptionWidth(const Option &O) const

void printOptionName(const Option &O, size_t GlobalWidth) const

virtual size_t getOptionWidth(const Option &O) const

virtual StringRef getDescription(unsigned N) const =0

virtual const GenericOptionValue & getOptionValue(unsigned N) const =0

virtual unsigned getNumOptions() const =0

virtual StringRef getOption(unsigned N) const =0

void printOptionDiff(const Option &O, const AnyOptionValue &V, const AnyOptionValue &Default, size_t GlobalWidth) const

void printGenericOptionDiff(const Option &O, const GenericOptionValue &V, const GenericOptionValue &Default, size_t GlobalWidth) const

virtual void printOptionInfo(const Option &O, size_t GlobalWidth) const

unsigned findOption(StringRef Name)

bool parse(Option &O, StringRef ArgName, StringRef Arg, DataType &V)

An efficient, type-erasing, non-owning reference to a callable.

A range adaptor for a pair of iterators.

This class implements an extremely fast bulk output stream that can only output to a stream.

raw_ostream & indent(unsigned NumSpaces)

indent - Insert 'NumSpaces' spaces.

static std::optional< std::string > GetEnv(StringRef name)

virtual llvm::ErrorOr< std::string > getCurrentWorkingDirectory() const =0

Get the working directory of this file system.

virtual std::error_code makeAbsolute(SmallVectorImpl< char > &Path) const

Make Path an absolute path.

llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getBufferForFile(const Twine &Name, int64_t FileSize=-1, bool RequiresNullTerminator=true, bool IsVolatile=false, bool IsText=true)

This is a convenience method that opens a file, gets its content and then closes the file.

virtual llvm::ErrorOr< Status > status(const Twine &Path)=0

Get the status of the entry at Path, if one exists.

The result of a status operation.

bool equivalent(const Status &Other) const

void LLVMParseCommandLineOptions(int argc, const char *const *argv, const char *Overview)

This function parses the given arguments using the LLVM command line parser.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

@ C

The default llvm calling convention, compatible with C.

@ SC

CHAIN = SC CHAIN, Imm128 - System call.

constexpr size_t NameSize

std::function< void(raw_ostream &)> VersionPrinterTy

void(*)(StringRef Source, StringSaver &Saver, SmallVectorImpl< const char * > &NewArgv, bool MarkEOLs) TokenizerCallback

String tokenization function type.

void PrintVersionMessage()

Utility function for printing version number.

bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, SmallVectorImpl< const char * > &Argv)

A convenience helper which supports the typical use case of expansion function call.

bool expandResponseFiles(int Argc, const char *const *Argv, const char *EnvVar, SmallVectorImpl< const char * > &NewArgv)

A convenience helper which concatenates the options specified by the environment variable EnvVar and ...

void TokenizeWindowsCommandLine(StringRef Source, StringSaver &Saver, SmallVectorImpl< const char * > &NewArgv, bool MarkEOLs=false)

Tokenizes a string of Windows command line arguments, which may contain quotes and escaped quotes.

OptionCategory & getGeneralCategory()

void ResetAllOptionOccurrences()

Reset all command line options to a state that looks as if they have never appeared on the command li...

void SetVersionPrinter(VersionPrinterTy func)

===------------------------------------------------------------------—===// Override the default (LLV...

void tokenizeConfigFile(StringRef Source, StringSaver &Saver, SmallVectorImpl< const char * > &NewArgv, bool MarkEOLs=false)

Tokenizes content of configuration file.

StringMap< Option * > & getRegisteredOptions(SubCommand &Sub=SubCommand::getTopLevel())

Use this to get a StringMap to all registered named options (e.g.

void ResetCommandLineParser()

Reset the command line parser back to its initial state.

bool ParseCommandLineOptions(int argc, const char *const *argv, StringRef Overview="", raw_ostream *Errs=nullptr, const char *EnvVar=nullptr, bool LongOptionsUseDoubleDash=false)

iterator_range< typename SmallPtrSet< SubCommand *, 4 >::iterator > getRegisteredSubcommands()

Use this to get all registered SubCommands from the provided parser.

void AddLiteralOption(Option &O, StringRef Name)

Adds a new option for parsing and provides the option it refers to.

void TokenizeWindowsCommandLineNoCopy(StringRef Source, StringSaver &Saver, SmallVectorImpl< StringRef > &NewArgv)

Tokenizes a Windows command line while attempting to avoid copies.

void printBuildConfig(raw_ostream &OS)

Prints the compiler build configuration.

bool ProvidePositionalOption(Option *Handler, StringRef Arg, int i)

Parses Arg into the option handler Handler.

initializer< Ty > init(const Ty &Val)

ArrayRef< StringRef > getCompilerBuildConfig()

An array of optional enabled settings in the LLVM build configuration, which may be of interest to co...

LocationClass< Ty > location(Ty &L)

void HideUnrelatedOptions(cl::OptionCategory &Category, SubCommand &Sub=SubCommand::getTopLevel())

Mark all options not part of this category as cl::ReallyHidden.

void AddExtraVersionPrinter(VersionPrinterTy func)

===------------------------------------------------------------------—===// Add an extra printer to u...

void PrintHelpMessage(bool Hidden=false, bool Categorized=false)

This function just prints the help message, exactly the same way as if the -help or -help-hidden opti...

void TokenizeWindowsCommandLineFull(StringRef Source, StringSaver &Saver, SmallVectorImpl< const char * > &NewArgv, bool MarkEOLs=false)

Tokenizes a Windows full command line, including command name at the start.

void TokenizeGNUCommandLine(StringRef Source, StringSaver &Saver, SmallVectorImpl< const char * > &NewArgv, bool MarkEOLs=false)

Tokenizes a command line that can contain escapes and quotes.

StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)

Get parent path.

bool has_parent_path(const Twine &path, Style style=Style::native)

Has parent path?

bool is_relative(const Twine &path, Style style=Style::native)

Is path relative?

StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)

Get filename.

bool is_absolute(const Twine &path, Style style=Style::native)

Is path absolute?

void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")

Append to path.

This is an optimization pass for GlobalISel generic memory operations.

auto drop_begin(T &&RangeOrContainer, size_t N=1)

Return a range covering RangeOrContainer with the first N elements excluded.

void initWithColorOptions()

auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)

Get the size of a range.

raw_fd_ostream & outs()

This returns a reference to a raw_fd_ostream for standard output.

iterator_range< T > make_range(T x, T y)

Convenience function for iterating over sub-ranges.

void interleaveComma(const Container &c, StreamT &os, UnaryFunctor each_fn)

bool hasUTF16ByteOrderMark(ArrayRef< char > SrcBytes)

Returns true if a blob of text starts with a UTF-16 big or little endian byte order mark.

void initDebugCounterOptions()

Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)

Create formatted StringError object.

Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr)

@ no_such_file_or_directory

decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)

raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

void report_fatal_error(Error Err, bool gen_crash_diag=true)

Report a serious error, calling any installed error handler.

bool convertUTF16ToUTF8String(ArrayRef< char > SrcBytes, std::string &Out)

Converts a stream of raw bytes assumed to be UTF16 into a UTF8 std::string.

void initSignalsOptions()

void initTypeSizeOptions()

void initStatisticOptions()

raw_ostream & nulls()

This returns a reference to a raw_ostream which simply discards output.

raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

void initRandomSeedOptions()

void initGraphWriterOptions()

raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)

auto count_if(R &&Range, UnaryPredicate P)

Wrapper function around std::count_if to count the number of times an element satisfying a given pred...

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.

const char * toString(DWARFSectionKind Kind)

void array_pod_sort(IteratorTy Start, IteratorTy End)

array_pod_sort - This sorts an array with the specified start and end extent.

@ Default

The result values are uniform if and only if all operands are uniform.