diff options
author | dim <dim@FreeBSD.org> | 2012-12-02 13:20:44 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2012-12-02 13:20:44 +0000 |
commit | 056abd2059c65a3e908193aeae16fad98017437c (patch) | |
tree | 2732d02d7d51218d6eed98ac7fcfc5b8794896b5 /utils/TableGen/OptParserEmitter.cpp | |
parent | cc73504950eb7b5dff2dded9bedd67bc36d64641 (diff) | |
download | FreeBSD-src-056abd2059c65a3e908193aeae16fad98017437c.zip FreeBSD-src-056abd2059c65a3e908193aeae16fad98017437c.tar.gz |
Vendor import of clang release_32 branch r168974 (effectively, 3.2 RC2):
http://llvm.org/svn/llvm-project/cfe/branches/release_32@168974
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 b0431a9..674c89a 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"; |