X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FTGParser.cpp;h=ba480e6e926b5d2192e48998c40d94b1d052fb05;hb=a4b048668418f74dfb2399421dc54db1d999c9cd;hp=967f5d0d5dd9904d3bbf20a7a6817519b51b1e6e;hpb=4afc509b7ffe2c4ea234dfd7af5105feb21685d9;p=oota-llvm.git diff --git a/utils/TableGen/TGParser.cpp b/utils/TableGen/TGParser.cpp index 967f5d0d5dd..ba480e6e926 100644 --- a/utils/TableGen/TGParser.cpp +++ b/utils/TableGen/TGParser.cpp @@ -11,12 +11,11 @@ // //===----------------------------------------------------------------------===// -#include - #include "TGParser.h" #include "Record.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/Support/Streams.h" +#include +#include using namespace llvm; //===----------------------------------------------------------------------===// @@ -25,7 +24,7 @@ using namespace llvm; namespace llvm { struct SubClassReference { - TGLoc RefLoc; + SMLoc RefLoc; Record *Rec; std::vector TemplateArgs; SubClassReference() : Rec(0) {} @@ -34,7 +33,7 @@ struct SubClassReference { }; struct SubMultiClassReference { - TGLoc RefLoc; + SMLoc RefLoc; MultiClass *MC; std::vector TemplateArgs; SubMultiClassReference() : MC(0) {} @@ -44,11 +43,11 @@ struct SubMultiClassReference { }; void SubMultiClassReference::dump() const { - cerr << "Multiclass:\n"; + errs() << "Multiclass:\n"; MC->dump(); - cerr << "Template args:\n"; + errs() << "Template args:\n"; for (std::vector::const_iterator i = TemplateArgs.begin(), iend = TemplateArgs.end(); i != iend; @@ -59,7 +58,7 @@ void SubMultiClassReference::dump() const { } // end namespace llvm -bool TGParser::AddValue(Record *CurRec, TGLoc Loc, const RecordVal &RV) { +bool TGParser::AddValue(Record *CurRec, SMLoc Loc, const RecordVal &RV) { if (CurRec == 0) CurRec = &CurMultiClass->Rec; @@ -78,7 +77,7 @@ bool TGParser::AddValue(Record *CurRec, TGLoc Loc, const RecordVal &RV) { /// SetValue - /// Return true on error, false on success. -bool TGParser::SetValue(Record *CurRec, TGLoc Loc, const std::string &ValName, +bool TGParser::SetValue(Record *CurRec, SMLoc Loc, const std::string &ValName, const std::vector &BitList, Init *V) { if (!V) return false; @@ -396,7 +395,7 @@ ParseSubClassReference(Record *CurRec, bool isDefm) { return Result; } - Result.TemplateArgs = ParseValueList(CurRec); + Result.TemplateArgs = ParseValueList(CurRec, Result.Rec); if (Result.TemplateArgs.empty()) { Result.Rec = 0; // Error parsing value list. return Result; @@ -438,7 +437,7 @@ ParseSubMultiClassReference(MultiClass *CurMC) { return Result; } - Result.TemplateArgs = ParseValueList(&CurMC->Rec); + Result.TemplateArgs = ParseValueList(&CurMC->Rec, &Result.MC->Rec); if (Result.TemplateArgs.empty()) { Result.MC = 0; // Error parsing value list. return Result; @@ -526,7 +525,7 @@ bool TGParser::ParseOptionalRangeList(std::vector &Ranges) { if (Lex.getCode() != tgtok::less) return false; - TGLoc StartLoc = Lex.getLoc(); + SMLoc StartLoc = Lex.getLoc(); Lex.Lex(); // eat the '<' // Parse the range list. @@ -548,7 +547,7 @@ bool TGParser::ParseOptionalBitList(std::vector &Ranges) { if (Lex.getCode() != tgtok::l_brace) return false; - TGLoc StartLoc = Lex.getLoc(); + SMLoc StartLoc = Lex.getLoc(); Lex.Lex(); // eat the '{' // Parse the range list. @@ -633,7 +632,7 @@ RecTy *TGParser::ParseType() { Init *TGParser::ParseIDValue(Record *CurRec) { assert(Lex.getCode() == tgtok::Id && "Expected ID in ParseIDValue"); std::string Name = Lex.getCurStrVal(); - TGLoc Loc = Lex.getLoc(); + SMLoc Loc = Lex.getLoc(); Lex.Lex(); return ParseIDValue(CurRec, Name, Loc); } @@ -641,7 +640,7 @@ Init *TGParser::ParseIDValue(Record *CurRec) { /// ParseIDValue - This is just like ParseIDValue above, but it assumes the ID /// has already been read. Init *TGParser::ParseIDValue(Record *CurRec, - const std::string &Name, TGLoc NameLoc) { + const std::string &Name, SMLoc NameLoc) { if (CurRec) { if (const RecordVal *RV = CurRec->getValue(Name)) return new VarInit(Name, RV->getType()); @@ -680,6 +679,9 @@ Init *TGParser::ParseOperation(Record *CurRec) { TokError("unknown operation"); return 0; break; + case tgtok::XCar: + case tgtok::XCdr: + case tgtok::XNull: case tgtok::XCast: { // Value ::= !unop '(' Value ')' UnOpInit::UnaryOp Code; RecTy *Type = 0; @@ -693,10 +695,23 @@ Init *TGParser::ParseOperation(Record *CurRec) { Type = ParseOperatorType(); if (Type == 0) { - TokError("did not get type for binary operator"); + TokError("did not get type for unary operator"); return 0; } + break; + case tgtok::XCar: + Lex.Lex(); // eat the operation + Code = UnOpInit::CAR; + break; + case tgtok::XCdr: + Lex.Lex(); // eat the operation + Code = UnOpInit::CDR; + break; + case tgtok::XNull: + Lex.Lex(); // eat the operation + Code = UnOpInit::LNULL; + Type = new IntRecTy; break; } if (Lex.getCode() != tgtok::l_paren) { @@ -708,6 +723,67 @@ Init *TGParser::ParseOperation(Record *CurRec) { Init *LHS = ParseValue(CurRec); if (LHS == 0) return 0; + if (Code == UnOpInit::CAR + || Code == UnOpInit::CDR + || Code == UnOpInit::LNULL) { + ListInit *LHSl = dynamic_cast(LHS); + StringInit *LHSs = dynamic_cast(LHS); + TypedInit *LHSt = dynamic_cast(LHS); + if (LHSl == 0 && LHSs == 0 && LHSt == 0) { + TokError("expected list or string type argument in unary operator"); + return 0; + } + if (LHSt) { + ListRecTy *LType = dynamic_cast(LHSt->getType()); + StringRecTy *SType = dynamic_cast(LHSt->getType()); + if (LType == 0 && SType == 0) { + TokError("expected list or string type argumnet in unary operator"); + return 0; + } + } + + if (Code == UnOpInit::CAR + || Code == UnOpInit::CDR) { + if (LHSl == 0 && LHSt == 0) { + TokError("expected list type argumnet in unary operator"); + return 0; + } + + if (LHSl && LHSl->getSize() == 0) { + TokError("empty list argument in unary operator"); + return 0; + } + if (LHSl) { + Init *Item = LHSl->getElement(0); + TypedInit *Itemt = dynamic_cast(Item); + if (Itemt == 0) { + TokError("untyped list element in unary operator"); + return 0; + } + if (Code == UnOpInit::CAR) { + Type = Itemt->getType(); + } + else { + Type = new ListRecTy(Itemt->getType()); + } + } + else { + assert(LHSt && "expected list type argument in unary operator"); + ListRecTy *LType = dynamic_cast(LHSt->getType()); + if (LType == 0) { + TokError("expected list type argumnet in unary operator"); + return 0; + } + if (Code == UnOpInit::CAR) { + Type = LType->getElementType(); + } + else { + Type = LType; + } + } + } + } + if (Lex.getCode() != tgtok::r_paren) { TokError("expected ')' in unary operator"); return 0; @@ -792,7 +868,8 @@ Init *TGParser::ParseOperation(Record *CurRec) { return (new BinOpInit(Code, LHS, RHS, Type))->Fold(CurRec, CurMultiClass); } -// case tgtok::XForEach: + case tgtok::XIf: + case tgtok::XForEach: case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')' TernOpInit::TernaryOp Code; RecTy *Type = 0; @@ -802,9 +879,12 @@ Init *TGParser::ParseOperation(Record *CurRec) { Lex.Lex(); // eat the operation switch (LexCode) { default: assert(0 && "Unhandled code!"); - //case tgtok::XForEach: - //Code = TernOpInit::FOREACH; - //break; + case tgtok::XIf: + Code = TernOpInit::IF; + break; + case tgtok::XForEach: + Code = TernOpInit::FOREACH; + break; case tgtok::XSubst: Code = TernOpInit::SUBST; break; @@ -844,15 +924,34 @@ Init *TGParser::ParseOperation(Record *CurRec) { switch (LexCode) { default: assert(0 && "Unhandled code!"); - //case tgtok::XForEach: { - //TypedInit *MHSt = dynamic_cast(MHS); - //if (MHSt == 0) { - // TokError("could not get type for !foreach"); - // return 0; - //} - //Type = MHSt->getType(); - //break; - //} + case tgtok::XIf: { + TypedInit *MHSt = dynamic_cast(MHS); + TypedInit *RHSt = dynamic_cast(RHS); + if (MHSt == 0 || RHSt == 0) { + TokError("could not get type for !if"); + return 0; + } + if (MHSt->getType()->typeIsConvertibleTo(RHSt->getType())) { + Type = RHSt->getType(); + } + else if (RHSt->getType()->typeIsConvertibleTo(MHSt->getType())) { + Type = MHSt->getType(); + } + else { + TokError("inconsistent types for !if"); + return 0; + } + break; + } + case tgtok::XForEach: { + TypedInit *MHSt = dynamic_cast(MHS); + if (MHSt == 0) { + TokError("could not get type for !foreach"); + return 0; + } + Type = MHSt->getType(); + break; + } case tgtok::XSubst: { TypedInit *RHSt = dynamic_cast(RHS); if (RHSt == 0) { @@ -918,7 +1017,7 @@ RecTy *TGParser::ParseOperatorType(void) { /// SimpleValue ::= SRLTOK '(' Value ',' Value ')' /// SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')' /// -Init *TGParser::ParseSimpleValue(Record *CurRec) { +Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) { Init *R = 0; switch (Lex.getCode()) { default: TokError("Unknown token when parsing a value"); break; @@ -940,7 +1039,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) { R = new CodeInit(Lex.getCurStrVal()); Lex.Lex(); break; case tgtok::question: R = new UnsetInit(); Lex.Lex(); break; case tgtok::Id: { - TGLoc NameLoc = Lex.getLoc(); + SMLoc NameLoc = Lex.getLoc(); std::string Name = Lex.getCurStrVal(); if (Lex.Lex() != tgtok::less) // consume the Id. return ParseIDValue(CurRec, Name, NameLoc); // Value ::= IDValue @@ -950,15 +1049,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) { TokError("expected non-empty value list"); return 0; } - std::vector ValueList = ParseValueList(CurRec); - if (ValueList.empty()) return 0; - - if (Lex.getCode() != tgtok::greater) { - TokError("expected '>' at end of value list"); - return 0; - } - Lex.Lex(); // eat the '>' - + // This is a CLASS expression. This is supposed to synthesize // a new anonymous definition, deriving from CLASS with no // body. @@ -967,6 +1058,15 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) { Error(NameLoc, "Expected a class name, got '" + Name + "'"); return 0; } + + std::vector ValueList = ParseValueList(CurRec, Class); + if (ValueList.empty()) return 0; + + if (Lex.getCode() != tgtok::greater) { + TokError("expected '>' at end of value list"); + return 0; + } + Lex.Lex(); // eat the '>' // Create the new record, set it as CurRec temporarily. static unsigned AnonCounter = 0; @@ -985,7 +1085,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) { return new DefInit(NewRec); } case tgtok::l_brace: { // Value ::= '{' ValueList '}' - TGLoc BraceLoc = Lex.getLoc(); + SMLoc BraceLoc = Lex.getLoc(); Lex.Lex(); // eat the '{' std::vector Vals; @@ -1015,8 +1115,22 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) { Lex.Lex(); // eat the '[' std::vector Vals; + RecTy *DeducedEltTy = 0; + ListRecTy *GivenListTy = 0; + + if (ItemType != 0) { + ListRecTy *ListType = dynamic_cast(ItemType); + if (ListType == 0) { + std::stringstream s; + s << "Type mismatch for list, expected list type, got " + << ItemType->getAsString(); + TokError(s.str()); + } + GivenListTy = ListType; + } + if (Lex.getCode() != tgtok::r_square) { - Vals = ParseValueList(CurRec); + Vals = ParseValueList(CurRec, 0, GivenListTy ? GivenListTy->getElementType() : 0); if (Vals.empty()) return 0; } if (Lex.getCode() != tgtok::r_square) { @@ -1024,7 +1138,77 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) { return 0; } Lex.Lex(); // eat the ']' - return new ListInit(Vals); + + RecTy *GivenEltTy = 0; + if (Lex.getCode() == tgtok::less) { + // Optional list element type + Lex.Lex(); // eat the '<' + + GivenEltTy = ParseType(); + if (GivenEltTy == 0) { + // Couldn't parse element type + return 0; + } + + if (Lex.getCode() != tgtok::greater) { + TokError("expected '>' at end of list element type"); + return 0; + } + Lex.Lex(); // eat the '>' + } + + // Check elements + RecTy *EltTy = 0; + for (std::vector::iterator i = Vals.begin(), ie = Vals.end(); + i != ie; + ++i) { + TypedInit *TArg = dynamic_cast(*i); + if (TArg == 0) { + TokError("Untyped list element"); + return 0; + } + if (EltTy != 0) { + EltTy = resolveTypes(EltTy, TArg->getType()); + if (EltTy == 0) { + TokError("Incompatible types in list elements"); + return 0; + } + } + else { + EltTy = TArg->getType(); + } + } + + if (GivenEltTy != 0) { + if (EltTy != 0) { + // Verify consistency + if (!EltTy->typeIsConvertibleTo(GivenEltTy)) { + TokError("Incompatible types in list elements"); + return 0; + } + } + EltTy = GivenEltTy; + } + + if (EltTy == 0) { + if (ItemType == 0) { + TokError("No type for list"); + return 0; + } + DeducedEltTy = GivenListTy->getElementType(); + } + else { + // Make sure the deduced type is compatible with the given type + if (GivenListTy) { + if (!EltTy->typeIsConvertibleTo(GivenListTy->getElementType())) { + TokError("Element type mismatch for list"); + return 0; + } + } + DeducedEltTy = EltTy; + } + + return new ListInit(Vals, DeducedEltTy); } case tgtok::l_paren: { // Value ::= '(' IDValue DagArgList ')' Lex.Lex(); // eat the '(' @@ -1072,6 +1256,9 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) { break; } + case tgtok::XCar: + case tgtok::XCdr: + case tgtok::XNull: case tgtok::XCast: // Value ::= !unop '(' Value ')' case tgtok::XConcat: case tgtok::XSRA: @@ -1079,7 +1266,8 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) { case tgtok::XSHL: case tgtok::XStrConcat: case tgtok::XNameConcat: // Value ::= !binop '(' Value ',' Value ')' - // case tgtok::XForEach: + case tgtok::XIf: + case tgtok::XForEach: case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')' return ParseOperation(CurRec); break; @@ -1096,8 +1284,8 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) { /// ValueSuffix ::= '[' BitList ']' /// ValueSuffix ::= '.' ID /// -Init *TGParser::ParseValue(Record *CurRec) { - Init *Result = ParseSimpleValue(CurRec); +Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType) { + Init *Result = ParseSimpleValue(CurRec, ItemType); if (Result == 0) return 0; // Parse the suffixes now if present. @@ -1105,7 +1293,7 @@ Init *TGParser::ParseValue(Record *CurRec) { switch (Lex.getCode()) { default: return Result; case tgtok::l_brace: { - TGLoc CurlyLoc = Lex.getLoc(); + SMLoc CurlyLoc = Lex.getLoc(); Lex.Lex(); // eat the '{' std::vector Ranges = ParseRangeList(); if (Ranges.empty()) return 0; @@ -1127,7 +1315,7 @@ Init *TGParser::ParseValue(Record *CurRec) { break; } case tgtok::l_square: { - TGLoc SquareLoc = Lex.getLoc(); + SMLoc SquareLoc = Lex.getLoc(); Lex.Lex(); // eat the '[' std::vector Ranges = ParseRangeList(); if (Ranges.empty()) return 0; @@ -1202,15 +1390,35 @@ TGParser::ParseDagArgList(Record *CurRec) { /// /// ValueList ::= Value (',' Value) /// -std::vector TGParser::ParseValueList(Record *CurRec) { +std::vector TGParser::ParseValueList(Record *CurRec, Record *ArgsRec, RecTy *EltTy) { std::vector Result; - Result.push_back(ParseValue(CurRec)); + RecTy *ItemType = EltTy; + unsigned int ArgN = 0; + if (ArgsRec != 0 && EltTy == 0) { + const std::vector &TArgs = ArgsRec->getTemplateArgs(); + const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]); + assert(RV && "Template argument record not found??"); + ItemType = RV->getType(); + ++ArgN; + } + Result.push_back(ParseValue(CurRec, ItemType)); if (Result.back() == 0) return std::vector(); while (Lex.getCode() == tgtok::comma) { Lex.Lex(); // Eat the comma - Result.push_back(ParseValue(CurRec)); + if (ArgsRec != 0 && EltTy == 0) { + const std::vector &TArgs = ArgsRec->getTemplateArgs(); + if (ArgN >= TArgs.size()) { + TokError("too many template arguments"); + return std::vector(); + } + const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]); + assert(RV && "Template argument record not found??"); + ItemType = RV->getType(); + ++ArgN; + } + Result.push_back(ParseValue(CurRec, ItemType)); if (Result.back() == 0) return std::vector(); } @@ -1243,7 +1451,7 @@ std::string TGParser::ParseDeclaration(Record *CurRec, return ""; } - TGLoc IdLoc = Lex.getLoc(); + SMLoc IdLoc = Lex.getLoc(); std::string DeclName = Lex.getCurStrVal(); Lex.Lex(); @@ -1264,8 +1472,8 @@ std::string TGParser::ParseDeclaration(Record *CurRec, // If a value is present, parse it. if (Lex.getCode() == tgtok::equal) { Lex.Lex(); - TGLoc ValLoc = Lex.getLoc(); - Init *Val = ParseValue(CurRec); + SMLoc ValLoc = Lex.getLoc(); + Init *Val = ParseValue(CurRec, Type); if (Val == 0 || SetValue(CurRec, ValLoc, DeclName, std::vector(), Val)) return ""; @@ -1330,7 +1538,7 @@ bool TGParser::ParseBodyItem(Record *CurRec) { if (Lex.Lex() != tgtok::Id) return TokError("expected field identifier after let"); - TGLoc IdLoc = Lex.getLoc(); + SMLoc IdLoc = Lex.getLoc(); std::string FieldName = Lex.getCurStrVal(); Lex.Lex(); // eat the field name. @@ -1343,7 +1551,13 @@ bool TGParser::ParseBodyItem(Record *CurRec) { return TokError("expected '=' in let expression"); Lex.Lex(); // eat the '='. - Init *Val = ParseValue(CurRec); + RecordVal *Field = CurRec->getValue(FieldName); + if (Field == 0) + return TokError("Value '" + FieldName + "' unknown!"); + + RecTy *Type = Field->getType(); + + Init *Val = ParseValue(CurRec, Type); if (Val == 0) return true; if (Lex.getCode() != tgtok::semi) @@ -1428,7 +1642,7 @@ bool TGParser::ParseObjectBody(Record *CurRec) { /// DefInst ::= DEF ObjectName ObjectBody /// llvm::Record *TGParser::ParseDef(MultiClass *CurMultiClass) { - TGLoc DefLoc = Lex.getLoc(); + SMLoc DefLoc = Lex.getLoc(); assert(Lex.getCode() == tgtok::Def && "Unknown tok"); Lex.Lex(); // Eat the 'def' token. @@ -1516,7 +1730,7 @@ std::vector TGParser::ParseLetList() { return std::vector(); } std::string Name = Lex.getCurStrVal(); - TGLoc NameLoc = Lex.getLoc(); + SMLoc NameLoc = Lex.getLoc(); Lex.Lex(); // Eat the identifier. // Check for an optional RangeList. @@ -1568,7 +1782,7 @@ bool TGParser::ParseTopLevelLet() { if (ParseObject()) return true; } else { // Object ::= LETCommand '{' ObjectList '}' - TGLoc BraceLoc = Lex.getLoc(); + SMLoc BraceLoc = Lex.getLoc(); // Otherwise, this is a group let. Lex.Lex(); // eat the '{'. @@ -1693,7 +1907,7 @@ bool TGParser::ParseDefm() { if (Lex.Lex() != tgtok::Id) // eat the defm. return TokError("expected identifier after defm"); - TGLoc DefmPrefixLoc = Lex.getLoc(); + SMLoc DefmPrefixLoc = Lex.getLoc(); std::string DefmPrefix = Lex.getCurStrVal(); if (Lex.Lex() != tgtok::colon) return TokError("expected ':' after defm identifier"); @@ -1701,7 +1915,7 @@ bool TGParser::ParseDefm() { // eat the colon. Lex.Lex(); - TGLoc SubClassLoc = Lex.getLoc(); + SMLoc SubClassLoc = Lex.getLoc(); SubClassReference Ref = ParseSubClassReference(0, true); while (1) {