X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTableGen%2FTGParser.cpp;h=9c061a8ae4cbc7c22f12ebfb55c5666184448fa0;hb=2b861c3a24fa299d6b8a2d5097114c1000354bee;hp=dd3a0967d1440550a54f0d5b9aab04702142edca;hpb=c34a25d59d382aa00a94b3f0603ce8724c66606d;p=oota-llvm.git diff --git a/lib/TableGen/TGParser.cpp b/lib/TableGen/TGParser.cpp index dd3a0967d14..9c061a8ae4c 100644 --- a/lib/TableGen/TGParser.cpp +++ b/lib/TableGen/TGParser.cpp @@ -135,11 +135,18 @@ bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName, V = BitsInit::get(NewBits); } - if (RV->setValue(V)) + if (RV->setValue(V)) { + std::string InitType = ""; + if (BitsInit *BI = dyn_cast(V)) { + InitType = (Twine("' of type bit initializer with length ") + + Twine(BI->getNumBits())).str(); + } return Error(Loc, "Value '" + ValName->getAsUnquotedString() + "' of type '" + RV->getType()->getAsString() + "' is incompatible with initializer '" + V->getAsString() + + InitType + "'"); + } return false; } @@ -229,8 +236,10 @@ bool TGParser::AddSubMultiClass(MultiClass *CurMC, // Add all of the values in the superclass into the current def. for (unsigned i = 0, e = MCVals.size(); i != e; ++i) - if (AddValue(NewDef, SubMultiClass.RefRange.Start, MCVals[i])) + if (AddValue(NewDef, SubMultiClass.RefRange.Start, MCVals[i])) { + delete NewDef; return true; + } CurMC->DefPrototypes.push_back(NewDef); } @@ -341,6 +350,7 @@ bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals){ TypedInit *IVal = dyn_cast(IterVals[i].IterValue); if (!IVal) { Error(Loc, "foreach iterator value is untyped"); + delete IterRec; return true; } @@ -349,6 +359,7 @@ bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals){ if (SetValue(IterRec, Loc, IterVar->getName(), std::vector(), IVal)) { Error(Loc, "when instantiating this def"); + delete IterRec; return true; } @@ -360,8 +371,14 @@ bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals){ } if (Records.getDef(IterRec->getNameInitAsString())) { - Error(Loc, "def already exists: " + IterRec->getNameInitAsString()); - return true; + // If this record is anonymous, it's no problem, just generate a new name + if (IterRec->isAnonymous()) + IterRec->setName(GetNewAnonymousName()); + else { + Error(Loc, "def already exists: " + IterRec->getNameInitAsString()); + delete IterRec; + return true; + } } Records.addDef(IterRec); @@ -782,7 +799,7 @@ Init *TGParser::ParseIDValue(Record *CurRec, /// /// Operation ::= XOperator ['<' Type '>'] '(' Args ')' /// -Init *TGParser::ParseOperation(Record *CurRec) { +Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) { switch (Lex.getCode()) { default: TokError("unknown operation"); @@ -845,7 +862,7 @@ Init *TGParser::ParseOperation(Record *CurRec) { ListRecTy *LType = dyn_cast(LHSt->getType()); StringRecTy *SType = dyn_cast(LHSt->getType()); if (!LType && !SType) { - TokError("expected list or string type argumnet in unary operator"); + TokError("expected list or string type argument in unary operator"); return nullptr; } } @@ -853,7 +870,7 @@ Init *TGParser::ParseOperation(Record *CurRec) { if (Code == UnOpInit::HEAD || Code == UnOpInit::TAIL) { if (!LHSl && !LHSt) { - TokError("expected list type argumnet in unary operator"); + TokError("expected list type argument in unary operator"); return nullptr; } @@ -877,7 +894,7 @@ Init *TGParser::ParseOperation(Record *CurRec) { assert(LHSt && "expected list type argument in unary operator"); ListRecTy *LType = dyn_cast(LHSt->getType()); if (!LType) { - TokError("expected list type argumnet in unary operator"); + TokError("expected list type argument in unary operator"); return nullptr; } if (Code == UnOpInit::HEAD) { @@ -899,10 +916,12 @@ Init *TGParser::ParseOperation(Record *CurRec) { case tgtok::XConcat: case tgtok::XADD: + case tgtok::XAND: case tgtok::XSRA: case tgtok::XSRL: case tgtok::XSHL: case tgtok::XEq: + case tgtok::XListConcat: case tgtok::XStrConcat: { // Value ::= !binop '(' Value ',' Value ')' tgtok::TokKind OpTok = Lex.getCode(); SMLoc OpLoc = Lex.getLoc(); @@ -915,10 +934,15 @@ Init *TGParser::ParseOperation(Record *CurRec) { default: llvm_unreachable("Unhandled code!"); case tgtok::XConcat: Code = BinOpInit::CONCAT;Type = DagRecTy::get(); break; case tgtok::XADD: Code = BinOpInit::ADD; Type = IntRecTy::get(); break; + case tgtok::XAND: Code = BinOpInit::AND; Type = IntRecTy::get(); break; case tgtok::XSRA: Code = BinOpInit::SRA; Type = IntRecTy::get(); break; case tgtok::XSRL: Code = BinOpInit::SRL; Type = IntRecTy::get(); break; case tgtok::XSHL: Code = BinOpInit::SHL; Type = IntRecTy::get(); break; case tgtok::XEq: Code = BinOpInit::EQ; Type = BitRecTy::get(); break; + case tgtok::XListConcat: + Code = BinOpInit::LISTCONCAT; + // We don't know the list type until we parse the first argument + break; case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; Type = StringRecTy::get(); @@ -949,9 +973,22 @@ Init *TGParser::ParseOperation(Record *CurRec) { } Lex.Lex(); // eat the ')' + // If we are doing !listconcat, we should know the type by now + if (OpTok == tgtok::XListConcat) { + if (VarInit *Arg0 = dyn_cast(InitList[0])) + Type = Arg0->getType(); + else if (ListInit *Arg0 = dyn_cast(InitList[0])) + Type = Arg0->getType(); + else { + InitList[0]->dump(); + Error(OpLoc, "expected a list"); + return nullptr; + } + } + // We allow multiple operands to associative operators like !strconcat as // shorthand for nesting them. - if (Code == BinOpInit::STRCONCAT) { + if (Code == BinOpInit::STRCONCAT || Code == BinOpInit::LISTCONCAT) { while (InitList.size() > 2) { Init *RHS = InitList.pop_back_val(); RHS = (BinOpInit::get(Code, InitList.back(), RHS, Type)) @@ -1003,8 +1040,9 @@ Init *TGParser::ParseOperation(Record *CurRec) { } Lex.Lex(); // eat the ',' - Init *MHS = ParseValue(CurRec); - if (!MHS) return nullptr; + Init *MHS = ParseValue(CurRec, ItemType); + if (!MHS) + return nullptr; if (Lex.getCode() != tgtok::comma) { TokError("expected ',' in ternary operator"); @@ -1012,8 +1050,9 @@ Init *TGParser::ParseOperation(Record *CurRec) { } Lex.Lex(); // eat the ',' - Init *RHS = ParseValue(CurRec); - if (!RHS) return nullptr; + Init *RHS = ParseValue(CurRec, ItemType); + if (!RHS) + return nullptr; if (Lex.getCode() != tgtok::r_paren) { TokError("expected ')' in binary operator"); @@ -1134,6 +1173,7 @@ RecTy *TGParser::ParseOperatorType() { /// SimpleValue ::= SHLTOK '(' Value ',' Value ')' /// SimpleValue ::= SRATOK '(' Value ',' Value ')' /// SimpleValue ::= SRLTOK '(' Value ',' Value ')' +/// SimpleValue ::= LISTCONCATTOK '(' Value ',' Value ')' /// SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')' /// Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, @@ -1147,6 +1187,15 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, Lex.Lex(); // Skip '#'. return ParseSimpleValue(CurRec, ItemType, Mode); case tgtok::IntVal: R = IntInit::get(Lex.getCurIntVal()); Lex.Lex(); break; + case tgtok::BinaryIntVal: { + auto BinaryVal = Lex.getCurBinaryIntVal(); + SmallVector Bits(BinaryVal.second); + for (unsigned i = 0, e = BinaryVal.second; i != e; ++i) + Bits[i] = BitInit::get(BinaryVal.first & (1LL << i)); + R = BitsInit::get(Bits); + Lex.Lex(); + break; + } case tgtok::StrVal: { std::string Val = Lex.getCurStrVal(); Lex.Lex(); @@ -1207,8 +1256,10 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, SCRef.Rec = Class; SCRef.TemplateArgs = ValueList; // Add info about the subclass to NewRec. - if (AddSubClass(NewRec, SCRef)) + if (AddSubClass(NewRec, SCRef)) { + delete NewRec; return nullptr; + } if (!CurMultiClass) { NewRec->resolveReferences(); Records.addDef(NewRec); @@ -1258,17 +1309,28 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, } Lex.Lex(); // eat the '}' - SmallVector NewBits(Vals.size()); + SmallVector NewBits; + // As we parse { a, b, ... }, 'a' is the highest bit, but we parse it + // first. We'll first read everything in to a vector, then we can reverse + // it to get the bits in the correct order for the BitsInit value. for (unsigned i = 0, e = Vals.size(); i != e; ++i) { + // bits values are allowed to initialize n bits. + if (BitsInit *BI = dyn_cast(Vals[i])) { + for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) + NewBits.push_back(BI->getBit((e - i) - 1)); + continue; + } + // All other values must be convertible to just a single bit. Init *Bit = Vals[i]->convertInitializerTo(BitRecTy::get()); if (!Bit) { Error(BraceLoc, "Element #" + utostr(i) + " (" + Vals[i]->getAsString()+ ") is not convertable to a bit"); return nullptr; } - NewBits[Vals.size()-i-1] = Bit; + NewBits.push_back(Bit); } + std::reverse(NewBits.begin(), NewBits.end()); return BitsInit::get(NewBits); } case tgtok::l_square: { // Value ::= '[' ValueList ']' @@ -1413,15 +1475,17 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, case tgtok::XCast: // Value ::= !unop '(' Value ')' case tgtok::XConcat: case tgtok::XADD: + case tgtok::XAND: case tgtok::XSRA: case tgtok::XSRL: case tgtok::XSHL: case tgtok::XEq: + case tgtok::XListConcat: case tgtok::XStrConcat: // Value ::= !binop '(' Value ',' Value ')' case tgtok::XIf: case tgtok::XForEach: case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')' - return ParseOperation(CurRec); + return ParseOperation(CurRec, ItemType); } } @@ -1700,7 +1764,10 @@ Init *TGParser::ParseDeclaration(Record *CurRec, Init *Val = ParseValue(CurRec, Type); if (!Val || SetValue(CurRec, ValLoc, DeclName, std::vector(), Val)) - return nullptr; + // Return the name, even if an error is thrown. This is so that we can + // continue to make some progress, even without the value having been + // initialized. + return DeclName; } return DeclName; @@ -1957,6 +2024,7 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) { // Parse ObjectName and make a record for it. Record *CurRec; + bool CurRecOwnershipTransferred = false; Init *Name = ParseObjectName(CurMultiClass); if (Name) CurRec = new Record(Name, DefLoc, Records); @@ -1971,9 +2039,11 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) { if (Records.getDef(CurRec->getNameInitAsString())) { Error(DefLoc, "def '" + CurRec->getNameInitAsString() + "' already defined"); + delete CurRec; return true; } Records.addDef(CurRec); + CurRecOwnershipTransferred = true; if (ParseObjectBody(CurRec)) return true; @@ -1983,8 +2053,10 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) { // before this object, instantiated prior to defs derived from this object, // and this available for indirect name resolution when defs derived from // this object are instantiated. - if (ParseObjectBody(CurRec)) + if (ParseObjectBody(CurRec)) { + delete CurRec; return true; + } // Otherwise, a def inside a multiclass, add it to the multiclass. for (unsigned i = 0, e = CurMultiClass->DefPrototypes.size(); i != e; ++i) @@ -1992,11 +2064,15 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) { == CurRec->getNameInit()) { Error(DefLoc, "def '" + CurRec->getNameInitAsString() + "' already defined in this multiclass!"); + delete CurRec; return true; } CurMultiClass->DefPrototypes.push_back(CurRec); - } else if (ParseObjectBody(CurRec)) + CurRecOwnershipTransferred = true; + } else if (ParseObjectBody(CurRec)) { + delete CurRec; return true; + } if (!CurMultiClass) // Def's in multiclasses aren't really defs. // See Record::setName(). This resolve step will see any new name @@ -2022,9 +2098,13 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) { if (ProcessForeachDefs(CurRec, DefLoc)) { Error(DefLoc, "Could not process loops for def" + CurRec->getNameInitAsString()); + if (!CurRecOwnershipTransferred) + delete CurRec; return true; } + if (!CurRecOwnershipTransferred) + delete CurRec; return false; } @@ -2338,6 +2418,7 @@ InstantiateMulticlassDef(MultiClass &MC, Error(DefmPrefixRange.Start, "Could not resolve " + CurRec->getNameInitAsString() + ":NAME to '" + DefmPrefix->getAsUnquotedString() + "'"); + delete CurRec; return nullptr; } @@ -2369,6 +2450,7 @@ InstantiateMulticlassDef(MultiClass &MC, Error(DefmPrefixRange.Start, "def '" + CurRec->getNameInitAsString() + "' already defined, instantiating defm with subdef '" + DefProto->getNameInitAsString() + "'"); + delete CurRec; return nullptr; }