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