21#include "llvm/Config/llvm-config.h"
68#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
70 errs() <<
"Multiclass:\n";
74 errs() <<
"Template args:\n";
82 for (
unsigned i = 0, e = BV->getNumBits(); i != e; ++i) {
83 const Init *Bit = BV->getBit(i);
84 bool IsReference =
false;
87 if (R.getValue(VI->getName()))
93 if (!(IsReference || Bit->isConcrete()))
100 for (
const RecordVal &RV : R.getValues()) {
105 if (RV.isNonconcreteOK())
108 const Init *V = RV.getValue();
112 Twine(
"Initializer of '") + RV.getNameInitAsString() +
113 "' in '" + R.getNameInitAsString() +
114 "' could not be fully resolved: " + V->getAsString());
129 NewName = BinOp->Fold(&CurRec);
145 bool TrackReferenceLocs)
const {
147 auto It = Vars.find(Name->getValue());
148 if (It != Vars.end())
151 auto FindValueInArgs = [&](
Record *Rec) ->
const Init * {
155 if (
RecordVal *RV = Rec->getTemplateArg(ArgName)) {
157 if (TrackReferenceLocs)
158 Rec->appendValueReferenceLoc(ArgName, NameLoc);
161 return Name->getValue() ==
"NAME"
175 if (TrackReferenceLocs)
176 CurRec->appendValueReferenceLoc(Name, NameLoc);
181 if (CurRec->isClass())
182 if (
auto *V = FindValueInArgs(CurRec))
189 if (CurLoop->IterVar) {
190 const VarInit *IterVar = CurLoop->IterVar;
199 if (
auto *V = FindValueInArgs(&CurMultiClass->Rec))
207 return Parent->getVar(Records, ParsingMultiClass, Name, NameLoc,
216 CurRec = &CurMultiClass->
Rec;
221 return Error(
Loc,
"New definition of '" + RV.
getName() +
"' of type '" +
223 "' is incompatible with " +
224 "previous definition of type '" +
225 ERV->getType()->getAsString() +
"'");
239 assert(V &&
"Cannot set a null value");
242 CurRec = &CurMultiClass->Rec;
245 RecordVal *RV = CurRec->
getValue(ValName);
256 if (!BitList.
empty())
257 return Error(Loc,
"Cannot use append/prepend with bit range");
259 const Init *CurrentValue = RV->
getValue();
260 const RecTy *FieldType = RV->
getType();
266 const Init *
LHS = IsAppendMode ? CurrentValue :
V;
267 const Init *
RHS = IsAppendMode ?
V : CurrentValue;
277 return Error(Loc, Twine(
"Cannot ") +
278 (IsAppendMode ?
"append to" :
"prepend to") +
280 "' of type '" + FieldType->getAsString() +
281 "' (expected list, string, code, or dag)");
291 if (
VI->getNameInit() == ValName)
292 return Error(Loc,
"Recursion / self-assignment forbidden");
296 if (!BitList.
empty()) {
300 "' is not a bits type");
305 return Error(Loc,
"Initializer is not compatible with bit range");
310 for (
unsigned i = 0, e = BitList.
size(); i != e; ++i) {
311 unsigned Bit = BitList[i];
313 return Error(Loc,
"Cannot set bit #" + Twine(Bit) +
" of value '" +
319 for (
unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i)
321 NewBits[i] = CurVal->getBit(i);
327 std::string InitType;
329 InitType = (Twine(
"' of type bit initializer with length ") +
330 Twine(BI->getNumBits()))
334 (Twine(
"' of type '") + TI->getType()->getAsString() +
"'").str();
338 "' is incompatible with value '" +
V->getAsString() +
348 MapResolver
R(CurRec);
356 if (resolveArgumentsOfClass(R, SC, ParentClass.
TemplateArgs,
380 "Already subclass of '" + SC->
getName() +
"'!\n");
388 return AddParentClass(
Entry.Rec.get(), ParentClass);
393 for (
auto &
E :
Entry.Loop->Entries) {
394 if (AddParentClass(
E, ParentClass))
407 if (resolveArgumentsOfMultiClass(
415 return resolve(ParentMC->
Entries, Substs,
false, &CurMultiClass->Entries);
420 assert((!!
E.Rec + !!
E.Loop + !!
E.Assertion + !!
E.Dump) == 1 &&
421 "RecordsEntry has invalid number of items");
424 if (!Loops.empty()) {
425 Loops.back()->Entries.push_back(std::move(
E));
432 return resolve(*
E.Loop, Stack, CurMultiClass ==
nullptr,
433 CurMultiClass ? &CurMultiClass->Entries :
nullptr);
438 CurMultiClass->Entries.push_back(std::move(
E));
444 CheckAssert(
E.Assertion->Loc,
E.Assertion->Condition,
E.Assertion->Message);
454 return addDefOne(std::move(
E.Rec));
462bool TGParser::resolve(
const ForeachLoop &
Loop, SubstStack &Substs,
bool Final,
463 std::vector<RecordsEntry> *Dest,
SMLoc *
Loc) {
466 for (
const auto &S : Substs)
467 R.set(S.first, S.second);
468 const Init *
List =
Loop.ListValue->resolveReferences(R);
478 const Init *OldLHS = TI->getLHS();
484 "' at end of containing scope");
487 const Init *MHS = TI->getMHS();
488 const Init *
RHS = TI->getRHS();
497 std::make_unique<ForeachLoop>(
Loop.Loc,
Loop.IterVar,
List));
498 return resolve(
Loop.Entries, Substs, Final, &Dest->back().Loop->Entries,
503 List->getAsString() +
"', expected a list");
508 for (
auto *Elt : *LI) {
510 Substs.emplace_back(
Loop.IterVar->getNameInit(), Elt);
511 Error = resolve(
Loop.Entries, Substs, Final, Dest);
525bool TGParser::resolve(
const std::vector<RecordsEntry> &Source,
526 SubstStack &Substs,
bool Final,
527 std::vector<RecordsEntry> *Dest,
SMLoc *
Loc) {
529 for (
auto &
E : Source) {
531 Error = resolve(*
E.Loop, Substs, Final, Dest);
533 }
else if (
E.Assertion) {
535 for (
const auto &S : Substs)
536 R.set(S.first, S.second);
537 const Init *Condition =
E.Assertion->Condition->resolveReferences(R);
538 const Init *Message =
E.Assertion->Message->resolveReferences(R);
541 Dest->push_back(std::make_unique<Record::AssertionInfo>(
542 E.Assertion->Loc, Condition, Message));
548 for (
const auto &S : Substs)
549 R.set(S.first, S.second);
554 std::make_unique<Record::DumpInfo>(
E.Dump->Loc, Message));
559 auto Rec = std::make_unique<Record>(*
E.Rec);
561 Rec->appendLoc(*Loc);
563 MapResolver
R(Rec.get());
564 for (
const auto &S : Substs)
565 R.set(S.first, S.second);
566 Rec->resolveReferences(R);
569 Dest->push_back(std::move(Rec));
571 Error = addDefOne(std::move(Rec));
580bool TGParser::addDefOne(std::unique_ptr<Record> Rec) {
581 const Init *NewName =
nullptr;
582 if (
const Record *Prev = Records.getDef(Rec->getNameInitAsString())) {
583 if (!Rec->isAnonymous()) {
585 "def already exists: " + Rec->getNameInitAsString());
586 PrintNote(Prev->getLoc(),
"location of previous definition");
589 NewName = Records.getNewAnonymousName();
592 Rec->resolveReferences(NewName);
596 PrintError(Rec->getLoc(), Twine(
"record name '") +
597 Rec->getNameInit()->getAsString() +
598 "' could not be fully resolved");
603 Rec->checkRecordAssertions();
606 Rec->emitRecordDumps();
609 assert(Rec->getTemplateArgs().empty() &&
"How'd this get template args?");
611 for (DefsetRecord *Defset : Defsets) {
612 DefInit *
I = Rec->getDefInit();
613 if (!
I->getType()->typeIsA(
Defset->EltTy)) {
614 PrintError(Rec->getLoc(), Twine(
"adding record of incompatible type '") +
615 I->getType()->getAsString() +
623 Records.addDef(std::move(Rec));
627bool TGParser::resolveArguments(
const Record *Rec,
629 SMLoc Loc, ArgValueHandler ArgValueHandler) {
632 "Too many template arguments allowed");
636 for (
auto *Arg : ArgValues) {
637 const Init *ArgName =
nullptr;
638 const Init *ArgValue = Arg->getValue();
639 if (Arg->isPositional())
640 ArgName =
Args[Arg->getIndex()].getNameInit();
642 ArgName = Arg->getName();
645 auto It =
find_if(UnsolvedArgs, [ArgName](
const RecordVal *UnsolvedArg) {
648 if (It == UnsolvedArgs.end())
649 return Error(Loc,
"We can only specify the template argument '" +
652 ArgValueHandler(ArgName, ArgValue);
653 UnsolvedArgs.erase(It);
657 for (
const RecordVal *UnsolvedArg : UnsolvedArgs) {
660 Error(Loc,
"value not specified for template argument '" +
677 return resolveArguments(
679 [&](
const Init *Name,
const Init *
Value) {
R.set(Name,
Value); });
684bool TGParser::resolveArgumentsOfMultiClass(
689 return resolveArguments(&MC->
Rec, ArgValues, Loc,
690 [&](
const Init *Name,
const Init *
Value) {
691 Substs.emplace_back(Name, Value);
700 if (Lex.getCode() == K) {
713const Init *TGParser::ParseObjectName() {
714 switch (Lex.getCode()) {
728 CurRec = &CurMultiClass->Rec;
737 HasReferenceResolver
R(NameStr);
738 Name->resolveReferences(R);
752const Record *TGParser::ParseClassID() {
754 TokError(
"expected name for ClassID");
758 const Record *
Result = Records.getClass(Lex.getCurStrVal());
760 std::string
Msg(
"Couldn't find class '" + Lex.getCurStrVal() +
"'");
761 if (MultiClasses[Lex.getCurStrVal()].get())
762 TokError(
Msg +
". Use 'defm' if you meant to use multiclass '" +
763 Lex.getCurStrVal() +
"'");
766 }
else if (TrackReferenceLocs) {
767 Result->appendReferenceLoc(Lex.getLocRange());
781 TokError(
"expected name for MultiClassID");
787 TokError(
"Couldn't find multiclass '" + Lex.getCurStrVal() +
"'");
801 Result.RefRange.Start = Lex.getLoc();
804 if (MultiClass *MC = ParseMultiClassID())
807 Result.Rec = ParseClassID();
814 Result.RefRange.End = Lex.getLoc();
819 if (ParseTemplateArgValueList(
Result.TemplateArgs, ArgLocs, CurRec,
825 if (CheckTemplateArgValues(
Result.TemplateArgs, ArgLocs,
Result.Rec)) {
830 Result.RefRange.End = Lex.getLoc();
841 MultiClassReference
Result;
842 Result.RefRange.Start = Lex.getLoc();
844 Result.MC = ParseMultiClassID();
850 Result.RefRange.End = Lex.getLoc();
855 if (ParseTemplateArgValueList(
Result.TemplateArgs, ArgLocs,
856 &CurMultiClass->Rec, &
Result.MC->Rec)) {
861 if (CheckTemplateArgValues(
Result.TemplateArgs, ArgLocs, &
Result.MC->Rec)) {
866 Result.RefRange.End = Lex.getLoc();
882 auto LHSLoc = Lex.getLoc();
883 auto *CurVal = ParseValue(CurRec);
888 const TypedInit *
RHS =
nullptr;
889 switch (Lex.getCode()) {
893 auto RHSLoc = Lex.getLoc();
894 CurVal = ParseValue(CurRec);
900 "expected int...int, got " + Twine(
RHS->
getType()->getAsString()));
906 auto i = -Lex.getCurIntVal();
908 TokError(
"invalid range, cannot be negative");
925 "expected int...int, got " + Twine(
LHS->
getType()->getAsString()));
946 const TypedInit *CurVal;
950 auto FlushElems = [&] {
951 if (!Elems.
empty()) {
958 auto LHSLoc = Lex.getLoc();
959 CurVal = ParseSliceElement(CurRec);
962 auto *CurValTy = CurVal->
getType();
967 "expected list<int>, got " + Twine(ListValTy->getAsString()));
977 "unhandled type " + Twine(CurValTy->getAsString()) +
" in range");
1004 const TypedInit *
Result =
nullptr;
1005 for (
auto *Slice : Slices) {
1021 const Init *CurVal = FirstItem;
1023 CurVal = ParseValue(
nullptr);
1027 return TokError(
"expected integer or bitrange");
1029 int64_t
Start =
II->getValue();
1033 return TokError(
"invalid range, cannot be negative");
1035 switch (Lex.getCode()) {
1044 const Init *I_End = ParseValue(
nullptr);
1047 TokError(
"expected integer value as end of range");
1051 End = II_End->getValue();
1055 End = -Lex.getCurIntVal();
1061 return TokError(
"invalid range, cannot be negative");
1079 if (ParseRangePiece(Result)) {
1085 if (ParseRangePiece(Result)) {
1095 SMLoc StartLoc = Lex.getLoc();
1100 ParseRangeList(Ranges);
1105 TokError(
"expected '}' at end of bit list");
1106 return Error(StartLoc,
"to match this '{'");
1122const RecTy *TGParser::ParseType() {
1123 switch (Lex.getCode()) {
1125 TokError(
"Unknown token when expecting a type");
1141 auto I = TypeAliases.find(Lex.getCurStrVal());
1142 if (
I != TypeAliases.end()) {
1146 if (
const Record *R = ParseClassID())
1153 TokError(
"expected '<' after bits type");
1157 TokError(
"expected integer in bits<n> type");
1162 TokError(
"expected '>' at end of bits<n> type");
1170 TokError(
"expected '<' after list type");
1174 const RecTy *SubType = ParseType();
1179 TokError(
"expected '>' at end of list<ty> type");
1190 if (
const Init *
I = CurScope->getVar(Records, CurMultiClass, Name, NameLoc,
1191 TrackReferenceLocs))
1194 if (
Mode == ParseNameMode)
1197 if (
const Init *
I = Records.getGlobal(
Name->getValue())) {
1199 if (TrackReferenceLocs) {
1201 Def->getDef()->appendReferenceLoc(NameLoc);
1208 if (CurRec && !CurRec->
isClass() && !CurMultiClass &&
1212 Error(NameLoc.
Start,
"Variable not defined: '" +
Name->getValue() +
"'");
1220const Init *TGParser::ParseOperation(
Record *CurRec,
const RecTy *ItemType) {
1221 switch (Lex.getCode()) {
1240 const RecTy *
Type =
nullptr;
1242 switch (Lex.getCode()) {
1249 Type = ParseOperatorType();
1252 TokError(
"did not get type for unary operator");
1311 Type = ParseOperatorType();
1314 TokError(
"did not get type for unary operator");
1319 TokError(
"type for !getdagop must be a record type");
1339 TokError(
"expected '(' after unary operator");
1343 const Init *
LHS = ParseValue(CurRec);
1352 if (!LHSl && !LHSs && !LHSd && !LHSt) {
1354 "expected string, list, or dag type argument in unary operator");
1360 "expected string, list, or dag type argument in unary operator");
1370 if (!LHSl && !LHSt) {
1371 TokError(
"expected list type argument in unary operator");
1376 TokError(
"expected list type argument in unary operator");
1381 if (LHSl && LHSl->empty()) {
1382 TokError(
"empty list argument in unary operator");
1385 bool UseElementType =
1388 const Init *Item = LHSl->getElement(0);
1391 TokError(
"untyped list element in unary operator");
1394 Type = UseElementType ? Itemt->getType()
1397 assert(LHSt &&
"expected list type argument in unary operator");
1399 Type = UseElementType ? LType->getElementType() : LType;
1417 TokError(
"expected ')' in unary operator");
1427 const RecTy *
Type = ParseOperatorType();
1432 TokError(
"expected '(' after type of !isa");
1436 const Init *
LHS = ParseValue(CurRec);
1452 const RecTy *
Type = ParseOperatorType();
1457 TokError(
"expected '(' after type of !exists");
1461 SMLoc ExprLoc = Lex.getLoc();
1462 const Init *Expr = ParseValue(CurRec);
1468 Error(ExprLoc,
"expected string type argument in !exists operator");
1475 "expected string type argument in !exists operator, please "
1476 "use !isa instead");
1482 Error(ExprLoc,
"expected string type argument in !exists operator");
1487 TokError(
"expected ')' in !exists");
1498 const RecTy *
Type = ParseOperatorType();
1503 TokError(
"expected '(' after type of !instances");
1510 SMLoc RegexLoc = Lex.getLoc();
1511 Regex = ParseValue(CurRec);
1515 Error(RegexLoc,
"expected string type argument in !instances operator");
1521 Error(RegexLoc,
"expected string type argument in !instances operator");
1530 TokError(
"expected ')' in !instances");
1565 SMLoc OpLoc = Lex.getLoc();
1655 const RecTy *
Type =
nullptr;
1656 const RecTy *ArgType =
nullptr;
1670 Type = ParseOperatorType();
1672 TokError(
"did not get type for !getdagarg operator");
1727 if (
Type && ItemType && !
Type->typeIsConvertibleTo(ItemType)) {
1729 "', got '" +
Type->getAsString() +
"'");
1734 TokError(
"expected '(' after binary operator");
1743 SMLoc InitLoc = Lex.getLoc();
1744 InitList.
push_back(ParseValue(CurRec, ArgType));
1745 if (!InitList.
back())
1749 if (!InitListBack) {
1750 Error(OpLoc, Twine(
"expected value to be a typed value, got '" +
1751 InitList.
back()->getAsString() +
"'"));
1754 const RecTy *ListType = InitListBack->getType();
1763 Error(InitLoc, Twine(
"expected a list, got value of type '") +
1769 if (ItemType && InitList.
size() == 1) {
1772 Twine(
"expected output type to be a list, got type '") +
1777 Error(OpLoc, Twine(
"expected first arg type to be '") +
1779 "', got value of type '" +
1788 Error(InitLoc, Twine(
"expected second parameter to be an int, got "
1789 "value of type '") +
1797 Error(InitLoc, Twine(
"expected a list, got value of type '") +
1807 Error(InitLoc, Twine(
"expected bit, bits, int, string, or record; "
1808 "got value of type '") +
1821 Error(InitLoc, Twine(
"expected bit, bits, int, or string; "
1822 "got value of type '") +
1828 switch (InitList.
size()) {
1834 Twine(
"expected list of string, int, bits, or bit; "
1835 "got value of type '") +
1842 Error(InitLoc, Twine(
"expected second argument to be a string, "
1843 "got value of type '") +
1860 Error(InitLoc, Twine(
"expected value of type '") +
1903 TokError(
"expected ')' in operator");
1923 while (InitList.
size() > 2) {
1930 if (InitList.
size() == 2)
1934 Error(OpLoc,
"expected two operands to operator");
1941 return ParseOperationListComprehension(CurRec, ItemType);
1945 SMLoc OpLoc = Lex.getLoc();
1949 TokError(
"expected '(' after !range operator");
1954 bool FirstArgIsList =
false;
1956 if (
Args.size() >= 3) {
1957 TokError(
"expected at most three values of integer");
1961 SMLoc InitLoc = Lex.getLoc();
1962 Args.push_back(ParseValue(CurRec));
1968 Error(OpLoc, Twine(
"expected value to be a typed value, got '" +
1969 Args.back()->getAsString() +
"'"));
1973 const RecTy *ArgBackType = ArgBack->getType();
1974 if (!FirstArgIsList ||
Args.size() == 1) {
1976 FirstArgIsList =
true;
1980 if (
Args.size() != 1)
1981 Error(InitLoc, Twine(
"expected value of type 'int', got '" +
1984 Error(InitLoc, Twine(
"expected list or int, got value of type '") +
1991 Error(InitLoc, Twine(
"expected one list, got extra value of type '") +
2000 TokError(
"expected ')' in operator");
2004 const Init *
LHS, *MHS, *
RHS;
2005 auto ArgCount =
Args.size();
2008 const auto *Arg0Ty = Arg0->getType();
2009 if (ArgCount == 1) {
2029 if (ArgCount == 3) {
2050 const RecTy *
Type =
nullptr;
2080 TokError(
"expected '(' after ternary operator");
2084 const Init *
LHS = ParseValue(CurRec);
2089 TokError(
"expected ',' in ternary operator");
2093 SMLoc MHSLoc = Lex.getLoc();
2094 const Init *MHS = ParseValue(CurRec, ItemType);
2099 TokError(
"expected ',' in ternary operator");
2103 SMLoc RHSLoc = Lex.getLoc();
2104 const Init *
RHS = ParseValue(CurRec, ItemType);
2109 TokError(
"expected ')' in binary operator");
2119 Error(MHSLoc,
"could not determine type of the child list in !dag");
2123 Error(MHSLoc, Twine(
"expected list of children, got type '") +
2124 MHSt->getType()->getAsString() +
"'");
2130 Error(RHSLoc,
"could not determine type of the name list in !dag");
2134 Error(RHSLoc, Twine(
"expected list<string>, got type '") +
2135 RHSt->getType()->getAsString() +
"'");
2139 if (!MHSt && !RHSt) {
2141 "cannot have both unset children and unset names in !dag");
2147 const RecTy *MHSTy =
nullptr;
2148 const RecTy *RHSTy =
nullptr;
2151 MHSTy = MHSt->getType();
2158 RHSTy = RHSt->getType();
2170 if (!MHSTy || !RHSTy) {
2171 TokError(
"could not get type for !if");
2186 TokError(
"could not get type for !subst");
2189 Type = RHSt->getType();
2195 Error(MHSLoc, Twine(
"expected integer index or string name, got ") +
2196 (MHSt ? (
"type '" + MHSt->getType()->getAsString())
2206 Error(MHSLoc, Twine(
"expected integer index or string name, got ") +
2207 (MHSt ? (
"type '" + MHSt->getType()->getAsString())
2215 Error(RHSLoc, Twine(
"expected string or unset name, got type '") +
2216 RHSt->getType()->getAsString() +
"'");
2226 return ParseOperationSubstr(CurRec, ItemType);
2229 return ParseOperationFind(CurRec, ItemType);
2232 return ParseOperationCond(CurRec, ItemType);
2235 return ParseOperationSwitch(CurRec, ItemType);
2241 TokError(
"expected '(' after !foldl");
2245 const Init *StartUntyped = ParseValue(CurRec);
2251 TokError(Twine(
"could not get type of !foldl start: '") +
2257 TokError(
"expected ',' in !foldl");
2261 const Init *ListUntyped = ParseValue(CurRec);
2267 TokError(Twine(
"could not get type of !foldl list: '") +
2274 TokError(Twine(
"!foldl list must be a list, but is of type '") +
2275 List->getType()->getAsString());
2280 TokError(
"expected ',' in !foldl");
2285 TokError(
"third argument of !foldl must be an identifier");
2291 TokError(Twine(
"left !foldl variable '") +
A->getAsString() +
2292 "' already defined");
2297 TokError(
"expected ',' in !foldl");
2302 TokError(
"fourth argument of !foldl must be an identifier");
2308 TokError(Twine(
"right !foldl variable '") +
B->getAsString() +
2309 "' already defined");
2314 TokError(
"expected ',' in !foldl");
2321 std::unique_ptr<Record> ParseRecTmp;
2322 Record *ParseRec = CurRec;
2326 ParseRec = ParseRecTmp.get();
2329 TGVarScope *FoldScope =
PushScope(ParseRec);
2333 const Init *ExprUntyped = ParseValue(ParseRec);
2334 ParseRec->removeValue(
A);
2335 ParseRec->removeValue(
B);
2342 TokError(
"could not get type of !foldl expression");
2346 if (Expr->getType() !=
Start->getType()) {
2347 TokError(Twine(
"!foldl expression must be of same type as start (") +
2348 Start->getType()->getAsString() +
"), but is of type " +
2354 TokError(
"expected ')' in fold operator");
2369const RecTy *TGParser::ParseOperatorType() {
2370 const RecTy *
Type =
nullptr;
2373 TokError(
"expected type name for operator");
2378 TokError(
"the 'code' type is not allowed in bang operators; use 'string'");
2383 TokError(
"expected type name for operator");
2388 TokError(
"expected type name for operator");
2398const Init *TGParser::ParseOperationSubstr(
Record *CurRec,
2399 const RecTy *ItemType) {
2406 TokError(
"expected '(' after !substr operator");
2410 const Init *
LHS = ParseValue(CurRec);
2415 TokError(
"expected ',' in !substr operator");
2419 SMLoc MHSLoc = Lex.getLoc();
2420 const Init *MHS = ParseValue(CurRec);
2424 SMLoc RHSLoc = Lex.getLoc();
2427 RHSLoc = Lex.getLoc();
2428 RHS = ParseValue(CurRec);
2436 TokError(
"expected ')' in !substr operator");
2440 if (ItemType && !
Type->typeIsConvertibleTo(ItemType)) {
2441 Error(RHSLoc, Twine(
"expected value of type '") + ItemType->
getAsString() +
2442 "', got '" +
Type->getAsString() +
"'");
2447 TokError(
"could not determine type of the string in !substr");
2451 TokError(Twine(
"expected string, got type '") +
2452 LHSt->getType()->getAsString() +
"'");
2458 TokError(
"could not determine type of the start position in !substr");
2462 Error(MHSLoc, Twine(
"expected int, got type '") +
2463 MHSt->getType()->getAsString() +
"'");
2470 TokError(
"could not determine type of the length in !substr");
2474 TokError(Twine(
"expected int, got type '") +
2475 RHSt->getType()->getAsString() +
"'");
2486const Init *TGParser::ParseOperationFind(
Record *CurRec,
2487 const RecTy *ItemType) {
2494 TokError(
"expected '(' after !find operator");
2498 const Init *
LHS = ParseValue(CurRec);
2503 TokError(
"expected ',' in !find operator");
2507 SMLoc MHSLoc = Lex.getLoc();
2508 const Init *MHS = ParseValue(CurRec);
2512 SMLoc RHSLoc = Lex.getLoc();
2515 RHSLoc = Lex.getLoc();
2516 RHS = ParseValue(CurRec);
2524 TokError(
"expected ')' in !find operator");
2528 if (ItemType && !
Type->typeIsConvertibleTo(ItemType)) {
2529 Error(RHSLoc, Twine(
"expected value of type '") + ItemType->
getAsString() +
2530 "', got '" +
Type->getAsString() +
"'");
2535 TokError(
"could not determine type of the source string in !find");
2539 TokError(Twine(
"expected string, got type '") +
2540 LHSt->getType()->getAsString() +
"'");
2546 TokError(
"could not determine type of the target string in !find");
2550 Error(MHSLoc, Twine(
"expected string, got type '") +
2551 MHSt->getType()->getAsString() +
"'");
2558 TokError(
"could not determine type of the start position in !find");
2562 TokError(Twine(
"expected int, got type '") +
2563 RHSt->getType()->getAsString() +
"'");
2576const Init *TGParser::ParseOperationListComprehension(
Record *CurRec,
2577 const RecTy *ItemType) {
2578 SMLoc OpLoc = Lex.getLoc();
2582 TokError(
"expected '(' after !foreach/!filter");
2587 TokError(
"first argument of !foreach/!filter must be an identifier");
2595 TokError(Twine(
"iteration variable '") +
LHS->getAsString() +
2596 "' is already defined");
2601 TokError(
"expected ',' in !foreach/!filter");
2605 const Init *MHS = ParseValue(CurRec);
2610 TokError(
"expected ',' in !foreach/!filter");
2616 TokError(
"could not get type of !foreach/!filter list or dag");
2620 const RecTy *InEltType =
nullptr;
2621 const RecTy *ExprEltType =
nullptr;
2625 InEltType = InListTy->getElementType();
2630 ExprEltType = OutListTy->getElementType();
2636 ExprEltType =
nullptr;
2642 Error(OpLoc,
"expected value of type '" +
2644 "', but got list type");
2651 TokError(
"!filter must have a list argument");
2654 TokError(
"!sort must have a list argument");
2661 InEltType = InDagTy;
2664 "', but got dag type");
2671 TokError(
"!foreach must have a list or dag argument");
2674 TokError(
"!filter must have a list argument");
2677 TokError(
"!sort must have a list argument");
2686 std::unique_ptr<Record> ParseRecTmp;
2687 Record *ParseRec = CurRec;
2691 ParseRec = ParseRecTmp.get();
2693 TGVarScope *TempScope =
PushScope(ParseRec);
2695 const Init *
RHS = ParseValue(ParseRec, ExprEltType);
2696 ParseRec->removeValue(
LHS);
2702 TokError(
"expected ')' in !foreach/!filter");
2706 const RecTy *OutType;
2712 OutType = InEltType;
2716 TokError(
"could not get type of !foreach result expression");
2740std::optional<const RecTy *>
2742 const RecTy *
Type =
nullptr;
2743 for (
const Init *V : Inits) {
2755 TokError(Twine(
"inconsistent types '") +
Type->getAsString() +
"' and '" +
2757 return std::nullopt;
2767const Init *TGParser::ParseOperationCond(
Record *CurRec,
2768 const RecTy *ItemType) {
2772 TokError(
"expected '(' after !cond operator");
2783 const Init *
V = ParseValue(CurRec);
2789 TokError(
"expected ':' following a condition in !cond operator");
2793 V = ParseValue(CurRec, ItemType);
2802 TokError(
"expected ',' or ')' following a value in !cond operator");
2807 if (Cases.
size() < 1) {
2809 "there should be at least 1 'condition : value' in the !cond operator");
2814 std::optional<const RecTy *> TypeOpt = resolveInitTypes(Vals,
"for !cond");
2817 const RecTy *
Type = *TypeOpt;
2819 TokError(
"could not determine type for !cond from its arguments");
2826const Init *TGParser::ParseOperationSwitch(
Record *CurRec,
2827 const RecTy *ItemType) {
2831 TokError(
"expected '(' after !switch operator");
2836 const Init *
Key = ParseValue(CurRec);
2843 TokError(
"expected ',' after key in !switch operator");
2851 const Init *
V = ParseValue(CurRec);
2860 if (
const Init *Coerced =
V->convertInitializerTo(ItemType))
2870 TokError(
"expected ':' after case key, or ')' to close !switch operator");
2875 V = ParseValue(CurRec, ItemType);
2881 TokError(
"expected ',' after case value in !switch operator");
2886 "inconsistent keys and values for !switch");
2888 if (KeyAndCases.
size() < 2) {
2890 "there should be at least 1 'case: value' in the !switch operator");
2895 std::optional<const RecTy *> ValTypeOpt =
2896 resolveInitTypes(Vals,
"for !switch values");
2899 const RecTy *
ValType = *ValTypeOpt;
2901 TokError(
"could not determine type for !switch from its arguments");
2908 if (!resolveInitTypes(KeyAndCases,
"between !switch key and case keys"))
2914 size_t ValsSize = Vals.
size();
2921 assert(Conds.
size() == ValsSize &&
"inconsistent !switch to !cond reduction");
2952const Init *TGParser::ParseSimpleValue(
Record *CurRec,
const RecTy *ItemType,
2954 const Init *
R =
nullptr;
2959 return ParseOperation(CurRec, ItemType);
2963 TokError(
"Unknown or reserved token when parsing a value");
2979 auto BinaryVal = Lex.getCurBinaryIntVal();
2981 for (
unsigned i = 0, e = BinaryVal.second; i != e; ++i)
2988 std::string Val = Lex.getCurStrVal();
2993 Val += Lex.getCurStrVal();
3009 SMRange NameLoc = Lex.getLocRange();
3015 return ParseIDValue(CurRec, Name, NameLoc,
Mode);
3023 "Expected a class name, got '" +
Name->getValue() +
"'");
3030 if (ParseTemplateArgValueList(Args, ArgLocs, CurRec, Class))
3033 if (CheckTemplateArgValues(Args, ArgLocs, Class))
3036 if (resolveArguments(Class, Args, NameLoc.
Start))
3039 if (TrackReferenceLocs)
3040 Class->appendReferenceLoc(NameLoc);
3044 SMLoc BraceLoc = Lex.getLoc();
3049 ParseValueList(Vals, CurRec);
3054 TokError(
"expected '}' at end of bit list value");
3069 for (
const Init *Bit :
reverse(BI->getBits()))
3076 for (
unsigned Bit :
reverse(
seq(BitsRec->getNumBits())))
3085 Error(BraceLoc,
"Element #" + Twine(
I) +
" (" + Val->getAsString() +
3086 ") is not convertable to a bit");
3091 std::reverse(NewBits.
begin(), NewBits.
end());
3098 const RecTy *DeducedEltTy =
nullptr;
3099 const ListRecTy *GivenListTy =
nullptr;
3104 TokError(Twine(
"Encountered a list when expecting a ") +
3108 GivenListTy = ListType;
3112 ParseValueList(Vals, CurRec,
3118 TokError(
"expected ']' at end of list value");
3122 const RecTy *GivenEltTy =
nullptr;
3125 GivenEltTy = ParseType();
3132 TokError(
"expected '>' at end of list element type");
3138 const RecTy *EltTy =
nullptr;
3139 for (
const Init *V : Vals) {
3145 TokError(
"Incompatible types in list elements");
3149 EltTy = TArg->getType();
3158 TokError(
"Incompatible types in list elements");
3175 TokError(Twine(
"Element type mismatch for list: element type '") +
3181 DeducedEltTy = EltTy;
3192 TokError(
"expected identifier or list of value types in dag init");
3196 const Init *
Operator = ParseValue(CurRec);
3201 const StringInit *OperatorName =
nullptr;
3204 TokError(
"expected variable name in dag operator");
3213 ParseDagArgList(DagArgs, CurRec);
3214 if (DagArgs.
empty())
3219 TokError(
"expected ')' in dag init");
3237const Init *TGParser::ParseValue(
Record *CurRec,
const RecTy *ItemType,
3239 SMLoc LHSLoc = Lex.getLoc();
3240 const Init *
Result = ParseSimpleValue(CurRec, ItemType,
Mode);
3246 switch (Lex.getCode()) {
3250 if (
Mode == ParseNameMode)
3254 SMLoc CurlyLoc = Lex.getLoc();
3256 SmallVector<unsigned, 16>
Ranges;
3257 ParseRangeList(Ranges);
3265 Error(CurlyLoc,
"Invalid bit range for value");
3271 TokError(
"expected '}' at end of bit range list");
3279 Error(LHSLoc,
"Invalid value, list expected");
3286 "' is invalid, list expected");
3291 const TypedInit *
RHS = ParseSliceElements(CurRec,
true);
3300 LHSTy->getElementType())
3308 TokError(
"expected ']' at end of list slice");
3315 TokError(
"expected field identifier after '.'");
3318 SMRange FieldNameLoc = Lex.getLocRange();
3319 const StringInit *FieldName =
3321 if (!
Result->getFieldType(FieldName)) {
3322 TokError(
"Cannot access field '" + Lex.getCurStrVal() +
"' of value '" +
3323 Result->getAsString() +
"'");
3328 if (TrackReferenceLocs) {
3330 DI->getDef()->appendValueReferenceLoc(FieldName, FieldNameLoc);
3333 for (
const Record *R : RecTy->getClasses())
3334 if (
R->getValue(FieldName))
3335 R->appendValueReferenceLoc(FieldName, FieldNameLoc);
3346 SMLoc PasteLoc = Lex.getLoc();
3349 Error(PasteLoc,
"LHS of paste is not typed!");
3357 assert(
Mode == ParseValueMode &&
"encountered paste of lists in name");
3359 switch (Lex.getCode()) {
3366 const Init *RHSResult = ParseValue(CurRec, ItemType, ParseValueMode);
3383 Twine(
"can't cast '") +
LHS->getAsString() +
"' to string");
3389 const TypedInit *
RHS =
nullptr;
3392 switch (Lex.getCode()) {
3405 const Init *RHSResult = ParseValue(CurRec,
nullptr, ParseNameMode);
3410 Error(PasteLoc,
"RHS of paste is not typed!");
3420 Twine(
"can't cast '") +
RHS->getAsString() +
"' to string");
3441void TGParser::ParseDagArgList(
3454 const Init *Val = ParseValue(CurRec);
3461 const StringInit *
VarName =
nullptr;
3464 TokError(
"expected variable name in dag literal");
3472 Result.emplace_back(Val, VarName);
3487 Result.push_back(ParseValue(CurRec, ItemType));
3497 Result.push_back(ParseValue(CurRec, ItemType));
3513bool TGParser::ParseTemplateArgValueList(
3516 assert(
Result.empty() &&
"Result vector is not empty");
3522 bool HasNamedArg =
false;
3523 unsigned ArgIndex = 0;
3525 if (ArgIndex >= TArgs.
size()) {
3526 TokError(
"Too many template arguments: " +
utostr(ArgIndex + 1));
3534 ParseValue(CurRec, HasNamedArg ?
nullptr : TArgs[ArgIndex].
getType());
3541 return Error(ValueLoc,
3542 "The name of named argument should be a valid identifier");
3546 const RecordVal *NamedArg = ArgsRec->
getTemplateArg(QualifiedName);
3548 return Error(ValueLoc,
3549 "Argument " +
Name->getAsString() +
" doesn't exist");
3552 ValueLoc = Lex.getLoc();
3556 return Error(ValueLoc,
3557 "The value of named argument should be initialized, "
3559 Value->getAsString() +
"'");
3566 return Error(ValueLoc,
3567 "Positional argument should be put before named argument");
3575 return TokError(
"Expected comma before next argument");
3590bool TGParser::ParseDeclaration(
Record *CurRec,
bool ParsingTemplateArgs) {
3591 SMLoc DeclLoc = Lex.getLoc();
3596 const RecTy *
Type = ParseType();
3601 return TokError(
"Expected identifier in declaration");
3603 std::string Str = Lex.getCurStrVal();
3605 return TokError(
"'" + Str +
"' is a reserved variable name");
3607 if (!ParsingTemplateArgs && CurScope->varAlreadyDefined(Str))
3608 return TokError(
"local variable of this name already exists");
3610 SMLoc IdLoc = Lex.getLoc();
3614 Record *Rec = CurRec ? CurRec : &CurMultiClass->Rec;
3619 if (!ParsingTemplateArgs &&
3620 AddValue(Rec, IdLoc,
3621 RecordVal(DeclName, IdLoc,
Type,
3627 const Init *Val =
nullptr;
3629 ValLoc = Lex.getLoc();
3630 Val = ParseValue(CurRec,
Type);
3633 if (ParsingTemplateArgs) {
3637 return Error(DeclLoc,
"template argument with the same name has already "
3644 SetValue(Rec, ValLoc, DeclName, {}, Val,
false);
3657TGParser::ParseForeachDeclaration(
const Init *&ForeachListValue) {
3659 TokError(
"Expected identifier in foreach declaration");
3668 TokError(
"Expected '=' in foreach declaration");
3672 const RecTy *IterType =
nullptr;
3673 SmallVector<unsigned, 16>
Ranges;
3675 switch (Lex.getCode()) {
3678 ParseRangeList(Ranges);
3680 TokError(
"expected '}' at end of bit range list");
3687 SMLoc ValueLoc = Lex.getLoc();
3688 const Init *
I = ParseValue(
nullptr);
3694 ForeachListValue =
I;
3700 if (ParseRangePiece(Ranges, TI))
3705 Error(ValueLoc,
"expected a list, got '" +
I->getAsString() +
"'");
3706 if (CurMultiClass) {
3707 PrintNote({},
"references to multiclass template arguments cannot be "
3708 "resolved at this time");
3715 assert(!IterType &&
"Type already initialized?");
3717 std::vector<Init *>
Values;
3718 for (
unsigned R : Ranges)
3736bool TGParser::ParseTemplateArgList(
Record *CurRec) {
3743 if (ParseDeclaration(CurRec,
true))
3748 return TokError(
"expected '>' at end of template argument list");
3765 SMLoc Loc = Lex.getLoc();
3767 std::string CurStr = Lex.getCurStrVal();
3769 LetMode Mode = llvm::StringSwitch<LetMode>(CurStr)
3779 LetModeAndName
Result = {
Mode, Lex.getLoc(), Lex.getCurStrVal()};
3797bool TGParser::ParseBodyItem(
Record *CurRec) {
3799 return ParseAssert(CurRec);
3802 return ParseDefvar(CurRec);
3805 return ParseDump(CurRec);
3808 if (ParseDeclaration(CurRec,
false))
3812 return TokError(
"expected ';' after declaration");
3820 return TokError(
"expected field identifier after let");
3822 auto [
Mode, IdLoc, FieldNameStr] = ParseLetModeAndName();
3825 SmallVector<unsigned, 16> BitList;
3826 if (ParseOptionalRangeList(BitList))
3828 std::reverse(BitList.
begin(), BitList.
end());
3831 return TokError(
"expected '=' in let expression");
3835 return Error(IdLoc,
"Value '" + FieldName->
getValue() +
"' unknown!");
3844 const Init *Val = ParseValue(CurRec,
Type);
3849 return TokError(
"expected ';' after let expression");
3851 return SetValue(CurRec, IdLoc, FieldName, BitList, Val,
3862bool TGParser::ParseBody(
Record *CurRec) {
3868 return TokError(
"Expected '{' to start body or ';' for declaration only");
3871 if (ParseBodyItem(CurRec))
3878 SMLoc SemiLoc = Lex.getLoc();
3880 PrintError(SemiLoc,
"A class or def body should not end with a semicolon");
3881 PrintNote(
"Semicolon ignored; remove to eliminate this error");
3889bool TGParser::ApplyLetStack(
Record *CurRec) {
3890 for (SmallVectorImpl<LetRecord> &LetInfo : LetStack)
3891 for (LetRecord &LR : LetInfo)
3892 if (SetValue(CurRec, LR.Loc, LR.Name, LR.Bits, LR.Value,
3901 return ApplyLetStack(
Entry.Rec.get());
3904 if (
Entry.Assertion)
3911 for (
auto &
E :
Entry.Loop->Entries) {
3912 if (ApplyLetStack(
E))
3928bool TGParser::ParseObjectBody(
Record *CurRec) {
3930 TGVarScope *ObjectScope =
PushScope(CurRec);
3935 ClassReference ParentClass = ParseClassReference(CurRec,
false);
3938 if (!ParentClass.
Rec)
3942 if (AddParentClass(CurRec, ParentClass))
3947 ParentClass = ParseClassReference(CurRec,
false);
3951 if (ApplyLetStack(CurRec))
3954 bool Result = ParseBody(CurRec);
3964bool TGParser::ParseDef() {
3965 SMLoc DefLoc = Lex.getLoc();
3972 SMLoc NameLoc = Lex.getCode() ==
tgtok::Id ? Lex.getLoc() : DefLoc;
3975 std::unique_ptr<Record> CurRec;
3976 const Init *
Name = ParseObjectName();
3981 CurRec = std::make_unique<Record>(Records.getNewAnonymousName(), DefLoc,
3984 CurRec = std::make_unique<Record>(Name, NameLoc, Records);
3987 if (ParseObjectBody(CurRec.get()))
3990 return addEntry(std::move(CurRec));
3997bool TGParser::ParseDefset() {
4002 Defset.Loc = Lex.getLoc();
4003 const RecTy *
Type = ParseType();
4011 return TokError(
"expected identifier");
4012 const StringInit *DeclName =
StringInit::get(Records, Lex.getCurStrVal());
4013 if (Records.getGlobal(DeclName->
getValue()))
4014 return TokError(
"def or global variable of this name already exists");
4020 SMLoc BraceLoc = Lex.getLoc();
4023 Defsets.push_back(&Defset);
4024 bool Err = ParseObjectList();
4030 TokError(
"expected '}' at end of defset");
4031 return Error(BraceLoc,
"to match this '{'");
4034 Records.addExtraGlobal(DeclName->
getValue(),
4043bool TGParser::ParseDeftype() {
4048 return TokError(
"expected identifier");
4050 const std::string
TypeName = Lex.getCurStrVal();
4051 if (TypeAliases.count(TypeName) || Records.getClass(TypeName))
4052 return TokError(
"type of this name '" + TypeName +
"' already exists");
4058 SMLoc Loc = Lex.getLoc();
4059 const RecTy *
Type = ParseType();
4064 return Error(Loc,
"cannot define type alias for class type '" +
4065 Type->getAsString() +
"'");
4079bool TGParser::ParseDefvar(
Record *CurRec) {
4084 return TokError(
"expected identifier");
4085 const StringInit *DeclName =
StringInit::get(Records, Lex.getCurStrVal());
4086 if (CurScope->varAlreadyDefined(DeclName->
getValue()))
4087 return TokError(
"local variable of this name already exists");
4091 return TokError(
"field of this name already exists");
4095 if (CurScope->isOutermost() && Records.getGlobal(DeclName->
getValue()))
4096 return TokError(
"def or global variable of this name already exists");
4102 const Init *
Value = ParseValue(CurRec);
4109 if (!CurScope->isOutermost())
4123bool TGParser::ParseForeach() {
4124 SMLoc Loc = Lex.getLoc();
4130 const Init *ListValue =
nullptr;
4131 const VarInit *IterName = ParseForeachDeclaration(ListValue);
4133 return TokError(
"expected declaration in for");
4139 auto TheLoop = std::make_unique<ForeachLoop>(Loc, IterName, ListValue);
4141 TGVarScope *ForeachScope =
PushScope(TheLoop.get());
4142 Loops.push_back(std::move(TheLoop));
4149 SMLoc BraceLoc = Lex.getLoc();
4154 if (ParseObjectList())
4158 TokError(
"expected '}' at end of foreach command");
4159 return Error(BraceLoc,
"to match this '{'");
4166 std::unique_ptr<ForeachLoop>
Loop = std::move(Loops.back());
4169 return addEntry(std::move(
Loop));
4177bool TGParser::ParseIf() {
4178 SMLoc Loc = Lex.getLoc();
4184 const Init *Condition = ParseValue(
nullptr);
4198 const ListInit *SingletonList =
4204 const Init *ThenClauseList =
4208 Loops.push_back(std::make_unique<ForeachLoop>(Loc,
nullptr, ThenClauseList));
4210 if (ParseIfBody(
"then"))
4213 std::unique_ptr<ForeachLoop>
Loop = std::move(Loops.back());
4216 if (addEntry(std::move(
Loop)))
4226 const Init *ElseClauseList =
4231 std::make_unique<ForeachLoop>(Loc,
nullptr, ElseClauseList));
4233 if (ParseIfBody(
"else"))
4236 Loop = std::move(Loops.back());
4239 if (addEntry(std::move(
Loop)))
4251bool TGParser::ParseIfBody(
StringRef Kind) {
4260 SMLoc BraceLoc = Lex.getLoc();
4265 if (ParseObjectList())
4269 TokError(
"expected '}' at end of '" + Kind +
"' clause");
4270 return Error(BraceLoc,
"to match this '{'");
4281bool TGParser::ParseAssert(
Record *CurRec) {
4285 SMLoc ConditionLoc = Lex.getLoc();
4286 const Init *Condition = ParseValue(CurRec);
4291 TokError(
"expected ',' in assert statement");
4295 const Init *Message = ParseValue(CurRec);
4303 CurRec->
addAssertion(ConditionLoc, Condition, Message);
4305 addEntry(std::make_unique<Record::AssertionInfo>(ConditionLoc, Condition,
4314bool TGParser::ParseClass() {
4319 return TokError(
"expected class name after 'class' keyword");
4321 const std::string &
Name = Lex.getCurStrVal();
4322 Record *CurRec =
const_cast<Record *
>(Records.getClass(Name));
4329 "' already defined");
4334 auto NewRec = std::make_unique<Record>(Lex.getCurStrVal(), Lex.getLoc(),
4336 CurRec = NewRec.get();
4337 Records.addClass(std::move(NewRec));
4340 if (TypeAliases.count(Name))
4341 return TokError(
"there is already a defined type alias '" + Name +
"'");
4346 TGVarScope *ClassScope =
PushScope(CurRec);
4349 if (ParseTemplateArgList(CurRec))
4352 if (ParseObjectBody(CurRec))
4355 if (!NoWarnOnUnusedTemplateArgs)
4371 TokError(
"expected identifier in let definition");
4376 auto [
Mode, NameLoc, NameStr] = ParseLetModeAndName();
4380 SmallVector<unsigned, 16>
Bits;
4381 if (ParseOptionalRangeList(Bits)) {
4385 std::reverse(
Bits.begin(),
Bits.end());
4388 TokError(
"expected '=' in let expression");
4393 const Init *Val = ParseValue(
nullptr);
4400 Result.emplace_back(Name, Bits, Val, NameLoc,
Mode);
4410bool TGParser::ParseTopLevelLet() {
4416 ParseLetList(LetInfo);
4417 if (LetInfo.
empty())
4419 LetStack.push_back(std::move(LetInfo));
4422 return TokError(
"expected 'in' at end of top-level 'let'");
4430 SMLoc BraceLoc = Lex.getLoc();
4438 if (ParseObjectList())
4442 TokError(
"expected '}' at end of top level let command");
4443 return Error(BraceLoc,
"to match this '{'");
4450 LetStack.pop_back();
4467bool TGParser::ParseMultiClass() {
4472 return TokError(
"expected identifier after multiclass for name");
4473 std::string
Name = Lex.getCurStrVal();
4475 auto Result = MultiClasses.try_emplace(
4476 Name, std::make_unique<MultiClass>(Name, Lex.getLoc(), Records));
4479 return TokError(
"multiclass '" + Name +
"' already defined");
4481 CurMultiClass =
Result.first->second.get();
4485 TGVarScope *MulticlassScope =
PushScope(CurMultiClass);
4489 if (ParseTemplateArgList(
nullptr))
4492 bool inherits =
false;
4499 MultiClassReference ParentMultiClass = ParseMultiClassReference();
4502 if (!ParentMultiClass.
MC)
4506 if (AddParentMultiClass(ParentMultiClass))
4511 ParentMultiClass = ParseMultiClassReference();
4517 return TokError(
"expected '{' in multiclass definition");
4519 return TokError(
"expected ';' in multiclass definition");
4522 return TokError(
"multiclass must contain at least one def");
4525 switch (Lex.getCode()) {
4527 return TokError(
"expected 'assert', 'def', 'defm', 'defvar', 'dump', "
4528 "'foreach', 'if', or 'let' in multiclass body");
4546 SMLoc SemiLoc = Lex.getLoc();
4548 PrintError(SemiLoc,
"A multiclass body should not end with a semicolon");
4549 PrintNote(
"Semicolon ignored; remove to eliminate this error");
4553 if (!NoWarnOnUnusedTemplateArgs)
4554 CurMultiClass->Rec.checkUnusedTemplateArgs();
4557 CurMultiClass =
nullptr;
4565bool TGParser::ParseDefm() {
4569 const Init *DefmName = ParseObjectName();
4573 DefmName = Records.getNewAnonymousName();
4582 return TokError(
"expected ':' after defm identifier");
4585 std::vector<RecordsEntry> NewEntries;
4588 bool InheritFromClass =
false;
4593 SMLoc ParentClassLoc = Lex.getLoc();
4594 ClassReference
Ref = ParseClassReference(
nullptr,
true);
4604 MultiClass *MC = MultiClasses[
Ref.Rec->getName().str()].get();
4605 assert(MC &&
"Didn't lookup multiclass correctly?");
4608 if (resolveArgumentsOfMultiClass(Substs, MC,
Ref.TemplateArgs, DefmName,
4612 if (resolve(MC->
Entries, Substs, !CurMultiClass && Loops.empty(),
4613 &NewEntries, &ParentClassLoc))
4620 return TokError(
"expected identifier");
4622 ParentClassLoc = Lex.getLoc();
4626 InheritFromClass = (Records.getClass(Lex.getCurStrVal()) !=
nullptr);
4628 if (InheritFromClass)
4631 Ref = ParseClassReference(
nullptr,
true);
4634 if (InheritFromClass) {
4637 ClassReference ParentClass = ParseClassReference(
nullptr,
false);
4640 if (!ParentClass.
Rec)
4645 for (
auto &
E : NewEntries) {
4647 if (AddParentClass(
E, ParentClass))
4653 ParentClass = ParseClassReference(
nullptr,
false);
4657 for (
auto &
E : NewEntries) {
4658 if (ApplyLetStack(
E))
4661 addEntry(std::move(
E));
4665 return TokError(
"expected ';' at end of defm");
4682bool TGParser::ParseObject() {
4683 switch (Lex.getCode()) {
4686 "Expected assert, class, def, defm, defset, dump, foreach, if, or let");
4688 return ParseAssert();
4694 return ParseDeftype();
4696 return ParseDefvar();
4700 return ParseForeach();
4704 return ParseTopLevelLet();
4707 return TokError(
"defset is not allowed inside multiclass");
4708 return ParseDefset();
4711 return TokError(
"class is not allowed inside multiclass");
4713 return TokError(
"class is not allowed inside foreach loop");
4714 return ParseClass();
4717 return TokError(
"multiclass is not allowed inside foreach loop");
4718 return ParseMultiClass();
4724bool TGParser::ParseObjectList() {
4735 if (ParseObjectList())
4746 return TokError(
"Unexpected token at top level");
4753bool TGParser::CheckTemplateArgValues(
4757 "expected as many values as locations");
4761 bool HasError =
false;
4764 ? &TArgs[
Value->getIndex()]
4769 auto *CastValue = ArgValue->
getCastTo(ArgType);
4773 "result of template arg value cast has wrong type");
4777 Loc,
"Value specified for template argument '" +
4779 ArgValue->getType()->
getAsString() +
"; expected type " +
4788#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4797 errs() <<
"foreach " <<
IterVar->getAsString() <<
" = "
4798 <<
ListValue->getAsString() <<
" in {\n";
4807 errs() <<
"Record:\n";
4810 errs() <<
"Defs:\n";
4816bool TGParser::ParseDump(
Record *CurRec) {
4822 const Init *Message = ParseValue(CurRec);
4842 addEntry(std::make_unique<Record::DumpInfo>(
Loc, ResolvedMessage));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
uint64_t IntrinsicInst * II
OptimizedStructLayoutField Field
PowerPC Reduce CR logical Operation
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
Provides some synthesis utilities to produce sequences of values.
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
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)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
bool empty() const
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)
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
static const ListInit * get(ArrayRef< const Init * > Range, const RecTy *EltTy)
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.
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>.
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.
bool setValue(const Init *V)
Set the value of the field from an Init.
SMLoc getLoc() const
Get the source location of the point where the field was defined.
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.
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()
bool addTemplateArg(const RecordVal &Arg)
Add a template argument.
std::string getNameInitAsString() const
void appendValueReferenceLocs(const Record &From, const Init *Name) const
Add the references to the value named Name in From.
RecordKeeper & getRecords() const
const RecordVal * getValue(const Init *Name) const
Return the field with the given name, or null if there is none.
const RecordVal * getTemplateArg(const Init *Name) const
Return the template argument with the given name, or null if there is none.
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
ArrayRef< RecordVal > getTemplateArgs() const
Return the template arguments of this class or multiclass.
void appendDumps(const Record *Rec)
bool isSubClassOf(const Record *R) const
ArrayRef< RecordVal > getValues() const
Return the fields of this record.
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...
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 reserve(size_type N)
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)
Represent a constant reference to a string, i.e.
tgtok::TokKind getCode() const
void PopScope(TGVarScope *ExpectedStackTop)
bool Error(SMLoc L, const Twine &Msg) const
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...
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)
const Init * getNameInit() const
#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.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
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.
RelativeUniformCounterPtr Values
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI void PrintError(const Twine &Msg)
std::string utostr(uint64_t X, bool isNeg=false)
LetMode
Specifies how a 'let' assignment interacts with the existing field value.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI bool CheckAssert(SMLoc Loc, const Init *Condition, const Init *Message)
auto dyn_cast_or_null(const Y &Val)
auto reverse(ContainerTy &&C)
LLVM_ABI void PrintNote(const Twine &Msg)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
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.
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void dumpMessage(SMLoc Loc, const Init *Message)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
const RecTy * resolveTypes(const RecTy *T1, const RecTy *T2)
Find a common type that T1 and T2 convert to.
@ End
Run the machine verifier once, at the end of the pipeline.
Implement std::hash so that hash_code can be used in STL containers.
SmallVector< const ArgumentInit *, 4 > TemplateArgs
ForeachLoop - Record the iteration state associated with a for loop.
std::vector< RecordsEntry > Entries
Parsed let mode keyword and field name (e.g.
SmallVector< const ArgumentInit *, 4 > TemplateArgs
MultiClassReference()=default
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