19#include "llvm/Config/llvm-config.h"
66#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
68 errs() <<
"Multiclass:\n";
72 errs() <<
"Template args:\n";
80 for (
unsigned i = 0, e = BV->getNumBits(); i != e; ++i) {
81 const Init *Bit = BV->getBit(i);
82 bool IsReference =
false;
85 if (R.getValue(VI->getName()))
91 if (!(IsReference || Bit->isConcrete()))
98 for (
const RecordVal &RV : R.getValues()) {
103 if (RV.isNonconcreteOK())
106 if (
const Init *V = RV.getValue()) {
110 RV.getNameInitAsString() +
"' in '" +
111 R.getNameInitAsString() +
112 "' could not be fully resolved: " +
113 RV.getValue()->getAsString());
129 NewName = BinOp->Fold(&CurRec);
149 bool TrackReferenceLocs)
const {
151 auto It = Vars.find(Name->getValue());
152 if (It != Vars.end())
155 auto FindValueInArgs = [&](
Record *Rec,
162 assert(RV &&
"Template arg doesn't exist??");
164 if (TrackReferenceLocs)
168 return Name->getValue() ==
"NAME"
182 if (TrackReferenceLocs)
183 RV->addReferenceLoc(NameLoc);
188 if (CurRec->isClass())
189 if (
auto *V = FindValueInArgs(CurRec, Name))
196 if (CurLoop->IterVar) {
197 const VarInit *IterVar = CurLoop->IterVar;
206 if (
auto *V = FindValueInArgs(&CurMultiClass->Rec, Name))
214 return Parent->getVar(Records, ParsingMultiClass, Name, NameLoc,
222 CurRec = &CurMultiClass->
Rec;
227 return Error(
Loc,
"New definition of '" + RV.
getName() +
"' of type '" +
229 "' is incompatible with " +
230 "previous definition of type '" +
231 ERV->getType()->getAsString() +
"'");
242 bool AllowSelfAssignment,
bool OverrideDefLoc,
248 CurRec = &CurMultiClass->Rec;
250 RecordVal *RV = CurRec->
getValue(ValName);
259 if (!BitList.
empty())
260 return Error(Loc,
"Cannot use append/prepend with bit range");
262 const Init *CurrentValue = RV->
getValue();
263 const RecTy *FieldType = RV->
getType();
269 const Init *
LHS = IsAppendMode ? CurrentValue :
V;
270 const Init *
RHS = IsAppendMode ?
V : CurrentValue;
280 return Error(Loc, Twine(
"Cannot ") +
281 (IsAppendMode ?
"append to" :
"prepend to") +
283 "' of type '" + FieldType->getAsString() +
284 "' (expected list, string, code, or dag)");
294 if (
VI->getNameInit() == ValName && !AllowSelfAssignment)
295 return Error(Loc,
"Recursion / self-assignment forbidden");
299 if (!BitList.
empty()) {
303 "' is not a bits type");
308 return Error(Loc,
"Initializer is not compatible with bit range");
313 for (
unsigned i = 0, e = BitList.
size(); i != e; ++i) {
314 unsigned Bit = BitList[i];
316 return Error(Loc,
"Cannot set bit #" + Twine(Bit) +
" of value '" +
322 for (
unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i)
324 NewBits[i] = CurVal->getBit(i);
330 std::string InitType;
332 InitType = (Twine(
"' of type bit initializer with length ") +
333 Twine(BI->getNumBits()))
337 (Twine(
"' of type '") + TI->getType()->getAsString() +
"'").str();
341 "' is incompatible with value '" +
V->getAsString() +
351 MapResolver
R(CurRec);
356 if (!
Field.isTemplateArg())
360 if (resolveArgumentsOfClass(R, SC, SubClass.
TemplateArgs,
384 "Already subclass of '" + SC->
getName() +
"'!\n");
391 return AddSubClass(
Entry.Rec.get(), SubClass);
396 for (
auto &
E :
Entry.Loop->Entries) {
397 if (AddSubClass(
E, SubClass))
407bool TGParser::AddSubMultiClass(
MultiClass *CurMC,
412 if (resolveArgumentsOfMultiClass(
425 assert((!!
E.Rec + !!
E.Loop + !!
E.Assertion + !!
E.Dump) == 1 &&
426 "RecordsEntry has invalid number of items");
429 if (!Loops.empty()) {
430 Loops.back()->Entries.push_back(std::move(
E));
437 return resolve(*
E.Loop, Stack, CurMultiClass ==
nullptr,
438 CurMultiClass ? &CurMultiClass->Entries :
nullptr);
443 CurMultiClass->Entries.push_back(std::move(
E));
449 CheckAssert(
E.Assertion->Loc,
E.Assertion->Condition,
E.Assertion->Message);
459 return addDefOne(std::move(
E.Rec));
467bool TGParser::resolve(
const ForeachLoop &
Loop, SubstStack &Substs,
bool Final,
468 std::vector<RecordsEntry> *Dest,
SMLoc *
Loc) {
471 for (
const auto &S : Substs)
472 R.set(S.first, S.second);
483 const Init *OldLHS = TI->getLHS();
487 PrintError(Loop.
Loc, Twine(
"unable to resolve if condition '") +
489 "' at end of containing scope");
492 const Init *MHS = TI->getMHS();
493 const Init *
RHS = TI->getRHS();
503 return resolve(Loop.
Entries, Substs, Final, &Dest->back().Loop->Entries,
508 List->getAsString() +
"', expected a list");
513 for (
auto *Elt : *LI) {
530bool TGParser::resolve(
const std::vector<RecordsEntry> &Source,
531 SubstStack &Substs,
bool Final,
532 std::vector<RecordsEntry> *Dest,
SMLoc *
Loc) {
534 for (
auto &
E : Source) {
536 Error = resolve(*
E.Loop, Substs, Final, Dest);
538 }
else if (
E.Assertion) {
540 for (
const auto &S : Substs)
541 R.set(S.first, S.second);
542 const Init *Condition =
E.Assertion->Condition->resolveReferences(R);
543 const Init *Message =
E.Assertion->Message->resolveReferences(R);
546 Dest->push_back(std::make_unique<Record::AssertionInfo>(
547 E.Assertion->Loc, Condition, Message));
553 for (
const auto &S : Substs)
554 R.set(S.first, S.second);
559 std::make_unique<Record::DumpInfo>(
E.Dump->Loc, Message));
564 auto Rec = std::make_unique<Record>(*
E.Rec);
566 Rec->appendLoc(*Loc);
568 MapResolver
R(Rec.get());
569 for (
const auto &S : Substs)
570 R.set(S.first, S.second);
571 Rec->resolveReferences(R);
574 Dest->push_back(std::move(Rec));
576 Error = addDefOne(std::move(Rec));
585bool TGParser::addDefOne(std::unique_ptr<Record> Rec) {
586 const Init *NewName =
nullptr;
587 if (
const Record *Prev = Records.getDef(Rec->getNameInitAsString())) {
588 if (!Rec->isAnonymous()) {
590 "def already exists: " + Rec->getNameInitAsString());
591 PrintNote(Prev->getLoc(),
"location of previous definition");
594 NewName = Records.getNewAnonymousName();
597 Rec->resolveReferences(NewName);
601 PrintError(Rec->getLoc(), Twine(
"record name '") +
602 Rec->getNameInit()->getAsString() +
603 "' could not be fully resolved");
608 Rec->checkRecordAssertions();
611 Rec->emitRecordDumps();
614 assert(Rec->getTemplateArgs().empty() &&
"How'd this get template args?");
616 for (DefsetRecord *Defset : Defsets) {
617 DefInit *
I = Rec->getDefInit();
618 if (!
I->getType()->typeIsA(
Defset->EltTy)) {
619 PrintError(Rec->getLoc(), Twine(
"adding record of incompatible type '") +
620 I->getType()->getAsString() +
628 Records.addDef(std::move(Rec));
632bool TGParser::resolveArguments(
const Record *Rec,
634 SMLoc Loc, ArgValueHandler ArgValueHandler) {
637 "Too many template arguments allowed");
641 for (
auto *Arg : ArgValues) {
642 const Init *ArgName =
nullptr;
643 const Init *ArgValue = Arg->getValue();
644 if (Arg->isPositional())
645 ArgName = ArgNames[Arg->getIndex()];
647 ArgName = Arg->getName();
651 return Error(Loc,
"We can only specify the template argument '" +
654 ArgValueHandler(ArgName, ArgValue);
659 for (
auto *UnsolvedArgName : UnsolvedArgNames) {
662 std::string
Name = UnsolvedArgName->getAsUnquotedString();
663 Error(Loc,
"value not specified for template argument '" + Name +
"'");
668 ArgValueHandler(UnsolvedArgName,
Default);
679 return resolveArguments(
681 [&](
const Init *Name,
const Init *
Value) {
R.set(Name,
Value); });
686bool TGParser::resolveArgumentsOfMultiClass(
691 return resolveArguments(&MC->
Rec, ArgValues, Loc,
692 [&](
const Init *Name,
const Init *
Value) {
693 Substs.emplace_back(Name, Value);
702 if (Lex.getCode() == K) {
716 switch (Lex.getCode()) {
730 CurRec = &CurMultiClass->Rec;
739 HasReferenceResolver
R(NameStr);
740 Name->resolveReferences(R);
754const Record *TGParser::ParseClassID() {
756 TokError(
"expected name for ClassID");
760 const Record *
Result = Records.getClass(Lex.getCurStrVal());
762 std::string Msg(
"Couldn't find class '" + Lex.getCurStrVal() +
"'");
763 if (MultiClasses[Lex.getCurStrVal()].get())
764 TokError(Msg +
". Use 'defm' if you meant to use multiclass '" +
765 Lex.getCurStrVal() +
"'");
768 }
else if (TrackReferenceLocs) {
769 Result->appendReferenceLoc(Lex.getLocRange());
783 TokError(
"expected name for MultiClassID");
789 TokError(
"Couldn't find multiclass '" + Lex.getCurStrVal() +
"'");
804 Result.RefRange.Start = Lex.getLoc();
807 if (MultiClass *MC = ParseMultiClassID())
810 Result.Rec = ParseClassID();
817 Result.RefRange.End = Lex.getLoc();
822 if (ParseTemplateArgValueList(
Result.TemplateArgs, ArgLocs, CurRec,
828 if (CheckTemplateArgValues(
Result.TemplateArgs, ArgLocs,
Result.Rec)) {
833 Result.RefRange.End = Lex.getLoc();
845TGParser::ParseSubMultiClassReference(
MultiClass *CurMC) {
846 SubMultiClassReference
Result;
847 Result.RefRange.Start = Lex.getLoc();
849 Result.MC = ParseMultiClassID();
855 Result.RefRange.End = Lex.getLoc();
860 if (ParseTemplateArgValueList(
Result.TemplateArgs, ArgLocs, &CurMC->
Rec,
866 if (CheckTemplateArgValues(
Result.TemplateArgs, ArgLocs, &
Result.MC->Rec)) {
871 Result.RefRange.End = Lex.getLoc();
887 auto LHSLoc = Lex.getLoc();
888 auto *CurVal = ParseValue(CurRec);
893 const TypedInit *
RHS =
nullptr;
894 switch (Lex.getCode()) {
898 auto RHSLoc = Lex.getLoc();
899 CurVal = ParseValue(CurRec);
905 "expected int...int, got " + Twine(
RHS->
getType()->getAsString()));
911 auto i = -Lex.getCurIntVal();
913 TokError(
"invalid range, cannot be negative");
930 "expected int...int, got " + Twine(
LHS->
getType()->getAsString()));
950const TypedInit *TGParser::ParseSliceElements(
Record *CurRec,
bool Single) {
951 const TypedInit *CurVal;
955 auto FlushElems = [&] {
956 if (!Elems.
empty()) {
963 auto LHSLoc = Lex.getLoc();
964 CurVal = ParseSliceElement(CurRec);
967 auto *CurValTy = CurVal->
getType();
972 "expected list<int>, got " + Twine(ListValTy->getAsString()));
982 "unhandled type " + Twine(CurValTy->getAsString()) +
" in range");
1009 const TypedInit *
Result =
nullptr;
1010 for (
auto *Slice : Slices) {
1026 const Init *CurVal = FirstItem;
1028 CurVal = ParseValue(
nullptr);
1032 return TokError(
"expected integer or bitrange");
1034 int64_t
Start =
II->getValue();
1038 return TokError(
"invalid range, cannot be negative");
1040 switch (Lex.getCode()) {
1049 const Init *I_End = ParseValue(
nullptr);
1052 TokError(
"expected integer value as end of range");
1056 End = II_End->getValue();
1060 End = -Lex.getCurIntVal();
1066 return TokError(
"invalid range, cannot be negative");
1084 if (ParseRangePiece(Result)) {
1090 if (ParseRangePiece(Result)) {
1100 SMLoc StartLoc = Lex.getLoc();
1105 ParseRangeList(Ranges);
1110 TokError(
"expected '}' at end of bit list");
1111 return Error(StartLoc,
"to match this '{'");
1127const RecTy *TGParser::ParseType() {
1128 switch (Lex.getCode()) {
1130 TokError(
"Unknown token when expecting a type");
1146 auto I = TypeAliases.find(Lex.getCurStrVal());
1147 if (
I != TypeAliases.end()) {
1151 if (
const Record *R = ParseClassID())
1158 TokError(
"expected '<' after bits type");
1162 TokError(
"expected integer in bits<n> type");
1165 uint64_t Val = Lex.getCurIntVal();
1167 TokError(
"expected '>' at end of bits<n> type");
1175 TokError(
"expected '<' after list type");
1179 const RecTy *SubType = ParseType();
1184 TokError(
"expected '>' at end of list<ty> type");
1195 if (
const Init *
I = CurScope->getVar(Records, CurMultiClass, Name, NameLoc,
1196 TrackReferenceLocs))
1199 if (
Mode == ParseNameMode)
1202 if (
const Init *
I = Records.getGlobal(
Name->getValue())) {
1204 if (TrackReferenceLocs) {
1206 Def->getDef()->appendReferenceLoc(NameLoc);
1213 if (CurRec && !CurRec->
isClass() && !CurMultiClass &&
1217 Error(NameLoc.
Start,
"Variable not defined: '" +
Name->getValue() +
"'");
1225const Init *TGParser::ParseOperation(
Record *CurRec,
const RecTy *ItemType) {
1226 switch (Lex.getCode()) {
1245 const RecTy *
Type =
nullptr;
1247 switch (Lex.getCode()) {
1254 Type = ParseOperatorType();
1257 TokError(
"did not get type for unary operator");
1316 Type = ParseOperatorType();
1319 TokError(
"did not get type for unary operator");
1324 TokError(
"type for !getdagop must be a record type");
1344 TokError(
"expected '(' after unary operator");
1348 const Init *
LHS = ParseValue(CurRec);
1357 if (!LHSl && !LHSs && !LHSd && !LHSt) {
1359 "expected string, list, or dag type argument in unary operator");
1365 "expected string, list, or dag type argument in unary operator");
1375 if (!LHSl && !LHSt) {
1376 TokError(
"expected list type argument in unary operator");
1381 TokError(
"expected list type argument in unary operator");
1386 if (LHSl && LHSl->empty()) {
1387 TokError(
"empty list argument in unary operator");
1390 bool UseElementType =
1393 const Init *Item = LHSl->getElement(0);
1396 TokError(
"untyped list element in unary operator");
1399 Type = UseElementType ? Itemt->getType()
1402 assert(LHSt &&
"expected list type argument in unary operator");
1404 Type = UseElementType ? LType->getElementType() : LType;
1422 TokError(
"expected ')' in unary operator");
1432 const RecTy *
Type = ParseOperatorType();
1437 TokError(
"expected '(' after type of !isa");
1441 const Init *
LHS = ParseValue(CurRec);
1457 const RecTy *
Type = ParseOperatorType();
1462 TokError(
"expected '(' after type of !exists");
1466 SMLoc ExprLoc = Lex.getLoc();
1467 const Init *Expr = ParseValue(CurRec);
1473 Error(ExprLoc,
"expected string type argument in !exists operator");
1480 "expected string type argument in !exists operator, please "
1481 "use !isa instead");
1487 Error(ExprLoc,
"expected string type argument in !exists operator");
1492 TokError(
"expected ')' in !exists");
1503 const RecTy *
Type = ParseOperatorType();
1508 TokError(
"expected '(' after type of !instances");
1515 SMLoc RegexLoc = Lex.getLoc();
1516 Regex = ParseValue(CurRec);
1520 Error(RegexLoc,
"expected string type argument in !instances operator");
1526 Error(RegexLoc,
"expected string type argument in !instances operator");
1535 TokError(
"expected ')' in !instances");
1570 SMLoc OpLoc = Lex.getLoc();
1660 const RecTy *
Type =
nullptr;
1661 const RecTy *ArgType =
nullptr;
1675 Type = ParseOperatorType();
1677 TokError(
"did not get type for !getdagarg operator");
1732 if (
Type && ItemType && !
Type->typeIsConvertibleTo(ItemType)) {
1734 "', got '" +
Type->getAsString() +
"'");
1739 TokError(
"expected '(' after binary operator");
1748 SMLoc InitLoc = Lex.getLoc();
1749 InitList.
push_back(ParseValue(CurRec, ArgType));
1750 if (!InitList.
back())
1754 if (!InitListBack) {
1755 Error(OpLoc, Twine(
"expected value to be a typed value, got '" +
1756 InitList.
back()->getAsString() +
"'"));
1759 const RecTy *ListType = InitListBack->getType();
1768 Error(InitLoc, Twine(
"expected a list, got value of type '") +
1774 if (ItemType && InitList.
size() == 1) {
1777 Twine(
"expected output type to be a list, got type '") +
1782 Error(OpLoc, Twine(
"expected first arg type to be '") +
1784 "', got value of type '" +
1793 Error(InitLoc, Twine(
"expected second parameter to be an int, got "
1794 "value of type '") +
1802 Error(InitLoc, Twine(
"expected a list, got value of type '") +
1812 Error(InitLoc, Twine(
"expected bit, bits, int, string, or record; "
1813 "got value of type '") +
1826 Error(InitLoc, Twine(
"expected bit, bits, int, or string; "
1827 "got value of type '") +
1833 switch (InitList.
size()) {
1839 Twine(
"expected list of string, int, bits, or bit; "
1840 "got value of type '") +
1847 Error(InitLoc, Twine(
"expected second argument to be a string, "
1848 "got value of type '") +
1865 Error(InitLoc, Twine(
"expected value of type '") +
1908 TokError(
"expected ')' in operator");
1928 while (InitList.
size() > 2) {
1935 if (InitList.
size() == 2)
1939 Error(OpLoc,
"expected two operands to operator");
1946 return ParseOperationListComprehension(CurRec, ItemType);
1950 SMLoc OpLoc = Lex.getLoc();
1954 TokError(
"expected '(' after !range operator");
1959 bool FirstArgIsList =
false;
1961 if (
Args.size() >= 3) {
1962 TokError(
"expected at most three values of integer");
1966 SMLoc InitLoc = Lex.getLoc();
1967 Args.push_back(ParseValue(CurRec));
1973 Error(OpLoc, Twine(
"expected value to be a typed value, got '" +
1974 Args.back()->getAsString() +
"'"));
1978 const RecTy *ArgBackType = ArgBack->getType();
1979 if (!FirstArgIsList ||
Args.size() == 1) {
1981 FirstArgIsList =
true;
1985 if (
Args.size() != 1)
1986 Error(InitLoc, Twine(
"expected value of type 'int', got '" +
1989 Error(InitLoc, Twine(
"expected list or int, got value of type '") +
1996 Error(InitLoc, Twine(
"expected one list, got extra value of type '") +
2005 TokError(
"expected ')' in operator");
2009 const Init *
LHS, *MHS, *
RHS;
2010 auto ArgCount =
Args.size();
2013 const auto *Arg0Ty = Arg0->getType();
2014 if (ArgCount == 1) {
2034 if (ArgCount == 3) {
2055 const RecTy *
Type =
nullptr;
2085 TokError(
"expected '(' after ternary operator");
2089 const Init *
LHS = ParseValue(CurRec);
2094 TokError(
"expected ',' in ternary operator");
2098 SMLoc MHSLoc = Lex.getLoc();
2099 const Init *MHS = ParseValue(CurRec, ItemType);
2104 TokError(
"expected ',' in ternary operator");
2108 SMLoc RHSLoc = Lex.getLoc();
2109 const Init *
RHS = ParseValue(CurRec, ItemType);
2114 TokError(
"expected ')' in binary operator");
2124 Error(MHSLoc,
"could not determine type of the child list in !dag");
2128 Error(MHSLoc, Twine(
"expected list of children, got type '") +
2129 MHSt->getType()->getAsString() +
"'");
2135 Error(RHSLoc,
"could not determine type of the name list in !dag");
2139 Error(RHSLoc, Twine(
"expected list<string>, got type '") +
2140 RHSt->getType()->getAsString() +
"'");
2144 if (!MHSt && !RHSt) {
2146 "cannot have both unset children and unset names in !dag");
2152 const RecTy *MHSTy =
nullptr;
2153 const RecTy *RHSTy =
nullptr;
2156 MHSTy = MHSt->getType();
2163 RHSTy = RHSt->getType();
2175 if (!MHSTy || !RHSTy) {
2176 TokError(
"could not get type for !if");
2191 TokError(
"could not get type for !subst");
2194 Type = RHSt->getType();
2200 Error(MHSLoc, Twine(
"expected integer index or string name, got ") +
2201 (MHSt ? (
"type '" + MHSt->getType()->getAsString())
2211 Error(MHSLoc, Twine(
"expected integer index or string name, got ") +
2212 (MHSt ? (
"type '" + MHSt->getType()->getAsString())
2220 Error(RHSLoc, Twine(
"expected string or unset name, got type '") +
2221 RHSt->getType()->getAsString() +
"'");
2231 return ParseOperationSubstr(CurRec, ItemType);
2234 return ParseOperationFind(CurRec, ItemType);
2237 return ParseOperationCond(CurRec, ItemType);
2243 TokError(
"expected '(' after !foldl");
2247 const Init *StartUntyped = ParseValue(CurRec);
2253 TokError(Twine(
"could not get type of !foldl start: '") +
2259 TokError(
"expected ',' in !foldl");
2263 const Init *ListUntyped = ParseValue(CurRec);
2269 TokError(Twine(
"could not get type of !foldl list: '") +
2276 TokError(Twine(
"!foldl list must be a list, but is of type '") +
2277 List->getType()->getAsString());
2282 TokError(
"expected ',' in !foldl");
2287 TokError(
"third argument of !foldl must be an identifier");
2293 TokError((Twine(
"left !foldl variable '") +
A->getAsString() +
2294 "' already defined")
2300 TokError(
"expected ',' in !foldl");
2305 TokError(
"fourth argument of !foldl must be an identifier");
2311 TokError((Twine(
"right !foldl variable '") +
B->getAsString() +
2312 "' already defined")
2318 TokError(
"expected ',' in !foldl");
2325 std::unique_ptr<Record> ParseRecTmp;
2326 Record *ParseRec = CurRec;
2330 ParseRec = ParseRecTmp.get();
2333 TGVarScope *FoldScope =
PushScope(ParseRec);
2337 const Init *ExprUntyped = ParseValue(ParseRec);
2338 ParseRec->removeValue(
A);
2339 ParseRec->removeValue(
B);
2346 TokError(
"could not get type of !foldl expression");
2350 if (Expr->getType() !=
Start->getType()) {
2351 TokError(Twine(
"!foldl expression must be of same type as start (") +
2352 Start->getType()->getAsString() +
"), but is of type " +
2358 TokError(
"expected ')' in fold operator");
2373const RecTy *TGParser::ParseOperatorType() {
2374 const RecTy *
Type =
nullptr;
2377 TokError(
"expected type name for operator");
2382 TokError(
"the 'code' type is not allowed in bang operators; use 'string'");
2387 TokError(
"expected type name for operator");
2392 TokError(
"expected type name for operator");
2402const Init *TGParser::ParseOperationSubstr(
Record *CurRec,
2403 const RecTy *ItemType) {
2410 TokError(
"expected '(' after !substr operator");
2414 const Init *
LHS = ParseValue(CurRec);
2419 TokError(
"expected ',' in !substr operator");
2423 SMLoc MHSLoc = Lex.getLoc();
2424 const Init *MHS = ParseValue(CurRec);
2428 SMLoc RHSLoc = Lex.getLoc();
2431 RHSLoc = Lex.getLoc();
2432 RHS = ParseValue(CurRec);
2440 TokError(
"expected ')' in !substr operator");
2444 if (ItemType && !
Type->typeIsConvertibleTo(ItemType)) {
2445 Error(RHSLoc, Twine(
"expected value of type '") + ItemType->
getAsString() +
2446 "', got '" +
Type->getAsString() +
"'");
2451 TokError(
"could not determine type of the string in !substr");
2455 TokError(Twine(
"expected string, got type '") +
2456 LHSt->getType()->getAsString() +
"'");
2462 TokError(
"could not determine type of the start position in !substr");
2466 Error(MHSLoc, Twine(
"expected int, got type '") +
2467 MHSt->getType()->getAsString() +
"'");
2474 TokError(
"could not determine type of the length in !substr");
2478 TokError(Twine(
"expected int, got type '") +
2479 RHSt->getType()->getAsString() +
"'");
2490const Init *TGParser::ParseOperationFind(
Record *CurRec,
2491 const RecTy *ItemType) {
2498 TokError(
"expected '(' after !find operator");
2502 const Init *
LHS = ParseValue(CurRec);
2507 TokError(
"expected ',' in !find operator");
2511 SMLoc MHSLoc = Lex.getLoc();
2512 const Init *MHS = ParseValue(CurRec);
2516 SMLoc RHSLoc = Lex.getLoc();
2519 RHSLoc = Lex.getLoc();
2520 RHS = ParseValue(CurRec);
2528 TokError(
"expected ')' in !find operator");
2532 if (ItemType && !
Type->typeIsConvertibleTo(ItemType)) {
2533 Error(RHSLoc, Twine(
"expected value of type '") + ItemType->
getAsString() +
2534 "', got '" +
Type->getAsString() +
"'");
2539 TokError(
"could not determine type of the source string in !find");
2543 TokError(Twine(
"expected string, got type '") +
2544 LHSt->getType()->getAsString() +
"'");
2550 TokError(
"could not determine type of the target string in !find");
2554 Error(MHSLoc, Twine(
"expected string, got type '") +
2555 MHSt->getType()->getAsString() +
"'");
2562 TokError(
"could not determine type of the start position in !find");
2566 TokError(Twine(
"expected int, got type '") +
2567 RHSt->getType()->getAsString() +
"'");
2580const Init *TGParser::ParseOperationListComprehension(
Record *CurRec,
2581 const RecTy *ItemType) {
2582 SMLoc OpLoc = Lex.getLoc();
2586 TokError(
"expected '(' after !foreach/!filter");
2591 TokError(
"first argument of !foreach/!filter must be an identifier");
2599 TokError((Twine(
"iteration variable '") +
LHS->getAsString() +
2600 "' is already defined")
2606 TokError(
"expected ',' in !foreach/!filter");
2610 const Init *MHS = ParseValue(CurRec);
2615 TokError(
"expected ',' in !foreach/!filter");
2621 TokError(
"could not get type of !foreach/!filter list or dag");
2625 const RecTy *InEltType =
nullptr;
2626 const RecTy *ExprEltType =
nullptr;
2630 InEltType = InListTy->getElementType();
2635 ExprEltType = OutListTy->getElementType();
2641 ExprEltType =
nullptr;
2647 Error(OpLoc,
"expected value of type '" +
2649 "', but got list type");
2656 TokError(
"!filter must have a list argument");
2659 TokError(
"!sort must have a list argument");
2666 InEltType = InDagTy;
2669 "', but got dag type");
2676 TokError(
"!foreach must have a list or dag argument");
2679 TokError(
"!filter must have a list argument");
2682 TokError(
"!sort must have a list argument");
2691 std::unique_ptr<Record> ParseRecTmp;
2692 Record *ParseRec = CurRec;
2696 ParseRec = ParseRecTmp.get();
2698 TGVarScope *TempScope =
PushScope(ParseRec);
2700 const Init *
RHS = ParseValue(ParseRec, ExprEltType);
2701 ParseRec->removeValue(
LHS);
2707 TokError(
"expected ')' in !foreach/!filter");
2711 const RecTy *OutType;
2717 OutType = InEltType;
2721 TokError(
"could not get type of !foreach result expression");
2741const Init *TGParser::ParseOperationCond(
Record *CurRec,
2742 const RecTy *ItemType) {
2746 TokError(
"expected '(' after !cond operator");
2757 const Init *
V = ParseValue(CurRec);
2763 TokError(
"expected ':' following a condition in !cond operator");
2767 V = ParseValue(CurRec, ItemType);
2776 TokError(
"expected ',' or ')' following a value in !cond operator");
2781 if (Case.
size() < 1) {
2783 "there should be at least 1 'condition : value' in the !cond operator");
2788 const RecTy *
Type =
nullptr;
2789 for (
const Init *V : Val) {
2790 const RecTy *VTy =
nullptr;
2792 VTy = Vt->getType();
2798 if (
Type ==
nullptr) {
2805 TokError(Twine(
"inconsistent types '") +
Type->getAsString() +
2815 TokError(
"could not determine type for !cond from its arguments");
2848const Init *TGParser::ParseSimpleValue(
Record *CurRec,
const RecTy *ItemType,
2850 const Init *
R =
nullptr;
2855 return ParseOperation(CurRec, ItemType);
2859 TokError(
"Unknown or reserved token when parsing a value");
2875 auto BinaryVal = Lex.getCurBinaryIntVal();
2877 for (
unsigned i = 0, e = BinaryVal.second; i != e; ++i)
2884 std::string Val = Lex.getCurStrVal();
2889 Val += Lex.getCurStrVal();
2905 SMRange NameLoc = Lex.getLocRange();
2911 return ParseIDValue(CurRec, Name, NameLoc,
Mode);
2919 "Expected a class name, got '" +
Name->getValue() +
"'");
2926 if (ParseTemplateArgValueList(Args, ArgLocs, CurRec, Class))
2929 if (CheckTemplateArgValues(Args, ArgLocs, Class))
2932 if (resolveArguments(Class, Args, NameLoc.
Start))
2935 if (TrackReferenceLocs)
2936 Class->appendReferenceLoc(NameLoc);
2940 SMLoc BraceLoc = Lex.getLoc();
2945 ParseValueList(Vals, CurRec);
2950 TokError(
"expected '}' at end of bit list value");
2959 for (
unsigned i = 0, e = Vals.
size(); i != e; ++i) {
2965 for (
unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
2972 for (
unsigned i = 0, e = BitsRec->getNumBits(); i != e; ++i)
2981 Error(BraceLoc,
"Element #" + Twine(i) +
" (" + Vals[i]->getAsString() +
2982 ") is not convertable to a bit");
2987 std::reverse(NewBits.
begin(), NewBits.
end());
2994 const RecTy *DeducedEltTy =
nullptr;
2995 const ListRecTy *GivenListTy =
nullptr;
3000 TokError(Twine(
"Encountered a list when expecting a ") +
3004 GivenListTy = ListType;
3008 ParseValueList(Vals, CurRec,
3014 TokError(
"expected ']' at end of list value");
3018 const RecTy *GivenEltTy =
nullptr;
3021 GivenEltTy = ParseType();
3028 TokError(
"expected '>' at end of list element type");
3034 const RecTy *EltTy =
nullptr;
3035 for (
const Init *V : Vals) {
3041 TokError(
"Incompatible types in list elements");
3045 EltTy = TArg->getType();
3054 TokError(
"Incompatible types in list elements");
3071 TokError(Twine(
"Element type mismatch for list: element type '") +
3077 DeducedEltTy = EltTy;
3088 TokError(
"expected identifier or list of value types in dag init");
3092 const Init *
Operator = ParseValue(CurRec);
3097 const StringInit *OperatorName =
nullptr;
3100 TokError(
"expected variable name in dag operator");
3109 ParseDagArgList(DagArgs, CurRec);
3110 if (DagArgs.
empty())
3115 TokError(
"expected ')' in dag init");
3133const Init *TGParser::ParseValue(
Record *CurRec,
const RecTy *ItemType,
3135 SMLoc LHSLoc = Lex.getLoc();
3136 const Init *
Result = ParseSimpleValue(CurRec, ItemType,
Mode);
3142 switch (Lex.getCode()) {
3146 if (
Mode == ParseNameMode)
3150 SMLoc CurlyLoc = Lex.getLoc();
3152 SmallVector<unsigned, 16>
Ranges;
3153 ParseRangeList(Ranges);
3161 Error(CurlyLoc,
"Invalid bit range for value");
3167 TokError(
"expected '}' at end of bit range list");
3175 Error(LHSLoc,
"Invalid value, list expected");
3182 "' is invalid, list expected");
3187 const TypedInit *
RHS = ParseSliceElements(CurRec,
true);
3196 LHSTy->getElementType())
3204 TokError(
"expected ']' at end of list slice");
3211 TokError(
"expected field identifier after '.'");
3214 SMRange FieldNameLoc = Lex.getLocRange();
3215 const StringInit *FieldName =
3217 if (!
Result->getFieldType(FieldName)) {
3218 TokError(
"Cannot access field '" + Lex.getCurStrVal() +
"' of value '" +
3219 Result->getAsString() +
"'");
3224 if (TrackReferenceLocs) {
3226 const RecordVal *
V = DI->getDef()->getValue(FieldName);
3227 const_cast<RecordVal *
>(
V)->addReferenceLoc(FieldNameLoc);
3230 for (
const Record *R : RecTy->getClasses())
3231 if (
const auto *RV =
R->getValue(FieldName))
3232 const_cast<RecordVal *
>(RV)->addReferenceLoc(FieldNameLoc);
3243 SMLoc PasteLoc = Lex.getLoc();
3246 Error(PasteLoc,
"LHS of paste is not typed!");
3254 assert(
Mode == ParseValueMode &&
"encountered paste of lists in name");
3256 switch (Lex.getCode()) {
3263 const Init *RHSResult = ParseValue(CurRec, ItemType, ParseValueMode);
3280 Twine(
"can't cast '") +
LHS->getAsString() +
"' to string");
3286 const TypedInit *
RHS =
nullptr;
3289 switch (Lex.getCode()) {
3302 const Init *RHSResult = ParseValue(CurRec,
nullptr, ParseNameMode);
3307 Error(PasteLoc,
"RHS of paste is not typed!");
3317 Twine(
"can't cast '") +
RHS->getAsString() +
"' to string");
3338void TGParser::ParseDagArgList(
3351 const Init *Val = ParseValue(CurRec);
3358 const StringInit *
VarName =
nullptr;
3361 TokError(
"expected variable name in dag literal");
3369 Result.emplace_back(Val, VarName);
3384 Result.push_back(ParseValue(CurRec, ItemType));
3394 Result.push_back(ParseValue(CurRec, ItemType));
3410bool TGParser::ParseTemplateArgValueList(
3413 assert(
Result.empty() &&
"Result vector is not empty");
3419 bool HasNamedArg =
false;
3420 unsigned ArgIndex = 0;
3422 if (ArgIndex >= TArgs.
size()) {
3423 TokError(
"Too many template arguments: " +
utostr(ArgIndex + 1));
3430 const Init *
Value = ParseValue(
3432 HasNamedArg ?
nullptr : ArgsRec->
getValue(TArgs[ArgIndex])->
getType());
3439 return Error(ValueLoc,
3440 "The name of named argument should be a valid identifier");
3444 auto *NamedArg = ArgsRec->
getValue(QualifiedName);
3446 return Error(ValueLoc,
3447 "Argument " +
Name->getAsString() +
" doesn't exist");
3450 ValueLoc = Lex.getLoc();
3451 Value = ParseValue(CurRec, NamedArg->getType());
3454 return Error(ValueLoc,
3455 "The value of named argument should be initialized, "
3457 Value->getAsString() +
"'");
3464 return Error(ValueLoc,
3465 "Positional argument should be put before named argument");
3473 return TokError(
"Expected comma before next argument");
3488const Init *TGParser::ParseDeclaration(
Record *CurRec,
3489 bool ParsingTemplateArgs) {
3493 const RecTy *
Type = ParseType();
3498 TokError(
"Expected identifier in declaration");
3502 std::string Str = Lex.getCurStrVal();
3503 if (Str ==
"NAME") {
3504 TokError(
"'" + Str +
"' is a reserved variable name");
3508 if (!ParsingTemplateArgs && CurScope->varAlreadyDefined(Str)) {
3509 TokError(
"local variable of this name already exists");
3513 SMLoc IdLoc = Lex.getLoc();
3518 if (!ParsingTemplateArgs) {
3519 BadField = AddValue(CurRec, IdLoc,
3520 RecordVal(DeclName, IdLoc,
Type,
3523 }
else if (CurRec) {
3526 AddValue(CurRec, IdLoc,
3529 assert(CurMultiClass &&
"invalid context for template argument");
3532 AddValue(CurRec, IdLoc,
3540 SMLoc ValLoc = Lex.getLoc();
3541 const Init *Val = ParseValue(CurRec,
Type);
3543 SetValue(CurRec, ValLoc, DeclName, {}, Val,
3564TGParser::ParseForeachDeclaration(
const Init *&ForeachListValue) {
3566 TokError(
"Expected identifier in foreach declaration");
3575 TokError(
"Expected '=' in foreach declaration");
3579 const RecTy *IterType =
nullptr;
3580 SmallVector<unsigned, 16>
Ranges;
3582 switch (Lex.getCode()) {
3585 ParseRangeList(Ranges);
3587 TokError(
"expected '}' at end of bit range list");
3594 SMLoc ValueLoc = Lex.getLoc();
3595 const Init *
I = ParseValue(
nullptr);
3601 ForeachListValue =
I;
3607 if (ParseRangePiece(Ranges, TI))
3612 Error(ValueLoc,
"expected a list, got '" +
I->getAsString() +
"'");
3613 if (CurMultiClass) {
3614 PrintNote({},
"references to multiclass template arguments cannot be "
3615 "resolved at this time");
3622 assert(!IterType &&
"Type already initialized?");
3624 std::vector<Init *> Values;
3625 for (
unsigned R : Ranges)
3643bool TGParser::ParseTemplateArgList(
Record *CurRec) {
3647 Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->Rec;
3650 const Init *TemplArg = ParseDeclaration(CurRec,
true );
3658 SMLoc Loc = Lex.getLoc();
3659 TemplArg = ParseDeclaration(CurRec,
true );
3664 return Error(Loc,
"template argument with the same name has already been "
3671 return TokError(
"expected '>' at end of template argument list");
3688 SMLoc Loc = Lex.getLoc();
3690 std::string CurStr = Lex.getCurStrVal();
3692 LetMode Mode = llvm::StringSwitch<LetMode>(CurStr)
3702 LetModeAndName
Result = {
Mode, Lex.getLoc(), Lex.getCurStrVal()};
3720bool TGParser::ParseBodyItem(
Record *CurRec) {
3722 return ParseAssert(
nullptr, CurRec);
3725 return ParseDefvar(CurRec);
3728 return ParseDump(
nullptr, CurRec);
3731 if (!ParseDeclaration(CurRec,
false))
3735 return TokError(
"expected ';' after declaration");
3743 return TokError(
"expected field identifier after let");
3745 auto [
Mode, IdLoc, FieldNameStr] = ParseLetModeAndName();
3748 SmallVector<unsigned, 16> BitList;
3749 if (ParseOptionalRangeList(BitList))
3751 std::reverse(BitList.
begin(), BitList.
end());
3754 return TokError(
"expected '=' in let expression");
3758 return Error(IdLoc,
"Value '" + FieldName->
getValue() +
"' unknown!");
3767 const Init *Val = ParseValue(CurRec,
Type);
3772 return TokError(
"expected ';' after let expression");
3774 return SetValue(CurRec, IdLoc, FieldName, BitList, Val,
3785bool TGParser::ParseBody(
Record *CurRec) {
3791 return TokError(
"Expected '{' to start body or ';' for declaration only");
3794 if (ParseBodyItem(CurRec))
3801 SMLoc SemiLoc = Lex.getLoc();
3803 PrintError(SemiLoc,
"A class or def body should not end with a semicolon");
3804 PrintNote(
"Semicolon ignored; remove to eliminate this error");
3812bool TGParser::ApplyLetStack(
Record *CurRec) {
3813 for (SmallVectorImpl<LetRecord> &LetInfo : LetStack)
3814 for (LetRecord &LR : LetInfo)
3815 if (SetValue(CurRec, LR.Loc, LR.Name, LR.Bits, LR.Value,
3825 return ApplyLetStack(
Entry.Rec.get());
3828 if (
Entry.Assertion)
3835 for (
auto &
E :
Entry.Loop->Entries) {
3836 if (ApplyLetStack(
E))
3852bool TGParser::ParseObjectBody(
Record *CurRec) {
3854 TGVarScope *ObjectScope =
PushScope(CurRec);
3859 SubClassReference SubClass = ParseSubClassReference(CurRec,
false);
3866 if (AddSubClass(CurRec, SubClass))
3871 SubClass = ParseSubClassReference(CurRec,
false);
3875 if (ApplyLetStack(CurRec))
3878 bool Result = ParseBody(CurRec);
3888bool TGParser::ParseDef(
MultiClass *CurMultiClass) {
3889 SMLoc DefLoc = Lex.getLoc();
3896 SMLoc NameLoc = Lex.getCode() ==
tgtok::Id ? Lex.getLoc() : DefLoc;
3899 std::unique_ptr<Record> CurRec;
3900 const Init *
Name = ParseObjectName(CurMultiClass);
3905 CurRec = std::make_unique<Record>(Records.getNewAnonymousName(), DefLoc,
3908 CurRec = std::make_unique<Record>(Name, NameLoc, Records);
3911 if (ParseObjectBody(CurRec.get()))
3914 return addEntry(std::move(CurRec));
3921bool TGParser::ParseDefset() {
3926 Defset.Loc = Lex.getLoc();
3927 const RecTy *
Type = ParseType();
3935 return TokError(
"expected identifier");
3936 const StringInit *DeclName =
StringInit::get(Records, Lex.getCurStrVal());
3937 if (Records.getGlobal(DeclName->
getValue()))
3938 return TokError(
"def or global variable of this name already exists");
3944 SMLoc BraceLoc = Lex.getLoc();
3947 Defsets.push_back(&Defset);
3948 bool Err = ParseObjectList(
nullptr);
3954 TokError(
"expected '}' at end of defset");
3955 return Error(BraceLoc,
"to match this '{'");
3958 Records.addExtraGlobal(DeclName->
getValue(),
3967bool TGParser::ParseDeftype() {
3972 return TokError(
"expected identifier");
3974 const std::string
TypeName = Lex.getCurStrVal();
3975 if (TypeAliases.count(TypeName) || Records.getClass(TypeName))
3976 return TokError(
"type of this name '" + TypeName +
"' already exists");
3982 SMLoc Loc = Lex.getLoc();
3983 const RecTy *
Type = ParseType();
3988 return Error(Loc,
"cannot define type alias for class type '" +
3989 Type->getAsString() +
"'");
4003bool TGParser::ParseDefvar(
Record *CurRec) {
4008 return TokError(
"expected identifier");
4009 const StringInit *DeclName =
StringInit::get(Records, Lex.getCurStrVal());
4010 if (CurScope->varAlreadyDefined(DeclName->
getValue()))
4011 return TokError(
"local variable of this name already exists");
4016 if (V && !
V->isTemplateArg())
4017 return TokError(
"field of this name already exists");
4022 if (CurScope->isOutermost() && Records.getGlobal(DeclName->
getValue()))
4023 return TokError(
"def or global variable of this name already exists");
4029 const Init *
Value = ParseValue(CurRec);
4036 if (!CurScope->isOutermost())
4050bool TGParser::ParseForeach(
MultiClass *CurMultiClass) {
4051 SMLoc Loc = Lex.getLoc();
4057 const Init *ListValue =
nullptr;
4058 const VarInit *IterName = ParseForeachDeclaration(ListValue);
4060 return TokError(
"expected declaration in for");
4066 auto TheLoop = std::make_unique<ForeachLoop>(Loc, IterName, ListValue);
4068 TGVarScope *ForeachScope =
PushScope(TheLoop.get());
4069 Loops.push_back(std::move(TheLoop));
4073 if (ParseObject(CurMultiClass))
4076 SMLoc BraceLoc = Lex.getLoc();
4081 if (ParseObjectList(CurMultiClass))
4085 TokError(
"expected '}' at end of foreach command");
4086 return Error(BraceLoc,
"to match this '{'");
4093 std::unique_ptr<ForeachLoop> Loop = std::move(Loops.back());
4096 return addEntry(std::move(Loop));
4104bool TGParser::ParseIf(
MultiClass *CurMultiClass) {
4105 SMLoc Loc = Lex.getLoc();
4111 const Init *Condition = ParseValue(
nullptr);
4125 const ListInit *SingletonList =
4131 const Init *ThenClauseList =
4135 Loops.push_back(std::make_unique<ForeachLoop>(Loc,
nullptr, ThenClauseList));
4137 if (ParseIfBody(CurMultiClass,
"then"))
4140 std::unique_ptr<ForeachLoop> Loop = std::move(Loops.back());
4143 if (addEntry(std::move(Loop)))
4153 const Init *ElseClauseList =
4158 std::make_unique<ForeachLoop>(Loc,
nullptr, ElseClauseList));
4160 if (ParseIfBody(CurMultiClass,
"else"))
4163 Loop = std::move(Loops.back());
4166 if (addEntry(std::move(Loop)))
4184 if (ParseObject(CurMultiClass))
4187 SMLoc BraceLoc = Lex.getLoc();
4192 if (ParseObjectList(CurMultiClass))
4196 TokError(
"expected '}' at end of '" + Kind +
"' clause");
4197 return Error(BraceLoc,
"to match this '{'");
4212 SMLoc ConditionLoc = Lex.getLoc();
4213 const Init *Condition = ParseValue(CurRec);
4218 TokError(
"expected ',' in assert statement");
4222 const Init *Message = ParseValue(CurRec);
4230 CurRec->
addAssertion(ConditionLoc, Condition, Message);
4232 addEntry(std::make_unique<Record::AssertionInfo>(ConditionLoc, Condition,
4241bool TGParser::ParseClass() {
4246 return TokError(
"expected class name after 'class' keyword");
4248 const std::string &
Name = Lex.getCurStrVal();
4249 Record *CurRec =
const_cast<Record *
>(Records.getClass(Name));
4256 "' already defined");
4261 auto NewRec = std::make_unique<Record>(Lex.getCurStrVal(), Lex.getLoc(),
4263 CurRec = NewRec.get();
4264 Records.addClass(std::move(NewRec));
4267 if (TypeAliases.count(Name))
4268 return TokError(
"there is already a defined type alias '" + Name +
"'");
4273 TGVarScope *ClassScope =
PushScope(CurRec);
4276 if (ParseTemplateArgList(CurRec))
4279 if (ParseObjectBody(CurRec))
4282 if (!NoWarnOnUnusedTemplateArgs)
4298 TokError(
"expected identifier in let definition");
4303 auto [
Mode, NameLoc, NameStr] = ParseLetModeAndName();
4307 SmallVector<unsigned, 16>
Bits;
4308 if (ParseOptionalRangeList(Bits)) {
4312 std::reverse(
Bits.begin(),
Bits.end());
4315 TokError(
"expected '=' in let expression");
4320 const Init *Val = ParseValue(
nullptr);
4327 Result.emplace_back(Name, Bits, Val, NameLoc,
Mode);
4337bool TGParser::ParseTopLevelLet(
MultiClass *CurMultiClass) {
4343 ParseLetList(LetInfo);
4344 if (LetInfo.
empty())
4346 LetStack.push_back(std::move(LetInfo));
4349 return TokError(
"expected 'in' at end of top-level 'let'");
4354 if (ParseObject(CurMultiClass))
4357 SMLoc BraceLoc = Lex.getLoc();
4365 if (ParseObjectList(CurMultiClass))
4369 TokError(
"expected '}' at end of top level let command");
4370 return Error(BraceLoc,
"to match this '{'");
4377 LetStack.pop_back();
4394bool TGParser::ParseMultiClass() {
4399 return TokError(
"expected identifier after multiclass for name");
4400 std::string
Name = Lex.getCurStrVal();
4402 auto Result = MultiClasses.try_emplace(
4403 Name, std::make_unique<MultiClass>(Name, Lex.getLoc(), Records));
4406 return TokError(
"multiclass '" + Name +
"' already defined");
4408 CurMultiClass =
Result.first->second.get();
4412 TGVarScope *MulticlassScope =
PushScope(CurMultiClass);
4416 if (ParseTemplateArgList(
nullptr))
4419 bool inherits =
false;
4426 SubMultiClassReference SubMultiClass =
4427 ParseSubMultiClassReference(CurMultiClass);
4430 if (!SubMultiClass.
MC)
4434 if (AddSubMultiClass(CurMultiClass, SubMultiClass))
4439 SubMultiClass = ParseSubMultiClassReference(CurMultiClass);
4445 return TokError(
"expected '{' in multiclass definition");
4447 return TokError(
"expected ';' in multiclass definition");
4450 return TokError(
"multiclass must contain at least one def");
4453 switch (Lex.getCode()) {
4455 return TokError(
"expected 'assert', 'def', 'defm', 'defvar', 'dump', "
4456 "'foreach', 'if', or 'let' in multiclass body");
4466 if (ParseObject(CurMultiClass))
4474 SMLoc SemiLoc = Lex.getLoc();
4476 PrintError(SemiLoc,
"A multiclass body should not end with a semicolon");
4477 PrintNote(
"Semicolon ignored; remove to eliminate this error");
4481 if (!NoWarnOnUnusedTemplateArgs)
4482 CurMultiClass->Rec.checkUnusedTemplateArgs();
4485 CurMultiClass =
nullptr;
4493bool TGParser::ParseDefm(
MultiClass *CurMultiClass) {
4497 const Init *DefmName = ParseObjectName(CurMultiClass);
4501 DefmName = Records.getNewAnonymousName();
4510 return TokError(
"expected ':' after defm identifier");
4513 std::vector<RecordsEntry> NewEntries;
4516 bool InheritFromClass =
false;
4521 SMLoc SubClassLoc = Lex.getLoc();
4522 SubClassReference
Ref = ParseSubClassReference(
nullptr,
true);
4532 MultiClass *MC = MultiClasses[
Ref.Rec->getName().str()].get();
4533 assert(MC &&
"Didn't lookup multiclass correctly?");
4536 if (resolveArgumentsOfMultiClass(Substs, MC,
Ref.TemplateArgs, DefmName,
4540 if (resolve(MC->
Entries, Substs, !CurMultiClass && Loops.empty(),
4541 &NewEntries, &SubClassLoc))
4548 return TokError(
"expected identifier");
4550 SubClassLoc = Lex.getLoc();
4554 InheritFromClass = (Records.getClass(Lex.getCurStrVal()) !=
nullptr);
4556 if (InheritFromClass)
4559 Ref = ParseSubClassReference(
nullptr,
true);
4562 if (InheritFromClass) {
4565 SubClassReference SubClass = ParseSubClassReference(
nullptr,
false);
4573 for (
auto &
E : NewEntries) {
4575 if (AddSubClass(
E, SubClass))
4581 SubClass = ParseSubClassReference(
nullptr,
false);
4585 for (
auto &
E : NewEntries) {
4586 if (ApplyLetStack(
E))
4589 addEntry(std::move(
E));
4593 return TokError(
"expected ';' at end of defm");
4611 switch (Lex.getCode()) {
4614 "Expected assert, class, def, defm, defset, dump, foreach, if, or let");
4616 return ParseAssert(MC);
4618 return ParseDef(MC);
4620 return ParseDefm(MC);
4622 return ParseDeftype();
4624 return ParseDefvar();
4626 return ParseDump(MC);
4628 return ParseForeach(MC);
4632 return ParseTopLevelLet(MC);
4635 return TokError(
"defset is not allowed inside multiclass");
4636 return ParseDefset();
4639 return TokError(
"class is not allowed inside multiclass");
4641 return TokError(
"class is not allowed inside foreach loop");
4642 return ParseClass();
4645 return TokError(
"multiclass is not allowed inside foreach loop");
4646 return ParseMultiClass();
4652bool TGParser::ParseObjectList(
MultiClass *MC) {
4654 if (ParseObject(MC))
4663 if (ParseObjectList())
4671 return TokError(
"Unexpected token at top level");
4678bool TGParser::CheckTemplateArgValues(
4682 "expected as many values as locations");
4686 bool HasError =
false;
4688 const Init *ArgName =
nullptr;
4689 if (
Value->isPositional())
4690 ArgName = TArgs[
Value->getIndex()];
4691 if (
Value->isNamed())
4698 auto *CastValue = ArgValue->
getCastTo(ArgType);
4702 "result of template arg value cast has wrong type");
4706 Loc,
"Value specified for template argument '" +
4708 ArgValue->getType()->
getAsString() +
"; expected type " +
4717#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4726 errs() <<
"foreach " <<
IterVar->getAsString() <<
" = "
4727 <<
ListValue->getAsString() <<
" in {\n";
4736 errs() <<
"Record:\n";
4739 errs() <<
"Defs:\n";
4751 const Init *Message = ParseValue(CurRec);
4771 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")))
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.
void setUsed(bool Used)
Whether this value is used.
bool setValue(const Init *V)
Set the value of the field from an Init.
const Init * getValue() const
Get the value of the field as an Init.
StringRef getName() const
Get the name of the field as a StringRef.
void addReferenceLoc(SMRange Loc)
Add a reference to this record value.
const Init * getNameInit() const
Get the name of the field as an Init.
const RecTy * getType() const
Get the type of the field value as a RecTy.
const RecordRecTy * getType() const
void addDump(SMLoc Loc, const Init *Message)
void checkUnusedTemplateArgs()
std::string getNameInitAsString() const
RecordKeeper & getRecords() const
const RecordVal * getValue(const Init *Name) const
void addTemplateArg(const Init *Name)
bool isMultiClass() const
void addValue(const RecordVal &RV)
void addAssertion(SMLoc Loc, const Init *Condition, const Init *Message)
ArrayRef< std::pair< const Record *, SMRange > > getDirectSuperClasses() const
Return the direct superclasses of this record.
StringRef getName() const
bool isTemplateArg(const Init *Name) const
void appendDumps(const Record *Rec)
bool isSubClassOf(const Record *R) const
ArrayRef< RecordVal > getValues() const
SMLoc getFieldLoc(StringRef FieldName) const
Return the source location for the named field.
void resolveReferences(const Init *NewName=nullptr)
If there are any field references that refer to fields that have been filled in, we can propagate the...
ArrayRef< const Init * > getTemplateArgs() const
void updateClassLoc(SMLoc Loc)
void addDirectSuperClass(const Record *R, SMRange Range)
void appendAssertions(const Record *Rec)
const Init * getNameInit() const
void setFinal(bool Final)
Represents a location in source code.
Represents a range in source code.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
"foo" - Represent an initialization by a string value.
static const StringInit * get(RecordKeeper &RK, StringRef, StringFormat Fmt=SF_String)
StringRef getValue() const
static const StringRecTy * get(RecordKeeper &RK)
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.
FunctionAddr VTableAddr Value
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.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
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.
bool CheckAssert(SMLoc Loc, const Init *Condition, const Init *Message)
auto dyn_cast_or_null(const Y &Val)
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
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_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.
FunctionAddr VTableAddr Next
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.
void dumpMessage(SMLoc Loc, const Init *Message)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
const RecTy * resolveTypes(const RecTy *T1, const RecTy *T2)
Find a common type that T1 and T2 convert to.
@ Default
The result value is uniform if and only if all operands are uniform.
Implement std::hash so that hash_code can be used in STL containers.
ForeachLoop - Record the iteration state associated with a for loop.
std::vector< RecordsEntry > Entries
Parsed let mode keyword and field name (e.g.
std::vector< RecordsEntry > Entries
RecordsEntry - Holds exactly one of a Record, ForeachLoop, or AssertionInfo.
std::unique_ptr< ForeachLoop > Loop
std::unique_ptr< Record::AssertionInfo > Assertion
std::unique_ptr< Record::DumpInfo > Dump
std::unique_ptr< Record > Rec
SubClassReference()=default
SmallVector< const ArgumentInit *, 4 > TemplateArgs
SubMultiClassReference()=default
SmallVector< const ArgumentInit *, 4 > TemplateArgs