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