diff options
Diffstat (limited to 'utils/TableGen/OptParserEmitter.cpp')
| -rw-r--r-- | utils/TableGen/OptParserEmitter.cpp | 101 | 
1 files changed, 89 insertions, 12 deletions
diff --git a/utils/TableGen/OptParserEmitter.cpp b/utils/TableGen/OptParserEmitter.cpp index b0431a9be16b..674c89af9f99 100644 --- a/utils/TableGen/OptParserEmitter.cpp +++ b/utils/TableGen/OptParserEmitter.cpp @@ -7,9 +7,15 @@  //  //===----------------------------------------------------------------------===// +#include "llvm/TableGen/Error.h"  #include "llvm/TableGen/Record.h"  #include "llvm/TableGen/TableGenBackend.h"  #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/Twine.h" + +#include <map> +  using namespace llvm;  static int StrCmpOptionName(const char *A, const char *B) { @@ -32,8 +38,8 @@ static int StrCmpOptionName(const char *A, const char *B) {  }  static int CompareOptionRecords(const void *Av, const void *Bv) { -  const Record *A = *(Record**) Av; -  const Record *B = *(Record**) Bv; +  const Record *A = *(const Record*const*) Av; +  const Record *B = *(const Record*const*) Bv;    // Sentinel options precede all others and are only ordered by precedence.    bool ASent = A->getValueAsDef("Kind")->getValueAsBit("Sentinel"); @@ -47,16 +53,38 @@ static int CompareOptionRecords(const void *Av, const void *Bv) {                                     B->getValueAsString("Name").c_str()))      return Cmp; +  if (!ASent) { +    std::vector<std::string> APrefixes = A->getValueAsListOfStrings("Prefixes"); +    std::vector<std::string> BPrefixes = B->getValueAsListOfStrings("Prefixes"); + +    for (std::vector<std::string>::const_iterator APre = APrefixes.begin(), +                                                  AEPre = APrefixes.end(), +                                                  BPre = BPrefixes.begin(), +                                                  BEPre = BPrefixes.end(); +                                                  APre != AEPre && +                                                  BPre != BEPre; +                                                  ++APre, ++BPre) { +      if (int Cmp = StrCmpOptionName(APre->c_str(), BPre->c_str())) +        return Cmp; +    } +  } +    // Then by the kind precedence;    int APrec = A->getValueAsDef("Kind")->getValueAsInt("Precedence");    int BPrec = B->getValueAsDef("Kind")->getValueAsInt("Precedence"); -  assert(APrec != BPrec && "Options are equivalent!"); +  if (APrec == BPrec && +      A->getValueAsListOfStrings("Prefixes") == +      B->getValueAsListOfStrings("Prefixes")) { +    PrintError(A->getLoc(), Twine("Option is equivilent to")); +    PrintError(B->getLoc(), Twine("Other defined here")); +    PrintFatalError("Equivalent Options found."); +  }    return APrec < BPrec ? -1 : 1;  }  static const std::string getOptionName(const Record &R) {    // Use the record name unless EnumName is defined. -  if (dynamic_cast<UnsetInit*>(R.getValueInit("EnumName"))) +  if (isa<UnsetInit>(R.getValueInit("EnumName")))      return R.getName();    return R.getValueAsString("EnumName"); @@ -86,6 +114,48 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS, bool GenDefs) {    array_pod_sort(Opts.begin(), Opts.end(), CompareOptionRecords);    if (GenDefs) { +    // Generate prefix groups. +    typedef SmallVector<SmallString<2>, 2> PrefixKeyT; +    typedef std::map<PrefixKeyT, std::string> PrefixesT; +    PrefixesT Prefixes; +    Prefixes.insert(std::make_pair(PrefixKeyT(), "prefix_0")); +    unsigned CurPrefix = 0; +    for (unsigned i = 0, e = Opts.size(); i != e; ++i) { +      const Record &R = *Opts[i]; +      std::vector<std::string> prf = R.getValueAsListOfStrings("Prefixes"); +      PrefixKeyT prfkey(prf.begin(), prf.end()); +      unsigned NewPrefix = CurPrefix + 1; +      if (Prefixes.insert(std::make_pair(prfkey, (Twine("prefix_") + +                                               Twine(NewPrefix)).str())).second) +        CurPrefix = NewPrefix; +    } + +    OS << "#ifndef PREFIX\n"; +    OS << "#error \"Define PREFIX prior to including this file!\"\n"; +    OS << "#endif\n\n"; + +    // Dump prefixes. +    OS << "/////////\n"; +    OS << "// Prefixes\n\n"; +    OS << "#define COMMA ,\n"; +    for (PrefixesT::const_iterator I = Prefixes.begin(), E = Prefixes.end(); +                                   I != E; ++I) { +      OS << "PREFIX("; + +      // Prefix name. +      OS << I->second; + +      // Prefix values. +      OS << ", {"; +      for (PrefixKeyT::const_iterator PI = I->first.begin(), +                                      PE = I->first.end(); PI != PE; ++PI) { +        OS << "\"" << *PI << "\" COMMA "; +      } +      OS << "0})\n"; +    } +    OS << "#undef COMMA\n"; +    OS << "\n"; +      OS << "#ifndef OPTION\n";      OS << "#error \"Define OPTION prior to including this file!\"\n";      OS << "#endif\n\n"; @@ -98,8 +168,11 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS, bool GenDefs) {        // Start a single option entry.        OS << "OPTION("; +      // The option prefix; +      OS << "0"; +        // The option string. -      OS << '"' << R.getValueAsString("Name") << '"'; +      OS << ", \"" << R.getValueAsString("Name") << '"';        // The option identifier name.        OS  << ", "<< getOptionName(R); @@ -109,7 +182,7 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS, bool GenDefs) {        // The containing option group (if any).        OS << ", "; -      if (const DefInit *DI = dynamic_cast<DefInit*>(R.getValueInit("Group"))) +      if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group")))          OS << getOptionName(*DI->getDef());        else          OS << "INVALID"; @@ -118,7 +191,7 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS, bool GenDefs) {        OS << ", INVALID, 0, 0";        // The option help text. -      if (!dynamic_cast<UnsetInit*>(R.getValueInit("HelpText"))) { +      if (!isa<UnsetInit>(R.getValueInit("HelpText"))) {          OS << ",\n";          OS << "       ";          write_cstring(OS, R.getValueAsString("HelpText")); @@ -138,6 +211,10 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS, bool GenDefs) {        // Start a single option entry.        OS << "OPTION("; +      // The option prefix; +      std::vector<std::string> prf = R.getValueAsListOfStrings("Prefixes"); +      OS << Prefixes[PrefixKeyT(prf.begin(), prf.end())] << ", "; +        // The option string.        write_cstring(OS, R.getValueAsString("Name")); @@ -149,14 +226,14 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS, bool GenDefs) {        // The containing option group (if any).        OS << ", "; -      if (const DefInit *DI = dynamic_cast<DefInit*>(R.getValueInit("Group"))) +      if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group")))          OS << getOptionName(*DI->getDef());        else          OS << "INVALID";        // The option alias (if any).        OS << ", "; -      if (const DefInit *DI = dynamic_cast<DefInit*>(R.getValueInit("Alias"))) +      if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Alias")))          OS << getOptionName(*DI->getDef());        else          OS << "INVALID"; @@ -170,7 +247,7 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS, bool GenDefs) {          for (unsigned i = 0, e = LI->size(); i != e; ++i) {            if (i)              OS << " | "; -          OS << dynamic_cast<DefInit*>(LI->getElement(i))->getDef()->getName(); +          OS << cast<DefInit>(LI->getElement(i))->getDef()->getName();          }        } @@ -178,7 +255,7 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS, bool GenDefs) {        OS << ", " << R.getValueAsInt("NumArgs");        // The option help text. -      if (!dynamic_cast<UnsetInit*>(R.getValueInit("HelpText"))) { +      if (!isa<UnsetInit>(R.getValueInit("HelpText"))) {          OS << ",\n";          OS << "       ";          write_cstring(OS, R.getValueAsString("HelpText")); @@ -187,7 +264,7 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS, bool GenDefs) {        // The option meta-variable name.        OS << ", "; -      if (!dynamic_cast<UnsetInit*>(R.getValueInit("MetaVarName"))) +      if (!isa<UnsetInit>(R.getValueInit("MetaVarName")))          write_cstring(OS, R.getValueAsString("MetaVarName"));        else          OS << "0";  | 
