17#include "llvm/Config/llvm-config.h"
56#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
58 errs() <<
"Multiclass:\n";
62 errs() <<
"Template args:\n";
72 for (
unsigned i = 0, e = BV->
getNumBits(); i != e; ++i) {
74 bool IsReference =
false;
75 if (
auto VBI = dyn_cast<VarBitInit>(Bit)) {
76 if (
auto VI = dyn_cast<VarInit>(VBI->getBitVar())) {
77 if (R.getValue(VI->getName()))
80 }
else if (isa<VarInit>(Bit)) {
83 if (!(IsReference || Bit->isConcrete()))
90 for (
const RecordVal &RV : R.getValues()) {
95 if (RV.isNonconcreteOK())
98 if (
Init *V = RV.getValue()) {
102 Twine(
"Initializer of '") + RV.getNameInitAsString() +
103 "' in '" + R.getNameInitAsString() +
104 "' could not be fully resolved: " +
105 RV.getValue()->getAsString());
120 if (
BinOpInit *BinOp = dyn_cast<BinOpInit>(NewName))
121 NewName = BinOp->Fold(&CurRec);
140 bool TrackReferenceLocs)
const {
142 auto It = Vars.find(
Name->getValue());
143 if (It != Vars.end())
152 assert(RV &&
"Template arg doesn't exist??");
154 if (TrackReferenceLocs)
158 return Name->getValue() ==
"NAME"
172 if (TrackReferenceLocs)
173 RV->addReferenceLoc(NameLoc);
179 if (
auto *V = FindValueInArgs(CurRec,
Name))
196 if (
auto *V = FindValueInArgs(&CurMultiClass->
Rec,
Name))
204 return Parent->getVar(Records, ParsingMultiClass,
Name, NameLoc,
212 CurRec = &CurMultiClass->
Rec;
217 return Error(Loc,
"New definition of '" + RV.
getName() +
"' of type '" +
219 "previous definition of type '" +
220 ERV->getType()->getAsString() +
"'");
231 bool AllowSelfAssignment,
bool OverrideDefLoc) {
232 if (!V)
return false;
234 if (!CurRec) CurRec = &CurMultiClass->
Rec;
244 if (
VarInit *VI = dyn_cast<VarInit>(V))
245 if (
VI->getNameInit() == ValName && !AllowSelfAssignment)
246 return Error(Loc,
"Recursion / self-assignment forbidden");
252 if (!BitList.
empty()) {
256 "' is not a bits type");
261 return Error(Loc,
"Initializer is not compatible with bit range");
266 for (
unsigned i = 0, e = BitList.
size(); i != e; ++i) {
267 unsigned Bit = BitList[i];
269 return Error(Loc,
"Cannot set bit #" +
Twine(Bit) +
" of value '" +
274 for (
unsigned i = 0, e = CurVal->
getNumBits(); i != e; ++i)
276 NewBits[i] = CurVal->
getBit(i);
282 std::string InitType;
283 if (
BitsInit *BI = dyn_cast<BitsInit>(V))
284 InitType = (
Twine(
"' of type bit initializer with length ") +
285 Twine(BI->getNumBits())).str();
286 else if (
TypedInit *TI = dyn_cast<TypedInit>(V))
287 InitType = (
Twine(
"' of type '") + TI->getType()->getAsString()).str();
290 "' is incompatible with value '" +
291 V->getAsString() + InitType +
"'");
305 if (!
Field.isTemplateArg())
309 if (resolveArgumentsOfClass(R, SC, SubClass.
TemplateArgs,
332 for (
const auto &SCPair : SCs) {
335 "Already subclass of '" + SCPair.first->getName() +
"'!\n");
341 "Already subclass of '" +
SC->getName() +
"'!\n");
348 return AddSubClass(
Entry.Rec.get(), SubClass);
353 for (
auto &E :
Entry.Loop->Entries) {
354 if (AddSubClass(E, SubClass))
364bool TGParser::AddSubMultiClass(
MultiClass *CurMC,
369 if (resolveArgumentsOfMultiClass(
383 "RecordsEntry has invalid number of items");
386 if (!Loops.empty()) {
387 Loops.back()->Entries.push_back(std::move(E));
394 return resolve(*E.
Loop, Stack, CurMultiClass ==
nullptr,
395 CurMultiClass ? &CurMultiClass->
Entries :
nullptr);
400 CurMultiClass->
Entries.push_back(std::move(E));
416 return addDefOne(std::move(E.
Rec));
425 bool Final, std::vector<RecordsEntry> *Dest,
429 for (
const auto &S : Substs)
430 R.set(S.first, S.second);
439 if (
auto *TI = dyn_cast<TernOpInit>(
List);
441 Init *OldLHS = TI->getLHS();
446 Twine(
"unable to resolve if condition '") +
447 LHS->getAsString() +
"' at end of containing scope");
450 Init *MHS = TI->getMHS();
456 auto LI = dyn_cast<ListInit>(
List);
459 Dest->emplace_back(std::make_unique<ForeachLoop>(
Loop.Loc,
Loop.IterVar,
461 return resolve(
Loop.Entries, Substs, Final, &Dest->back().Loop->Entries,
466 List->getAsString() +
"', expected a list");
471 for (
auto *Elt : *LI) {
473 Substs.emplace_back(
Loop.IterVar->getNameInit(), Elt);
474 Error = resolve(
Loop.Entries, Substs, Final, Dest);
488bool TGParser::resolve(
const std::vector<RecordsEntry> &Source,
489 SubstStack &Substs,
bool Final,
490 std::vector<RecordsEntry> *Dest,
SMLoc *Loc) {
492 for (
auto &E : Source) {
494 Error = resolve(*E.
Loop, Substs, Final, Dest);
498 for (
const auto &S : Substs)
499 R.set(S.first, S.second);
500 Init *Condition = E.
Assertion->Condition->resolveReferences(R);
504 Dest->push_back(std::make_unique<Record::AssertionInfo>(
511 for (
const auto &S : Substs)
512 R.set(S.first, S.second);
513 Init *Message = E.
Dump->Message->resolveReferences(R);
517 std::make_unique<Record::DumpInfo>(E.
Dump->Loc, Message));
522 auto Rec = std::make_unique<Record>(*E.
Rec);
524 Rec->appendLoc(*Loc);
527 for (
const auto &S : Substs)
528 R.set(S.first, S.second);
529 Rec->resolveReferences(R);
532 Dest->push_back(std::move(Rec));
534 Error = addDefOne(std::move(Rec));
543bool TGParser::addDefOne(std::unique_ptr<Record> Rec) {
544 Init *NewName =
nullptr;
545 if (
Record *Prev = Records.
getDef(Rec->getNameInitAsString())) {
546 if (!Rec->isAnonymous()) {
548 "def already exists: " + Rec->getNameInitAsString());
549 PrintNote(Prev->getLoc(),
"location of previous definition");
558 if (!isa<StringInit>(Rec->getNameInit())) {
560 Rec->getNameInit()->getAsString() +
561 "' could not be fully resolved");
566 Rec->checkRecordAssertions();
569 Rec->emitRecordDumps();
572 assert(Rec->getTemplateArgs().empty() &&
"How'd this get template args?");
576 if (!
I->getType()->typeIsA(
Defset->EltTy)) {
577 PrintError(Rec->getLoc(),
Twine(
"adding record of incompatible type '") +
578 I->getType()->getAsString() +
586 Records.
addDef(std::move(Rec));
591 SMLoc Loc, ArgValueHandler ArgValueHandler) {
594 "Too many template arguments allowed");
598 for (
auto *Arg : ArgValues) {
599 Init *ArgName =
nullptr;
600 Init *ArgValue = Arg->getValue();
601 if (Arg->isPositional())
602 ArgName = ArgNames[Arg->getIndex()];
604 ArgName = Arg->getName();
608 return Error(Loc,
"We can only specify the template argument '" +
611 ArgValueHandler(ArgName, ArgValue);
616 for (
auto *UnsolvedArgName : UnsolvedArgNames) {
619 std::string
Name = UnsolvedArgName->getAsUnquotedString();
620 Error(Loc,
"value not specified for template argument '" +
Name +
"'");
625 ArgValueHandler(UnsolvedArgName,
Default);
636 return resolveArguments(Rec, ArgValues, Loc,
642bool TGParser::resolveArgumentsOfMultiClass(SubstStack &Substs,
MultiClass *MC,
647 return resolveArguments(
648 &MC->
Rec, ArgValues, Loc,
685 CurRec = &CurMultiClass->
Rec;
694 Name->resolveReferences(R);
708Record *TGParser::ParseClassID() {
710 TokError(
"expected name for ClassID");
716 std::string Msg(
"Couldn't find class '" + Lex.
getCurStrVal() +
"'");
718 TokError(Msg +
". Use 'defm' if you meant to use multiclass '" +
722 }
else if (TrackReferenceLocs) {
737 TokError(
"expected name for MultiClassID");
756ParseSubClassReference(
Record *CurRec,
bool isDefm) {
764 Result.Rec = ParseClassID();
774 if (ParseTemplateArgValueList(
Result.TemplateArgs, CurRec,
Result.Rec)) {
779 if (CheckTemplateArgValues(
Result.TemplateArgs,
Result.RefRange.Start,
797ParseSubMultiClassReference(
MultiClass *CurMC) {
801 Result.MC = ParseMultiClassID();
810 if (ParseTemplateArgValueList(
Result.TemplateArgs, &CurMC->
Rec,
832 auto LHSLoc = Lex.
getLoc();
833 auto *CurVal = ParseValue(CurRec);
836 auto *
LHS = cast<TypedInit>(CurVal);
843 auto RHSLoc = Lex.
getLoc();
844 CurVal = ParseValue(CurRec);
847 RHS = cast<TypedInit>(CurVal);
858 TokError(
"invalid range, cannot be negative");
900 auto FlushElems = [&] {
901 if (!Elems.
empty()) {
908 auto LHSLoc = Lex.
getLoc();
909 CurVal = ParseSliceElement(CurRec);
912 auto *CurValTy = CurVal->
getType();
914 if (
auto *ListValTy = dyn_cast<ListRecTy>(CurValTy)) {
915 if (!isa<IntRecTy>(ListValTy->getElementType())) {
917 "expected list<int>, got " +
Twine(ListValTy->getAsString()));
925 }
else if (!isa<IntRecTy>(CurValTy)) {
927 "unhandled type " +
Twine(CurValTy->getAsString()) +
" in range");
955 for (
auto *Slice : Slices) {
971 Init *CurVal = FirstItem;
973 CurVal = ParseValue(
nullptr);
975 IntInit *
II = dyn_cast_or_null<IntInit>(CurVal);
977 return TokError(
"expected integer or bitrange");
979 int64_t Start =
II->getValue();
983 return TokError(
"invalid range, cannot be negative");
994 Init *I_End = ParseValue(
nullptr);
995 IntInit *II_End = dyn_cast_or_null<IntInit>(I_End);
997 TokError(
"expected integer value as end of range");
1011 return TokError(
"invalid range, cannot be negative");
1015 for (; Start <=
End; ++Start)
1018 for (; Start >=
End; --Start)
1029 if (ParseRangePiece(Result)) {
1035 if (ParseRangePiece(Result)) {
1050 ParseRangeList(Ranges);
1051 if (
Ranges.empty())
return true;
1054 TokError(
"expected '>' at end of range list");
1055 return Error(StartLoc,
"to match this '<'");
1069 ParseRangeList(Ranges);
1070 if (
Ranges.empty())
return true;
1073 TokError(
"expected '}' at end of bit list");
1074 return Error(StartLoc,
"to match this '{'");
1090RecTy *TGParser::ParseType() {
1092 default:
TokError(
"Unknown token when expecting a type");
return nullptr;
1108 if (
I != TypeAliases.end()) {
1112 if (
Record *R = ParseClassID())
1119 TokError(
"expected '<' after bits type");
1123 TokError(
"expected integer in bits<n> type");
1128 TokError(
"expected '>' at end of bits<n> type");
1136 TokError(
"expected '<' after list type");
1140 RecTy *SubType = ParseType();
1141 if (!SubType)
return nullptr;
1144 TokError(
"expected '>' at end of list<ty> type");
1155 if (
Init *
I = CurScope->getVar(Records, CurMultiClass,
Name, NameLoc,
1156 TrackReferenceLocs))
1159 if (Mode == ParseNameMode)
1164 if (TrackReferenceLocs) {
1165 if (
auto *Def = dyn_cast<DefInit>(
I))
1166 Def->getDef()->appendReferenceLoc(NameLoc);
1173 if (CurRec && !CurRec->
isClass() && !CurMultiClass &&
1177 Error(NameLoc.
Start,
"Variable not defined: '" +
Name->getValue() +
"'");
1210 Type = ParseOperatorType();
1213 TokError(
"did not get type for unary operator");
1267 Type = ParseOperatorType();
1270 TokError(
"did not get type for unary operator");
1274 if (!isa<RecordRecTy>(
Type)) {
1275 TokError(
"type for !getdagop must be a record type");
1285 TokError(
"expected '(' after unary operator");
1289 Init *
LHS = ParseValue(CurRec);
1290 if (!LHS)
return nullptr;
1293 ListInit *LHSl = dyn_cast<ListInit>(LHS);
1294 StringInit *LHSs = dyn_cast<StringInit>(LHS);
1295 DagInit *LHSd = dyn_cast<DagInit>(LHS);
1296 TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
1297 if (!LHSl && !LHSs && !LHSd && !LHSt) {
1298 TokError(
"expected string, list, or dag type argument in unary operator");
1305 if (!LType && !SType && !DType) {
1306 TokError(
"expected string, list, or dag type argument in unary operator");
1313 ListInit *LHSl = dyn_cast<ListInit>(LHS);
1314 TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
1315 if (!LHSl && !LHSt) {
1316 TokError(
"expected list type argument in unary operator");
1322 TokError(
"expected list type argument in unary operator");
1327 if (LHSl && LHSl->
empty()) {
1328 TokError(
"empty list argument in unary operator");
1333 TypedInit *Itemt = dyn_cast<TypedInit>(Item);
1335 TokError(
"untyped list element in unary operator");
1341 assert(LHSt &&
"expected list type argument in unary operator");
1348 TokError(
"expected ')' in unary operator");
1363 TokError(
"expected '(' after type of !isa");
1367 Init *
LHS = ParseValue(CurRec);
1388 TokError(
"expected '(' after type of !exists");
1393 Init *Expr = ParseValue(CurRec);
1397 TypedInit *ExprType = dyn_cast<TypedInit>(Expr);
1399 Error(ExprLoc,
"expected string type argument in !exists operator");
1406 "expected string type argument in !exists operator, please "
1407 "use !isa instead");
1413 Error(ExprLoc,
"expected string type argument in !exists operator");
1418 TokError(
"expected ')' in !exists");
1491 RecTy *ArgType =
nullptr;
1501 Type = ParseOperatorType();
1503 TokError(
"did not get type for !getdagarg operator");
1554 if (
Type && ItemType && !
Type->typeIsConvertibleTo(ItemType)) {
1555 Error(OpLoc,
Twine(
"expected value of type '") +
1557 Type->getAsString() +
"'");
1562 TokError(
"expected '(' after binary operator");
1572 InitList.
push_back(ParseValue(CurRec, ArgType));
1573 if (!InitList.
back())
return nullptr;
1575 TypedInit *InitListBack = dyn_cast<TypedInit>(InitList.
back());
1576 if (!InitListBack) {
1577 Error(OpLoc,
Twine(
"expected value to be a typed value, got '" +
1578 InitList.
back()->getAsString() +
"'"));
1589 if (!isa<ListRecTy>(ArgType)) {
1590 Error(InitLoc,
Twine(
"expected a list, got value of type '") +
1596 if (ItemType && InitList.
size() == 1) {
1597 if (!isa<ListRecTy>(ItemType)) {
1599 Twine(
"expected output type to be a list, got type '") +
1604 Error(OpLoc,
Twine(
"expected first arg type to be '") +
1606 "', got value of type '" +
1607 cast<ListRecTy>(ItemType)
1614 if (InitList.
size() == 2 && !isa<IntRecTy>(ArgType)) {
1615 Error(InitLoc,
Twine(
"expected second parameter to be an int, got "
1616 "value of type '") +
1623 if (!isa<ListRecTy>(ArgType)) {
1624 Error(InitLoc,
Twine(
"expected a list, got value of type '") +
1634 Error(InitLoc,
Twine(
"expected bit, bits, int, string, or record; "
1648 Error(InitLoc,
Twine(
"expected bit, bits, int, or string; "
1655 switch (InitList.
size()) {
1660 Error(InitLoc,
Twine(
"expected list of string, int, bits, or bit; "
1661 "got value of type '") +
1667 if (!isa<StringRecTy>(ArgType)) {
1668 Error(InitLoc,
Twine(
"expected second argument to be a string, "
1669 "got value of type '") +
1685 Error(InitLoc,
Twine(
"expected value of type '") +
1724 TokError(
"expected ')' in operator");
1733 Type = cast<TypedInit>(InitList.
front())->getType()->getListTy();
1744 while (InitList.
size() > 2) {
1751 if (InitList.
size() == 2)
1755 Error(OpLoc,
"expected two operands to operator");
1761 return ParseOperationForEachFilter(CurRec, ItemType);
1769 TokError(
"expected '(' after !range operator");
1774 bool FirstArgIsList =
false;
1776 if (
Args.size() >= 3) {
1777 TokError(
"expected at most three values of integer");
1782 Args.push_back(ParseValue(CurRec));
1788 Error(OpLoc,
Twine(
"expected value to be a typed value, got '" +
1789 Args.back()->getAsString() +
"'"));
1794 if (!FirstArgIsList ||
Args.size() == 1) {
1795 if (
Args.size() == 1 && isa<ListRecTy>(ArgBackType)) {
1796 FirstArgIsList =
true;
1797 }
else if (isa<IntRecTy>(ArgBackType)) {
1800 if (
Args.size() != 1)
1801 Error(InitLoc,
Twine(
"expected value of type 'int', got '" +
1804 Error(InitLoc,
Twine(
"expected list or int, got value of type '") +
1810 assert(isa<ListRecTy>(cast<TypedInit>(Args[0])->
getType()));
1811 Error(InitLoc,
Twine(
"expected one list, got extra value of type '") +
1820 TokError(
"expected ')' in operator");
1825 auto ArgCount =
Args.size();
1827 auto *Arg0 = cast<TypedInit>(Args[0]);
1828 auto *Arg0Ty = Arg0->getType();
1829 if (ArgCount == 1) {
1830 if (isa<ListRecTy>(Arg0Ty)) {
1837 assert(isa<IntRecTy>(Arg0Ty));
1844 assert(isa<IntRecTy>(Arg0Ty));
1845 auto *Arg1 = cast<TypedInit>(Args[1]);
1846 assert(isa<IntRecTy>(Arg1->getType()));
1849 if (ArgCount == 3) {
1851 auto *Arg2 = cast<TypedInit>(Args[2]);
1852 assert(isa<IntRecTy>(Arg2->getType()));
1898 TokError(
"expected '(' after ternary operator");
1902 Init *
LHS = ParseValue(CurRec);
1903 if (!LHS)
return nullptr;
1906 TokError(
"expected ',' in ternary operator");
1911 Init *MHS = ParseValue(CurRec, ItemType);
1916 TokError(
"expected ',' in ternary operator");
1921 Init *
RHS = ParseValue(CurRec, ItemType);
1926 TokError(
"expected ')' in binary operator");
1933 TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
1934 if (!MHSt && !isa<UnsetInit>(MHS)) {
1935 Error(MHSLoc,
"could not determine type of the child list in !dag");
1938 if (MHSt && !isa<ListRecTy>(MHSt->
getType())) {
1939 Error(MHSLoc,
Twine(
"expected list of children, got type '") +
1944 TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
1945 if (!RHSt && !isa<UnsetInit>(RHS)) {
1946 Error(RHSLoc,
"could not determine type of the name list in !dag");
1950 Error(RHSLoc,
Twine(
"expected list<string>, got type '") +
1955 if (!MHSt && !RHSt) {
1957 "cannot have both unset children and unset names in !dag");
1963 RecTy *MHSTy =
nullptr;
1964 RecTy *RHSTy =
nullptr;
1966 if (
TypedInit *MHSt = dyn_cast<TypedInit>(MHS))
1968 if (
BitsInit *MHSbits = dyn_cast<BitsInit>(MHS))
1970 if (isa<BitInit>(MHS))
1973 if (
TypedInit *RHSt = dyn_cast<TypedInit>(RHS))
1975 if (
BitsInit *RHSbits = dyn_cast<BitsInit>(RHS))
1977 if (isa<BitInit>(RHS))
1981 if (isa<UnsetInit>(MHS))
1983 if (isa<UnsetInit>(RHS))
1986 if (!MHSTy || !RHSTy) {
1987 TokError(
"could not get type for !if");
2000 TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
2002 TokError(
"could not get type for !subst");
2009 TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
2010 if (!MHSt || !isa<IntRecTy, StringRecTy>(MHSt->
getType())) {
2011 Error(MHSLoc,
Twine(
"expected integer index or string name, got ") +
2020 TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
2021 if (!MHSt || !isa<IntRecTy, StringRecTy>(MHSt->
getType())) {
2022 Error(MHSLoc,
Twine(
"expected integer index or string name, got ") +
2028 TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
2030 if (RHSt && !isa<StringRecTy>(RHSt->
getType())) {
2031 Error(RHSLoc,
Twine(
"expected string or unset name, got type '") +
2042 return ParseOperationSubstr(CurRec, ItemType);
2045 return ParseOperationFind(CurRec, ItemType);
2048 return ParseOperationCond(CurRec, ItemType);
2054 TokError(
"expected '(' after !foldl");
2058 Init *StartUntyped = ParseValue(CurRec);
2062 TypedInit *Start = dyn_cast<TypedInit>(StartUntyped);
2070 TokError(
"expected ',' in !foldl");
2074 Init *ListUntyped = ParseValue(CurRec);
2087 TokError(
Twine(
"!foldl list must be a list, but is of type '") +
2088 List->getType()->getAsString());
2093 TokError(
"expected ',' in !foldl");
2098 TokError(
"third argument of !foldl must be an identifier");
2105 "' already defined")
2111 TokError(
"expected ',' in !foldl");
2116 TokError(
"fourth argument of !foldl must be an identifier");
2123 "' already defined")
2129 TokError(
"expected ',' in !foldl");
2136 std::unique_ptr<Record> ParseRecTmp;
2137 Record *ParseRec = CurRec;
2139 ParseRecTmp = std::make_unique<Record>(
".parse",
ArrayRef<SMLoc>{}, Records);
2140 ParseRec = ParseRecTmp.get();
2147 Init *ExprUntyped = ParseValue(ParseRec);
2148 ParseRec->removeValue(
A);
2149 ParseRec->removeValue(
B);
2154 TypedInit *Expr = dyn_cast<TypedInit>(ExprUntyped);
2156 TokError(
"could not get type of !foldl expression");
2160 if (Expr->
getType() != Start->getType()) {
2161 TokError(
Twine(
"!foldl expression must be of same type as start (") +
2162 Start->getType()->getAsString() +
"), but is of type " +
2168 TokError(
"expected ')' in fold operator");
2183RecTy *TGParser::ParseOperatorType() {
2187 TokError(
"expected type name for operator");
2192 TokError(
"the 'code' type is not allowed in bang operators; use 'string'");
2197 TokError(
"expected type name for operator");
2202 TokError(
"expected type name for operator");
2212Init *TGParser::ParseOperationSubstr(
Record *CurRec,
RecTy *ItemType) {
2219 TokError(
"expected '(' after !substr operator");
2223 Init *
LHS = ParseValue(CurRec);
2228 TokError(
"expected ',' in !substr operator");
2233 Init *MHS = ParseValue(CurRec);
2241 RHS = ParseValue(CurRec);
2249 TokError(
"expected ')' in !substr operator");
2253 if (ItemType && !
Type->typeIsConvertibleTo(ItemType)) {
2254 Error(RHSLoc,
Twine(
"expected value of type '") +
2256 Type->getAsString() +
"'");
2259 TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
2260 if (!LHSt && !isa<UnsetInit>(LHS)) {
2261 TokError(
"could not determine type of the string in !substr");
2264 if (LHSt && !isa<StringRecTy>(LHSt->
getType())) {
2270 TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
2271 if (!MHSt && !isa<UnsetInit>(MHS)) {
2272 TokError(
"could not determine type of the start position in !substr");
2275 if (MHSt && !isa<IntRecTy>(MHSt->
getType())) {
2276 Error(MHSLoc,
Twine(
"expected int, got type '") +
2282 TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
2283 if (!RHSt && !isa<UnsetInit>(RHS)) {
2284 TokError(
"could not determine type of the length in !substr");
2287 if (RHSt && !isa<IntRecTy>(RHSt->
getType())) {
2307 TokError(
"expected '(' after !find operator");
2311 Init *
LHS = ParseValue(CurRec);
2316 TokError(
"expected ',' in !find operator");
2321 Init *MHS = ParseValue(CurRec);
2329 RHS = ParseValue(CurRec);
2337 TokError(
"expected ')' in !find operator");
2341 if (ItemType && !
Type->typeIsConvertibleTo(ItemType)) {
2342 Error(RHSLoc,
Twine(
"expected value of type '") +
2344 Type->getAsString() +
"'");
2347 TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
2348 if (!LHSt && !isa<UnsetInit>(LHS)) {
2349 TokError(
"could not determine type of the source string in !find");
2352 if (LHSt && !isa<StringRecTy>(LHSt->
getType())) {
2358 TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
2359 if (!MHSt && !isa<UnsetInit>(MHS)) {
2360 TokError(
"could not determine type of the target string in !find");
2363 if (MHSt && !isa<StringRecTy>(MHSt->
getType())) {
2364 Error(MHSLoc,
Twine(
"expected string, got type '") +
2370 TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
2371 if (!RHSt && !isa<UnsetInit>(RHS)) {
2372 TokError(
"could not determine type of the start position in !find");
2375 if (RHSt && !isa<IntRecTy>(RHSt->
getType())) {
2389Init *TGParser::ParseOperationForEachFilter(
Record *CurRec,
RecTy *ItemType) {
2394 TokError(
"expected '(' after !foreach/!filter");
2399 TokError(
"first argument of !foreach/!filter must be an identifier");
2406 if (CurRec && CurRec->
getValue(LHS)) {
2408 "' is already defined")
2414 TokError(
"expected ',' in !foreach/!filter");
2418 Init *MHS = ParseValue(CurRec);
2423 TokError(
"expected ',' in !foreach/!filter");
2427 TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
2429 TokError(
"could not get type of !foreach/!filter list or dag");
2433 RecTy *InEltType =
nullptr;
2434 RecTy *ExprEltType =
nullptr;
2438 InEltType = InListTy->getElementType();
2440 if (
ListRecTy *OutListTy = dyn_cast<ListRecTy>(ItemType)) {
2442 ? OutListTy->getElementType()
2446 "expected value of type '" +
2448 "', but got list type");
2454 TokError(
"!filter must have a list argument");
2457 InEltType = InDagTy;
2458 if (ItemType && !isa<DagRecTy>(ItemType)) {
2461 "', but got dag type");
2467 TokError(
"!foreach must have a list or dag argument");
2469 TokError(
"!filter must have a list argument");
2475 std::unique_ptr<Record> ParseRecTmp;
2476 Record *ParseRec = CurRec;
2480 ParseRec = ParseRecTmp.get();
2484 Init *
RHS = ParseValue(ParseRec, ExprEltType);
2485 ParseRec->removeValue(LHS);
2491 TokError(
"expected ')' in !foreach/!filter");
2495 RecTy *OutType = InEltType;
2497 TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
2499 TokError(
"could not get type of !foreach result expression");
2509 LHS, MHS, RHS, OutType))
2517 TokError(
"expected '(' after !cond operator");
2528 Init *
V = ParseValue(CurRec);
2534 TokError(
"expected ':' following a condition in !cond operator");
2538 V = ParseValue(CurRec, ItemType);
2547 TokError(
"expected ',' or ')' following a value in !cond operator");
2552 if (Case.
size() < 1) {
2553 TokError(
"there should be at least 1 'condition : value' in the !cond operator");
2559 for (
Init *V : Val) {
2560 RecTy *VTy =
nullptr;
2561 if (
TypedInit *Vt = dyn_cast<TypedInit>(V))
2562 VTy = Vt->getType();
2563 if (
BitsInit *Vbits = dyn_cast<BitsInit>(V))
2565 if (isa<BitInit>(V))
2568 if (
Type ==
nullptr) {
2569 if (!isa<UnsetInit>(V))
2572 if (!isa<UnsetInit>(V)) {
2585 TokError(
"could not determine type for !cond from its arguments");
2625 return ParseOperation(CurRec, ItemType);
2628 default:
TokError(
"Unknown or reserved token when parsing a value");
break;
2645 for (
unsigned i = 0, e = BinaryVal.second; i != e; ++i)
2679 return ParseIDValue(CurRec,
Name, NameLoc, Mode);
2687 "Expected a class name, got '" +
Name->getValue() +
"'");
2693 if (ParseTemplateArgValueList(Args, CurRec, Class))
2696 if (CheckTemplateArgValues(Args, NameLoc.
Start, Class))
2699 if (resolveArguments(Class, Args, NameLoc.
Start))
2702 if (TrackReferenceLocs)
2703 Class->appendReferenceLoc(NameLoc);
2712 ParseValueList(Vals, CurRec);
2713 if (Vals.
empty())
return nullptr;
2716 TokError(
"expected '}' at end of bit list value");
2725 for (
unsigned i = 0, e = Vals.
size(); i != e; ++i) {
2730 if (
BitsInit *BI = dyn_cast<BitsInit>(Vals[i])) {
2731 for (
unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
2736 if (
VarInit *VI = dyn_cast<VarInit>(Vals[i])) {
2737 if (
BitsRecTy *BitsRec = dyn_cast<BitsRecTy>(
VI->getType())) {
2738 for (
unsigned i = 0, e = BitsRec->getNumBits(); i != e; ++i)
2747 Error(BraceLoc,
"Element #" +
Twine(i) +
" (" + Vals[i]->getAsString() +
2748 ") is not convertable to a bit");
2753 std::reverse(NewBits.
begin(), NewBits.
end());
2760 RecTy *DeducedEltTy =
nullptr;
2764 ListRecTy *ListType = dyn_cast<ListRecTy>(ItemType);
2770 GivenListTy = ListType;
2774 ParseValueList(Vals, CurRec,
2776 if (Vals.
empty())
return nullptr;
2779 TokError(
"expected ']' at end of list value");
2783 RecTy *GivenEltTy =
nullptr;
2786 GivenEltTy = ParseType();
2793 TokError(
"expected '>' at end of list element type");
2799 RecTy *EltTy =
nullptr;
2800 for (
Init *V : Vals) {
2801 TypedInit *TArg = dyn_cast<TypedInit>(V);
2806 TokError(
"Incompatible types in list elements");
2819 TokError(
"Incompatible types in list elements");
2836 TokError(
Twine(
"Element type mismatch for list: element type '") +
2842 DeducedEltTy = EltTy;
2851 TokError(
"expected identifier in dag init");
2862 TokError(
"expected variable name in dag operator");
2871 ParseDagArgList(DagArgs, CurRec);
2872 if (DagArgs.
empty())
return nullptr;
2876 TokError(
"expected ')' in dag init");
2894Init *TGParser::ParseValue(
Record *CurRec,
RecTy *ItemType, IDParseMode Mode) {
2896 Init *
Result = ParseSimpleValue(CurRec, ItemType, Mode);
2897 if (!Result)
return nullptr;
2904 if (Mode == ParseNameMode)
2911 ParseRangeList(Ranges);
2912 if (
Ranges.empty())
return nullptr;
2918 Error(CurlyLoc,
"Invalid bit range for value");
2924 TokError(
"expected '}' at end of bit range list");
2930 auto *
LHS = dyn_cast<TypedInit>(Result);
2932 Error(LHSLoc,
"Invalid value, list expected");
2936 auto *LHSTy = dyn_cast<ListRecTy>(
LHS->
getType());
2939 "' is invalid, list expected");
2953 LHSTy->getElementType())
2961 TokError(
"expected ']' at end of list slice");
2968 TokError(
"expected field identifier after '.'");
2973 if (!
Result->getFieldType(FieldName)) {
2975 Result->getAsString() +
"'");
2980 if (TrackReferenceLocs) {
2981 if (
auto *DI = dyn_cast<DefInit>(Result)) {
2982 DI->getDef()->getValue(FieldName)->addReferenceLoc(FieldNameLoc);
2983 }
else if (
auto *TI = dyn_cast<TypedInit>(Result)) {
2984 if (
auto *
RecTy = dyn_cast<RecordRecTy>(TI->getType())) {
2986 if (
auto *RV =
R->getValue(FieldName))
3001 Error(PasteLoc,
"LHS of paste is not typed!");
3009 assert(Mode == ParseValueMode &&
"encountered paste of lists in name");
3018 Init *RHSResult = ParseValue(CurRec, ItemType, ParseValueMode);
3030 auto CastLHS = dyn_cast<TypedInit>(
3035 Twine(
"can't cast '") +
LHS->getAsString() +
"' to string");
3057 Init *RHSResult = ParseValue(CurRec,
nullptr, ParseNameMode);
3060 RHS = dyn_cast<TypedInit>(RHSResult);
3062 Error(PasteLoc,
"RHS of paste is not typed!");
3067 auto CastRHS = dyn_cast<TypedInit>(
3072 Twine(
"can't cast '") +
RHS->getAsString() +
"' to string");
3093void TGParser::ParseDagArgList(
3106 Init *Val = ParseValue(CurRec);
3116 TokError(
"expected variable name in dag literal");
3124 Result.push_back(std::make_pair(Val, VarName));
3140 Result.push_back(ParseValue(CurRec, ItemType));
3150 Result.push_back(ParseValue(CurRec, ItemType));
3166bool TGParser::ParseTemplateArgValueList(
3168 assert(
Result.empty() &&
"Result vector is not empty");
3174 bool HasNamedArg =
false;
3175 unsigned ArgIndex = 0;
3177 if (ArgIndex >= TArgs.
size()) {
3178 TokError(
"Too many template arguments: " + utostr(ArgIndex + 1));
3187 HasNamedArg ?
nullptr : ArgsRec->
getValue(TArgs[ArgIndex])->
getType());
3193 if (!isa<StringInit>(
Value))
3194 return Error(ValueLoc,
3195 "The name of named argument should be a valid identifier");
3201 return Error(ValueLoc,
3202 "Argument " +
Name->getAsString() +
" doesn't exist");
3206 Value = ParseValue(CurRec, NamedArg->getType());
3208 if (isa<UnsetInit>(
Value))
3209 return Error(ValueLoc,
3210 "The value of named argument should be initialized, "
3212 Value->getAsString() +
"'");
3219 return Error(ValueLoc,
3220 "Positional argument should be put before named argument");
3228 return TokError(
"Expected comma before next argument");
3243Init *TGParser::ParseDeclaration(
Record *CurRec,
3244 bool ParsingTemplateArgs) {
3249 if (!
Type)
return nullptr;
3252 TokError(
"Expected identifier in declaration");
3257 if (Str ==
"NAME") {
3258 TokError(
"'" + Str +
"' is a reserved variable name");
3262 if (!ParsingTemplateArgs && CurScope->varAlreadyDefined(Str)) {
3263 TokError(
"local variable of this name already exists");
3272 if (!ParsingTemplateArgs) {
3273 BadField = AddValue(CurRec, IdLoc,
3277 }
else if (CurRec) {
3280 AddValue(CurRec, IdLoc,
3283 assert(CurMultiClass &&
"invalid context for template argument");
3286 AddValue(CurRec, IdLoc,
3295 Init *Val = ParseValue(CurRec,
Type);
3297 SetValue(CurRec, ValLoc, DeclName, std::nullopt, Val,
3317VarInit *TGParser::ParseForeachDeclaration(
Init *&ForeachListValue) {
3319 TokError(
"Expected identifier in foreach declaration");
3328 TokError(
"Expected '=' in foreach declaration");
3332 RecTy *IterType =
nullptr;
3338 ParseRangeList(Ranges);
3340 TokError(
"expected '}' at end of bit range list");
3348 Init *
I = ParseValue(
nullptr);
3353 if (TI && isa<ListRecTy>(TI->
getType())) {
3354 ForeachListValue =
I;
3355 IterType = cast<ListRecTy>(TI->
getType())->getElementType();
3360 if (ParseRangePiece(Ranges, TI))
3365 Error(ValueLoc,
"expected a list, got '" +
I->getAsString() +
"'");
3366 if (CurMultiClass) {
3367 PrintNote({},
"references to multiclass template arguments cannot be "
3368 "resolved at this time");
3376 assert(!IterType &&
"Type already initialized?");
3378 std::vector<Init *> Values;
3379 for (
unsigned R : Ranges)
3397bool TGParser::ParseTemplateArgList(
Record *CurRec) {
3401 Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->
Rec;
3404 Init *TemplArg = ParseDeclaration(CurRec,
true);
3413 TemplArg = ParseDeclaration(CurRec,
true);
3418 return Error(Loc,
"template argument with the same name has already been "
3425 return TokError(
"expected '>' at end of template argument list");
3437bool TGParser::ParseBodyItem(
Record *CurRec) {
3439 return ParseAssert(
nullptr, CurRec);
3442 return ParseDefvar(CurRec);
3445 return ParseDump(
nullptr, CurRec);
3448 if (!ParseDeclaration(CurRec,
false))
3452 return TokError(
"expected ';' after declaration");
3458 return TokError(
"expected field identifier after let");
3465 if (ParseOptionalBitList(BitList))
3467 std::reverse(BitList.
begin(), BitList.
end());
3470 return TokError(
"expected '=' in let expression");
3477 if (!BitList.
empty() && isa<BitsRecTy>(
Type)) {
3483 Init *Val = ParseValue(CurRec,
Type);
3484 if (!Val)
return true;
3487 return TokError(
"expected ';' after let expression");
3489 return SetValue(CurRec, IdLoc, FieldName, BitList, Val);
3499bool TGParser::ParseBody(
Record *CurRec) {
3505 return TokError(
"Expected '{' to start body or ';' for declaration only");
3508 if (ParseBodyItem(CurRec))
3517 PrintError(SemiLoc,
"A class or def body should not end with a semicolon");
3518 PrintNote(
"Semicolon ignored; remove to eliminate this error");
3526bool TGParser::ApplyLetStack(
Record *CurRec) {
3529 if (SetValue(CurRec, LR.Loc, LR.Name, LR.Bits, LR.Value))
3537 return ApplyLetStack(
Entry.Rec.get());
3540 if (
Entry.Assertion)
3547 for (
auto &E :
Entry.Loop->Entries) {
3548 if (ApplyLetStack(E))
3564bool TGParser::ParseObjectBody(
Record *CurRec) {
3574 if (!SubClass.
Rec)
return true;
3577 if (AddSubClass(CurRec, SubClass))
3582 SubClass = ParseSubClassReference(CurRec,
false);
3586 if (ApplyLetStack(CurRec))
3589 bool Result = ParseBody(CurRec);
3599bool TGParser::ParseDef(
MultiClass *CurMultiClass) {
3610 std::unique_ptr<Record> CurRec;
3611 Init *
Name = ParseObjectName(CurMultiClass);
3615 if (isa<UnsetInit>(
Name)) {
3619 CurRec = std::make_unique<Record>(
Name, NameLoc, Records);
3622 if (ParseObjectBody(CurRec.get()))
3625 return addEntry(std::move(CurRec));
3632bool TGParser::ParseDefset() {
3641 if (!isa<ListRecTy>(
Type))
3643 Defset.EltTy = cast<ListRecTy>(
Type)->getElementType();
3646 return TokError(
"expected identifier");
3649 return TokError(
"def or global variable of this name already exists");
3658 Defsets.push_back(&Defset);
3659 bool Err = ParseObjectList(
nullptr);
3665 TokError(
"expected '}' at end of defset");
3666 return Error(BraceLoc,
"to match this '{'");
3678bool TGParser::ParseDeftype() {
3683 return TokError(
"expected identifier");
3686 if (TypeAliases.count(TypeName) || Records.
getClass(TypeName))
3687 return TokError(
"type of this name '" + TypeName +
"' already exists");
3699 return Error(Loc,
"cannot define type alias for class type '" +
3700 Type->getAsString() +
"'");
3714bool TGParser::ParseDefvar(
Record *CurRec) {
3719 return TokError(
"expected identifier");
3721 if (CurScope->varAlreadyDefined(DeclName->
getValue()))
3722 return TokError(
"local variable of this name already exists");
3727 if (V && !
V->isTemplateArg())
3728 return TokError(
"field of this name already exists");
3734 return TokError(
"def or global variable of this name already exists");
3747 if (!CurScope->isOutermost())
3761bool TGParser::ParseForeach(
MultiClass *CurMultiClass) {
3768 Init *ListValue =
nullptr;
3769 VarInit *IterName = ParseForeachDeclaration(ListValue);
3771 return TokError(
"expected declaration in for");
3777 auto TheLoop = std::make_unique<ForeachLoop>(Loc, IterName, ListValue);
3780 Loops.push_back(std::move(TheLoop));
3784 if (ParseObject(CurMultiClass))
3792 if (ParseObjectList(CurMultiClass))
3796 TokError(
"expected '}' at end of foreach command");
3797 return Error(BraceLoc,
"to match this '{'");
3804 std::unique_ptr<ForeachLoop>
Loop = std::move(Loops.back());
3807 return addEntry(std::move(
Loop));
3815bool TGParser::ParseIf(
MultiClass *CurMultiClass) {
3822 Init *Condition = ParseValue(
nullptr);
3842 Init *ThenClauseList =
3846 Loops.push_back(std::make_unique<ForeachLoop>(Loc,
nullptr, ThenClauseList));
3848 if (ParseIfBody(CurMultiClass,
"then"))
3851 std::unique_ptr<ForeachLoop>
Loop = std::move(Loops.back());
3854 if (addEntry(std::move(
Loop)))
3864 Init *ElseClauseList =
3869 std::make_unique<ForeachLoop>(Loc,
nullptr, ElseClauseList));
3871 if (ParseIfBody(CurMultiClass,
"else"))
3874 Loop = std::move(Loops.back());
3877 if (addEntry(std::move(
Loop)))
3895 if (ParseObject(CurMultiClass))
3903 if (ParseObjectList(CurMultiClass))
3907 TokError(
"expected '}' at end of '" + Kind +
"' clause");
3908 return Error(BraceLoc,
"to match this '{'");
3924 Init *Condition = ParseValue(CurRec);
3929 TokError(
"expected ',' in assert statement");
3933 Init *Message = ParseValue(CurRec);
3941 CurRec->
addAssertion(ConditionLoc, Condition, Message);
3943 addEntry(std::make_unique<Record::AssertionInfo>(ConditionLoc, Condition,
3952bool TGParser::ParseClass() {
3957 return TokError(
"expected class name after 'class' keyword");
3967 "' already defined");
3974 CurRec = NewRec.get();
3975 Records.
addClass(std::move(NewRec));
3978 if (TypeAliases.count(
Name))
3979 return TokError(
"there is already a defined type alias '" +
Name +
"'");
3987 if (ParseTemplateArgList(CurRec))
3990 if (ParseObjectBody(CurRec))
3993 if (!NoWarnOnUnusedTemplateArgs)
4009 TokError(
"expected identifier in let definition");
4020 if (ParseOptionalRangeList(Bits)) {
4024 std::reverse(
Bits.begin(),
Bits.end());
4027 TokError(
"expected '=' in let expression");
4032 Init *Val = ParseValue(
nullptr);
4039 Result.emplace_back(
Name, Bits, Val, NameLoc);
4049bool TGParser::ParseTopLevelLet(
MultiClass *CurMultiClass) {
4055 ParseLetList(LetInfo);
4056 if (LetInfo.
empty())
return true;
4060 return TokError(
"expected 'in' at end of top-level 'let'");
4065 if (ParseObject(CurMultiClass))
4076 if (ParseObjectList(CurMultiClass))
4080 TokError(
"expected '}' at end of top level let command");
4081 return Error(BraceLoc,
"to match this '{'");
4105bool TGParser::ParseMultiClass() {
4110 return TokError(
"expected identifier after multiclass for name");
4114 MultiClasses.insert(std::make_pair(
Name,
4115 std::make_unique<MultiClass>(
Name, Lex.
getLoc(),Records)));
4118 return TokError(
"multiclass '" +
Name +
"' already defined");
4120 CurMultiClass =
Result.first->second.get();
4128 if (ParseTemplateArgList(
nullptr))
4131 bool inherits =
false;
4139 ParseSubMultiClassReference(CurMultiClass);
4142 if (!SubMultiClass.
MC)
return true;
4145 if (AddSubMultiClass(CurMultiClass, SubMultiClass))
4150 SubMultiClass = ParseSubMultiClassReference(CurMultiClass);
4156 return TokError(
"expected '{' in multiclass definition");
4158 return TokError(
"expected ';' in multiclass definition");
4161 return TokError(
"multiclass must contain at least one def");
4166 return TokError(
"expected 'assert', 'def', 'defm', 'defvar', 'dump', "
4167 "'foreach', 'if', or 'let' in multiclass body");
4177 if (ParseObject(CurMultiClass))
4187 PrintError(SemiLoc,
"A multiclass body should not end with a semicolon");
4188 PrintNote(
"Semicolon ignored; remove to eliminate this error");
4192 if (!NoWarnOnUnusedTemplateArgs)
4196 CurMultiClass =
nullptr;
4204bool TGParser::ParseDefm(
MultiClass *CurMultiClass) {
4208 Init *DefmName = ParseObjectName(CurMultiClass);
4211 if (isa<UnsetInit>(DefmName)) {
4221 return TokError(
"expected ':' after defm identifier");
4224 std::vector<RecordsEntry> NewEntries;
4227 bool InheritFromClass =
false;
4236 if (!
Ref.Rec)
return true;
4242 MultiClass *MC = MultiClasses[std::string(
Ref.Rec->getName())].get();
4243 assert(MC &&
"Didn't lookup multiclass correctly?");
4246 if (resolveArgumentsOfMultiClass(Substs, MC,
Ref.TemplateArgs, DefmName,
4250 if (resolve(MC->
Entries, Substs, !CurMultiClass && Loops.empty(),
4251 &NewEntries, &SubClassLoc))
4258 return TokError(
"expected identifier");
4260 SubClassLoc = Lex.
getLoc();
4266 if (InheritFromClass)
4269 Ref = ParseSubClassReference(
nullptr,
true);
4272 if (InheritFromClass) {
4278 if (!SubClass.
Rec)
return true;
4282 for (
auto &E : NewEntries) {
4284 if (AddSubClass(E, SubClass))
4290 SubClass = ParseSubClassReference(
nullptr,
false);
4294 for (
auto &E : NewEntries) {
4295 if (ApplyLetStack(E))
4298 addEntry(std::move(E));
4302 return TokError(
"expected ';' at end of defm");
4323 "Expected assert, class, def, defm, defset, dump, foreach, if, or let");
4328 return ParseDeftype();
4331 return ParseDump(MC);
4334 case tgtok::Let:
return ParseTopLevelLet(MC);
4337 return TokError(
"defset is not allowed inside multiclass");
4338 return ParseDefset();
4341 return TokError(
"class is not allowed inside multiclass");
4343 return TokError(
"class is not allowed inside foreach loop");
4344 return ParseClass();
4347 return TokError(
"multiclass is not allowed inside foreach loop");
4348 return ParseMultiClass();
4354bool TGParser::ParseObjectList(
MultiClass *MC) {
4356 if (ParseObject(MC))
4365 if (ParseObjectList())
4373 return TokError(
"Unexpected token at top level");
4380bool TGParser::CheckTemplateArgValues(
4385 Init *ArgName =
nullptr;
4386 if (
Value->isPositional())
4387 ArgName = TArgs[
Value->getIndex()];
4388 if (
Value->isNamed())
4394 if (
TypedInit *ArgValue = dyn_cast<TypedInit>(
Value->getValue())) {
4395 auto *CastValue = ArgValue->
getCastTo(ArgType);
4397 assert((!isa<TypedInit>(CastValue) ||
4398 cast<TypedInit>(CastValue)->
getType()->typeIsA(ArgType)) &&
4399 "result of template arg value cast has wrong type");
4414#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4433 errs() <<
"Record:\n";
4436 errs() <<
"Defs:\n";
4448 Init *Message = ParseValue(CurRec);
4454 if (isa<DefInit>(Message))
4462 CurRec->
addDump(Loc, Message);
4468 addEntry(std::make_unique<Record::DumpInfo>(Loc, ResolvedMessage));
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
uint64_t IntrinsicInst * II
PowerPC Reduce CR logical Operation
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
static bool checkBitsConcrete(Record &R, const RecordVal &RV)
static Init * QualifyName(Record &CurRec, Init *Name)
Return an Init with a qualifier prefix referring to CurRec's name.
static Init * QualifiedNameOfImplicitName(Record &Rec)
Return the qualified version of the implicit 'NAME' template argument.
static void checkConcrete(Record &R)
static SymbolRef::Type getType(const Symbol *Sym)
static ArgumentInit * get(Init *Value, ArgAuxType Aux)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
!op (X, Y) - Combine two inits.
Init * Fold(Record *CurRec) const
static Init * getStrConcat(Init *lhs, Init *rhs)
static Init * getListConcat(TypedInit *lhs, Init *rhs)
static BinOpInit * get(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type)
static BitInit * get(RecordKeeper &RK, bool V)
static BitRecTy * get(RecordKeeper &RK)
'{ a, b, c }' - Represents an initializer for a BitsRecTy value.
Init * getBit(unsigned Bit) const override
Get the Init value of the specified bit.
unsigned getNumBits() const
static BitsInit * get(RecordKeeper &RK, ArrayRef< Init * > Range)
'bits<n>' - Represent a fixed number of bits
static BitsRecTy * get(RecordKeeper &RK, unsigned Sz)
static CondOpInit * get(ArrayRef< Init * > C, ArrayRef< Init * > V, RecTy *Type)
Init * Fold(Record *CurRec) const
(v a, b) - Represent a DAG tree value.
static DagInit * get(Init *V, StringInit *VN, ArrayRef< Init * > ArgRange, ArrayRef< StringInit * > NameRange)
'dag' - Represent a dag fragment
static DagRecTy * get(RecordKeeper &RK)
AL - Represent a reference to a 'def' in the description.
Lightweight error class with error context and mandatory checking.
static ExistsOpInit * get(RecTy *CheckType, Init *Expr)
Init * Fold(Record *CurRec) const
static FieldInit * get(Init *R, StringInit *FN)
Init * Fold(Record *CurRec) const
static FoldOpInit * get(Init *Start, Init *List, Init *A, Init *B, Init *Expr, RecTy *Type)
Do not resolve anything, but keep track of whether a given variable was referenced.
virtual Init * getBit(unsigned Bit) const =0
Get the Init value of the specified bit.
virtual Init * resolveReferences(Resolver &R) const
This function is used by classes that refer to other variables which may not be defined at the time t...
virtual std::string getAsUnquotedString() const
Convert this value to a literal form, without adding quotes around a string.
virtual std::string getAsString() const =0
Convert this value to a literal form.
virtual Init * getCastTo(RecTy *Ty) const =0
If this value is convertible to type Ty, return a value whose type is Ty, generating a !...
'7' - Represent an initialization by a literal integer value.
static IntInit * get(RecordKeeper &RK, int64_t V)
static IntRecTy * get(RecordKeeper &RK)
static IsAOpInit * get(RecTy *CheckType, Init *Expr)
[AL, AH, CL] - Represent a list of defs
static ListInit * get(ArrayRef< Init * > Range, RecTy *EltTy)
Init * getElement(unsigned i) const
'list<Ty>' - Represent a list of element values, all of which must be of the specified type.
bool typeIsConvertibleTo(const RecTy *RHS) const override
Return true if all values of 'this' type can be converted to the specified type.
RecTy * getElementType() const
static ListRecTy * get(RecTy *T)
Represents a single loop in the control flow graph.
Resolve arbitrary mappings.
This is a utility class that provides an abstraction for the common functionality between Instruction...
ListRecTy * getListTy()
Returns the type representing list<thistype>.
virtual bool typeIsConvertibleTo(const RecTy *RHS) const
Return true if all values of 'this' type can be converted to the specified type.
virtual std::string getAsString() const =0
void addDef(std::unique_ptr< Record > R)
void addClass(std::unique_ptr< Record > R)
Record * getDef(StringRef Name) const
Get the concrete record with the specified name.
Record * getClass(StringRef Name) const
Get the class with the specified name.
void addExtraGlobal(StringRef Name, Init *I)
Init * getNewAnonymousName()
GetNewAnonymousName - Generate a unique anonymous name that can be used as an identifier.
Init * getGlobal(StringRef Name) const
Get the Init value of the specified global variable.
'[classname]' - Type of record values that have zero or more superclasses.
static RecordRecTy * get(RecordKeeper &RK, ArrayRef< Record * > Classes)
Get the record type with the given non-redundant list of superclasses.
This class represents a field in a record, including its name, type, value, and source location.
bool setValue(Init *V)
Set the value of the field from an Init.
std::string getNameInitAsString() const
Get the name of the field as a std::string.
void setUsed(bool Used)
Whether this value is used.
StringRef getName() const
Get the name of the field as a StringRef.
void addReferenceLoc(SMRange Loc)
Add a reference to this record value.
RecTy * getType() const
Get the type of the field value as a RecTy.
Init * getNameInit() const
Get the name of the field as an Init.
Init * getValue() const
Get the value of the field as an Init.
void addAssertion(SMLoc Loc, Init *Condition, Init *Message)
void addDump(SMLoc Loc, Init *Message)
void checkUnusedTemplateArgs()
std::string getNameInitAsString() const
Init * getNameInit() const
RecordKeeper & getRecords() const
const RecordVal * getValue(const Init *Name) const
bool isMultiClass() const
void addValue(const RecordVal &RV)
void appendDumps(const Record *Rec)
void addTemplateArg(Init *Name)
ArrayRef< Init * > getTemplateArgs() const
bool isSubClassOf(const Record *R) const
ArrayRef< RecordVal > getValues() const
SMLoc getFieldLoc(StringRef FieldName) const
Return the source location for the named field.
void addSuperClass(Record *R, SMRange Range)
bool isTemplateArg(Init *Name) const
void updateClassLoc(SMLoc Loc)
void resolveReferences(Init *NewName=nullptr)
If there are any field references that refer to fields that have been filled in, we can propagate the...
void appendAssertions(const Record *Rec)
ArrayRef< std::pair< Record *, SMRange > > getSuperClasses() const
void setFinal(bool Final)
Represents a location in source code.
Represents a range in source code.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
"foo" - Represent an initialization by a string value.
StringRef getValue() const
static StringInit * get(RecordKeeper &RK, StringRef, StringFormat Fmt=SF_String)
'string' - Represent an string value
static StringRecTy * get(RecordKeeper &RK)
StringRef - Represent a constant reference to a string, i.e.
SMRange getLocRange() const
int64_t getCurIntVal() const
std::pair< int64_t, unsigned > getCurBinaryIntVal() const
const std::string & getCurStrVal() const
tgtok::TokKind getCode() const
void PopScope(TGVarScope *ExpectedStackTop)
bool TokError(const Twine &Msg) const
bool ParseFile()
ParseFile - Main entrypoint for parsing a tblgen file.
Init * getVar(RecordKeeper &Records, MultiClass *ParsingMultiClass, StringInit *Name, SMRange NameLoc, bool TrackReferenceLocs) const
Init * Fold(Record *CurRec) const
static TernOpInit * get(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, RecTy *Type)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
This is the common superclass of types that have a specific, explicit type, stored in ValueTy.
RecTy * getType() const
Get the type of the Init as a RecTy.
Init * Fold(Record *CurRec, bool IsFinal=false) const
static UnOpInit * get(UnaryOp opc, Init *lhs, RecTy *Type)
static UnsetInit * get(RecordKeeper &RK)
Get the singleton unset Init.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
StringRef getName() const
Return a constant reference to the value's name.
static VarDefInit * get(Record *Class, ArrayRef< ArgumentInit * > Args)
'Opcode' - Represent a reference to an entire variable object.
Init * getNameInit() const
std::string getAsString() const override
Convert this value to a literal form.
static VarInit * get(StringRef VN, RecTy *T)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
@ Resolved
Queried, materialization begun.
NodeAddr< DefNode * > Def
NodeAddr< CodeNode * > Code
static bool isBangOperator(tgtok::TokKind Kind)
isBangOperator - Return true if this is a bang operator.
static bool isObjectStart(tgtok::TokKind Kind)
isObjectStart - Return true if this is a valid first token for a statement.
This is an optimization pass for GlobalISel generic memory operations.
void PrintFatalError(const Twine &Msg)
void PrintError(const Twine &Msg)
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
RecTy * resolveTypes(RecTy *T1, RecTy *T2)
Find a common type that T1 and T2 convert to.
void CheckAssert(SMLoc Loc, Init *Condition, Init *Message)
void dumpMessage(SMLoc Loc, Init *Message)
void PrintNote(const Twine &Msg)
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Ref
The access may reference the value stored in memory.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
@ Default
The result values are uniform if and only if all operands are uniform.
ForeachLoop - Record the iteration state associated with a for loop.
std::vector< RecordsEntry > Entries
std::vector< RecordsEntry > Entries
RecordsEntry - Holds exactly one of a Record, ForeachLoop, or AssertionInfo.
std::unique_ptr< ForeachLoop > Loop
std::unique_ptr< Record::AssertionInfo > Assertion
std::unique_ptr< Record::DumpInfo > Dump
std::unique_ptr< Record > Rec
SubClassReference()=default
SmallVector< ArgumentInit *, 4 > TemplateArgs
SubMultiClassReference()=default
SmallVector< ArgumentInit *, 4 > TemplateArgs