18#include "llvm/Config/llvm-config.h"
40 : Assertion(
std::
move(Assertion)) {}
65#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
67 errs() <<
"Multiclass:\n";
71 errs() <<
"Template args:\n";
80 const auto *BV = cast<BitsInit>(RV.
getValue());
81 for (
unsigned i = 0, e = BV->getNumBits(); i != e; ++i) {
82 const Init *Bit = BV->getBit(i);
83 bool IsReference =
false;
84 if (
const auto *VBI = dyn_cast<VarBitInit>(Bit)) {
85 if (
const auto *VI = dyn_cast<VarInit>(VBI->getBitVar())) {
86 if (R.getValue(VI->getName()))
89 }
else if (isa<VarInit>(Bit)) {
92 if (!(IsReference || Bit->isConcrete()))
99 for (
const RecordVal &RV : R.getValues()) {
104 if (RV.isNonconcreteOK())
107 if (
const Init *V = RV.getValue()) {
111 RV.getNameInitAsString() +
"' in '" +
112 R.getNameInitAsString() +
113 "' could not be fully resolved: " +
114 RV.getValue()->getAsString());
129 if (
const auto *BinOp = dyn_cast<BinOpInit>(NewName))
130 NewName = BinOp->Fold(&CurRec);
150 bool TrackReferenceLocs)
const {
152 auto It = Vars.find(
Name->getValue());
153 if (It != Vars.end())
156 auto FindValueInArgs = [&](
Record *Rec,
163 assert(RV &&
"Template arg doesn't exist??");
165 if (TrackReferenceLocs)
169 return Name->getValue() ==
"NAME"
183 if (TrackReferenceLocs)
184 RV->addReferenceLoc(NameLoc);
190 if (
auto *V = FindValueInArgs(CurRec,
Name))
198 const auto *IterVar = dyn_cast<VarInit>(CurLoop->
IterVar);
199 if (IterVar && IterVar->getNameInit() ==
Name)
207 if (
auto *V = FindValueInArgs(&CurMultiClass->
Rec,
Name))
215 return Parent->getVar(Records, ParsingMultiClass,
Name, NameLoc,
223 CurRec = &CurMultiClass->
Rec;
228 return Error(Loc,
"New definition of '" + RV.
getName() +
"' of type '" +
230 "' is incompatible with " +
231 "previous definition of type '" +
232 ERV->getType()->getAsString() +
"'");
243 bool AllowSelfAssignment,
bool OverrideDefLoc) {
248 CurRec = &CurMultiClass->
Rec;
258 if (
const auto *VI = dyn_cast<VarInit>(V))
259 if (
VI->getNameInit() == ValName && !AllowSelfAssignment)
260 return Error(Loc,
"Recursion / self-assignment forbidden");
264 if (!BitList.
empty()) {
265 const auto *CurVal = dyn_cast<BitsInit>(RV->
getValue());
268 "' is not a bits type");
273 return Error(Loc,
"Initializer is not compatible with bit range");
278 for (
unsigned i = 0, e = BitList.
size(); i != e; ++i) {
279 unsigned Bit = BitList[i];
281 return Error(Loc,
"Cannot set bit #" +
Twine(Bit) +
" of value '" +
287 for (
unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i)
289 NewBits[i] = CurVal->
getBit(i);
295 std::string InitType;
296 if (
const auto *BI = dyn_cast<BitsInit>(V))
297 InitType = (
Twine(
"' of type bit initializer with length ") +
298 Twine(BI->getNumBits()))
300 else if (
const auto *TI = dyn_cast<TypedInit>(V))
302 (
Twine(
"' of type '") + TI->getType()->getAsString() +
"'").str();
306 "' is incompatible with value '" +
V->getAsString() +
321 if (!
Field.isTemplateArg())
325 if (resolveArgumentsOfClass(R, SC, SubClass.
TemplateArgs,
349 "Already subclass of '" + SC->
getName() +
"'!\n");
356 return AddSubClass(
Entry.Rec.get(), SubClass);
361 for (
auto &E :
Entry.Loop->Entries) {
362 if (AddSubClass(E, SubClass))
372bool TGParser::AddSubMultiClass(
MultiClass *CurMC,
377 if (resolveArgumentsOfMultiClass(
391 "RecordsEntry has invalid number of items");
394 if (!Loops.empty()) {
395 Loops.back()->Entries.push_back(std::move(E));
402 return resolve(*E.
Loop, Stack, CurMultiClass ==
nullptr,
403 CurMultiClass ? &CurMultiClass->
Entries :
nullptr);
408 CurMultiClass->
Entries.push_back(std::move(E));
424 return addDefOne(std::move(E.
Rec));
432bool TGParser::resolve(
const ForeachLoop &
Loop, SubstStack &Substs,
bool Final,
433 std::vector<RecordsEntry> *Dest,
SMLoc *Loc) {
436 for (
const auto &S : Substs)
437 R.set(S.first, S.second);
438 const Init *
List =
Loop.ListValue->resolveReferences(R);
446 if (
const auto *TI = dyn_cast<TernOpInit>(
List);
448 const Init *OldLHS = TI->getLHS();
454 "' at end of containing scope");
457 const Init *MHS = TI->getMHS();
458 const Init *
RHS = TI->getRHS();
463 const auto *LI = dyn_cast<ListInit>(
List);
467 std::make_unique<ForeachLoop>(
Loop.Loc,
Loop.IterVar,
List));
468 return resolve(
Loop.Entries, Substs, Final, &Dest->back().Loop->Entries,
473 List->getAsString() +
"', expected a list");
478 for (
auto *Elt : *LI) {
480 Substs.emplace_back(
Loop.IterVar->getNameInit(), Elt);
481 Error = resolve(
Loop.Entries, Substs, Final, Dest);
495bool TGParser::resolve(
const std::vector<RecordsEntry> &Source,
496 SubstStack &Substs,
bool Final,
497 std::vector<RecordsEntry> *Dest,
SMLoc *Loc) {
499 for (
auto &E : Source) {
501 Error = resolve(*E.
Loop, Substs, Final, Dest);
505 for (
const auto &S : Substs)
506 R.set(S.first, S.second);
507 const Init *Condition = E.
Assertion->Condition->resolveReferences(R);
508 const Init *Message = E.
Assertion->Message->resolveReferences(R);
511 Dest->push_back(std::make_unique<Record::AssertionInfo>(
518 for (
const auto &S : Substs)
519 R.set(S.first, S.second);
520 const Init *Message = E.
Dump->Message->resolveReferences(R);
524 std::make_unique<Record::DumpInfo>(E.
Dump->Loc, Message));
529 auto Rec = std::make_unique<Record>(*E.
Rec);
531 Rec->appendLoc(*Loc);
534 for (
const auto &S : Substs)
535 R.set(S.first, S.second);
536 Rec->resolveReferences(R);
539 Dest->push_back(std::move(Rec));
541 Error = addDefOne(std::move(Rec));
550bool TGParser::addDefOne(std::unique_ptr<Record> Rec) {
551 const Init *NewName =
nullptr;
552 if (
const Record *Prev = Records.
getDef(Rec->getNameInitAsString())) {
553 if (!Rec->isAnonymous()) {
555 "def already exists: " + Rec->getNameInitAsString());
556 PrintNote(Prev->getLoc(),
"location of previous definition");
565 if (!isa<StringInit>(Rec->getNameInit())) {
567 Rec->getNameInit()->getAsString() +
568 "' could not be fully resolved");
573 Rec->checkRecordAssertions();
576 Rec->emitRecordDumps();
579 assert(Rec->getTemplateArgs().empty() &&
"How'd this get template args?");
583 if (!
I->getType()->typeIsA(
Defset->EltTy)) {
584 PrintError(Rec->getLoc(),
Twine(
"adding record of incompatible type '") +
585 I->getType()->getAsString() +
593 Records.
addDef(std::move(Rec));
597bool TGParser::resolveArguments(
const Record *Rec,
599 SMLoc Loc, ArgValueHandler ArgValueHandler) {
602 "Too many template arguments allowed");
606 for (
auto *Arg : ArgValues) {
607 const Init *ArgName =
nullptr;
608 const Init *ArgValue = Arg->getValue();
609 if (Arg->isPositional())
610 ArgName = ArgNames[Arg->getIndex()];
612 ArgName = Arg->getName();
616 return Error(Loc,
"We can only specify the template argument '" +
619 ArgValueHandler(ArgName, ArgValue);
624 for (
auto *UnsolvedArgName : UnsolvedArgNames) {
627 std::string
Name = UnsolvedArgName->getAsUnquotedString();
628 Error(Loc,
"value not specified for template argument '" +
Name +
"'");
633 ArgValueHandler(UnsolvedArgName,
Default);
644 return resolveArguments(
651bool TGParser::resolveArgumentsOfMultiClass(
656 return resolveArguments(&MC->
Rec, ArgValues, Loc,
658 Substs.emplace_back(Name, Value);
695 CurRec = &CurMultiClass->
Rec;
705 Name->resolveReferences(R);
719const Record *TGParser::ParseClassID() {
721 TokError(
"expected name for ClassID");
727 std::string Msg(
"Couldn't find class '" + Lex.
getCurStrVal() +
"'");
729 TokError(Msg +
". Use 'defm' if you meant to use multiclass '" +
733 }
else if (TrackReferenceLocs) {
748 TokError(
"expected name for MultiClassID");
775 Result.Rec = ParseClassID();
787 if (ParseTemplateArgValueList(
Result.TemplateArgs, ArgLocs, CurRec,
793 if (CheckTemplateArgValues(
Result.TemplateArgs, ArgLocs,
Result.Rec)) {
810TGParser::ParseSubMultiClassReference(
MultiClass *CurMC) {
814 Result.MC = ParseMultiClassID();
825 if (ParseTemplateArgValueList(
Result.TemplateArgs, ArgLocs, &CurMC->
Rec,
847 auto LHSLoc = Lex.
getLoc();
848 auto *CurVal = ParseValue(CurRec);
851 const auto *
LHS = cast<TypedInit>(CurVal);
858 auto RHSLoc = Lex.
getLoc();
859 CurVal = ParseValue(CurRec);
862 RHS = cast<TypedInit>(CurVal);
873 TokError(
"invalid range, cannot be negative");
910const TypedInit *TGParser::ParseSliceElements(
Record *CurRec,
bool Single) {
915 auto FlushElems = [&] {
916 if (!Elems.
empty()) {
923 auto LHSLoc = Lex.
getLoc();
924 CurVal = ParseSliceElement(CurRec);
927 auto *CurValTy = CurVal->
getType();
929 if (
const auto *ListValTy = dyn_cast<ListRecTy>(CurValTy)) {
930 if (!isa<IntRecTy>(ListValTy->getElementType())) {
932 "expected list<int>, got " +
Twine(ListValTy->getAsString()));
940 }
else if (!isa<IntRecTy>(CurValTy)) {
942 "unhandled type " +
Twine(CurValTy->getAsString()) +
" in range");
970 for (
auto *Slice : Slices) {
986 const Init *CurVal = FirstItem;
988 CurVal = ParseValue(
nullptr);
990 const auto *
II = dyn_cast_or_null<IntInit>(CurVal);
992 return TokError(
"expected integer or bitrange");
994 int64_t Start =
II->getValue();
998 return TokError(
"invalid range, cannot be negative");
1009 const Init *I_End = ParseValue(
nullptr);
1010 const auto *II_End = dyn_cast_or_null<IntInit>(I_End);
1012 TokError(
"expected integer value as end of range");
1016 End = II_End->getValue();
1026 return TokError(
"invalid range, cannot be negative");
1030 for (; Start <=
End; ++Start)
1033 for (; Start >=
End; --Start)
1044 if (ParseRangePiece(Result)) {
1050 if (ParseRangePiece(Result)) {
1065 ParseRangeList(Ranges);
1070 TokError(
"expected '>' at end of range list");
1071 return Error(StartLoc,
"to match this '<'");
1085 ParseRangeList(Ranges);
1090 TokError(
"expected '}' at end of bit list");
1091 return Error(StartLoc,
"to match this '{'");
1107const RecTy *TGParser::ParseType() {
1110 TokError(
"Unknown token when expecting a type");
1127 if (
I != TypeAliases.end()) {
1131 if (
const Record *R = ParseClassID())
1138 TokError(
"expected '<' after bits type");
1142 TokError(
"expected integer in bits<n> type");
1147 TokError(
"expected '>' at end of bits<n> type");
1155 TokError(
"expected '<' after list type");
1159 const RecTy *SubType = ParseType();
1164 TokError(
"expected '>' at end of list<ty> type");
1174 SMRange NameLoc, IDParseMode Mode) {
1175 if (
const Init *
I = CurScope->getVar(Records, CurMultiClass,
Name, NameLoc,
1176 TrackReferenceLocs))
1179 if (Mode == ParseNameMode)
1184 if (TrackReferenceLocs) {
1185 if (
const auto *Def = dyn_cast<DefInit>(
I))
1186 Def->getDef()->appendReferenceLoc(NameLoc);
1193 if (CurRec && !CurRec->
isClass() && !CurMultiClass &&
1197 Error(NameLoc.
Start,
"Variable not defined: '" +
Name->getValue() +
"'");
1205const Init *TGParser::ParseOperation(
Record *CurRec,
const RecTy *ItemType) {
1234 Type = ParseOperatorType();
1237 TokError(
"did not get type for unary operator");
1296 Type = ParseOperatorType();
1299 TokError(
"did not get type for unary operator");
1303 if (!isa<RecordRecTy>(
Type)) {
1304 TokError(
"type for !getdagop must be a record type");
1324 TokError(
"expected '(' after unary operator");
1328 const Init *
LHS = ParseValue(CurRec);
1333 const auto *LHSl = dyn_cast<ListInit>(LHS);
1334 const auto *LHSs = dyn_cast<StringInit>(LHS);
1335 const auto *LHSd = dyn_cast<DagInit>(LHS);
1336 const auto *LHSt = dyn_cast<TypedInit>(LHS);
1337 if (!LHSl && !LHSs && !LHSd && !LHSt) {
1339 "expected string, list, or dag type argument in unary operator");
1343 if (!isa<ListRecTy, StringRecTy, DagRecTy>(LHSt->getType())) {
1345 "expected string, list, or dag type argument in unary operator");
1353 const auto *LHSl = dyn_cast<ListInit>(LHS);
1354 const auto *LHSt = dyn_cast<TypedInit>(LHS);
1355 if (!LHSl && !LHSt) {
1356 TokError(
"expected list type argument in unary operator");
1360 if (!isa<ListRecTy>(LHSt->getType())) {
1361 TokError(
"expected list type argument in unary operator");
1366 if (LHSl && LHSl->empty()) {
1367 TokError(
"empty list argument in unary operator");
1370 bool UseElementType =
1373 const Init *Item = LHSl->getElement(0);
1374 const auto *Itemt = dyn_cast<TypedInit>(Item);
1376 TokError(
"untyped list element in unary operator");
1379 Type = UseElementType ? Itemt->getType()
1382 assert(LHSt &&
"expected list type argument in unary operator");
1383 const auto *LType = dyn_cast<ListRecTy>(LHSt->getType());
1384 Type = UseElementType ? LType->getElementType() : LType;
1390 const auto *InnerListTy = dyn_cast<ListRecTy>(
Type);
1402 TokError(
"expected ')' in unary operator");
1412 const RecTy *
Type = ParseOperatorType();
1417 TokError(
"expected '(' after type of !isa");
1421 const Init *
LHS = ParseValue(CurRec);
1437 const RecTy *
Type = ParseOperatorType();
1442 TokError(
"expected '(' after type of !exists");
1447 const Init *Expr = ParseValue(CurRec);
1451 const auto *ExprType = dyn_cast<TypedInit>(Expr);
1453 Error(ExprLoc,
"expected string type argument in !exists operator");
1457 const auto *RecType = dyn_cast<RecordRecTy>(ExprType->getType());
1460 "expected string type argument in !exists operator, please "
1461 "use !isa instead");
1465 const auto *SType = dyn_cast<StringRecTy>(ExprType->getType());
1467 Error(ExprLoc,
"expected string type argument in !exists operator");
1472 TokError(
"expected ')' in !exists");
1483 const RecTy *
Type = ParseOperatorType();
1488 TokError(
"expected '(' after type of !instances");
1496 Regex = ParseValue(CurRec);
1498 const auto *RegexType = dyn_cast<TypedInit>(
Regex);
1500 Error(RegexLoc,
"expected string type argument in !instances operator");
1504 const auto *SType = dyn_cast<StringRecTy>(RegexType->getType());
1506 Error(RegexLoc,
"expected string type argument in !instances operator");
1515 TokError(
"expected ')' in !instances");
1641 const RecTy *ArgType =
nullptr;
1655 Type = ParseOperatorType();
1657 TokError(
"did not get type for !getdagarg operator");
1712 if (
Type && ItemType && !
Type->typeIsConvertibleTo(ItemType)) {
1714 "', got '" +
Type->getAsString() +
"'");
1719 TokError(
"expected '(' after binary operator");
1729 InitList.
push_back(ParseValue(CurRec, ArgType));
1730 if (!InitList.
back())
1733 const auto *InitListBack = dyn_cast<TypedInit>(InitList.
back());
1734 if (!InitListBack) {
1735 Error(OpLoc,
Twine(
"expected value to be a typed value, got '" +
1736 InitList.
back()->getAsString() +
"'"));
1739 const RecTy *ListType = InitListBack->getType();
1747 if (!isa<ListRecTy>(ArgType)) {
1748 Error(InitLoc,
Twine(
"expected a list, got value of type '") +
1754 if (ItemType && InitList.
size() == 1) {
1755 if (!isa<ListRecTy>(ItemType)) {
1757 Twine(
"expected output type to be a list, got type '") +
1762 Error(OpLoc,
Twine(
"expected first arg type to be '") +
1764 "', got value of type '" +
1765 cast<ListRecTy>(ItemType)
1772 if (InitList.
size() == 2 && !isa<IntRecTy>(ArgType)) {
1773 Error(InitLoc,
Twine(
"expected second parameter to be an int, got "
1774 "value of type '") +
1781 if (!isa<ListRecTy>(ArgType)) {
1782 Error(InitLoc,
Twine(
"expected a list, got value of type '") +
1792 Error(InitLoc,
Twine(
"expected bit, bits, int, string, or record; "
1793 "got value of type '") +
1806 Error(InitLoc,
Twine(
"expected bit, bits, int, or string; "
1807 "got value of type '") +
1813 switch (InitList.
size()) {
1819 Twine(
"expected list of string, int, bits, or bit; "
1820 "got value of type '") +
1826 if (!isa<StringRecTy>(ArgType)) {
1827 Error(InitLoc,
Twine(
"expected second argument to be a string, "
1828 "got value of type '") +
1845 Error(InitLoc,
Twine(
"expected value of type '") +
1888 TokError(
"expected ')' in operator");
1897 Type = cast<TypedInit>(InitList.
front())->getType()->getListTy();
1908 while (InitList.
size() > 2) {
1915 if (InitList.
size() == 2)
1919 Error(OpLoc,
"expected two operands to operator");
1925 return ParseOperationForEachFilter(CurRec, ItemType);
1933 TokError(
"expected '(' after !range operator");
1938 bool FirstArgIsList =
false;
1940 if (
Args.size() >= 3) {
1941 TokError(
"expected at most three values of integer");
1946 Args.push_back(ParseValue(CurRec));
1950 const auto *ArgBack = dyn_cast<TypedInit>(
Args.back());
1952 Error(OpLoc,
Twine(
"expected value to be a typed value, got '" +
1953 Args.back()->getAsString() +
"'"));
1957 const RecTy *ArgBackType = ArgBack->getType();
1958 if (!FirstArgIsList ||
Args.size() == 1) {
1959 if (
Args.size() == 1 && isa<ListRecTy>(ArgBackType)) {
1960 FirstArgIsList =
true;
1961 }
else if (isa<IntRecTy>(ArgBackType)) {
1964 if (
Args.size() != 1)
1965 Error(InitLoc,
Twine(
"expected value of type 'int', got '" +
1968 Error(InitLoc,
Twine(
"expected list or int, got value of type '") +
1974 assert(isa<ListRecTy>(cast<TypedInit>(Args[0])->
getType()));
1975 Error(InitLoc,
Twine(
"expected one list, got extra value of type '") +
1984 TokError(
"expected ')' in operator");
1989 auto ArgCount =
Args.size();
1991 const auto *Arg0 = cast<TypedInit>(Args[0]);
1992 const auto *Arg0Ty = Arg0->getType();
1993 if (ArgCount == 1) {
1994 if (isa<ListRecTy>(Arg0Ty)) {
2001 assert(isa<IntRecTy>(Arg0Ty));
2008 assert(isa<IntRecTy>(Arg0Ty));
2009 const auto *Arg1 = cast<TypedInit>(Args[1]);
2010 assert(isa<IntRecTy>(Arg1->getType()));
2013 if (ArgCount == 3) {
2015 const auto *Arg2 = cast<TypedInit>(Args[2]);
2016 assert(isa<IntRecTy>(Arg2->getType()));
2064 TokError(
"expected '(' after ternary operator");
2068 const Init *
LHS = ParseValue(CurRec);
2073 TokError(
"expected ',' in ternary operator");
2078 const Init *MHS = ParseValue(CurRec, ItemType);
2083 TokError(
"expected ',' in ternary operator");
2088 const Init *
RHS = ParseValue(CurRec, ItemType);
2093 TokError(
"expected ')' in binary operator");
2101 const auto *MHSt = dyn_cast<TypedInit>(MHS);
2102 if (!MHSt && !isa<UnsetInit>(MHS)) {
2103 Error(MHSLoc,
"could not determine type of the child list in !dag");
2106 if (MHSt && !isa<ListRecTy>(MHSt->getType())) {
2107 Error(MHSLoc,
Twine(
"expected list of children, got type '") +
2108 MHSt->getType()->getAsString() +
"'");
2112 const auto *RHSt = dyn_cast<TypedInit>(RHS);
2113 if (!RHSt && !isa<UnsetInit>(RHS)) {
2114 Error(RHSLoc,
"could not determine type of the name list in !dag");
2118 Error(RHSLoc,
Twine(
"expected list<string>, got type '") +
2119 RHSt->getType()->getAsString() +
"'");
2123 if (!MHSt && !RHSt) {
2125 "cannot have both unset children and unset names in !dag");
2131 const RecTy *MHSTy =
nullptr;
2132 const RecTy *RHSTy =
nullptr;
2134 if (
const auto *MHSt = dyn_cast<TypedInit>(MHS))
2135 MHSTy = MHSt->getType();
2136 if (
const auto *MHSbits = dyn_cast<BitsInit>(MHS))
2138 if (isa<BitInit>(MHS))
2141 if (
const auto *RHSt = dyn_cast<TypedInit>(RHS))
2142 RHSTy = RHSt->getType();
2143 if (
const auto *RHSbits = dyn_cast<BitsInit>(RHS))
2145 if (isa<BitInit>(RHS))
2149 if (isa<UnsetInit>(MHS))
2151 if (isa<UnsetInit>(RHS))
2154 if (!MHSTy || !RHSTy) {
2155 TokError(
"could not get type for !if");
2168 const auto *RHSt = dyn_cast<TypedInit>(RHS);
2170 TokError(
"could not get type for !subst");
2173 Type = RHSt->getType();
2177 const auto *MHSt = dyn_cast<TypedInit>(MHS);
2178 if (!MHSt || !isa<IntRecTy, StringRecTy>(MHSt->getType())) {
2179 Error(MHSLoc,
Twine(
"expected integer index or string name, got ") +
2180 (MHSt ? (
"type '" + MHSt->getType()->getAsString())
2188 const auto *MHSt = dyn_cast<TypedInit>(MHS);
2189 if (!MHSt || !isa<IntRecTy, StringRecTy>(MHSt->getType())) {
2190 Error(MHSLoc,
Twine(
"expected integer index or string name, got ") +
2191 (MHSt ? (
"type '" + MHSt->getType()->getAsString())
2196 const auto *RHSt = dyn_cast<TypedInit>(RHS);
2198 if (RHSt && !isa<StringRecTy>(RHSt->getType())) {
2199 Error(RHSLoc,
Twine(
"expected string or unset name, got type '") +
2200 RHSt->getType()->getAsString() +
"'");
2210 return ParseOperationSubstr(CurRec, ItemType);
2213 return ParseOperationFind(CurRec, ItemType);
2216 return ParseOperationCond(CurRec, ItemType);
2222 TokError(
"expected '(' after !foldl");
2226 const Init *StartUntyped = ParseValue(CurRec);
2230 const auto *Start = dyn_cast<TypedInit>(StartUntyped);
2238 TokError(
"expected ',' in !foldl");
2242 const Init *ListUntyped = ParseValue(CurRec);
2246 const auto *
List = dyn_cast<TypedInit>(ListUntyped);
2253 const auto *ListType = dyn_cast<ListRecTy>(
List->getType());
2255 TokError(
Twine(
"!foldl list must be a list, but is of type '") +
2256 List->getType()->getAsString());
2261 TokError(
"expected ',' in !foldl");
2266 TokError(
"third argument of !foldl must be an identifier");
2273 "' already defined")
2279 TokError(
"expected ',' in !foldl");
2284 TokError(
"fourth argument of !foldl must be an identifier");
2291 "' already defined")
2297 TokError(
"expected ',' in !foldl");
2304 std::unique_ptr<Record> ParseRecTmp;
2305 Record *ParseRec = CurRec;
2309 ParseRec = ParseRecTmp.get();
2316 const Init *ExprUntyped = ParseValue(ParseRec);
2317 ParseRec->removeValue(
A);
2318 ParseRec->removeValue(
B);
2323 const auto *Expr = dyn_cast<TypedInit>(ExprUntyped);
2325 TokError(
"could not get type of !foldl expression");
2329 if (Expr->getType() != Start->getType()) {
2330 TokError(
Twine(
"!foldl expression must be of same type as start (") +
2331 Start->getType()->getAsString() +
"), but is of type " +
2337 TokError(
"expected ')' in fold operator");
2352const RecTy *TGParser::ParseOperatorType() {
2356 TokError(
"expected type name for operator");
2361 TokError(
"the 'code' type is not allowed in bang operators; use 'string'");
2366 TokError(
"expected type name for operator");
2371 TokError(
"expected type name for operator");
2381const Init *TGParser::ParseOperationSubstr(
Record *CurRec,
2382 const RecTy *ItemType) {
2389 TokError(
"expected '(' after !substr operator");
2393 const Init *
LHS = ParseValue(CurRec);
2398 TokError(
"expected ',' in !substr operator");
2403 const Init *MHS = ParseValue(CurRec);
2411 RHS = ParseValue(CurRec);
2419 TokError(
"expected ')' in !substr operator");
2423 if (ItemType && !
Type->typeIsConvertibleTo(ItemType)) {
2425 "', got '" +
Type->getAsString() +
"'");
2428 const auto *LHSt = dyn_cast<TypedInit>(LHS);
2429 if (!LHSt && !isa<UnsetInit>(LHS)) {
2430 TokError(
"could not determine type of the string in !substr");
2433 if (LHSt && !isa<StringRecTy>(LHSt->getType())) {
2435 LHSt->getType()->getAsString() +
"'");
2439 const auto *MHSt = dyn_cast<TypedInit>(MHS);
2440 if (!MHSt && !isa<UnsetInit>(MHS)) {
2441 TokError(
"could not determine type of the start position in !substr");
2444 if (MHSt && !isa<IntRecTy>(MHSt->getType())) {
2445 Error(MHSLoc,
Twine(
"expected int, got type '") +
2446 MHSt->getType()->getAsString() +
"'");
2451 const auto *RHSt = dyn_cast<TypedInit>(RHS);
2452 if (!RHSt && !isa<UnsetInit>(RHS)) {
2453 TokError(
"could not determine type of the length in !substr");
2456 if (RHSt && !isa<IntRecTy>(RHSt->getType())) {
2458 RHSt->getType()->getAsString() +
"'");
2469const Init *TGParser::ParseOperationFind(
Record *CurRec,
2470 const RecTy *ItemType) {
2477 TokError(
"expected '(' after !find operator");
2481 const Init *
LHS = ParseValue(CurRec);
2486 TokError(
"expected ',' in !find operator");
2491 const Init *MHS = ParseValue(CurRec);
2499 RHS = ParseValue(CurRec);
2507 TokError(
"expected ')' in !find operator");
2511 if (ItemType && !
Type->typeIsConvertibleTo(ItemType)) {
2513 "', got '" +
Type->getAsString() +
"'");
2516 const auto *LHSt = dyn_cast<TypedInit>(LHS);
2517 if (!LHSt && !isa<UnsetInit>(LHS)) {
2518 TokError(
"could not determine type of the source string in !find");
2521 if (LHSt && !isa<StringRecTy>(LHSt->getType())) {
2523 LHSt->getType()->getAsString() +
"'");
2527 const auto *MHSt = dyn_cast<TypedInit>(MHS);
2528 if (!MHSt && !isa<UnsetInit>(MHS)) {
2529 TokError(
"could not determine type of the target string in !find");
2532 if (MHSt && !isa<StringRecTy>(MHSt->getType())) {
2533 Error(MHSLoc,
Twine(
"expected string, got type '") +
2534 MHSt->getType()->getAsString() +
"'");
2539 const auto *RHSt = dyn_cast<TypedInit>(RHS);
2540 if (!RHSt && !isa<UnsetInit>(RHS)) {
2541 TokError(
"could not determine type of the start position in !find");
2544 if (RHSt && !isa<IntRecTy>(RHSt->getType())) {
2546 RHSt->getType()->getAsString() +
"'");
2558const Init *TGParser::ParseOperationForEachFilter(
Record *CurRec,
2559 const RecTy *ItemType) {
2564 TokError(
"expected '(' after !foreach/!filter");
2569 TokError(
"first argument of !foreach/!filter must be an identifier");
2576 if (CurRec && CurRec->
getValue(LHS)) {
2578 "' is already defined")
2584 TokError(
"expected ',' in !foreach/!filter");
2588 const Init *MHS = ParseValue(CurRec);
2593 TokError(
"expected ',' in !foreach/!filter");
2597 const auto *MHSt = dyn_cast<TypedInit>(MHS);
2599 TokError(
"could not get type of !foreach/!filter list or dag");
2603 const RecTy *InEltType =
nullptr;
2604 const RecTy *ExprEltType =
nullptr;
2607 if (
const auto *InListTy = dyn_cast<ListRecTy>(MHSt->getType())) {
2608 InEltType = InListTy->getElementType();
2610 if (
const auto *OutListTy = dyn_cast<ListRecTy>(ItemType)) {
2612 ? OutListTy->getElementType()
2615 Error(OpLoc,
"expected value of type '" +
2617 "', but got list type");
2621 }
else if (
const auto *InDagTy = dyn_cast<DagRecTy>(MHSt->getType())) {
2623 TokError(
"!filter must have a list argument");
2626 InEltType = InDagTy;
2627 if (ItemType && !isa<DagRecTy>(ItemType)) {
2629 "', but got dag type");
2635 TokError(
"!foreach must have a list or dag argument");
2637 TokError(
"!filter must have a list argument");
2643 std::unique_ptr<Record> ParseRecTmp;
2644 Record *ParseRec = CurRec;
2648 ParseRec = ParseRecTmp.get();
2652 const Init *
RHS = ParseValue(ParseRec, ExprEltType);
2653 ParseRec->removeValue(LHS);
2659 TokError(
"expected ')' in !foreach/!filter");
2663 const RecTy *OutType = InEltType;
2665 const auto *RHSt = dyn_cast<TypedInit>(RHS);
2667 TokError(
"could not get type of !foreach result expression");
2677 LHS, MHS, RHS, OutType))
2681const Init *TGParser::ParseOperationCond(
Record *CurRec,
2682 const RecTy *ItemType) {
2686 TokError(
"expected '(' after !cond operator");
2697 const Init *
V = ParseValue(CurRec);
2703 TokError(
"expected ':' following a condition in !cond operator");
2707 V = ParseValue(CurRec, ItemType);
2716 TokError(
"expected ',' or ')' following a value in !cond operator");
2721 if (Case.
size() < 1) {
2723 "there should be at least 1 'condition : value' in the !cond operator");
2729 for (
const Init *V : Val) {
2730 const RecTy *VTy =
nullptr;
2731 if (
const auto *Vt = dyn_cast<TypedInit>(V))
2732 VTy = Vt->getType();
2733 if (
const auto *Vbits = dyn_cast<BitsInit>(V))
2735 if (isa<BitInit>(V))
2738 if (
Type ==
nullptr) {
2739 if (!isa<UnsetInit>(V))
2742 if (!isa<UnsetInit>(V)) {
2755 TokError(
"could not determine type for !cond from its arguments");
2788const Init *TGParser::ParseSimpleValue(
Record *CurRec,
const RecTy *ItemType,
2790 const Init *
R =
nullptr;
2795 return ParseOperation(CurRec, ItemType);
2799 TokError(
"Unknown or reserved token when parsing a value");
2817 for (
unsigned i = 0, e = BinaryVal.second; i != e; ++i)
2851 return ParseIDValue(CurRec,
Name, NameLoc, Mode);
2859 "Expected a class name, got '" +
Name->getValue() +
"'");
2866 if (ParseTemplateArgValueList(Args, ArgLocs, CurRec, Class))
2869 if (CheckTemplateArgValues(Args, ArgLocs, Class))
2872 if (resolveArguments(Class, Args, NameLoc.
Start))
2875 if (TrackReferenceLocs)
2876 Class->appendReferenceLoc(NameLoc);
2885 ParseValueList(Vals, CurRec);
2890 TokError(
"expected '}' at end of bit list value");
2899 for (
unsigned i = 0, e = Vals.
size(); i != e; ++i) {
2904 if (
const auto *BI = dyn_cast<BitsInit>(Vals[i])) {
2905 for (
unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
2910 if (
const auto *VI = dyn_cast<VarInit>(Vals[i])) {
2911 if (
const auto *BitsRec = dyn_cast<BitsRecTy>(
VI->getType())) {
2912 for (
unsigned i = 0, e = BitsRec->getNumBits(); i != e; ++i)
2921 Error(BraceLoc,
"Element #" +
Twine(i) +
" (" + Vals[i]->getAsString() +
2922 ") is not convertable to a bit");
2927 std::reverse(NewBits.
begin(), NewBits.
end());
2934 const RecTy *DeducedEltTy =
nullptr;
2938 const auto *ListType = dyn_cast<ListRecTy>(ItemType);
2944 GivenListTy = ListType;
2948 ParseValueList(Vals, CurRec,
2954 TokError(
"expected ']' at end of list value");
2958 const RecTy *GivenEltTy =
nullptr;
2961 GivenEltTy = ParseType();
2968 TokError(
"expected '>' at end of list element type");
2974 const RecTy *EltTy =
nullptr;
2975 for (
const Init *V : Vals) {
2976 const auto *TArg = dyn_cast<TypedInit>(V);
2981 TokError(
"Incompatible types in list elements");
2985 EltTy = TArg->getType();
2994 TokError(
"Incompatible types in list elements");
3011 TokError(
Twine(
"Element type mismatch for list: element type '") +
3017 DeducedEltTy = EltTy;
3028 TokError(
"expected identifier or list of value types in dag init");
3040 TokError(
"expected variable name in dag operator");
3049 ParseDagArgList(DagArgs, CurRec);
3050 if (DagArgs.
empty())
3055 TokError(
"expected ')' in dag init");
3073const Init *TGParser::ParseValue(
Record *CurRec,
const RecTy *ItemType,
3076 const Init *
Result = ParseSimpleValue(CurRec, ItemType, Mode);
3086 if (Mode == ParseNameMode)
3093 ParseRangeList(Ranges);
3101 Error(CurlyLoc,
"Invalid bit range for value");
3107 TokError(
"expected '}' at end of bit range list");
3113 const auto *
LHS = dyn_cast<TypedInit>(Result);
3115 Error(LHSLoc,
"Invalid value, list expected");
3119 const auto *LHSTy = dyn_cast<ListRecTy>(
LHS->
getType());
3122 "' is invalid, list expected");
3127 const TypedInit *
RHS = ParseSliceElements(CurRec,
true);
3136 LHSTy->getElementType())
3144 TokError(
"expected ']' at end of list slice");
3151 TokError(
"expected field identifier after '.'");
3157 if (!
Result->getFieldType(FieldName)) {
3159 Result->getAsString() +
"'");
3164 if (TrackReferenceLocs) {
3165 if (
const auto *DI = dyn_cast<DefInit>(Result)) {
3166 const RecordVal *
V = DI->getDef()->getValue(FieldName);
3167 const_cast<RecordVal *
>(
V)->addReferenceLoc(FieldNameLoc);
3168 }
else if (
const auto *TI = dyn_cast<TypedInit>(Result)) {
3169 if (
const auto *
RecTy = dyn_cast<RecordRecTy>(TI->getType())) {
3171 if (
const auto *RV =
R->getValue(FieldName))
3184 const auto *
LHS = dyn_cast<TypedInit>(Result);
3186 Error(PasteLoc,
"LHS of paste is not typed!");
3194 assert(Mode == ParseValueMode &&
"encountered paste of lists in name");
3203 const Init *RHSResult = ParseValue(CurRec, ItemType, ParseValueMode);
3215 auto CastLHS = dyn_cast<TypedInit>(
3220 Twine(
"can't cast '") +
LHS->getAsString() +
"' to string");
3242 const Init *RHSResult = ParseValue(CurRec,
nullptr, ParseNameMode);
3245 RHS = dyn_cast<TypedInit>(RHSResult);
3247 Error(PasteLoc,
"RHS of paste is not typed!");
3252 auto CastRHS = dyn_cast<TypedInit>(
3257 Twine(
"can't cast '") +
RHS->getAsString() +
"' to string");
3278void TGParser::ParseDagArgList(
3291 const Init *Val = ParseValue(CurRec);
3301 TokError(
"expected variable name in dag literal");
3309 Result.emplace_back(Val, VarName);
3324 Result.push_back(ParseValue(CurRec, ItemType));
3334 Result.push_back(ParseValue(CurRec, ItemType));
3350bool TGParser::ParseTemplateArgValueList(
3353 assert(
Result.empty() &&
"Result vector is not empty");
3359 bool HasNamedArg =
false;
3360 unsigned ArgIndex = 0;
3362 if (ArgIndex >= TArgs.
size()) {
3363 TokError(
"Too many template arguments: " + utostr(ArgIndex + 1));
3372 HasNamedArg ?
nullptr : ArgsRec->
getValue(TArgs[ArgIndex])->
getType());
3378 if (!isa<StringInit>(
Value))
3379 return Error(ValueLoc,
3380 "The name of named argument should be a valid identifier");
3386 return Error(ValueLoc,
3387 "Argument " +
Name->getAsString() +
" doesn't exist");
3391 Value = ParseValue(CurRec, NamedArg->getType());
3393 if (isa<UnsetInit>(
Value))
3394 return Error(ValueLoc,
3395 "The value of named argument should be initialized, "
3397 Value->getAsString() +
"'");
3404 return Error(ValueLoc,
3405 "Positional argument should be put before named argument");
3413 return TokError(
"Expected comma before next argument");
3428const Init *TGParser::ParseDeclaration(
Record *CurRec,
3429 bool ParsingTemplateArgs) {
3438 TokError(
"Expected identifier in declaration");
3443 if (Str ==
"NAME") {
3444 TokError(
"'" + Str +
"' is a reserved variable name");
3448 if (!ParsingTemplateArgs && CurScope->varAlreadyDefined(Str)) {
3449 TokError(
"local variable of this name already exists");
3458 if (!ParsingTemplateArgs) {
3459 BadField = AddValue(CurRec, IdLoc,
3463 }
else if (CurRec) {
3466 AddValue(CurRec, IdLoc,
3469 assert(CurMultiClass &&
"invalid context for template argument");
3472 AddValue(CurRec, IdLoc,
3481 const Init *Val = ParseValue(CurRec,
Type);
3483 SetValue(CurRec, ValLoc, DeclName, {}, Val,
3504TGParser::ParseForeachDeclaration(
const Init *&ForeachListValue) {
3506 TokError(
"Expected identifier in foreach declaration");
3515 TokError(
"Expected '=' in foreach declaration");
3519 const RecTy *IterType =
nullptr;
3525 ParseRangeList(Ranges);
3527 TokError(
"expected '}' at end of bit range list");
3535 const Init *
I = ParseValue(
nullptr);
3539 const auto *TI = dyn_cast<TypedInit>(
I);
3540 if (TI && isa<ListRecTy>(TI->getType())) {
3541 ForeachListValue =
I;
3542 IterType = cast<ListRecTy>(TI->getType())->getElementType();
3547 if (ParseRangePiece(Ranges, TI))
3552 Error(ValueLoc,
"expected a list, got '" +
I->getAsString() +
"'");
3553 if (CurMultiClass) {
3554 PrintNote({},
"references to multiclass template arguments cannot be "
3555 "resolved at this time");
3562 assert(!IterType &&
"Type already initialized?");
3564 std::vector<Init *> Values;
3565 for (
unsigned R : Ranges)
3583bool TGParser::ParseTemplateArgList(
Record *CurRec) {
3587 Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->
Rec;
3590 const Init *TemplArg = ParseDeclaration(CurRec,
true );
3599 TemplArg = ParseDeclaration(CurRec,
true );
3604 return Error(Loc,
"template argument with the same name has already been "
3611 return TokError(
"expected '>' at end of template argument list");
3623bool TGParser::ParseBodyItem(
Record *CurRec) {
3625 return ParseAssert(
nullptr, CurRec);
3628 return ParseDefvar(CurRec);
3631 return ParseDump(
nullptr, CurRec);
3634 if (!ParseDeclaration(CurRec,
false))
3638 return TokError(
"expected ';' after declaration");
3644 return TokError(
"expected field identifier after let");
3651 if (ParseOptionalBitList(BitList))
3653 std::reverse(BitList.
begin(), BitList.
end());
3656 return TokError(
"expected '=' in let expression");
3660 return Error(IdLoc,
"Value '" + FieldName->
getValue() +
"' unknown!");
3663 if (!BitList.
empty() && isa<BitsRecTy>(
Type)) {
3669 const Init *Val = ParseValue(CurRec,
Type);
3674 return TokError(
"expected ';' after let expression");
3676 return SetValue(CurRec, IdLoc, FieldName, BitList, Val);
3686bool TGParser::ParseBody(
Record *CurRec) {
3692 return TokError(
"Expected '{' to start body or ';' for declaration only");
3695 if (ParseBodyItem(CurRec))
3704 PrintError(SemiLoc,
"A class or def body should not end with a semicolon");
3705 PrintNote(
"Semicolon ignored; remove to eliminate this error");
3713bool TGParser::ApplyLetStack(
Record *CurRec) {
3716 if (SetValue(CurRec, LR.Loc, LR.Name, LR.Bits, LR.Value))
3724 return ApplyLetStack(
Entry.Rec.get());
3727 if (
Entry.Assertion)
3734 for (
auto &E :
Entry.Loop->Entries) {
3735 if (ApplyLetStack(E))
3751bool TGParser::ParseObjectBody(
Record *CurRec) {
3765 if (AddSubClass(CurRec, SubClass))
3770 SubClass = ParseSubClassReference(CurRec,
false);
3774 if (ApplyLetStack(CurRec))
3777 bool Result = ParseBody(CurRec);
3787bool TGParser::ParseDef(
MultiClass *CurMultiClass) {
3798 std::unique_ptr<Record> CurRec;
3799 const Init *
Name = ParseObjectName(CurMultiClass);
3803 if (isa<UnsetInit>(
Name)) {
3807 CurRec = std::make_unique<Record>(
Name, NameLoc, Records);
3810 if (ParseObjectBody(CurRec.get()))
3813 return addEntry(std::move(CurRec));
3820bool TGParser::ParseDefset() {
3829 if (!isa<ListRecTy>(
Type))
3831 Defset.EltTy = cast<ListRecTy>(
Type)->getElementType();
3834 return TokError(
"expected identifier");
3837 return TokError(
"def or global variable of this name already exists");
3846 Defsets.push_back(&Defset);
3847 bool Err = ParseObjectList(
nullptr);
3853 TokError(
"expected '}' at end of defset");
3854 return Error(BraceLoc,
"to match this '{'");
3866bool TGParser::ParseDeftype() {
3871 return TokError(
"expected identifier");
3874 if (TypeAliases.count(TypeName) || Records.
getClass(TypeName))
3875 return TokError(
"type of this name '" + TypeName +
"' already exists");
3887 return Error(Loc,
"cannot define type alias for class type '" +
3888 Type->getAsString() +
"'");
3902bool TGParser::ParseDefvar(
Record *CurRec) {
3907 return TokError(
"expected identifier");
3909 if (CurScope->varAlreadyDefined(DeclName->
getValue()))
3910 return TokError(
"local variable of this name already exists");
3915 if (V && !
V->isTemplateArg())
3916 return TokError(
"field of this name already exists");
3922 return TokError(
"def or global variable of this name already exists");
3935 if (!CurScope->isOutermost())
3949bool TGParser::ParseForeach(
MultiClass *CurMultiClass) {
3956 const Init *ListValue =
nullptr;
3957 const VarInit *IterName = ParseForeachDeclaration(ListValue);
3959 return TokError(
"expected declaration in for");
3965 auto TheLoop = std::make_unique<ForeachLoop>(Loc, IterName, ListValue);
3968 Loops.push_back(std::move(TheLoop));
3972 if (ParseObject(CurMultiClass))
3980 if (ParseObjectList(CurMultiClass))
3984 TokError(
"expected '}' at end of foreach command");
3985 return Error(BraceLoc,
"to match this '{'");
3992 std::unique_ptr<ForeachLoop>
Loop = std::move(Loops.back());
3995 return addEntry(std::move(
Loop));
4003bool TGParser::ParseIf(
MultiClass *CurMultiClass) {
4010 const Init *Condition = ParseValue(
nullptr);
4030 const Init *ThenClauseList =
4034 Loops.push_back(std::make_unique<ForeachLoop>(Loc,
nullptr, ThenClauseList));
4036 if (ParseIfBody(CurMultiClass,
"then"))
4039 std::unique_ptr<ForeachLoop>
Loop = std::move(Loops.back());
4042 if (addEntry(std::move(
Loop)))
4052 const Init *ElseClauseList =
4057 std::make_unique<ForeachLoop>(Loc,
nullptr, ElseClauseList));
4059 if (ParseIfBody(CurMultiClass,
"else"))
4062 Loop = std::move(Loops.back());
4065 if (addEntry(std::move(
Loop)))
4083 if (ParseObject(CurMultiClass))
4091 if (ParseObjectList(CurMultiClass))
4095 TokError(
"expected '}' at end of '" + Kind +
"' clause");
4096 return Error(BraceLoc,
"to match this '{'");
4112 const Init *Condition = ParseValue(CurRec);
4117 TokError(
"expected ',' in assert statement");
4121 const Init *Message = ParseValue(CurRec);
4129 CurRec->
addAssertion(ConditionLoc, Condition, Message);
4131 addEntry(std::make_unique<Record::AssertionInfo>(ConditionLoc, Condition,
4140bool TGParser::ParseClass() {
4145 return TokError(
"expected class name after 'class' keyword");
4155 "' already defined");
4162 CurRec = NewRec.get();
4163 Records.
addClass(std::move(NewRec));
4166 if (TypeAliases.count(
Name))
4167 return TokError(
"there is already a defined type alias '" +
Name +
"'");
4175 if (ParseTemplateArgList(CurRec))
4178 if (ParseObjectBody(CurRec))
4181 if (!NoWarnOnUnusedTemplateArgs)
4197 TokError(
"expected identifier in let definition");
4208 if (ParseOptionalRangeList(Bits)) {
4212 std::reverse(
Bits.begin(),
Bits.end());
4215 TokError(
"expected '=' in let expression");
4220 const Init *Val = ParseValue(
nullptr);
4227 Result.emplace_back(
Name, Bits, Val, NameLoc);
4237bool TGParser::ParseTopLevelLet(
MultiClass *CurMultiClass) {
4243 ParseLetList(LetInfo);
4244 if (LetInfo.
empty())
4249 return TokError(
"expected 'in' at end of top-level 'let'");
4254 if (ParseObject(CurMultiClass))
4265 if (ParseObjectList(CurMultiClass))
4269 TokError(
"expected '}' at end of top level let command");
4270 return Error(BraceLoc,
"to match this '{'");
4294bool TGParser::ParseMultiClass() {
4299 return TokError(
"expected identifier after multiclass for name");
4302 auto Result = MultiClasses.try_emplace(
4303 Name, std::make_unique<MultiClass>(
Name, Lex.
getLoc(), Records));
4306 return TokError(
"multiclass '" +
Name +
"' already defined");
4308 CurMultiClass =
Result.first->second.get();
4316 if (ParseTemplateArgList(
nullptr))
4319 bool inherits =
false;
4327 ParseSubMultiClassReference(CurMultiClass);
4330 if (!SubMultiClass.
MC)
4334 if (AddSubMultiClass(CurMultiClass, SubMultiClass))
4339 SubMultiClass = ParseSubMultiClassReference(CurMultiClass);
4345 return TokError(
"expected '{' in multiclass definition");
4347 return TokError(
"expected ';' in multiclass definition");
4350 return TokError(
"multiclass must contain at least one def");
4355 return TokError(
"expected 'assert', 'def', 'defm', 'defvar', 'dump', "
4356 "'foreach', 'if', or 'let' in multiclass body");
4366 if (ParseObject(CurMultiClass))
4376 PrintError(SemiLoc,
"A multiclass body should not end with a semicolon");
4377 PrintNote(
"Semicolon ignored; remove to eliminate this error");
4381 if (!NoWarnOnUnusedTemplateArgs)
4385 CurMultiClass =
nullptr;
4393bool TGParser::ParseDefm(
MultiClass *CurMultiClass) {
4397 const Init *DefmName = ParseObjectName(CurMultiClass);
4400 if (isa<UnsetInit>(DefmName)) {
4410 return TokError(
"expected ':' after defm identifier");
4413 std::vector<RecordsEntry> NewEntries;
4416 bool InheritFromClass =
false;
4432 MultiClass *MC = MultiClasses[
Ref.Rec->getName().str()].get();
4433 assert(MC &&
"Didn't lookup multiclass correctly?");
4436 if (resolveArgumentsOfMultiClass(Substs, MC,
Ref.TemplateArgs, DefmName,
4440 if (resolve(MC->
Entries, Substs, !CurMultiClass && Loops.empty(),
4441 &NewEntries, &SubClassLoc))
4448 return TokError(
"expected identifier");
4450 SubClassLoc = Lex.
getLoc();
4456 if (InheritFromClass)
4459 Ref = ParseSubClassReference(
nullptr,
true);
4462 if (InheritFromClass) {
4473 for (
auto &E : NewEntries) {
4475 if (AddSubClass(E, SubClass))
4481 SubClass = ParseSubClassReference(
nullptr,
false);
4485 for (
auto &E : NewEntries) {
4486 if (ApplyLetStack(E))
4489 addEntry(std::move(E));
4493 return TokError(
"expected ';' at end of defm");
4514 "Expected assert, class, def, defm, defset, dump, foreach, if, or let");
4516 return ParseAssert(MC);
4518 return ParseDef(MC);
4520 return ParseDefm(MC);
4522 return ParseDeftype();
4524 return ParseDefvar();
4526 return ParseDump(MC);
4528 return ParseForeach(MC);
4532 return ParseTopLevelLet(MC);
4535 return TokError(
"defset is not allowed inside multiclass");
4536 return ParseDefset();
4539 return TokError(
"class is not allowed inside multiclass");
4541 return TokError(
"class is not allowed inside foreach loop");
4542 return ParseClass();
4545 return TokError(
"multiclass is not allowed inside foreach loop");
4546 return ParseMultiClass();
4552bool TGParser::ParseObjectList(
MultiClass *MC) {
4554 if (ParseObject(MC))
4563 if (ParseObjectList())
4571 return TokError(
"Unexpected token at top level");
4578bool TGParser::CheckTemplateArgValues(
4582 "expected as many values as locations");
4586 bool HasError =
false;
4588 const Init *ArgName =
nullptr;
4589 if (
Value->isPositional())
4590 ArgName = TArgs[
Value->getIndex()];
4591 if (
Value->isNamed())
4597 if (
const auto *ArgValue = dyn_cast<TypedInit>(
Value->getValue())) {
4598 auto *CastValue = ArgValue->
getCastTo(ArgType);
4600 assert((!isa<TypedInit>(CastValue) ||
4601 cast<TypedInit>(CastValue)->
getType()->typeIsA(ArgType)) &&
4602 "result of template arg value cast has wrong type");
4606 Loc,
"Value specified for template argument '" +
4608 ArgValue->getType()->
getAsString() +
"; expected type " +
4617#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4636 errs() <<
"Record:\n";
4639 errs() <<
"Defs:\n";
4651 const Init *Message = ParseValue(CurRec);
4657 if (isa<DefInit>(Message))
4665 CurRec->
addDump(Loc, Message);
4671 addEntry(std::make_unique<Record::DumpInfo>(Loc, ResolvedMessage));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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
This file defines the SmallVector class.
static bool checkBitsConcrete(Record &R, const RecordVal &RV)
static const Init * QualifyName(const Record &CurRec, const Init *Name)
Return an Init with a qualifier prefix referring to CurRec's name.
static const Init * QualifiedNameOfImplicitName(const 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 const ArgumentInit * get(const 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.
static const BinOpInit * get(BinaryOp opc, const Init *lhs, const Init *rhs, const RecTy *Type)
static const Init * getStrConcat(const Init *lhs, const Init *rhs)
static const Init * getListConcat(const TypedInit *lhs, const Init *rhs)
const Init * Fold(const Record *CurRec) const
static BitInit * get(RecordKeeper &RK, bool V)
static const BitRecTy * get(RecordKeeper &RK)
static BitsInit * get(RecordKeeper &RK, ArrayRef< const Init * > Range)
static const BitsRecTy * get(RecordKeeper &RK, unsigned Sz)
const Init * Fold(const Record *CurRec) const
static const CondOpInit * get(ArrayRef< const Init * > Conds, ArrayRef< const Init * > Values, const RecTy *Type)
static const DagInit * get(const Init *V, const StringInit *VN, ArrayRef< const Init * > Args, ArrayRef< const StringInit * > ArgNames)
static const DagRecTy * get(RecordKeeper &RK)
AL - Represent a reference to a 'def' in the description.
Lightweight error class with error context and mandatory checking.
static const ExistsOpInit * get(const RecTy *CheckType, const Init *Expr)
const Init * Fold(const Record *CurRec) const
static const FieldInit * get(const Init *R, const StringInit *FN)
const Init * Fold(const Record *CurRec) const
static const FoldOpInit * get(const Init *Start, const Init *List, const Init *A, const Init *B, const Init *Expr, const RecTy *Type)
Do not resolve anything, but keep track of whether a given variable was referenced.
virtual const 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 const Init * getBit(unsigned Bit) const =0
Get the Init value of the specified bit.
virtual const Init * getCastTo(const RecTy *Ty) const =0
If this value is convertible to type Ty, return a value whose type is Ty, generating a !...
const Init * Fold(const Record *CurRec, bool IsFinal=false) const
static const InstancesOpInit * get(const RecTy *Type, const Init *Regex)
static IntInit * get(RecordKeeper &RK, int64_t V)
static const IntRecTy * get(RecordKeeper &RK)
static const IsAOpInit * get(const RecTy *CheckType, const Init *Expr)
const Init * Fold() const
[AL, AH, CL] - Represent a list of defs
static const ListInit * get(ArrayRef< const Init * > Range, const RecTy *EltTy)
'list<Ty>' - Represent a list of element values, all of which must be of the specified type.
const RecTy * getElementType() const
static const ListRecTy * get(const RecTy *T)
bool typeIsConvertibleTo(const RecTy *RHS) const override
Return true if all values of 'this' type can be converted to the specified type.
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...
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
const ListRecTy * getListTy() const
Returns the type representing list<thistype>.
void addDef(std::unique_ptr< Record > R)
void addClass(std::unique_ptr< Record > R)
const Record * getClass(StringRef Name) const
Get the class with the specified name.
const Init * getNewAnonymousName()
GetNewAnonymousName - Generate a unique anonymous name that can be used as an identifier.
const Init * getGlobal(StringRef Name) const
Get the Init value of the specified global variable.
void addExtraGlobal(StringRef Name, const Init *I)
const Record * getDef(StringRef Name) const
Get the concrete record with the specified name.
static const RecordRecTy * get(RecordKeeper &RK, ArrayRef< const 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.
std::string getNameInitAsString() const
Get the name of the field as a std::string.
void setUsed(bool Used)
Whether this value is used.
bool setValue(const Init *V)
Set the value of the field from an Init.
const Init * getValue() const
Get the value of the field as an Init.
StringRef getName() const
Get the name of the field as a StringRef.
void addReferenceLoc(SMRange Loc)
Add a reference to this record value.
const Init * getNameInit() const
Get the name of the field as an Init.
const RecTy * getType() const
Get the type of the field value as a RecTy.
const RecordRecTy * getType() const
void addDump(SMLoc Loc, const Init *Message)
void checkUnusedTemplateArgs()
std::string getNameInitAsString() const
RecordKeeper & getRecords() const
const RecordVal * getValue(const Init *Name) const
void addTemplateArg(const Init *Name)
bool isMultiClass() const
void addValue(const RecordVal &RV)
void addAssertion(SMLoc Loc, const Init *Condition, const Init *Message)
ArrayRef< std::pair< const Record *, SMRange > > getDirectSuperClasses() const
Return the direct superclasses of this record.
StringRef getName() const
bool isTemplateArg(const Init *Name) const
void appendDumps(const Record *Rec)
bool isSubClassOf(const Record *R) const
ArrayRef< RecordVal > getValues() const
SMLoc getFieldLoc(StringRef FieldName) const
Return the source location for the named field.
void resolveReferences(const Init *NewName=nullptr)
If there are any field references that refer to fields that have been filled in, we can propagate the...
ArrayRef< const Init * > getTemplateArgs() const
void updateClassLoc(SMLoc Loc)
void addDirectSuperClass(const Record *R, SMRange Range)
void appendAssertions(const Record *Rec)
const Init * getNameInit() 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...
reference emplace_back(ArgTypes &&... Args)
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.
static const StringInit * get(RecordKeeper &RK, StringRef, StringFormat Fmt=SF_String)
StringRef getValue() const
static const 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.
const Init * getVar(RecordKeeper &Records, MultiClass *ParsingMultiClass, const StringInit *Name, SMRange NameLoc, bool TrackReferenceLocs) const
const Init * Fold(const Record *CurRec) const
static const TernOpInit * get(TernaryOp opc, const Init *lhs, const Init *mhs, const Init *rhs, const 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.
const RecTy * getType() const
Get the type of the Init as a RecTy.
static const UnOpInit * get(UnaryOp opc, const Init *lhs, const RecTy *Type)
const Init * Fold(const Record *CurRec, bool IsFinal=false) const
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.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
static const VarDefInit * get(SMLoc Loc, const Record *Class, ArrayRef< const ArgumentInit * > Args)
const Init * Fold() const
'Opcode' - Represent a reference to an entire variable object.
static const VarInit * get(StringRef VN, const RecTy *T)
std::string getAsString() const override
Convert this value to a literal form.
#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.
@ 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.
detail::zippy< detail::zip_first, T, U, Args... > zip_equal(T &&t, U &&u, Args &&...args)
zip iterator that assumes that all iteratees have the same length.
void PrintError(const Twine &Msg)
bool CheckAssert(SMLoc Loc, const Init *Condition, const Init *Message)
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
void PrintNote(const Twine &Msg)
LLVM_ABI 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.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
void dumpMessage(SMLoc Loc, const Init *Message)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
const RecTy * resolveTypes(const RecTy *T1, const RecTy *T2)
Find a common type that T1 and T2 convert to.
@ Default
The result values are uniform if and only if all operands are uniform.
Implement std::hash so that hash_code can be used in STL containers.
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< const ArgumentInit *, 4 > TemplateArgs
SubMultiClassReference()=default
SmallVector< const ArgumentInit *, 4 > TemplateArgs