X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FTGParser.cpp;h=59097f986f79b573e883845d3d29689f2cd25586;hb=eef965f04bab483a7d2fd46a7d51559197eda5cf;hp=188ba4d2b1be6dbf34856ea9ed63631b2e1ea857;hpb=46f55527d848bcc7cff1210137caff29bbf1b010;p=oota-llvm.git diff --git a/utils/TableGen/TGParser.cpp b/utils/TableGen/TGParser.cpp index 188ba4d2b1b..59097f986f7 100644 --- a/utils/TableGen/TGParser.cpp +++ b/utils/TableGen/TGParser.cpp @@ -20,11 +20,6 @@ #include "llvm/Support/CommandLine.h" using namespace llvm; -/// LLVMCHack - This is a temporary hack that changes how "(foo [1, 2, 3])" -/// parses. -/// FIXME: REMOVE THIS. -static cl::opt LLVMCHack("llvmc-temp-hack", cl::ReallyHidden); - //===----------------------------------------------------------------------===// // Support Code for the Semantic Actions. //===----------------------------------------------------------------------===// @@ -314,7 +309,7 @@ static std::string GetNewAnonymousName() { std::string TGParser::ParseObjectName() { if (Lex.getCode() != tgtok::Id) return GetNewAnonymousName(); - + std::string Ret = Lex.getCurStrVal(); Lex.Lex(); return Ret; @@ -688,9 +683,9 @@ Init *TGParser::ParseOperation(Record *CurRec) { TokError("unknown operation"); return 0; break; - case tgtok::XCar: - case tgtok::XCdr: - case tgtok::XNull: + case tgtok::XHead: + case tgtok::XTail: + case tgtok::XEmpty: case tgtok::XCast: { // Value ::= !unop '(' Value ')' UnOpInit::UnaryOp Code; RecTy *Type = 0; @@ -709,17 +704,17 @@ Init *TGParser::ParseOperation(Record *CurRec) { } break; - case tgtok::XCar: + case tgtok::XHead: Lex.Lex(); // eat the operation - Code = UnOpInit::CAR; + Code = UnOpInit::HEAD; break; - case tgtok::XCdr: + case tgtok::XTail: Lex.Lex(); // eat the operation - Code = UnOpInit::CDR; + Code = UnOpInit::TAIL; break; - case tgtok::XNull: + case tgtok::XEmpty: Lex.Lex(); // eat the operation - Code = UnOpInit::LNULL; + Code = UnOpInit::EMPTY; Type = new IntRecTy; break; } @@ -732,9 +727,9 @@ Init *TGParser::ParseOperation(Record *CurRec) { Init *LHS = ParseValue(CurRec); if (LHS == 0) return 0; - if (Code == UnOpInit::CAR - || Code == UnOpInit::CDR - || Code == UnOpInit::LNULL) { + if (Code == UnOpInit::HEAD + || Code == UnOpInit::TAIL + || Code == UnOpInit::EMPTY) { ListInit *LHSl = dynamic_cast(LHS); StringInit *LHSs = dynamic_cast(LHS); TypedInit *LHSt = dynamic_cast(LHS); @@ -751,8 +746,8 @@ Init *TGParser::ParseOperation(Record *CurRec) { } } - if (Code == UnOpInit::CAR - || Code == UnOpInit::CDR) { + if (Code == UnOpInit::HEAD + || Code == UnOpInit::TAIL) { if (LHSl == 0 && LHSt == 0) { TokError("expected list type argumnet in unary operator"); return 0; @@ -769,7 +764,7 @@ Init *TGParser::ParseOperation(Record *CurRec) { TokError("untyped list element in unary operator"); return 0; } - if (Code == UnOpInit::CAR) { + if (Code == UnOpInit::HEAD) { Type = Itemt->getType(); } else { Type = new ListRecTy(Itemt->getType()); @@ -781,7 +776,7 @@ Init *TGParser::ParseOperation(Record *CurRec) { TokError("expected list type argumnet in unary operator"); return 0; } - if (Code == UnOpInit::CAR) { + if (Code == UnOpInit::HEAD) { Type = LType->getElementType(); } else { Type = LType; @@ -817,13 +812,13 @@ Init *TGParser::ParseOperation(Record *CurRec) { case tgtok::XSRA: Code = BinOpInit::SRA; Type = new IntRecTy(); break; case tgtok::XSRL: Code = BinOpInit::SRL; Type = new IntRecTy(); break; case tgtok::XSHL: Code = BinOpInit::SHL; Type = new IntRecTy(); break; - case tgtok::XEq: Code = BinOpInit::EQ; Type = new IntRecTy(); break; + case tgtok::XEq: Code = BinOpInit::EQ; Type = new BitRecTy(); break; case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; Type = new StringRecTy(); break; } - + if (Lex.getCode() != tgtok::l_paren) { TokError("expected '(' after binary operator"); return 0; @@ -831,7 +826,7 @@ Init *TGParser::ParseOperation(Record *CurRec) { Lex.Lex(); // eat the '(' SmallVector InitList; - + InitList.push_back(ParseValue(CurRec)); if (InitList.back() == 0) return 0; @@ -858,11 +853,11 @@ Init *TGParser::ParseOperation(Record *CurRec) { InitList.back() = RHS; } } - + if (InitList.size() == 2) return (new BinOpInit(Code, InitList[0], InitList[1], Type)) ->Fold(CurRec, CurMultiClass); - + Error(OpLoc, "expected two operands to operator"); return 0; } @@ -873,7 +868,6 @@ Init *TGParser::ParseOperation(Record *CurRec) { TernOpInit::TernaryOp Code; RecTy *Type = 0; - tgtok::TokKind LexCode = Lex.getCode(); Lex.Lex(); // eat the operation switch (LexCode) { @@ -924,16 +918,45 @@ Init *TGParser::ParseOperation(Record *CurRec) { switch (LexCode) { default: assert(0 && "Unhandled code!"); case tgtok::XIf: { - TypedInit *MHSt = dynamic_cast(MHS); - TypedInit *RHSt = dynamic_cast(RHS); - if (MHSt == 0 || RHSt == 0) { + // FIXME: The `!if' operator doesn't handle non-TypedInit well at + // all. This can be made much more robust. + TypedInit *MHSt = dynamic_cast(MHS); + TypedInit *RHSt = dynamic_cast(RHS); + + RecTy *MHSTy = 0; + RecTy *RHSTy = 0; + + if (MHSt == 0 && RHSt == 0) { + BitsInit *MHSbits = dynamic_cast(MHS); + BitsInit *RHSbits = dynamic_cast(RHS); + + if (MHSbits && RHSbits && + MHSbits->getNumBits() == RHSbits->getNumBits()) { + Type = new BitRecTy(); + break; + } else { + BitInit *MHSbit = dynamic_cast(MHS); + BitInit *RHSbit = dynamic_cast(RHS); + + if (MHSbit && RHSbit) { + Type = new BitRecTy(); + break; + } + } + } else if (MHSt != 0 && RHSt != 0) { + MHSTy = MHSt->getType(); + RHSTy = RHSt->getType(); + } + + if (!MHSTy || !RHSTy) { 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(); + + if (MHSTy->typeIsConvertibleTo(RHSTy)) { + Type = RHSTy; + } else if (RHSTy->typeIsConvertibleTo(MHSTy)) { + Type = MHSTy; } else { TokError("inconsistent types for !if"); return 0; @@ -1073,7 +1096,9 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) { // Create the new record, set it as CurRec temporarily. static unsigned AnonCounter = 0; - Record *NewRec = new Record("anonymous.val."+utostr(AnonCounter++),NameLoc); + Record *NewRec = new Record("anonymous.val."+utostr(AnonCounter++), + NameLoc, + Records); SubClassReference SCRef; SCRef.RefLoc = NameLoc; SCRef.Rec = Class; @@ -1128,6 +1153,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) { s << "Type mismatch for list, expected list type, got " << ItemType->getAsString(); TokError(s.str()); + return 0; } GivenListTy = ListType; } @@ -1219,18 +1245,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) { return 0; } - Init *Operator; - /// LLVMC Requires an old grammar and I don't know how to update it, placate - /// it in the short term by changing the grammar specifically for llvmc. - /// FIXME: REMOVE THIS. - if (!LLVMCHack) - Operator = ParseValue(CurRec); - else { - if (Lex.getCode() == tgtok::Id) - Operator = ParseIDValue(CurRec); - else - Operator = ParseOperation(CurRec); - } + Init *Operator = ParseValue(CurRec); if (Operator == 0) return 0; // If the operator name is present, parse it. @@ -1259,9 +1274,9 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) { return new DagInit(Operator, OperatorName, DagArgs); } - case tgtok::XCar: - case tgtok::XCdr: - case tgtok::XNull: + case tgtok::XHead: + case tgtok::XTail: + case tgtok::XEmpty: case tgtok::XCast: // Value ::= !unop '(' Value ')' case tgtok::XConcat: case tgtok::XSRA: @@ -1648,7 +1663,7 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) { Lex.Lex(); // Eat the 'def' token. // Parse ObjectName and make a record for it. - Record *CurRec = new Record(ParseObjectName(), DefLoc); + Record *CurRec = new Record(ParseObjectName(), DefLoc, Records); if (!CurMultiClass) { // Top-level def definition. @@ -1715,7 +1730,7 @@ bool TGParser::ParseClass() { return TokError("Class '" + CurRec->getName() + "' already defined"); } else { // If this is the first reference to this class, create and add it. - CurRec = new Record(Lex.getCurStrVal(), Lex.getLoc()); + CurRec = new Record(Lex.getCurStrVal(), Lex.getLoc(), Records); Records.addClass(CurRec); } Lex.Lex(); // eat the name. @@ -1832,7 +1847,8 @@ bool TGParser::ParseMultiClass() { if (MultiClasses.count(Name)) return TokError("multiclass '" + Name + "' already defined"); - CurMultiClass = MultiClasses[Name] = new MultiClass(Name, Lex.getLoc()); + CurMultiClass = MultiClasses[Name] = new MultiClass(Name, + Lex.getLoc(), Records); Lex.Lex(); // Eat the identifier. // If there are template args, parse them. @@ -1907,7 +1923,7 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) { DefmPrefix = Lex.getCurStrVal(); Lex.Lex(); // Eat the defm prefix. } - + SMLoc DefmPrefixLoc = Lex.getLoc(); if (Lex.getCode() != tgtok::colon) return TokError("expected ':' after defm identifier"); @@ -1961,7 +1977,7 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) { } } - Record *CurRec = new Record(DefName, DefmPrefixLoc); + Record *CurRec = new Record(DefName, DefmPrefixLoc, Records); SubClassReference Ref; Ref.RefLoc = DefmPrefixLoc; @@ -2103,7 +2119,8 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) { /// Object ::= LETCommand Object bool TGParser::ParseObject(MultiClass *MC) { switch (Lex.getCode()) { - default: assert(0 && "This is not an object"); + default: + return TokError("Expected class, def, defm, multiclass or let definition"); case tgtok::Let: return ParseTopLevelLet(MC); case tgtok::Def: return ParseDef(MC); case tgtok::Defm: return ParseDefm(MC);