OptParserEmitter.cpp revision 327952
175295Sdes//===- OptParserEmitter.cpp - Table Driven Command Line Parsing -----------===// 2230132Suqs// 375295Sdes// The LLVM Compiler Infrastructure 475295Sdes// 575295Sdes// This file is distributed under the University of Illinois Open Source 675295Sdes// License. See LICENSE.TXT for details. 775295Sdes// 875295Sdes//===----------------------------------------------------------------------===// 975295Sdes 1075295Sdes#include "llvm/TableGen/Error.h" 1175295Sdes#include "llvm/ADT/STLExtras.h" 1275295Sdes#include "llvm/ADT/SmallString.h" 1375295Sdes#include "llvm/ADT/Twine.h" 1475295Sdes#include "llvm/TableGen/Record.h" 1575295Sdes#include "llvm/TableGen/TableGenBackend.h" 1675295Sdes#include <cctype> 1775295Sdes#include <cstring> 1875295Sdes#include <map> 1975295Sdes 2075295Sdesusing namespace llvm; 2175295Sdes 2275295Sdes// Ordering on Info. The logic should match with the consumer-side function in 2375295Sdes// llvm/Option/OptTable.h. 2475295Sdes// FIXME: Mmake this take StringRefs instead of null terminated strings to 2575295Sdes// simplify callers. 2675295Sdesstatic int StrCmpOptionName(const char *A, const char *B) { 2775295Sdes const char *X = A, *Y = B; 2875295Sdes char a = tolower(*A), b = tolower(*B); 2975295Sdes while (a == b) { 3075295Sdes if (a == '\0') 3175295Sdes return strcmp(A, B); 3275295Sdes 3375295Sdes a = tolower(*++X); 3475295Sdes b = tolower(*++Y); 3575295Sdes } 3675295Sdes 3775295Sdes if (a == '\0') // A is a prefix of B. 3875295Sdes return 1; 3975295Sdes if (b == '\0') // B is a prefix of A. 4077998Sdes return -1; 4177998Sdes 4277998Sdes // Otherwise lexicographic. 4377998Sdes return (a < b) ? -1 : 1; 4477998Sdes} 4584247Sdes 4684247Sdesstatic int CompareOptionRecords(Record *const *Av, Record *const *Bv) { 47168637Sdes const Record *A = *Av; 4877998Sdes const Record *B = *Bv; 4977998Sdes 5077998Sdes // Sentinel options precede all others and are only ordered by precedence. 5175295Sdes bool ASent = A->getValueAsDef("Kind")->getValueAsBit("Sentinel"); 5275295Sdes bool BSent = B->getValueAsDef("Kind")->getValueAsBit("Sentinel"); 5375295Sdes if (ASent != BSent) 5475295Sdes return ASent ? -1 : 1; 5575295Sdes 5677998Sdes // Compare options by name, unless they are sentinels. 5775295Sdes if (!ASent) 5875295Sdes if (int Cmp = StrCmpOptionName(A->getValueAsString("Name").str().c_str(), 5975295Sdes B->getValueAsString("Name").str().c_str())) 6075295Sdes return Cmp; 6175295Sdes 6275295Sdes if (!ASent) { 6375295Sdes std::vector<StringRef> APrefixes = A->getValueAsListOfStrings("Prefixes"); 64168720Sdes std::vector<StringRef> BPrefixes = B->getValueAsListOfStrings("Prefixes"); 65168720Sdes 6675295Sdes for (std::vector<StringRef>::const_iterator APre = APrefixes.begin(), 67168764Sdes AEPre = APrefixes.end(), 68168764Sdes BPre = BPrefixes.begin(), 69168764Sdes BEPre = BPrefixes.end(); 70168764Sdes APre != AEPre && 71168764Sdes BPre != BEPre; 72168764Sdes ++APre, ++BPre) { 73168764Sdes if (int Cmp = StrCmpOptionName(APre->str().c_str(), BPre->str().c_str())) 74168764Sdes return Cmp; 75168764Sdes } 76168764Sdes } 77168764Sdes 78168764Sdes // Then by the kind precedence; 79168764Sdes int APrec = A->getValueAsDef("Kind")->getValueAsInt("Precedence"); 80168764Sdes int BPrec = B->getValueAsDef("Kind")->getValueAsInt("Precedence"); 81168764Sdes if (APrec == BPrec && 82168764Sdes A->getValueAsListOfStrings("Prefixes") == 83168764Sdes B->getValueAsListOfStrings("Prefixes")) { 84168764Sdes PrintError(A->getLoc(), Twine("Option is equivalent to")); 85168764Sdes PrintError(B->getLoc(), Twine("Other defined here")); 86168764Sdes PrintFatalError("Equivalent Options found."); 87168764Sdes } 88168764Sdes return APrec < BPrec ? -1 : 1; 89168764Sdes} 90168764Sdes 91168764Sdesstatic const std::string getOptionName(const Record &R) { 92168764Sdes // Use the record name unless EnumName is defined. 93168764Sdes if (isa<UnsetInit>(R.getValueInit("EnumName"))) 9475295Sdes return R.getName(); 95168764Sdes 96168764Sdes return R.getValueAsString("EnumName"); 97168764Sdes} 98168764Sdes 99168764Sdesstatic raw_ostream &write_cstring(raw_ostream &OS, llvm::StringRef Str) { 100168764Sdes OS << '"'; 101168764Sdes OS.write_escaped(Str); 102168764Sdes OS << '"'; 103168764Sdes return OS; 104168764Sdes} 105168764Sdes 106168764Sdes/// OptParserEmitter - This tablegen backend takes an input .td file 107168764Sdes/// describing a list of options and emits a data structure for parsing and 108168764Sdes/// working with those options when given an input command line. 109168764Sdesnamespace llvm { 110168764Sdesvoid EmitOptParser(RecordKeeper &Records, raw_ostream &OS) { 111168764Sdes // Get the option groups and options. 112168764Sdes const std::vector<Record*> &Groups = 113168764Sdes Records.getAllDerivedDefinitions("OptionGroup"); 114168764Sdes std::vector<Record*> Opts = Records.getAllDerivedDefinitions("Option"); 115168764Sdes 116168764Sdes emitSourceFileHeader("Option Parsing Definitions", OS); 117168764Sdes 118168764Sdes array_pod_sort(Opts.begin(), Opts.end(), CompareOptionRecords); 119168764Sdes // Generate prefix groups. 120168764Sdes typedef SmallVector<SmallString<2>, 2> PrefixKeyT; 121168764Sdes typedef std::map<PrefixKeyT, std::string> PrefixesT; 122168764Sdes PrefixesT Prefixes; 123168764Sdes Prefixes.insert(std::make_pair(PrefixKeyT(), "prefix_0")); 124168764Sdes unsigned CurPrefix = 0; 125168764Sdes for (unsigned i = 0, e = Opts.size(); i != e; ++i) { 126168764Sdes const Record &R = *Opts[i]; 127168764Sdes std::vector<StringRef> prf = R.getValueAsListOfStrings("Prefixes"); 128168764Sdes PrefixKeyT prfkey(prf.begin(), prf.end()); 129168764Sdes unsigned NewPrefix = CurPrefix + 1; 130168764Sdes if (Prefixes.insert(std::make_pair(prfkey, (Twine("prefix_") + 131168764Sdes Twine(NewPrefix)).str())).second) 132168764Sdes CurPrefix = NewPrefix; 133168764Sdes } 134168764Sdes 135168764Sdes // Dump prefixes. 136168764Sdes 137168764Sdes OS << "/////////\n"; 138168764Sdes OS << "// Prefixes\n\n"; 139168764Sdes OS << "#ifdef PREFIX\n"; 140168764Sdes OS << "#define COMMA ,\n"; 141168764Sdes for (PrefixesT::const_iterator I = Prefixes.begin(), E = Prefixes.end(); 142168764Sdes I != E; ++I) { 143168764Sdes OS << "PREFIX("; 144168764Sdes 145168764Sdes // Prefix name. 146168764Sdes OS << I->second; 147168764Sdes 148168764Sdes // Prefix values. 149168764Sdes OS << ", {"; 150168764Sdes for (PrefixKeyT::const_iterator PI = I->first.begin(), 151168764Sdes PE = I->first.end(); PI != PE; ++PI) { 152168764Sdes OS << "\"" << *PI << "\" COMMA "; 153168764Sdes } 154168764Sdes OS << "nullptr})\n"; 155168764Sdes } 156168764Sdes OS << "#undef COMMA\n"; 157168764Sdes OS << "#endif // PREFIX\n\n"; 158168764Sdes 159168764Sdes OS << "/////////\n"; 160168764Sdes OS << "// Groups\n\n"; 161168764Sdes OS << "#ifdef OPTION\n"; 162168764Sdes for (unsigned i = 0, e = Groups.size(); i != e; ++i) { 163168764Sdes const Record &R = *Groups[i]; 164168764Sdes 165168764Sdes // Start a single option entry. 166168764Sdes OS << "OPTION("; 167168764Sdes 168168764Sdes // The option prefix; 169168764Sdes OS << "nullptr"; 170168764Sdes 171168764Sdes // The option string. 172168764Sdes OS << ", \"" << R.getValueAsString("Name") << '"'; 173168764Sdes 174168764Sdes // The option identifier name. 175168764Sdes OS << ", "<< getOptionName(R); 176168764Sdes 177168764Sdes // The option kind. 178168764Sdes OS << ", Group"; 179168764Sdes 180168764Sdes // The containing option group (if any). 181168764Sdes OS << ", "; 182168764Sdes if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) 183168764Sdes OS << getOptionName(*DI->getDef()); 184168764Sdes else 185168764Sdes OS << "INVALID"; 186168764Sdes 187168764Sdes // The other option arguments (unused for groups). 188168764Sdes OS << ", INVALID, nullptr, 0, 0"; 189168764Sdes 190168764Sdes // The option help text. 191168764Sdes if (!isa<UnsetInit>(R.getValueInit("HelpText"))) { 192168764Sdes OS << ",\n"; 193168764Sdes OS << " "; 194168764Sdes write_cstring(OS, R.getValueAsString("HelpText")); 195168764Sdes } else 196168764Sdes OS << ", nullptr"; 197168764Sdes 198168764Sdes // The option meta-variable name (unused). 199168764Sdes OS << ", nullptr"; 200168764Sdes 201168764Sdes // The option Values (unused for groups). 202168764Sdes OS << ", nullptr)\n"; 203168764Sdes } 204168764Sdes OS << "\n"; 205168764Sdes 206168764Sdes OS << "//////////\n"; 207168764Sdes OS << "// Options\n\n"; 208168764Sdes for (unsigned i = 0, e = Opts.size(); i != e; ++i) { 209168764Sdes const Record &R = *Opts[i]; 210168764Sdes 211168764Sdes // 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