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/TableGen/Record.h" 12 #include "llvm/TableGen/TableGenBackend.h" 13 #include "llvm/ADT/STLExtras.h" 14 #include "llvm/ADT/SmallString.h" 15 #include "llvm/ADT/Twine.h" 16 17 #include <map> 18 19 using namespace llvm; 20 21 static int StrCmpOptionName(const char *A, const char *B) { 22 char a = *A, b = *B; 23 while (a == b) { 24 if (a == '\0') 25 return 0; 26 27 a = *++A; 28 b = *++B; 29 } 30 31 if (a == '\0') // A is a prefix of B. 32 return 1; 33 if (b == '\0') // B is a prefix of A. 34 return -1; 35 36 // Otherwise lexicographic. 37 return (a < b) ? -1 : 1; 38 } 39 40 static int CompareOptionRecords(const void *Av, const void *Bv) { 41 const Record *A = *(const Record*const*) Av; 42 const Record *B = *(const Record*const*) Bv; 43 44 // Sentinel options precede all others and are only ordered by precedence. 45 bool ASent = A->getValueAsDef("Kind")->getValueAsBit("Sentinel"); 46 bool BSent = B->getValueAsDef("Kind")->getValueAsBit("Sentinel"); 47 if (ASent != BSent) 48 return ASent ? -1 : 1; 49 50 // Compare options by name, unless they are sentinels. 51 if (!ASent) 52 if (int Cmp = StrCmpOptionName(A->getValueAsString("Name").c_str(), 53 B->getValueAsString("Name").c_str())) 54 return Cmp; 55 56 if (!ASent) { 57 std::vector<std::string> APrefixes = A->getValueAsListOfStrings("Prefixes"); 58 std::vector<std::string> BPrefixes = B->getValueAsListOfStrings("Prefixes"); 59 60 for (std::vector<std::string>::const_iterator APre = APrefixes.begin(), 61 AEPre = APrefixes.end(), 62 BPre = BPrefixes.begin(), 63 BEPre = BPrefixes.end(); 64 APre != AEPre && 65 BPre != BEPre; 66 ++APre, ++BPre) { 67 if (int Cmp = StrCmpOptionName(APre->c_str(), BPre->c_str())) 68 return Cmp; 69 } 70 } 71 72 // Then by the kind precedence; 73 int APrec = A->getValueAsDef("Kind")->getValueAsInt("Precedence"); 74 int BPrec = B->getValueAsDef("Kind")->getValueAsInt("Precedence"); 75 if (APrec == BPrec && 76 A->getValueAsListOfStrings("Prefixes") == 77 B->getValueAsListOfStrings("Prefixes")) { 78 PrintError(A->getLoc(), Twine("Option is equivilent to")); 79 PrintError(B->getLoc(), Twine("Other defined here")); 80 PrintFatalError("Equivalent Options found."); 81 } 82 return APrec < BPrec ? -1 : 1; 83 } 84 85 static const std::string getOptionName(const Record &R) { 86 // Use the record name unless EnumName is defined. 87 if (isa<UnsetInit>(R.getValueInit("EnumName"))) 88 return R.getName(); 89 90 return R.getValueAsString("EnumName"); 91 } 92 93 static raw_ostream &write_cstring(raw_ostream &OS, llvm::StringRef Str) { 94 OS << '"'; 95 OS.write_escaped(Str); 96 OS << '"'; 97 return OS; 98 } 99 100 /// OptParserEmitter - This tablegen backend takes an input .td file 101 /// describing a list of options and emits a data structure for parsing and 102 /// working with those options when given an input command line. 103 namespace llvm { 104 void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) { 105 // Get the option groups and options. 106 const std::vector<Record*> &Groups = 107 Records.getAllDerivedDefinitions("OptionGroup"); 108 std::vector<Record*> Opts = Records.getAllDerivedDefinitions("Option"); 109 110 emitSourceFileHeader("Option Parsing Definitions", OS); 111 112 array_pod_sort(Opts.begin(), Opts.end(), CompareOptionRecords); 113 // Generate prefix groups. 114 typedef SmallVector<SmallString<2>, 2> PrefixKeyT; 115 typedef std::map<PrefixKeyT, std::string> PrefixesT; 116 PrefixesT Prefixes; 117 Prefixes.insert(std::make_pair(PrefixKeyT(), "prefix_0")); 118 unsigned CurPrefix = 0; 119 for (unsigned i = 0, e = Opts.size(); i != e; ++i) { 120 const Record &R = *Opts[i]; 121 std::vector<std::string> prf = R.getValueAsListOfStrings("Prefixes"); 122 PrefixKeyT prfkey(prf.begin(), prf.end()); 123 unsigned NewPrefix = CurPrefix + 1; 124 if (Prefixes.insert(std::make_pair(prfkey, (Twine("prefix_") + 125 Twine(NewPrefix)).str())).second) 126 CurPrefix = NewPrefix; 127 } 128 129 // Dump prefixes. 130 131 OS << "/////////\n"; 132 OS << "// Prefixes\n\n"; 133 OS << "#ifdef PREFIX\n"; 134 OS << "#define COMMA ,\n"; 135 for (PrefixesT::const_iterator I = Prefixes.begin(), E = Prefixes.end(); 136 I != E; ++I) { 137 OS << "PREFIX("; 138 139 // Prefix name. 140 OS << I->second; 141 142 // Prefix values. 143 OS << ", {"; 144 for (PrefixKeyT::const_iterator PI = I->first.begin(), 145 PE = I->first.end(); PI != PE; ++PI) { 146 OS << "\"" << *PI << "\" COMMA "; 147 } 148 OS << "0})\n"; 149 } 150 OS << "#undef COMMA\n"; 151 OS << "#endif\n\n"; 152 153 OS << "/////////\n"; 154 OS << "// Groups\n\n"; 155 OS << "#ifdef OPTION\n"; 156 for (unsigned i = 0, e = Groups.size(); i != e; ++i) { 157 const Record &R = *Groups[i]; 158 159 // Start a single option entry. 160 OS << "OPTION("; 161 162 // The option prefix; 163 OS << "0"; 164 165 // The option string. 166 OS << ", \"" << R.getValueAsString("Name") << '"'; 167 168 // The option identifier name. 169 OS << ", "<< getOptionName(R); 170 171 // The option kind. 172 OS << ", Group"; 173 174 // The containing option group (if any). 175 OS << ", "; 176 if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) 177 OS << getOptionName(*DI->getDef()); 178 else 179 OS << "INVALID"; 180 181 // The other option arguments (unused for groups). 182 OS << ", INVALID, 0, 0"; 183 184 // The option help text. 185 if (!isa<UnsetInit>(R.getValueInit("HelpText"))) { 186 OS << ",\n"; 187 OS << " "; 188 write_cstring(OS, R.getValueAsString("HelpText")); 189 } else 190 OS << ", 0"; 191 192 // The option meta-variable name (unused). 193 OS << ", 0)\n"; 194 } 195 OS << "\n"; 196 197 OS << "//////////\n"; 198 OS << "// Options\n\n"; 199 for (unsigned i = 0, e = Opts.size(); i != e; ++i) { 200 const Record &R = *Opts[i]; 201 202 // Start a single option entry. 203 OS << "OPTION("; 204 205 // The option prefix; 206 std::vector<std::string> prf = R.getValueAsListOfStrings("Prefixes"); 207 OS << Prefixes[PrefixKeyT(prf.begin(), prf.end())] << ", "; 208 209 // The option string. 210 write_cstring(OS, R.getValueAsString("Name")); 211 212 // The option identifier name. 213 OS << ", "<< getOptionName(R); 214 215 // The option kind. 216 OS << ", " << R.getValueAsDef("Kind")->getValueAsString("Name"); 217 218 // The containing option group (if any). 219 OS << ", "; 220 if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) 221 OS << getOptionName(*DI->getDef()); 222 else 223 OS << "INVALID"; 224 225 // The option alias (if any). 226 OS << ", "; 227 if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Alias"))) 228 OS << getOptionName(*DI->getDef()); 229 else 230 OS << "INVALID"; 231 232 // The option flags. 233 const ListInit *LI = R.getValueAsListInit("Flags"); 234 if (LI->empty()) { 235 OS << ", 0"; 236 } else { 237 OS << ", "; 238 for (unsigned i = 0, e = LI->size(); i != e; ++i) { 239 if (i) 240 OS << " | "; 241 OS << cast<DefInit>(LI->getElement(i))->getDef()->getName(); 242 } 243 } 244 245 // The option parameter field. 246 OS << ", " << R.getValueAsInt("NumArgs"); 247 248 // The option help text. 249 if (!isa<UnsetInit>(R.getValueInit("HelpText"))) { 250 OS << ",\n"; 251 OS << " "; 252 write_cstring(OS, R.getValueAsString("HelpText")); 253 } else 254 OS << ", 0"; 255 256 // The option meta-variable name. 257 OS << ", "; 258 if (!isa<UnsetInit>(R.getValueInit("MetaVarName"))) 259 write_cstring(OS, R.getValueAsString("MetaVarName")); 260 else 261 OS << "0"; 262 263 OS << ")\n"; 264 } 265 OS << "#endif\n"; 266 } 267 } // end namespace llvm 268