1 //===- OptParserEmitter.cpp - Table Driven Command Line Parsing -----------===// 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 #include "OptEmitter.h" 10 #include "llvm/ADT/STLExtras.h" 11 #include "llvm/ADT/SmallString.h" 12 #include "llvm/ADT/Twine.h" 13 #include "llvm/Support/raw_ostream.h" 14 #include "llvm/TableGen/Record.h" 15 #include "llvm/TableGen/TableGenBackend.h" 16 #include <cctype> 17 #include <cstring> 18 #include <map> 19 #include <memory> 20 21 using namespace llvm; 22 23 static const std::string getOptionName(const Record &R) { 24 // Use the record name unless EnumName is defined. 25 if (isa<UnsetInit>(R.getValueInit("EnumName"))) 26 return std::string(R.getName()); 27 28 return std::string(R.getValueAsString("EnumName")); 29 } 30 31 static raw_ostream &write_cstring(raw_ostream &OS, llvm::StringRef Str) { 32 OS << '"'; 33 OS.write_escaped(Str); 34 OS << '"'; 35 return OS; 36 } 37 38 static const std::string getOptionSpelling(const Record &R, 39 size_t &PrefixLength) { 40 std::vector<StringRef> Prefixes = R.getValueAsListOfStrings("Prefixes"); 41 StringRef Name = R.getValueAsString("Name"); 42 43 if (Prefixes.empty()) { 44 PrefixLength = 0; 45 return Name.str(); 46 } 47 48 PrefixLength = Prefixes[0].size(); 49 return (Twine(Prefixes[0]) + Twine(Name)).str(); 50 } 51 52 static const std::string getOptionSpelling(const Record &R) { 53 size_t PrefixLength; 54 return getOptionSpelling(R, PrefixLength); 55 } 56 57 static void emitNameUsingSpelling(raw_ostream &OS, const Record &R) { 58 size_t PrefixLength; 59 OS << "&"; 60 write_cstring(OS, StringRef(getOptionSpelling(R, PrefixLength))); 61 OS << "[" << PrefixLength << "]"; 62 } 63 64 class MarshallingKindInfo { 65 public: 66 const Record &R; 67 const char *MacroName; 68 bool ShouldAlwaysEmit; 69 StringRef KeyPath; 70 StringRef DefaultValue; 71 StringRef NormalizedValuesScope; 72 73 void emit(raw_ostream &OS) const { 74 write_cstring(OS, StringRef(getOptionSpelling(R))); 75 OS << ", "; 76 OS << ShouldAlwaysEmit; 77 OS << ", "; 78 OS << KeyPath; 79 OS << ", "; 80 emitScopedNormalizedValue(OS, DefaultValue); 81 OS << ", "; 82 emitSpecific(OS); 83 } 84 85 virtual Optional<StringRef> emitValueTable(raw_ostream &OS) const { 86 return None; 87 } 88 89 virtual ~MarshallingKindInfo() = default; 90 91 static std::unique_ptr<MarshallingKindInfo> create(const Record &R); 92 93 protected: 94 void emitScopedNormalizedValue(raw_ostream &OS, 95 StringRef NormalizedValue) const { 96 if (!NormalizedValuesScope.empty()) 97 OS << NormalizedValuesScope << "::"; 98 OS << NormalizedValue; 99 } 100 101 virtual void emitSpecific(raw_ostream &OS) const = 0; 102 MarshallingKindInfo(const Record &R, const char *MacroName) 103 : R(R), MacroName(MacroName) {} 104 }; 105 106 class MarshallingFlagInfo final : public MarshallingKindInfo { 107 public: 108 bool IsPositive; 109 110 void emitSpecific(raw_ostream &OS) const override { OS << IsPositive; } 111 112 static std::unique_ptr<MarshallingKindInfo> create(const Record &R) { 113 std::unique_ptr<MarshallingFlagInfo> Ret(new MarshallingFlagInfo(R)); 114 Ret->IsPositive = R.getValueAsBit("IsPositive"); 115 // FIXME: This is a workaround for a bug in older versions of clang (< 3.9) 116 // The constructor that is supposed to allow for Derived to Base 117 // conversion does not work. Remove this if we drop support for such 118 // configurations. 119 return std::unique_ptr<MarshallingKindInfo>(Ret.release()); 120 } 121 122 private: 123 MarshallingFlagInfo(const Record &R) 124 : MarshallingKindInfo(R, "OPTION_WITH_MARSHALLING_FLAG") {} 125 }; 126 127 class MarshallingStringInfo final : public MarshallingKindInfo { 128 public: 129 StringRef NormalizerRetTy; 130 StringRef Normalizer; 131 StringRef Denormalizer; 132 int TableIndex = -1; 133 std::vector<StringRef> Values; 134 std::vector<StringRef> NormalizedValues; 135 std::string ValueTableName; 136 137 static constexpr const char *ValueTablePreamble = R"( 138 struct SimpleEnumValue { 139 const char *Name; 140 unsigned Value; 141 }; 142 143 struct SimpleEnumValueTable { 144 const SimpleEnumValue *Table; 145 unsigned Size; 146 }; 147 )"; 148 149 static constexpr const char *ValueTablesDecl = 150 "static const SimpleEnumValueTable SimpleEnumValueTables[] = "; 151 152 void emitSpecific(raw_ostream &OS) const override { 153 emitScopedNormalizedValue(OS, NormalizerRetTy); 154 OS << ", "; 155 OS << Normalizer; 156 OS << ", "; 157 OS << Denormalizer; 158 OS << ", "; 159 OS << TableIndex; 160 } 161 162 Optional<StringRef> emitValueTable(raw_ostream &OS) const override { 163 if (TableIndex == -1) 164 return {}; 165 OS << "static const SimpleEnumValue " << ValueTableName << "[] = {\n"; 166 for (unsigned I = 0, E = Values.size(); I != E; ++I) { 167 OS << "{"; 168 write_cstring(OS, Values[I]); 169 OS << ","; 170 OS << "static_cast<unsigned>("; 171 emitScopedNormalizedValue(OS, NormalizedValues[I]); 172 OS << ")},"; 173 } 174 OS << "};\n"; 175 return StringRef(ValueTableName); 176 } 177 178 static std::unique_ptr<MarshallingKindInfo> create(const Record &R) { 179 assert(!isa<UnsetInit>(R.getValueInit("NormalizerRetTy")) && 180 "String options must have a type"); 181 182 std::unique_ptr<MarshallingStringInfo> Ret(new MarshallingStringInfo(R)); 183 Ret->NormalizerRetTy = R.getValueAsString("NormalizerRetTy"); 184 185 Ret->Normalizer = R.getValueAsString("Normalizer"); 186 Ret->Denormalizer = R.getValueAsString("Denormalizer"); 187 188 if (!isa<UnsetInit>(R.getValueInit("NormalizedValues"))) { 189 assert(!isa<UnsetInit>(R.getValueInit("Values")) && 190 "Cannot provide normalized values for value-less options"); 191 Ret->TableIndex = NextTableIndex++; 192 Ret->NormalizedValues = R.getValueAsListOfStrings("NormalizedValues"); 193 Ret->Values.reserve(Ret->NormalizedValues.size()); 194 Ret->ValueTableName = getOptionName(R) + "ValueTable"; 195 196 StringRef ValuesStr = R.getValueAsString("Values"); 197 for (;;) { 198 size_t Idx = ValuesStr.find(','); 199 if (Idx == StringRef::npos) 200 break; 201 if (Idx > 0) 202 Ret->Values.push_back(ValuesStr.slice(0, Idx)); 203 ValuesStr = ValuesStr.slice(Idx + 1, StringRef::npos); 204 } 205 if (!ValuesStr.empty()) 206 Ret->Values.push_back(ValuesStr); 207 208 assert(Ret->Values.size() == Ret->NormalizedValues.size() && 209 "The number of normalized values doesn't match the number of " 210 "values"); 211 } 212 213 // FIXME: This is a workaround for a bug in older versions of clang (< 3.9) 214 // The constructor that is supposed to allow for Derived to Base 215 // conversion does not work. Remove this if we drop support for such 216 // configurations. 217 return std::unique_ptr<MarshallingKindInfo>(Ret.release()); 218 } 219 220 private: 221 MarshallingStringInfo(const Record &R) 222 : MarshallingKindInfo(R, "OPTION_WITH_MARSHALLING_STRING") {} 223 224 static size_t NextTableIndex; 225 }; 226 227 size_t MarshallingStringInfo::NextTableIndex = 0; 228 229 std::unique_ptr<MarshallingKindInfo> 230 MarshallingKindInfo::create(const Record &R) { 231 assert(!isa<UnsetInit>(R.getValueInit("KeyPath")) && 232 !isa<UnsetInit>(R.getValueInit("DefaultValue")) && 233 "Must provide at least a key-path and a default value for emitting " 234 "marshalling information"); 235 236 std::unique_ptr<MarshallingKindInfo> Ret = nullptr; 237 StringRef MarshallingKindStr = R.getValueAsString("MarshallingKind"); 238 239 if (MarshallingKindStr == "flag") 240 Ret = MarshallingFlagInfo::create(R); 241 else if (MarshallingKindStr == "string") 242 Ret = MarshallingStringInfo::create(R); 243 244 Ret->ShouldAlwaysEmit = R.getValueAsBit("ShouldAlwaysEmit"); 245 Ret->KeyPath = R.getValueAsString("KeyPath"); 246 Ret->DefaultValue = R.getValueAsString("DefaultValue"); 247 if (!isa<UnsetInit>(R.getValueInit("NormalizedValuesScope"))) 248 Ret->NormalizedValuesScope = R.getValueAsString("NormalizedValuesScope"); 249 return Ret; 250 } 251 252 /// OptParserEmitter - This tablegen backend takes an input .td file 253 /// describing a list of options and emits a data structure for parsing and 254 /// working with those options when given an input command line. 255 namespace llvm { 256 void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) { 257 // Get the option groups and options. 258 const std::vector<Record*> &Groups = 259 Records.getAllDerivedDefinitions("OptionGroup"); 260 std::vector<Record*> Opts = Records.getAllDerivedDefinitions("Option"); 261 262 emitSourceFileHeader("Option Parsing Definitions", OS); 263 264 array_pod_sort(Opts.begin(), Opts.end(), CompareOptionRecords); 265 // Generate prefix groups. 266 typedef SmallVector<SmallString<2>, 2> PrefixKeyT; 267 typedef std::map<PrefixKeyT, std::string> PrefixesT; 268 PrefixesT Prefixes; 269 Prefixes.insert(std::make_pair(PrefixKeyT(), "prefix_0")); 270 unsigned CurPrefix = 0; 271 for (unsigned i = 0, e = Opts.size(); i != e; ++i) { 272 const Record &R = *Opts[i]; 273 std::vector<StringRef> prf = R.getValueAsListOfStrings("Prefixes"); 274 PrefixKeyT prfkey(prf.begin(), prf.end()); 275 unsigned NewPrefix = CurPrefix + 1; 276 if (Prefixes.insert(std::make_pair(prfkey, (Twine("prefix_") + 277 Twine(NewPrefix)).str())).second) 278 CurPrefix = NewPrefix; 279 } 280 281 // Dump prefixes. 282 283 OS << "/////////\n"; 284 OS << "// Prefixes\n\n"; 285 OS << "#ifdef PREFIX\n"; 286 OS << "#define COMMA ,\n"; 287 for (PrefixesT::const_iterator I = Prefixes.begin(), E = Prefixes.end(); 288 I != E; ++I) { 289 OS << "PREFIX("; 290 291 // Prefix name. 292 OS << I->second; 293 294 // Prefix values. 295 OS << ", {"; 296 for (PrefixKeyT::const_iterator PI = I->first.begin(), 297 PE = I->first.end(); PI != PE; ++PI) { 298 OS << "\"" << *PI << "\" COMMA "; 299 } 300 OS << "nullptr})\n"; 301 } 302 OS << "#undef COMMA\n"; 303 OS << "#endif // PREFIX\n\n"; 304 305 OS << "/////////\n"; 306 OS << "// Groups\n\n"; 307 OS << "#ifdef OPTION\n"; 308 for (unsigned i = 0, e = Groups.size(); i != e; ++i) { 309 const Record &R = *Groups[i]; 310 311 // Start a single option entry. 312 OS << "OPTION("; 313 314 // The option prefix; 315 OS << "nullptr"; 316 317 // The option string. 318 OS << ", \"" << R.getValueAsString("Name") << '"'; 319 320 // The option identifier name. 321 OS << ", " << getOptionName(R); 322 323 // The option kind. 324 OS << ", Group"; 325 326 // The containing option group (if any). 327 OS << ", "; 328 if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) 329 OS << getOptionName(*DI->getDef()); 330 else 331 OS << "INVALID"; 332 333 // The other option arguments (unused for groups). 334 OS << ", INVALID, nullptr, 0, 0"; 335 336 // The option help text. 337 if (!isa<UnsetInit>(R.getValueInit("HelpText"))) { 338 OS << ",\n"; 339 OS << " "; 340 write_cstring(OS, R.getValueAsString("HelpText")); 341 } else 342 OS << ", nullptr"; 343 344 // The option meta-variable name (unused). 345 OS << ", nullptr"; 346 347 // The option Values (unused for groups). 348 OS << ", nullptr)\n"; 349 } 350 OS << "\n"; 351 352 OS << "//////////\n"; 353 OS << "// Options\n\n"; 354 355 auto WriteOptRecordFields = [&](raw_ostream &OS, const Record &R) { 356 // The option prefix; 357 std::vector<StringRef> prf = R.getValueAsListOfStrings("Prefixes"); 358 OS << Prefixes[PrefixKeyT(prf.begin(), prf.end())] << ", "; 359 360 // The option string. 361 emitNameUsingSpelling(OS, R); 362 363 // The option identifier name. 364 OS << ", " << getOptionName(R); 365 366 // The option kind. 367 OS << ", " << R.getValueAsDef("Kind")->getValueAsString("Name"); 368 369 // The containing option group (if any). 370 OS << ", "; 371 const ListInit *GroupFlags = nullptr; 372 if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) { 373 GroupFlags = DI->getDef()->getValueAsListInit("Flags"); 374 OS << getOptionName(*DI->getDef()); 375 } else 376 OS << "INVALID"; 377 378 // The option alias (if any). 379 OS << ", "; 380 if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Alias"))) 381 OS << getOptionName(*DI->getDef()); 382 else 383 OS << "INVALID"; 384 385 // The option alias arguments (if any). 386 // Emitted as a \0 separated list in a string, e.g. ["foo", "bar"] 387 // would become "foo\0bar\0". Note that the compiler adds an implicit 388 // terminating \0 at the end. 389 OS << ", "; 390 std::vector<StringRef> AliasArgs = R.getValueAsListOfStrings("AliasArgs"); 391 if (AliasArgs.size() == 0) { 392 OS << "nullptr"; 393 } else { 394 OS << "\""; 395 for (size_t i = 0, e = AliasArgs.size(); i != e; ++i) 396 OS << AliasArgs[i] << "\\0"; 397 OS << "\""; 398 } 399 400 // The option flags. 401 OS << ", "; 402 int NumFlags = 0; 403 const ListInit *LI = R.getValueAsListInit("Flags"); 404 for (Init *I : *LI) 405 OS << (NumFlags++ ? " | " : "") << cast<DefInit>(I)->getDef()->getName(); 406 if (GroupFlags) { 407 for (Init *I : *GroupFlags) 408 OS << (NumFlags++ ? " | " : "") 409 << cast<DefInit>(I)->getDef()->getName(); 410 } 411 if (NumFlags == 0) 412 OS << '0'; 413 414 // The option parameter field. 415 OS << ", " << R.getValueAsInt("NumArgs"); 416 417 // The option help text. 418 if (!isa<UnsetInit>(R.getValueInit("HelpText"))) { 419 OS << ",\n"; 420 OS << " "; 421 write_cstring(OS, R.getValueAsString("HelpText")); 422 } else 423 OS << ", nullptr"; 424 425 // The option meta-variable name. 426 OS << ", "; 427 if (!isa<UnsetInit>(R.getValueInit("MetaVarName"))) 428 write_cstring(OS, R.getValueAsString("MetaVarName")); 429 else 430 OS << "nullptr"; 431 432 // The option Values. Used for shell autocompletion. 433 OS << ", "; 434 if (!isa<UnsetInit>(R.getValueInit("Values"))) 435 write_cstring(OS, R.getValueAsString("Values")); 436 else 437 OS << "nullptr"; 438 }; 439 440 auto IsMarshallingOption = [](const Record &R) { 441 return !isa<UnsetInit>(R.getValueInit("MarshallingKind")) && 442 !R.getValueAsString("KeyPath").empty(); 443 }; 444 445 std::vector<const Record *> OptsWithMarshalling; 446 for (unsigned I = 0, E = Opts.size(); I != E; ++I) { 447 const Record &R = *Opts[I]; 448 449 // Start a single option entry. 450 OS << "OPTION("; 451 WriteOptRecordFields(OS, R); 452 OS << ")\n"; 453 if (IsMarshallingOption(R)) 454 OptsWithMarshalling.push_back(&R); 455 } 456 OS << "#endif // OPTION\n"; 457 458 auto CmpMarshallingOpts = [](const Record *const *A, const Record *const *B) { 459 unsigned AID = (*A)->getID(); 460 unsigned BID = (*B)->getID(); 461 462 if (AID < BID) 463 return -1; 464 if (AID > BID) 465 return 1; 466 return 0; 467 }; 468 // The RecordKeeper stores records (options) in lexicographical order, and we 469 // have reordered the options again when generating prefix groups. We need to 470 // restore the original definition order of options with marshalling to honor 471 // the topology of the dependency graph implied by `DefaultAnyOf`. 472 array_pod_sort(OptsWithMarshalling.begin(), OptsWithMarshalling.end(), 473 CmpMarshallingOpts); 474 475 std::vector<std::unique_ptr<MarshallingKindInfo>> MarshallingKindInfos; 476 for (const auto *R : OptsWithMarshalling) 477 MarshallingKindInfos.push_back(MarshallingKindInfo::create(*R)); 478 479 for (const auto &KindInfo : MarshallingKindInfos) { 480 OS << "#ifdef " << KindInfo->MacroName << "\n"; 481 OS << KindInfo->MacroName << "("; 482 WriteOptRecordFields(OS, KindInfo->R); 483 OS << ", "; 484 KindInfo->emit(OS); 485 OS << ")\n"; 486 OS << "#endif // " << KindInfo->MacroName << "\n"; 487 } 488 489 OS << "\n"; 490 OS << "#ifdef SIMPLE_ENUM_VALUE_TABLE"; 491 OS << "\n"; 492 OS << MarshallingStringInfo::ValueTablePreamble; 493 std::vector<StringRef> ValueTableNames; 494 for (const auto &KindInfo : MarshallingKindInfos) 495 if (auto MaybeValueTableName = KindInfo->emitValueTable(OS)) 496 ValueTableNames.push_back(*MaybeValueTableName); 497 498 OS << MarshallingStringInfo::ValueTablesDecl << "{"; 499 for (auto ValueTableName : ValueTableNames) 500 OS << "{" << ValueTableName << ", sizeof(" << ValueTableName 501 << ") / sizeof(SimpleEnumValue)" 502 << "},\n"; 503 OS << "};\n"; 504 OS << "static const unsigned SimpleEnumValueTablesSize = " 505 "sizeof(SimpleEnumValueTables) / sizeof(SimpleEnumValueTable);\n"; 506 507 OS << "#endif // SIMPLE_ENUM_VALUE_TABLE\n"; 508 OS << "\n"; 509 510 OS << "\n"; 511 OS << "#ifdef OPTTABLE_ARG_INIT\n"; 512 OS << "//////////\n"; 513 OS << "// Option Values\n\n"; 514 for (unsigned I = 0, E = Opts.size(); I != E; ++I) { 515 const Record &R = *Opts[I]; 516 if (isa<UnsetInit>(R.getValueInit("ValuesCode"))) 517 continue; 518 OS << "{\n"; 519 OS << "bool ValuesWereAdded;\n"; 520 OS << R.getValueAsString("ValuesCode"); 521 OS << "\n"; 522 for (StringRef Prefix : R.getValueAsListOfStrings("Prefixes")) { 523 OS << "ValuesWereAdded = Opt.addValues("; 524 std::string S(Prefix); 525 S += R.getValueAsString("Name"); 526 write_cstring(OS, S); 527 OS << ", Values);\n"; 528 OS << "(void)ValuesWereAdded;\n"; 529 OS << "assert(ValuesWereAdded && \"Couldn't add values to " 530 "OptTable!\");\n"; 531 } 532 OS << "}\n"; 533 } 534 OS << "\n"; 535 OS << "#endif // OPTTABLE_ARG_INIT\n"; 536 } 537 } // end namespace llvm 538