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