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