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 "llvm/TableGen/Error.h" 10 #include "llvm/ADT/STLExtras.h" 11 #include "llvm/ADT/SmallString.h" 12 #include "llvm/ADT/Twine.h" 13 #include "llvm/TableGen/Record.h" 14 #include "llvm/TableGen/TableGenBackend.h" 15 #include <cctype> 16 #include <cstring> 17 #include <map> 18 19 using namespace llvm; 20 21 // Ordering on Info. The logic should match with the consumer-side function in 22 // llvm/Option/OptTable.h. 23 // FIXME: Mmake this take StringRefs instead of null terminated strings to 24 // simplify callers. 25 static int StrCmpOptionName(const char *A, const char *B) { 26 const char *X = A, *Y = B; 27 char a = tolower(*A), b = tolower(*B); 28 while (a == b) { 29 if (a == '\0') 30 return strcmp(A, B); 31 32 a = tolower(*++X); 33 b = tolower(*++Y); 34 } 35 36 if (a == '\0') // A is a prefix of B. 37 return 1; 38 if (b == '\0') // B is a prefix of A. 39 return -1; 40 41 // Otherwise lexicographic. 42 return (a < b) ? -1 : 1; 43 } 44 45 static int CompareOptionRecords(Record *const *Av, Record *const *Bv) { 46 const Record *A = *Av; 47 const Record *B = *Bv; 48 49 // Sentinel options precede all others and are only ordered by precedence. 50 bool ASent = A->getValueAsDef("Kind")->getValueAsBit("Sentinel"); 51 bool BSent = B->getValueAsDef("Kind")->getValueAsBit("Sentinel"); 52 if (ASent != BSent) 53 return ASent ? -1 : 1; 54 55 // Compare options by name, unless they are sentinels. 56 if (!ASent) 57 if (int Cmp = StrCmpOptionName(A->getValueAsString("Name").str().c_str(), 58 B->getValueAsString("Name").str().c_str())) 59 return Cmp; 60 61 if (!ASent) { 62 std::vector<StringRef> APrefixes = A->getValueAsListOfStrings("Prefixes"); 63 std::vector<StringRef> BPrefixes = B->getValueAsListOfStrings("Prefixes"); 64 65 for (std::vector<StringRef>::const_iterator APre = APrefixes.begin(), 66 AEPre = APrefixes.end(), 67 BPre = BPrefixes.begin(), 68 BEPre = BPrefixes.end(); 69 APre != AEPre && 70 BPre != BEPre; 71 ++APre, ++BPre) { 72 if (int Cmp = StrCmpOptionName(APre->str().c_str(), BPre->str().c_str())) 73 return Cmp; 74 } 75 } 76 77 // Then by the kind precedence; 78 int APrec = A->getValueAsDef("Kind")->getValueAsInt("Precedence"); 79 int BPrec = B->getValueAsDef("Kind")->getValueAsInt("Precedence"); 80 if (APrec == BPrec && 81 A->getValueAsListOfStrings("Prefixes") == 82 B->getValueAsListOfStrings("Prefixes")) { 83 PrintError(A->getLoc(), Twine("Option is equivalent to")); 84 PrintError(B->getLoc(), Twine("Other defined here")); 85 PrintFatalError("Equivalent Options found."); 86 } 87 return APrec < BPrec ? -1 : 1; 88 } 89 90 static const std::string getOptionName(const Record &R) { 91 // Use the record name unless EnumName is defined. 92 if (isa<UnsetInit>(R.getValueInit("EnumName"))) 93 return R.getName(); 94 95 return R.getValueAsString("EnumName"); 96 } 97 98 static raw_ostream &write_cstring(raw_ostream &OS, llvm::StringRef Str) { 99 OS << '"'; 100 OS.write_escaped(Str); 101 OS << '"'; 102 return OS; 103 } 104 105 /// OptParserEmitter - This tablegen backend takes an input .td file 106 /// describing a list of options and emits a data structure for parsing and 107 /// working with those options when given an input command line. 108 namespace llvm { 109 void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) { 110 // Get the option groups and options. 111 const std::vector<Record*> &Groups = 112 Records.getAllDerivedDefinitions("OptionGroup"); 113 std::vector<Record*> Opts = Records.getAllDerivedDefinitions("Option"); 114 115 emitSourceFileHeader("Option Parsing Definitions", OS); 116 117 array_pod_sort(Opts.begin(), Opts.end(), CompareOptionRecords); 118 // Generate prefix groups. 119 typedef SmallVector<SmallString<2>, 2> PrefixKeyT; 120 typedef std::map<PrefixKeyT, std::string> PrefixesT; 121 PrefixesT Prefixes; 122 Prefixes.insert(std::make_pair(PrefixKeyT(), "prefix_0")); 123 unsigned CurPrefix = 0; 124 for (unsigned i = 0, e = Opts.size(); i != e; ++i) { 125 const Record &R = *Opts[i]; 126 std::vector<StringRef> prf = R.getValueAsListOfStrings("Prefixes"); 127 PrefixKeyT prfkey(prf.begin(), prf.end()); 128 unsigned NewPrefix = CurPrefix + 1; 129 if (Prefixes.insert(std::make_pair(prfkey, (Twine("prefix_") + 130 Twine(NewPrefix)).str())).second) 131 CurPrefix = NewPrefix; 132 } 133 134 // Dump prefixes. 135 136 OS << "/////////\n"; 137 OS << "// Prefixes\n\n"; 138 OS << "#ifdef PREFIX\n"; 139 OS << "#define COMMA ,\n"; 140 for (PrefixesT::const_iterator I = Prefixes.begin(), E = Prefixes.end(); 141 I != E; ++I) { 142 OS << "PREFIX("; 143 144 // Prefix name. 145 OS << I->second; 146 147 // Prefix values. 148 OS << ", {"; 149 for (PrefixKeyT::const_iterator PI = I->first.begin(), 150 PE = I->first.end(); PI != PE; ++PI) { 151 OS << "\"" << *PI << "\" COMMA "; 152 } 153 OS << "nullptr})\n"; 154 } 155 OS << "#undef COMMA\n"; 156 OS << "#endif // PREFIX\n\n"; 157 158 OS << "/////////\n"; 159 OS << "// Groups\n\n"; 160 OS << "#ifdef OPTION\n"; 161 for (unsigned i = 0, e = Groups.size(); i != e; ++i) { 162 const Record &R = *Groups[i]; 163 164 // Start a single option entry. 165 OS << "OPTION("; 166 167 // The option prefix; 168 OS << "nullptr"; 169 170 // The option string. 171 OS << ", \"" << R.getValueAsString("Name") << '"'; 172 173 // The option identifier name. 174 OS << ", "<< getOptionName(R); 175 176 // The option kind. 177 OS << ", Group"; 178 179 // The containing option group (if any). 180 OS << ", "; 181 if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) 182 OS << getOptionName(*DI->getDef()); 183 else 184 OS << "INVALID"; 185 186 // The other option arguments (unused for groups). 187 OS << ", INVALID, nullptr, 0, 0"; 188 189 // The option help text. 190 if (!isa<UnsetInit>(R.getValueInit("HelpText"))) { 191 OS << ",\n"; 192 OS << " "; 193 write_cstring(OS, R.getValueAsString("HelpText")); 194 } else 195 OS << ", nullptr"; 196 197 // The option meta-variable name (unused). 198 OS << ", nullptr"; 199 200 // The option Values (unused for groups). 201 OS << ", nullptr)\n"; 202 } 203 OS << "\n"; 204 205 OS << "//////////\n"; 206 OS << "// Options\n\n"; 207 for (unsigned i = 0, e = Opts.size(); i != e; ++i) { 208 const Record &R = *Opts[i]; 209 210 // Start a single option entry. 211 OS << "OPTION("; 212 213 // The option prefix; 214 std::vector<StringRef> prf = R.getValueAsListOfStrings("Prefixes"); 215 OS << Prefixes[PrefixKeyT(prf.begin(), prf.end())] << ", "; 216 217 // The option string. 218 write_cstring(OS, R.getValueAsString("Name")); 219 220 // The option identifier name. 221 OS << ", "<< getOptionName(R); 222 223 // The option kind. 224 OS << ", " << R.getValueAsDef("Kind")->getValueAsString("Name"); 225 226 // The containing option group (if any). 227 OS << ", "; 228 const ListInit *GroupFlags = nullptr; 229 if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) { 230 GroupFlags = DI->getDef()->getValueAsListInit("Flags"); 231 OS << getOptionName(*DI->getDef()); 232 } else 233 OS << "INVALID"; 234 235 // The option alias (if any). 236 OS << ", "; 237 if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Alias"))) 238 OS << getOptionName(*DI->getDef()); 239 else 240 OS << "INVALID"; 241 242 // The option alias arguments (if any). 243 // Emitted as a \0 separated list in a string, e.g. ["foo", "bar"] 244 // would become "foo\0bar\0". Note that the compiler adds an implicit 245 // terminating \0 at the end. 246 OS << ", "; 247 std::vector<StringRef> AliasArgs = R.getValueAsListOfStrings("AliasArgs"); 248 if (AliasArgs.size() == 0) { 249 OS << "nullptr"; 250 } else { 251 OS << "\""; 252 for (size_t i = 0, e = AliasArgs.size(); i != e; ++i) 253 OS << AliasArgs[i] << "\\0"; 254 OS << "\""; 255 } 256 257 // The option flags. 258 OS << ", "; 259 int NumFlags = 0; 260 const ListInit *LI = R.getValueAsListInit("Flags"); 261 for (Init *I : *LI) 262 OS << (NumFlags++ ? " | " : "") 263 << cast<DefInit>(I)->getDef()->getName(); 264 if (GroupFlags) { 265 for (Init *I : *GroupFlags) 266 OS << (NumFlags++ ? " | " : "") 267 << cast<DefInit>(I)->getDef()->getName(); 268 } 269 if (NumFlags == 0) 270 OS << '0'; 271 272 // The option parameter field. 273 OS << ", " << R.getValueAsInt("NumArgs"); 274 275 // The option help text. 276 if (!isa<UnsetInit>(R.getValueInit("HelpText"))) { 277 OS << ",\n"; 278 OS << " "; 279 write_cstring(OS, R.getValueAsString("HelpText")); 280 } else 281 OS << ", nullptr"; 282 283 // The option meta-variable name. 284 OS << ", "; 285 if (!isa<UnsetInit>(R.getValueInit("MetaVarName"))) 286 write_cstring(OS, R.getValueAsString("MetaVarName")); 287 else 288 OS << "nullptr"; 289 290 // The option Values. Used for shell autocompletion. 291 OS << ", "; 292 if (!isa<UnsetInit>(R.getValueInit("Values"))) 293 write_cstring(OS, R.getValueAsString("Values")); 294 else 295 OS << "nullptr"; 296 297 OS << ")\n"; 298 } 299 OS << "#endif // OPTION\n"; 300 301 OS << "\n"; 302 OS << "#ifdef OPTTABLE_ARG_INIT\n"; 303 OS << "//////////\n"; 304 OS << "// Option Values\n\n"; 305 for (unsigned I = 0, E = Opts.size(); I != E; ++I) { 306 const Record &R = *Opts[I]; 307 if (isa<UnsetInit>(R.getValueInit("ValuesCode"))) 308 continue; 309 OS << "{\n"; 310 OS << "bool ValuesWereAdded;\n"; 311 OS << R.getValueAsString("ValuesCode"); 312 OS << "\n"; 313 for (const std::string &Pref : R.getValueAsListOfStrings("Prefixes")) { 314 OS << "ValuesWereAdded = Opt.addValues("; 315 std::string S = (Pref + R.getValueAsString("Name")).str(); 316 write_cstring(OS, S); 317 OS << ", Values);\n"; 318 OS << "(void)ValuesWereAdded;\n"; 319 OS << "assert(ValuesWereAdded && \"Couldn't add values to " 320 "OptTable!\");\n"; 321 } 322 OS << "}\n"; 323 } 324 OS << "\n"; 325 OS << "#endif // OPTTABLE_ARG_INIT\n"; 326 } 327 } // end namespace llvm 328