18#include "llvm/Config/llvm-config.h"
57#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
59 errs() <<
"Multiclass:\n";
63 errs() <<
"Template args:\n";
73 for (
unsigned i = 0, e = BV->
getNumBits(); i != e; ++i) {
75 bool IsReference =
false;
76 if (
auto VBI = dyn_cast<VarBitInit>(Bit)) {
77 if (
auto VI = dyn_cast<VarInit>(VBI->getBitVar())) {
78 if (R.getValue(
VI->getName()))
81 }
else if (isa<VarInit>(Bit)) {
84 if (!(IsReference || Bit->isConcrete()))
91 for (
const RecordVal &RV : R.getValues()) {
96 if (RV.isNonconcreteOK())
99 if (
Init *V = RV.getValue()) {
103 Twine(
"Initializer of '") + RV.getNameInitAsString() +
104 "' in '" + R.getNameInitAsString() +
105 "' could not be fully resolved: " +
106 RV.getValue()->getAsString());
120 if (CurMultiClass && Scoper !=
"::") {
126 if (
BinOpInit *BinOp = dyn_cast<BinOpInit>(NewName))
127 NewName = BinOp->Fold(&CurRec);
144 CurRec = &CurMultiClass->
Rec;
149 return Error(Loc,
"New definition of '" + RV.
getName() +
"' of type '" +
151 "previous definition of type '" +
152 ERV->getType()->getAsString() +
"'");
163 bool AllowSelfAssignment,
bool OverrideDefLoc) {
164 if (!V)
return false;
166 if (!CurRec) CurRec = &CurMultiClass->
Rec;
176 if (
VarInit *VI = dyn_cast<VarInit>(V))
177 if (
VI->getNameInit() == ValName && !AllowSelfAssignment)
178 return Error(Loc,
"Recursion / self-assignment forbidden");
184 if (!BitList.
empty()) {
188 "' is not a bits type");
193 return Error(Loc,
"Initializer is not compatible with bit range");
198 for (
unsigned i = 0, e = BitList.
size(); i != e; ++i) {
199 unsigned Bit = BitList[i];
201 return Error(Loc,
"Cannot set bit #" +
Twine(Bit) +
" of value '" +
206 for (
unsigned i = 0, e = CurVal->
getNumBits(); i != e; ++i)
208 NewBits[i] = CurVal->
getBit(i);
214 std::string InitType;
215 if (
BitsInit *BI = dyn_cast<BitsInit>(V))
216 InitType = (
Twine(
"' of type bit initializer with length ") +
217 Twine(BI->getNumBits())).str();
218 else if (
TypedInit *TI = dyn_cast<TypedInit>(V))
219 InitType = (
Twine(
"' of type '") + TI->getType()->getAsString()).str();
222 "' is incompatible with value '" +
223 V->getAsString() + InitType +
"'");
237 if (
Field.isTemplateArg()) {
247 "Too many template arguments allowed");
251 for (
unsigned I = 0,
E = TArgs.
size();
I !=
E; ++
I) {
254 else if (!
R.isComplete(TArgs[
I]))
256 "Value not specified for template argument '" +
257 TArgs[
I]->getAsUnquotedString() +
"' (#" +
Twine(
I) +
258 ") of parent class '" +
SC->getNameInitAsString() +
"'");
277 for (
const auto &SCPair : SCs) {
280 "Already subclass of '" + SCPair.first->getName() +
"'!\n");
286 "Already subclass of '" +
SC->getName() +
"'!\n");
293 return AddSubClass(Entry.Rec.get(), SubClass);
298 for (
auto &
E : Entry.Loop->Entries) {
299 if (AddSubClass(
E, SubClass))
309bool TGParser::AddSubMultiClass(
MultiClass *CurMC,
316 "More template args specified than expected");
321 for (
unsigned i = 0, e = SMCTArgs.
size(); i != e; ++i) {
328 "value not specified for template argument #" +
Twine(i) +
329 " (" + SMCTArgs[i]->getAsUnquotedString() +
347 assert((!!
E.Rec + !!
E.Loop + !!
E.Assertion) == 1 &&
348 "RecordsEntry has invalid number of items");
351 if (!Loops.empty()) {
352 Loops.back()->Entries.push_back(std::move(
E));
359 return resolve(*
E.Loop, Stack, CurMultiClass ==
nullptr,
360 CurMultiClass ? &CurMultiClass->
Entries :
nullptr);
365 CurMultiClass->
Entries.push_back(std::move(
E));
371 CheckAssert(
E.Assertion->Loc,
E.Assertion->Condition,
E.Assertion->Message);
376 return addDefOne(std::move(
E.Rec));
385 bool Final, std::vector<RecordsEntry> *Dest,
389 for (
const auto &S : Substs)
390 R.set(S.first, S.second);
399 if (
auto *TI = dyn_cast<TernOpInit>(
List);
401 Init *OldLHS = TI->getLHS();
406 Twine(
"unable to resolve if condition '") +
407 LHS->getAsString() +
"' at end of containing scope");
410 Init *MHS = TI->getMHS();
416 auto LI = dyn_cast<ListInit>(
List);
419 Dest->emplace_back(std::make_unique<ForeachLoop>(
Loop.Loc,
Loop.IterVar,
421 return resolve(
Loop.Entries, Substs, Final, &Dest->back().Loop->Entries,
426 List->getAsString() +
"', expected a list");
431 for (
auto *Elt : *LI) {
433 Substs.emplace_back(
Loop.IterVar->getNameInit(), Elt);
434 Error = resolve(
Loop.Entries, Substs, Final, Dest);
448bool TGParser::resolve(
const std::vector<RecordsEntry> &Source,
449 SubstStack &Substs,
bool Final,
450 std::vector<RecordsEntry> *Dest,
SMLoc *Loc) {
452 for (
auto &
E : Source) {
454 Error = resolve(*
E.Loop, Substs, Final, Dest);
456 }
else if (
E.Assertion) {
458 for (
const auto &S : Substs)
459 R.set(S.first, S.second);
460 Init *Condition =
E.Assertion->Condition->resolveReferences(R);
461 Init *Message =
E.Assertion->Message->resolveReferences(R);
464 Dest->push_back(std::make_unique<Record::AssertionInfo>(
465 E.Assertion->Loc, Condition, Message));
470 auto Rec = std::make_unique<Record>(*
E.Rec);
472 Rec->appendLoc(*Loc);
475 for (
const auto &S : Substs)
476 R.set(S.first, S.second);
477 Rec->resolveReferences(R);
480 Dest->push_back(std::move(Rec));
482 Error = addDefOne(std::move(Rec));
491bool TGParser::addDefOne(std::unique_ptr<Record> Rec) {
492 Init *NewName =
nullptr;
493 if (
Record *Prev = Records.
getDef(Rec->getNameInitAsString())) {
494 if (!Rec->isAnonymous()) {
496 "def already exists: " + Rec->getNameInitAsString());
497 PrintNote(Prev->getLoc(),
"location of previous definition");
506 if (!isa<StringInit>(Rec->getNameInit())) {
508 Rec->getNameInit()->getAsString() +
509 "' could not be fully resolved");
514 Rec->checkRecordAssertions();
517 assert(Rec->getTemplateArgs().empty() &&
"How'd this get template args?");
521 if (!
I->getType()->typeIsA(
Defset->EltTy)) {
522 PrintError(Rec->getLoc(),
Twine(
"adding record of incompatible type '") +
523 I->getType()->getAsString() +
531 Records.
addDef(std::move(Rec));
576 CurRec = &CurMultiClass->
Rec;
585 Name->resolveReferences(R);
599Record *TGParser::ParseClassID() {
601 TokError(
"expected name for ClassID");
609 TokError(Msg +
". Use 'defm' if you meant to use multiclass '" +
613 }
else if (TrackReferenceLocs) {
628 TokError(
"expected name for MultiClassID");
647ParseSubClassReference(
Record *CurRec,
bool isDefm) {
655 Result.Rec = ParseClassID();
665 if (ParseTemplateArgValueList(
Result.TemplateArgs, CurRec,
Result.Rec)) {
670 if (CheckTemplateArgValues(
Result.TemplateArgs,
Result.RefRange.Start,
688ParseSubMultiClassReference(
MultiClass *CurMC) {
692 Result.MC = ParseMultiClassID();
701 if (ParseTemplateArgValueList(
Result.TemplateArgs, &CurMC->
Rec,
720 Init *CurVal = FirstItem;
722 CurVal = ParseValue(
nullptr);
724 IntInit *II = dyn_cast_or_null<IntInit>(CurVal);
726 return TokError(
"expected integer or bitrange");
732 return TokError(
"invalid range, cannot be negative");
743 Init *I_End = ParseValue(
nullptr);
744 IntInit *II_End = dyn_cast_or_null<IntInit>(I_End);
746 TokError(
"expected integer value as end of range");
760 return TokError(
"invalid range, cannot be negative");
764 for (; Start <= End; ++Start)
767 for (; Start >= End; --Start)
778 if (ParseRangePiece(Result)) {
784 if (ParseRangePiece(Result)) {
799 ParseRangeList(Ranges);
800 if (
Ranges.empty())
return true;
803 TokError(
"expected '>' at end of range list");
804 return Error(StartLoc,
"to match this '<'");
818 ParseRangeList(Ranges);
819 if (
Ranges.empty())
return true;
822 TokError(
"expected '}' at end of bit list");
823 return Error(StartLoc,
"to match this '{'");
839RecTy *TGParser::ParseType() {
841 default:
TokError(
"Unknown token when expecting a type");
return nullptr;
856 if (
Record *R = ParseClassID())
862 TokError(
"expected '<' after bits type");
866 TokError(
"expected integer in bits<n> type");
871 TokError(
"expected '>' at end of bits<n> type");
879 TokError(
"expected '<' after list type");
883 RecTy *SubType = ParseType();
884 if (!SubType)
return nullptr;
887 TokError(
"expected '>' at end of list<ty> type");
900 if (TrackReferenceLocs)
906 if ((CurRec && CurRec->
isClass()) || CurMultiClass) {
907 Init *TemplateArgName;
914 Record *TemplateRec = CurMultiClass ? &CurMultiClass->
Rec : CurRec;
917 assert(RV &&
"Template arg doesn't exist??");
919 if (TrackReferenceLocs)
922 }
else if (
Name->getValue() ==
"NAME") {
928 if (
Init *
I = CurLocalScope->getVar(
Name->getValue()))
932 for (
const auto &L : Loops) {
934 VarInit *IterVar = dyn_cast<VarInit>(
L->IterVar);
940 if (Mode == ParseNameMode)
945 if (TrackReferenceLocs) {
946 if (
auto *Def = dyn_cast<DefInit>(
I))
947 Def->getDef()->appendReferenceLoc(NameLoc);
954 if (CurRec && !CurRec->
isClass() && !CurMultiClass &&
958 Error(NameLoc.
Start,
"Variable not defined: '" +
Name->getValue() +
"'");
990 Type = ParseOperatorType();
993 TokError(
"did not get type for unary operator");
1042 Type = ParseOperatorType();
1045 TokError(
"did not get type for unary operator");
1049 if (!isa<RecordRecTy>(
Type)) {
1050 TokError(
"type for !getdagop must be a record type");
1060 TokError(
"expected '(' after unary operator");
1064 Init *
LHS = ParseValue(CurRec);
1065 if (!LHS)
return nullptr;
1068 ListInit *LHSl = dyn_cast<ListInit>(LHS);
1069 StringInit *LHSs = dyn_cast<StringInit>(LHS);
1070 DagInit *LHSd = dyn_cast<DagInit>(LHS);
1071 TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
1072 if (!LHSl && !LHSs && !LHSd && !LHSt) {
1073 TokError(
"expected string, list, or dag type argument in unary operator");
1080 if (!LType && !SType && !DType) {
1081 TokError(
"expected string, list, or dag type argument in unary operator");
1088 ListInit *LHSl = dyn_cast<ListInit>(LHS);
1089 TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
1090 if (!LHSl && !LHSt) {
1091 TokError(
"expected list type argument in unary operator");
1097 TokError(
"expected list type argument in unary operator");
1102 if (LHSl && LHSl->
empty()) {
1103 TokError(
"empty list argument in unary operator");
1108 TypedInit *Itemt = dyn_cast<TypedInit>(Item);
1110 TokError(
"untyped list element in unary operator");
1116 assert(LHSt &&
"expected list type argument in unary operator");
1123 TokError(
"expected ')' in unary operator");
1138 TokError(
"expected '(' after type of !isa");
1142 Init *
LHS = ParseValue(CurRec);
1163 TokError(
"expected '(' after type of !exists");
1168 Init *Expr = ParseValue(CurRec);
1172 TypedInit *ExprType = dyn_cast<TypedInit>(Expr);
1174 Error(ExprLoc,
"expected string type argument in !exists operator");
1181 "expected string type argument in !exists operator, please "
1182 "use !isa instead");
1188 Error(ExprLoc,
"expected string type argument in !exists operator");
1193 TokError(
"expected ')' in !exists");
1256 RecTy *ArgType =
nullptr;
1307 if (
Type && ItemType && !
Type->typeIsConvertibleTo(ItemType)) {
1308 Error(OpLoc,
Twine(
"expected value of type '") +
1310 Type->getAsString() +
"'");
1315 TokError(
"expected '(' after binary operator");
1325 InitList.
push_back(ParseValue(CurRec, ArgType));
1326 if (!InitList.
back())
return nullptr;
1328 TypedInit *InitListBack = dyn_cast<TypedInit>(InitList.
back());
1329 if (!InitListBack) {
1330 Error(OpLoc,
Twine(
"expected value to be a typed value, got '" +
1331 InitList.
back()->getAsString() +
"'"));
1342 if (!isa<ListRecTy>(ArgType)) {
1343 Error(InitLoc,
Twine(
"expected a list, got value of type '") +
1349 if (ItemType && InitList.
size() == 1) {
1350 if (!isa<ListRecTy>(ItemType)) {
1352 Twine(
"expected output type to be a list, got type '") +
1357 Error(OpLoc,
Twine(
"expected first arg type to be '") +
1359 "', got value of type '" +
1360 cast<ListRecTy>(ItemType)
1367 if (InitList.
size() == 2 && !isa<IntRecTy>(ArgType)) {
1368 Error(InitLoc,
Twine(
"expected second parameter to be an int, got "
1369 "value of type '") +
1376 if (!isa<ListRecTy>(ArgType)) {
1377 Error(InitLoc,
Twine(
"expected a list, got value of type '") +
1387 Error(InitLoc,
Twine(
"expected bit, bits, int, string, or record; "
1399 Error(InitLoc,
Twine(
"expected bit, bits, int, or string; "
1406 switch (InitList.
size()) {
1411 Error(InitLoc,
Twine(
"expected list of string, int, bits, or bit; "
1412 "got value of type '") +
1418 if (!isa<StringRecTy>(ArgType)) {
1419 Error(InitLoc,
Twine(
"expected second argument to be a string, "
1420 "got value of type '") +
1436 Error(InitLoc,
Twine(
"expected value of type '") +
1466 TokError(
"expected ')' in operator");
1475 Type = cast<TypedInit>(InitList.
front())->getType()->getListTy();
1486 while (InitList.
size() > 2) {
1493 if (InitList.
size() == 2)
1497 Error(OpLoc,
"expected two operands to operator");
1503 return ParseOperationForEachFilter(CurRec, ItemType);
1529 TokError(
"expected '(' after ternary operator");
1533 Init *
LHS = ParseValue(CurRec);
1534 if (!LHS)
return nullptr;
1537 TokError(
"expected ',' in ternary operator");
1542 Init *MHS = ParseValue(CurRec, ItemType);
1547 TokError(
"expected ',' in ternary operator");
1552 Init *
RHS = ParseValue(CurRec, ItemType);
1557 TokError(
"expected ')' in binary operator");
1564 TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
1565 if (!MHSt && !isa<UnsetInit>(MHS)) {
1566 Error(MHSLoc,
"could not determine type of the child list in !dag");
1569 if (MHSt && !isa<ListRecTy>(MHSt->
getType())) {
1570 Error(MHSLoc,
Twine(
"expected list of children, got type '") +
1575 TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
1576 if (!RHSt && !isa<UnsetInit>(RHS)) {
1577 Error(RHSLoc,
"could not determine type of the name list in !dag");
1581 Error(RHSLoc,
Twine(
"expected list<string>, got type '") +
1586 if (!MHSt && !RHSt) {
1588 "cannot have both unset children and unset names in !dag");
1594 RecTy *MHSTy =
nullptr;
1595 RecTy *RHSTy =
nullptr;
1597 if (
TypedInit *MHSt = dyn_cast<TypedInit>(MHS))
1599 if (
BitsInit *MHSbits = dyn_cast<BitsInit>(MHS))
1601 if (isa<BitInit>(MHS))
1604 if (
TypedInit *RHSt = dyn_cast<TypedInit>(RHS))
1606 if (
BitsInit *RHSbits = dyn_cast<BitsInit>(RHS))
1608 if (isa<BitInit>(RHS))
1612 if (isa<UnsetInit>(MHS))
1614 if (isa<UnsetInit>(RHS))
1617 if (!MHSTy || !RHSTy) {
1618 TokError(
"could not get type for !if");
1631 TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
1633 TokError(
"could not get type for !subst");
1644 return ParseOperationSubstr(CurRec, ItemType);
1647 return ParseOperationFind(CurRec, ItemType);
1650 return ParseOperationCond(CurRec, ItemType);
1656 TokError(
"expected '(' after !foldl");
1660 Init *StartUntyped = ParseValue(CurRec);
1664 TypedInit *Start = dyn_cast<TypedInit>(StartUntyped);
1672 TokError(
"expected ',' in !foldl");
1676 Init *ListUntyped = ParseValue(CurRec);
1689 TokError(
Twine(
"!foldl list must be a list, but is of type '") +
1690 List->getType()->getAsString());
1695 TokError(
"expected ',' in !foldl");
1700 TokError(
"third argument of !foldl must be an identifier");
1707 "' already defined")
1713 TokError(
"expected ',' in !foldl");
1718 TokError(
"fourth argument of !foldl must be an identifier");
1725 "' already defined")
1731 TokError(
"expected ',' in !foldl");
1738 std::unique_ptr<Record> ParseRecTmp;
1739 Record *ParseRec = CurRec;
1741 ParseRecTmp = std::make_unique<Record>(
".parse",
ArrayRef<SMLoc>{}, Records);
1742 ParseRec = ParseRecTmp.get();
1748 Init *ExprUntyped = ParseValue(ParseRec);
1749 ParseRec->removeValue(
A);
1750 ParseRec->removeValue(
B);
1754 TypedInit *Expr = dyn_cast<TypedInit>(ExprUntyped);
1756 TokError(
"could not get type of !foldl expression");
1760 if (Expr->
getType() != Start->getType()) {
1761 TokError(
Twine(
"!foldl expression must be of same type as start (") +
1762 Start->getType()->getAsString() +
"), but is of type " +
1768 TokError(
"expected ')' in fold operator");
1783RecTy *TGParser::ParseOperatorType() {
1787 TokError(
"expected type name for operator");
1792 TokError(
"the 'code' type is not allowed in bang operators; use 'string'");
1797 TokError(
"expected type name for operator");
1802 TokError(
"expected type name for operator");
1812Init *TGParser::ParseOperationSubstr(
Record *CurRec,
RecTy *ItemType) {
1819 TokError(
"expected '(' after !substr operator");
1823 Init *
LHS = ParseValue(CurRec);
1828 TokError(
"expected ',' in !substr operator");
1833 Init *MHS = ParseValue(CurRec);
1841 RHS = ParseValue(CurRec);
1849 TokError(
"expected ')' in !substr operator");
1853 if (ItemType && !
Type->typeIsConvertibleTo(ItemType)) {
1854 Error(RHSLoc,
Twine(
"expected value of type '") +
1856 Type->getAsString() +
"'");
1859 TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
1860 if (!LHSt && !isa<UnsetInit>(LHS)) {
1861 TokError(
"could not determine type of the string in !substr");
1864 if (LHSt && !isa<StringRecTy>(LHSt->
getType())) {
1870 TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
1871 if (!MHSt && !isa<UnsetInit>(MHS)) {
1872 TokError(
"could not determine type of the start position in !substr");
1875 if (MHSt && !isa<IntRecTy>(MHSt->
getType())) {
1876 Error(MHSLoc,
Twine(
"expected int, got type '") +
1882 TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
1883 if (!RHSt && !isa<UnsetInit>(RHS)) {
1884 TokError(
"could not determine type of the length in !substr");
1887 if (RHSt && !isa<IntRecTy>(RHSt->
getType())) {
1907 TokError(
"expected '(' after !find operator");
1911 Init *
LHS = ParseValue(CurRec);
1916 TokError(
"expected ',' in !find operator");
1921 Init *MHS = ParseValue(CurRec);
1929 RHS = ParseValue(CurRec);
1937 TokError(
"expected ')' in !find operator");
1941 if (ItemType && !
Type->typeIsConvertibleTo(ItemType)) {
1942 Error(RHSLoc,
Twine(
"expected value of type '") +
1944 Type->getAsString() +
"'");
1947 TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
1948 if (!LHSt && !isa<UnsetInit>(LHS)) {
1949 TokError(
"could not determine type of the source string in !find");
1952 if (LHSt && !isa<StringRecTy>(LHSt->
getType())) {
1958 TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
1959 if (!MHSt && !isa<UnsetInit>(MHS)) {
1960 TokError(
"could not determine type of the target string in !find");
1963 if (MHSt && !isa<StringRecTy>(MHSt->
getType())) {
1964 Error(MHSLoc,
Twine(
"expected string, got type '") +
1970 TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
1971 if (!RHSt && !isa<UnsetInit>(RHS)) {
1972 TokError(
"could not determine type of the start position in !find");
1975 if (RHSt && !isa<IntRecTy>(RHSt->
getType())) {
1989Init *TGParser::ParseOperationForEachFilter(
Record *CurRec,
RecTy *ItemType) {
1994 TokError(
"expected '(' after !foreach/!filter");
1999 TokError(
"first argument of !foreach/!filter must be an identifier");
2006 if (CurRec && CurRec->
getValue(LHS)) {
2008 "' is already defined")
2014 TokError(
"expected ',' in !foreach/!filter");
2018 Init *MHS = ParseValue(CurRec);
2023 TokError(
"expected ',' in !foreach/!filter");
2027 TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
2029 TokError(
"could not get type of !foreach/!filter list or dag");
2033 RecTy *InEltType =
nullptr;
2034 RecTy *ExprEltType =
nullptr;
2038 InEltType = InListTy->getElementType();
2040 if (
ListRecTy *OutListTy = dyn_cast<ListRecTy>(ItemType)) {
2042 ? OutListTy->getElementType()
2046 "expected value of type '" +
2048 "', but got list type");
2054 TokError(
"!filter must have a list argument");
2057 InEltType = InDagTy;
2058 if (ItemType && !isa<DagRecTy>(ItemType)) {
2061 "', but got dag type");
2067 TokError(
"!foreach must have a list or dag argument");
2069 TokError(
"!filter must have a list argument");
2075 std::unique_ptr<Record> ParseRecTmp;
2076 Record *ParseRec = CurRec;
2080 ParseRec = ParseRecTmp.get();
2084 Init *
RHS = ParseValue(ParseRec, ExprEltType);
2085 ParseRec->removeValue(LHS);
2090 TokError(
"expected ')' in !foreach/!filter");
2094 RecTy *OutType = InEltType;
2096 TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
2098 TokError(
"could not get type of !foreach result expression");
2108 LHS, MHS, RHS, OutType))
2116 TokError(
"expected '(' after !cond operator");
2127 Init *
V = ParseValue(CurRec);
2133 TokError(
"expected ':' following a condition in !cond operator");
2137 V = ParseValue(CurRec, ItemType);
2146 TokError(
"expected ',' or ')' following a value in !cond operator");
2151 if (Case.
size() < 1) {
2152 TokError(
"there should be at least 1 'condition : value' in the !cond operator");
2158 for (
Init *V : Val) {
2159 RecTy *VTy =
nullptr;
2160 if (
TypedInit *Vt = dyn_cast<TypedInit>(V))
2161 VTy = Vt->getType();
2162 if (
BitsInit *Vbits = dyn_cast<BitsInit>(V))
2164 if (isa<BitInit>(V))
2167 if (
Type ==
nullptr) {
2168 if (!isa<UnsetInit>(V))
2171 if (!isa<UnsetInit>(V)) {
2184 TokError(
"could not determine type for !cond from its arguments");
2218 default:
TokError(
"Unknown or reserved token when parsing a value");
break;
2235 for (
unsigned i = 0, e = BinaryVal.second; i != e; ++i)
2266 return ParseIDValue(CurRec,
Name, NameLoc, Mode);
2274 "Expected a class name, got '" +
Name->getValue() +
"'");
2280 if (ParseTemplateArgValueList(Args, CurRec, Class))
2283 if (CheckTemplateArgValues(Args, NameLoc.
Start, Class))
2289 for (
unsigned I =
Args.size(),
E = TArgs.
size();
I <
E; ++
I) {
2291 if (!
Arg->getValue()->isComplete()) {
2292 Error(NameLoc.
Start,
"Value not specified for template argument '" +
2293 TArgs[
I]->getAsUnquotedString() +
"' (#" +
2294 Twine(
I) +
") of parent class '" +
2295 Class->getNameInitAsString() +
"'");
2299 if (TrackReferenceLocs)
2300 Class->appendReferenceLoc(NameLoc);
2309 ParseValueList(Vals, CurRec);
2310 if (Vals.
empty())
return nullptr;
2313 TokError(
"expected '}' at end of bit list value");
2322 for (
unsigned i = 0, e = Vals.
size(); i != e; ++i) {
2327 if (
BitsInit *BI = dyn_cast<BitsInit>(Vals[i])) {
2328 for (
unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
2333 if (
VarInit *VI = dyn_cast<VarInit>(Vals[i])) {
2334 if (
BitsRecTy *BitsRec = dyn_cast<BitsRecTy>(
VI->getType())) {
2335 for (
unsigned i = 0, e = BitsRec->getNumBits(); i != e; ++i)
2344 Error(BraceLoc,
"Element #" +
Twine(i) +
" (" + Vals[i]->getAsString() +
2345 ") is not convertable to a bit");
2350 std::reverse(NewBits.
begin(), NewBits.
end());
2357 RecTy *DeducedEltTy =
nullptr;
2361 ListRecTy *ListType = dyn_cast<ListRecTy>(ItemType);
2367 GivenListTy = ListType;
2371 ParseValueList(Vals, CurRec,
2373 if (Vals.
empty())
return nullptr;
2376 TokError(
"expected ']' at end of list value");
2380 RecTy *GivenEltTy =
nullptr;
2383 GivenEltTy = ParseType();
2390 TokError(
"expected '>' at end of list element type");
2396 RecTy *EltTy =
nullptr;
2397 for (
Init *V : Vals) {
2398 TypedInit *TArg = dyn_cast<TypedInit>(V);
2403 TokError(
"Incompatible types in list elements");
2416 TokError(
"Incompatible types in list elements");
2433 TokError(
Twine(
"Element type mismatch for list: element type '") +
2439 DeducedEltTy = EltTy;
2448 TokError(
"expected identifier in dag init");
2459 TokError(
"expected variable name in dag operator");
2468 ParseDagArgList(DagArgs, CurRec);
2469 if (DagArgs.
empty())
return nullptr;
2473 TokError(
"expected ')' in dag init");
2524 return ParseOperation(CurRec, ItemType);
2538Init *TGParser::ParseValue(
Record *CurRec,
RecTy *ItemType, IDParseMode Mode) {
2539 Init *
Result = ParseSimpleValue(CurRec, ItemType, Mode);
2540 if (!Result)
return nullptr;
2547 if (Mode == ParseNameMode)
2554 ParseRangeList(Ranges);
2555 if (
Ranges.empty())
return nullptr;
2561 Error(CurlyLoc,
"Invalid bit range for value");
2567 TokError(
"expected '}' at end of bit range list");
2576 ParseRangeList(Ranges);
2577 if (
Ranges.empty())
return nullptr;
2581 Error(SquareLoc,
"Invalid range for list slice");
2587 TokError(
"expected ']' at end of list slice");
2594 TokError(
"expected field identifier after '.'");
2599 if (!
Result->getFieldType(FieldName)) {
2601 Result->getAsString() +
"'");
2606 if (TrackReferenceLocs) {
2607 if (
auto *DI = dyn_cast<DefInit>(Result)) {
2608 DI->getDef()->getValue(FieldName)->addReferenceLoc(FieldNameLoc);
2609 }
else if (
auto *TI = dyn_cast<TypedInit>(Result)) {
2610 if (
auto *
RecTy = dyn_cast<RecordRecTy>(TI->getType())) {
2612 if (
auto *RV =
R->getValue(FieldName))
2627 Error(PasteLoc,
"LHS of paste is not typed!");
2635 assert(Mode == ParseValueMode &&
"encountered paste of lists in name");
2644 Init *RHSResult = ParseValue(CurRec, ItemType, ParseValueMode);
2656 auto CastLHS = dyn_cast<TypedInit>(
2661 Twine(
"can't cast '") +
LHS->getAsString() +
"' to string");
2683 Init *RHSResult = ParseValue(CurRec,
nullptr, ParseNameMode);
2686 RHS = dyn_cast<TypedInit>(RHSResult);
2688 Error(PasteLoc,
"RHS of paste is not typed!");
2693 auto CastRHS = dyn_cast<TypedInit>(
2698 Twine(
"can't cast '") +
RHS->getAsString() +
"' to string");
2719void TGParser::ParseDagArgList(
2732 Init *Val = ParseValue(CurRec);
2742 TokError(
"expected variable name in dag literal");
2750 Result.push_back(std::make_pair(Val, VarName));
2766 Result.push_back(ParseValue(CurRec, ItemType));
2776 Result.push_back(ParseValue(CurRec, ItemType));
2793 assert(
Result.empty() &&
"Result vector is not empty");
2795 unsigned ArgIndex = 0;
2802 if (ArgIndex >= TArgs.
size()) {
2803 TokError(
"Too many template arguments: " + utostr(ArgIndex + 1));
2807 assert(
Arg &&
"Template argument record not found");
2809 ItemType =
Arg->getType();
2810 Init *
Value = ParseValue(CurRec, ItemType);
2818 return TokError(
"Expected comma before next argument");
2833Init *TGParser::ParseDeclaration(
Record *CurRec,
2834 bool ParsingTemplateArgs) {
2839 if (!
Type)
return nullptr;
2842 TokError(
"Expected identifier in declaration");
2847 if (Str ==
"NAME") {
2848 TokError(
"'" + Str +
"' is a reserved variable name");
2857 if (!ParsingTemplateArgs) {
2858 BadField = AddValue(CurRec, IdLoc,
2863 }
else if (CurRec) {
2864 DeclName =
QualifyName(*CurRec, CurMultiClass, DeclName,
":");
2865 BadField = AddValue(CurRec, IdLoc,
RecordVal(DeclName, IdLoc,
Type,
2869 assert(CurMultiClass &&
"invalid context for template argument");
2870 DeclName =
QualifyName(CurMultiClass->
Rec, CurMultiClass, DeclName,
"::");
2871 BadField = AddValue(CurRec, IdLoc,
RecordVal(DeclName, IdLoc,
Type,
2880 Init *Val = ParseValue(CurRec,
Type);
2882 SetValue(CurRec, ValLoc, DeclName, std::nullopt, Val,
2902VarInit *TGParser::ParseForeachDeclaration(
Init *&ForeachListValue) {
2904 TokError(
"Expected identifier in foreach declaration");
2913 TokError(
"Expected '=' in foreach declaration");
2917 RecTy *IterType =
nullptr;
2923 ParseRangeList(Ranges);
2925 TokError(
"expected '}' at end of bit range list");
2933 Init *
I = ParseValue(
nullptr);
2938 if (TI && isa<ListRecTy>(TI->
getType())) {
2939 ForeachListValue =
I;
2940 IterType = cast<ListRecTy>(TI->
getType())->getElementType();
2945 if (ParseRangePiece(Ranges, TI))
2950 Error(ValueLoc,
"expected a list, got '" +
I->getAsString() +
"'");
2951 if (CurMultiClass) {
2952 PrintNote({},
"references to multiclass template arguments cannot be "
2953 "resolved at this time");
2961 assert(!IterType &&
"Type already initialized?");
2963 std::vector<Init *> Values;
2964 for (
unsigned R : Ranges)
2982bool TGParser::ParseTemplateArgList(
Record *CurRec) {
2986 Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->
Rec;
2989 Init *TemplArg = ParseDeclaration(CurRec,
true);
2998 TemplArg = ParseDeclaration(CurRec,
true);
3003 return Error(Loc,
"template argument with the same name has already been "
3010 return TokError(
"expected '>' at end of template argument list");
3021bool TGParser::ParseBodyItem(
Record *CurRec) {
3023 return ParseAssert(
nullptr, CurRec);
3026 return ParseDefvar();
3029 if (!ParseDeclaration(CurRec,
false))
3033 return TokError(
"expected ';' after declaration");
3039 return TokError(
"expected field identifier after let");
3046 if (ParseOptionalBitList(BitList))
3048 std::reverse(BitList.
begin(), BitList.
end());
3051 return TokError(
"expected '=' in let expression");
3058 if (!BitList.
empty() && isa<BitsRecTy>(
Type)) {
3064 Init *Val = ParseValue(CurRec,
Type);
3065 if (!Val)
return true;
3068 return TokError(
"expected ';' after let expression");
3070 return SetValue(CurRec, IdLoc, FieldName, BitList, Val);
3080bool TGParser::ParseBody(
Record *CurRec) {
3086 return TokError(
"Expected '{' to start body or ';' for declaration only");
3092 if (ParseBodyItem(CurRec))
3103 PrintError(SemiLoc,
"A class or def body should not end with a semicolon");
3104 PrintNote(
"Semicolon ignored; remove to eliminate this error");
3112bool TGParser::ApplyLetStack(
Record *CurRec) {
3115 if (SetValue(CurRec, LR.Loc, LR.Name, LR.Bits, LR.Value))
3123 return ApplyLetStack(Entry.Rec.get());
3126 if (Entry.Assertion)
3129 for (
auto &
E : Entry.Loop->Entries) {
3130 if (ApplyLetStack(
E))
3146bool TGParser::ParseObjectBody(
Record *CurRec) {
3154 if (!SubClass.
Rec)
return true;
3157 if (AddSubClass(CurRec, SubClass))
3162 SubClass = ParseSubClassReference(CurRec,
false);
3166 if (ApplyLetStack(CurRec))
3169 return ParseBody(CurRec);
3177bool TGParser::ParseDef(
MultiClass *CurMultiClass) {
3188 std::unique_ptr<Record> CurRec;
3189 Init *
Name = ParseObjectName(CurMultiClass);
3193 if (isa<UnsetInit>(
Name)) {
3198 CurRec = std::make_unique<Record>(
Name, NameLoc, Records);
3201 if (ParseObjectBody(CurRec.get()))
3204 return addEntry(std::move(CurRec));
3211bool TGParser::ParseDefset() {
3220 if (!isa<ListRecTy>(
Type))
3222 Defset.EltTy = cast<ListRecTy>(
Type)->getElementType();
3225 return TokError(
"expected identifier");
3228 return TokError(
"def or global variable of this name already exists");
3237 Defsets.push_back(&Defset);
3238 bool Err = ParseObjectList(
nullptr);
3244 TokError(
"expected '}' at end of defset");
3245 return Error(BraceLoc,
"to match this '{'");
3257bool TGParser::ParseDefvar() {
3262 return TokError(
"expected identifier");
3264 if (CurLocalScope) {
3265 if (CurLocalScope->varAlreadyDefined(DeclName->
getValue()))
3266 return TokError(
"local variable of this name already exists");
3269 return TokError(
"def or global variable of this name already exists");
3297bool TGParser::ParseForeach(
MultiClass *CurMultiClass) {
3304 Init *ListValue =
nullptr;
3305 VarInit *IterName = ParseForeachDeclaration(ListValue);
3307 return TokError(
"expected declaration in for");
3313 Loops.push_back(std::make_unique<ForeachLoop>(Loc, IterName, ListValue));
3320 if (ParseObject(CurMultiClass))
3328 if (ParseObjectList(CurMultiClass))
3332 TokError(
"expected '}' at end of foreach command");
3333 return Error(BraceLoc,
"to match this '{'");
3340 std::unique_ptr<ForeachLoop>
Loop = std::move(
Loops.back());
3343 return addEntry(std::move(
Loop));
3351bool TGParser::ParseIf(
MultiClass *CurMultiClass) {
3358 Init *Condition = ParseValue(
nullptr);
3378 Init *ThenClauseList =
3382 Loops.push_back(std::make_unique<ForeachLoop>(Loc,
nullptr, ThenClauseList));
3384 if (ParseIfBody(CurMultiClass,
"then"))
3387 std::unique_ptr<ForeachLoop>
Loop = std::move(
Loops.back());
3390 if (addEntry(std::move(
Loop)))
3400 Init *ElseClauseList =
3405 std::make_unique<ForeachLoop>(Loc,
nullptr, ElseClauseList));
3407 if (ParseIfBody(CurMultiClass,
"else"))
3413 if (addEntry(std::move(
Loop)))
3430 if (ParseObject(CurMultiClass))
3438 if (ParseObjectList(CurMultiClass))
3442 TokError(
"expected '}' at end of '" + Kind +
"' clause");
3443 return Error(BraceLoc,
"to match this '{'");
3459 Init *Condition = ParseValue(CurRec);
3464 TokError(
"expected ',' in assert statement");
3468 Init *Message = ParseValue(CurRec);
3476 CurRec->
addAssertion(ConditionLoc, Condition, Message);
3478 addEntry(std::make_unique<Record::AssertionInfo>(ConditionLoc, Condition,
3487bool TGParser::ParseClass() {
3492 return TokError(
"expected class name after 'class' keyword");
3501 "' already defined");
3509 CurRec = NewRec.get();
3510 Records.
addClass(std::move(NewRec));
3516 if (ParseTemplateArgList(CurRec))
3519 if (ParseObjectBody(CurRec))
3522 if (!NoWarnOnUnusedTemplateArgs)
3536 TokError(
"expected identifier in let definition");
3547 if (ParseOptionalRangeList(Bits)) {
3551 std::reverse(
Bits.begin(),
Bits.end());
3554 TokError(
"expected '=' in let expression");
3559 Init *Val = ParseValue(
nullptr);
3566 Result.emplace_back(
Name, Bits, Val, NameLoc);
3576bool TGParser::ParseTopLevelLet(
MultiClass *CurMultiClass) {
3582 ParseLetList(LetInfo);
3583 if (LetInfo.
empty())
return true;
3587 return TokError(
"expected 'in' at end of top-level 'let'");
3594 if (ParseObject(CurMultiClass))
3602 if (ParseObjectList(CurMultiClass))
3606 TokError(
"expected '}' at end of top level let command");
3607 return Error(BraceLoc,
"to match this '{'");
3631bool TGParser::ParseMultiClass() {
3636 return TokError(
"expected identifier after multiclass for name");
3640 MultiClasses.insert(std::make_pair(
Name,
3641 std::make_unique<MultiClass>(
Name, Lex.
getLoc(),Records)));
3644 return TokError(
"multiclass '" +
Name +
"' already defined");
3646 CurMultiClass =
Result.first->second.get();
3651 if (ParseTemplateArgList(
nullptr))
3654 bool inherits =
false;
3662 ParseSubMultiClassReference(CurMultiClass);
3665 if (!SubMultiClass.
MC)
return true;
3668 if (AddSubMultiClass(CurMultiClass, SubMultiClass))
3673 SubMultiClass = ParseSubMultiClassReference(CurMultiClass);
3679 return TokError(
"expected '{' in multiclass definition");
3681 return TokError(
"expected ';' in multiclass definition");
3684 return TokError(
"multiclass must contain at least one def");
3692 return TokError(
"expected 'assert', 'def', 'defm', 'defvar', "
3693 "'foreach', 'if', or 'let' in multiclass body");
3702 if (ParseObject(CurMultiClass))
3712 PrintError(SemiLoc,
"A multiclass body should not end with a semicolon");
3713 PrintNote(
"Semicolon ignored; remove to eliminate this error");
3719 if (!NoWarnOnUnusedTemplateArgs)
3722 CurMultiClass =
nullptr;
3730bool TGParser::ParseDefm(
MultiClass *CurMultiClass) {
3734 Init *DefmName = ParseObjectName(CurMultiClass);
3737 if (isa<UnsetInit>(DefmName)) {
3747 return TokError(
"expected ':' after defm identifier");
3750 std::vector<RecordsEntry> NewEntries;
3753 bool InheritFromClass =
false;
3762 if (!
Ref.Rec)
return true;
3768 MultiClass *MC = MultiClasses[std::string(
Ref.Rec->getName())].get();
3769 assert(MC &&
"Didn't lookup multiclass correctly?");
3775 for (
unsigned i = 0, e = TArgs.
size(); i != e; ++i) {
3776 if (i < TemplateVals.
size()) {
3777 Substs.emplace_back(TArgs[i], TemplateVals[i]);
3781 return Error(SubClassLoc,
3782 "value not specified for template argument '" +
3783 TArgs[i]->getAsUnquotedString() +
"' (#" +
3784 Twine(i) +
") of multiclass '" +
3786 Substs.emplace_back(TArgs[i],
Default);
3792 if (resolve(MC->
Entries, Substs, !CurMultiClass &&
Loops.empty(),
3793 &NewEntries, &SubClassLoc))
3800 return TokError(
"expected identifier");
3802 SubClassLoc = Lex.
getLoc();
3808 if (InheritFromClass)
3811 Ref = ParseSubClassReference(
nullptr,
true);
3814 if (InheritFromClass) {
3820 if (!SubClass.
Rec)
return true;
3824 for (
auto &
E : NewEntries) {
3826 if (AddSubClass(
E, SubClass))
3832 SubClass = ParseSubClassReference(
nullptr,
false);
3836 for (
auto &
E : NewEntries) {
3837 if (ApplyLetStack(
E))
3840 addEntry(std::move(
E));
3844 return TokError(
"expected ';' at end of defm");
3863 "Expected assert, class, def, defm, defset, foreach, if, or let");
3870 case tgtok::Let:
return ParseTopLevelLet(MC);
3873 return TokError(
"defset is not allowed inside multiclass");
3874 return ParseDefset();
3877 return TokError(
"class is not allowed inside multiclass");
3879 return TokError(
"class is not allowed inside foreach loop");
3880 return ParseClass();
3883 return TokError(
"multiclass is not allowed inside foreach loop");
3884 return ParseMultiClass();
3890bool TGParser::ParseObjectList(
MultiClass *MC) {
3892 if (ParseObject(MC))
3900 if (ParseObjectList())
return true;
3906 return TokError(
"Unexpected token at top level");
3918 for (
unsigned I = 0,
E = Values.
size();
I <
E; ++
I) {
3924 auto *CastValue = ArgValue->getCastTo(ArgType);
3926 assert((!isa<TypedInit>(CastValue) ||
3927 cast<TypedInit>(CastValue)->
getType()->typeIsA(ArgType)) &&
3928 "result of template arg value cast has wrong type");
3929 Values[
I] = CastValue;
3932 "Value specified for template argument '" +
3933 Arg->getNameInitAsString() +
"' (#" +
Twine(
I) +
3934 ") is of type " + ArgValue->getType()->getAsString() +
3935 "; expected type " + ArgType->
getAsString() +
": " +
3936 ArgValue->getAsString());
3944#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3963 errs() <<
"Record:\n";
3966 errs() <<
"Defs:\n";
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file defines DenseMapInfo traits for DenseMap.
PowerPC Reduce CR logical Operation
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
static Init * QualifyName(Record &CurRec, MultiClass *CurMultiClass, Init *Name, StringRef Scoper)
Return an Init with a qualifier prefix referring to CurRec's name.
static bool isObjectStart(tgtok::TokKind K)
isObjectStart - Return true if this is a valid first token for a statement.
static Init * QualifiedNameOfImplicitName(Record &Rec, MultiClass *MC=nullptr)
Return the qualified version of the implicit 'NAME' template argument.
static bool checkBitsConcrete(Record &R, const RecordVal &RV)
static void checkConcrete(Record &R)
static SymbolRef::Type getType(const Symbol *Sym)
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.
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.
'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.
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 checkUnusedTemplateArgs()
std::string getNameInitAsString() const
Init * getNameInit() const
RecordKeeper & getRecords() const
const RecordVal * getValue(const Init *Name) const
void addValue(const RecordVal &RV)
void addTemplateArg(Init *Name)
ArrayRef< Init * > getTemplateArgs() const
bool isSubClassOf(const Record *R) const
ArrayRef< RecordVal > getValues() const
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
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
bool TokError(const Twine &Msg) const
TGLocalVarScope * PushLocalScope()
bool ParseFile()
ParseFile - Main entrypoint for parsing a tblgen file.
void PopLocalScope(TGLocalVarScope *ExpectedStackTop)
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.
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.
static VarDefInit * get(Record *Class, ArrayRef< Init * > 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 Args[]
Key for Kernel::Metadata::mArgs.
const CustomOperand< const MCSubtargetInfo & > Msg[]
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
@ Resolved
Queried, materialization begun.
This is an optimization pass for GlobalISel generic memory operations.
void PrintFatalError(const Twine &Msg)
void PrintError(const Twine &Msg)
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 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.
@ 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< Record > Rec
SmallVector< Init *, 4 > TemplateArgs
SmallVector< Init *, 4 > TemplateArgs