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