1226584Sdim//===- TGParser.cpp - Parser for TableGen Files ---------------------------===// 2226584Sdim// 3226584Sdim// The LLVM Compiler Infrastructure 4226584Sdim// 5226584Sdim// This file is distributed under the University of Illinois Open Source 6226584Sdim// License. See LICENSE.TXT for details. 7226584Sdim// 8226584Sdim//===----------------------------------------------------------------------===// 9226584Sdim// 10226584Sdim// Implement the Parser for TableGen. 11226584Sdim// 12226584Sdim//===----------------------------------------------------------------------===// 13226584Sdim 14226584Sdim#include "TGParser.h" 15288943Sdim#include "llvm/ADT/STLExtras.h" 16249423Sdim#include "llvm/ADT/SmallVector.h" 17249423Sdim#include "llvm/ADT/StringExtras.h" 18249423Sdim#include "llvm/Support/CommandLine.h" 19226584Sdim#include "llvm/TableGen/Record.h" 20226584Sdim#include <algorithm> 21226584Sdim#include <sstream> 22226584Sdimusing namespace llvm; 23226584Sdim 24226584Sdim//===----------------------------------------------------------------------===// 25226584Sdim// Support Code for the Semantic Actions. 26226584Sdim//===----------------------------------------------------------------------===// 27226584Sdim 28226584Sdimnamespace llvm { 29226584Sdimstruct SubClassReference { 30249423Sdim SMRange RefRange; 31226584Sdim Record *Rec; 32226584Sdim std::vector<Init*> TemplateArgs; 33276479Sdim SubClassReference() : Rec(nullptr) {} 34226584Sdim 35276479Sdim bool isInvalid() const { return Rec == nullptr; } 36226584Sdim}; 37226584Sdim 38226584Sdimstruct SubMultiClassReference { 39249423Sdim SMRange RefRange; 40226584Sdim MultiClass *MC; 41226584Sdim std::vector<Init*> TemplateArgs; 42276479Sdim SubMultiClassReference() : MC(nullptr) {} 43226584Sdim 44276479Sdim bool isInvalid() const { return MC == nullptr; } 45226584Sdim void dump() const; 46226584Sdim}; 47226584Sdim 48226584Sdimvoid SubMultiClassReference::dump() const { 49226584Sdim errs() << "Multiclass:\n"; 50226584Sdim 51226584Sdim MC->dump(); 52226584Sdim 53226584Sdim errs() << "Template args:\n"; 54288943Sdim for (Init *TA : TemplateArgs) 55288943Sdim TA->dump(); 56226584Sdim} 57226584Sdim 58226584Sdim} // end namespace llvm 59226584Sdim 60226584Sdimbool TGParser::AddValue(Record *CurRec, SMLoc Loc, const RecordVal &RV) { 61276479Sdim if (!CurRec) 62226584Sdim CurRec = &CurMultiClass->Rec; 63226584Sdim 64234353Sdim if (RecordVal *ERV = CurRec->getValue(RV.getNameInit())) { 65226584Sdim // The value already exists in the class, treat this as a set. 66226584Sdim if (ERV->setValue(RV.getValue())) 67226584Sdim return Error(Loc, "New definition of '" + RV.getName() + "' of type '" + 68226584Sdim RV.getType()->getAsString() + "' is incompatible with " + 69226584Sdim "previous definition of type '" + 70226584Sdim ERV->getType()->getAsString() + "'"); 71226584Sdim } else { 72226584Sdim CurRec->addValue(RV); 73226584Sdim } 74226584Sdim return false; 75226584Sdim} 76226584Sdim 77226584Sdim/// SetValue - 78226584Sdim/// Return true on error, false on success. 79234353Sdimbool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName, 80296417Sdim ArrayRef<unsigned> BitList, Init *V, 81296417Sdim bool AllowSelfAssignment) { 82226584Sdim if (!V) return false; 83226584Sdim 84276479Sdim if (!CurRec) CurRec = &CurMultiClass->Rec; 85226584Sdim 86226584Sdim RecordVal *RV = CurRec->getValue(ValName); 87276479Sdim if (!RV) 88288943Sdim return Error(Loc, "Value '" + ValName->getAsUnquotedString() + 89288943Sdim "' unknown!"); 90226584Sdim 91226584Sdim // Do not allow assignments like 'X = X'. This will just cause infinite loops 92226584Sdim // in the resolution machinery. 93226584Sdim if (BitList.empty()) 94243830Sdim if (VarInit *VI = dyn_cast<VarInit>(V)) 95296417Sdim if (VI->getNameInit() == ValName && !AllowSelfAssignment) 96296417Sdim return true; 97226584Sdim 98226584Sdim // If we are assigning to a subset of the bits in the value... then we must be 99226584Sdim // assigning to a field of BitsRecTy, which must have a BitsInit 100226584Sdim // initializer. 101226584Sdim // 102226584Sdim if (!BitList.empty()) { 103243830Sdim BitsInit *CurVal = dyn_cast<BitsInit>(RV->getValue()); 104276479Sdim if (!CurVal) 105288943Sdim return Error(Loc, "Value '" + ValName->getAsUnquotedString() + 106288943Sdim "' is not a bits type"); 107226584Sdim 108226584Sdim // Convert the incoming value to a bits type of the appropriate size... 109226584Sdim Init *BI = V->convertInitializerTo(BitsRecTy::get(BitList.size())); 110288943Sdim if (!BI) 111226584Sdim return Error(Loc, "Initializer is not compatible with bit range"); 112226584Sdim 113226584Sdim // We should have a BitsInit type now. 114288943Sdim BitsInit *BInit = cast<BitsInit>(BI); 115226584Sdim 116226584Sdim SmallVector<Init *, 16> NewBits(CurVal->getNumBits()); 117226584Sdim 118226584Sdim // Loop over bits, assigning values as appropriate. 119226584Sdim for (unsigned i = 0, e = BitList.size(); i != e; ++i) { 120226584Sdim unsigned Bit = BitList[i]; 121226584Sdim if (NewBits[Bit]) 122288943Sdim return Error(Loc, "Cannot set bit #" + Twine(Bit) + " of value '" + 123234353Sdim ValName->getAsUnquotedString() + "' more than once"); 124226584Sdim NewBits[Bit] = BInit->getBit(i); 125226584Sdim } 126226584Sdim 127226584Sdim for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i) 128276479Sdim if (!NewBits[i]) 129226584Sdim NewBits[i] = CurVal->getBit(i); 130226584Sdim 131226584Sdim V = BitsInit::get(NewBits); 132226584Sdim } 133226584Sdim 134280031Sdim if (RV->setValue(V)) { 135280031Sdim std::string InitType = ""; 136288943Sdim if (BitsInit *BI = dyn_cast<BitsInit>(V)) 137280031Sdim InitType = (Twine("' of type bit initializer with length ") + 138280031Sdim Twine(BI->getNumBits())).str(); 139288943Sdim return Error(Loc, "Value '" + ValName->getAsUnquotedString() + 140288943Sdim "' of type '" + RV->getType()->getAsString() + 141288943Sdim "' is incompatible with initializer '" + V->getAsString() + 142288943Sdim InitType + "'"); 143280031Sdim } 144226584Sdim return false; 145226584Sdim} 146226584Sdim 147226584Sdim/// AddSubClass - Add SubClass as a subclass to CurRec, resolving its template 148226584Sdim/// args as SubClass's template arguments. 149226584Sdimbool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) { 150226584Sdim Record *SC = SubClass.Rec; 151226584Sdim // Add all of the values in the subclass into the current class. 152288943Sdim for (const RecordVal &Val : SC->getValues()) 153288943Sdim if (AddValue(CurRec, SubClass.RefRange.Start, Val)) 154226584Sdim return true; 155226584Sdim 156296417Sdim ArrayRef<Init *> TArgs = SC->getTemplateArgs(); 157226584Sdim 158226584Sdim // Ensure that an appropriate number of template arguments are specified. 159226584Sdim if (TArgs.size() < SubClass.TemplateArgs.size()) 160249423Sdim return Error(SubClass.RefRange.Start, 161249423Sdim "More template args specified than expected"); 162226584Sdim 163226584Sdim // Loop over all of the template arguments, setting them to the specified 164226584Sdim // value or leaving them as the default if necessary. 165226584Sdim for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { 166226584Sdim if (i < SubClass.TemplateArgs.size()) { 167226584Sdim // If a value is specified for this template arg, set it now. 168249423Sdim if (SetValue(CurRec, SubClass.RefRange.Start, TArgs[i], 169296417Sdim None, SubClass.TemplateArgs[i])) 170226584Sdim return true; 171226584Sdim 172226584Sdim // Resolve it next. 173226584Sdim CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i])); 174226584Sdim 175226584Sdim // Now remove it. 176226584Sdim CurRec->removeValue(TArgs[i]); 177226584Sdim 178226584Sdim } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) { 179249423Sdim return Error(SubClass.RefRange.Start, 180288943Sdim "Value not specified for template argument #" + 181288943Sdim Twine(i) + " (" + TArgs[i]->getAsUnquotedString() + 182288943Sdim ") of subclass '" + SC->getNameInitAsString() + "'!"); 183226584Sdim } 184226584Sdim } 185226584Sdim 186226584Sdim // Since everything went well, we can now set the "superclass" list for the 187226584Sdim // current record. 188288943Sdim ArrayRef<Record *> SCs = SC->getSuperClasses(); 189249423Sdim ArrayRef<SMRange> SCRanges = SC->getSuperClassRanges(); 190226584Sdim for (unsigned i = 0, e = SCs.size(); i != e; ++i) { 191226584Sdim if (CurRec->isSubClassOf(SCs[i])) 192249423Sdim return Error(SubClass.RefRange.Start, 193226584Sdim "Already subclass of '" + SCs[i]->getName() + "'!\n"); 194249423Sdim CurRec->addSuperClass(SCs[i], SCRanges[i]); 195226584Sdim } 196226584Sdim 197226584Sdim if (CurRec->isSubClassOf(SC)) 198249423Sdim return Error(SubClass.RefRange.Start, 199226584Sdim "Already subclass of '" + SC->getName() + "'!\n"); 200249423Sdim CurRec->addSuperClass(SC, SubClass.RefRange); 201226584Sdim return false; 202226584Sdim} 203226584Sdim 204226584Sdim/// AddSubMultiClass - Add SubMultiClass as a subclass to 205226584Sdim/// CurMC, resolving its template args as SubMultiClass's 206226584Sdim/// template arguments. 207226584Sdimbool TGParser::AddSubMultiClass(MultiClass *CurMC, 208226584Sdim SubMultiClassReference &SubMultiClass) { 209226584Sdim MultiClass *SMC = SubMultiClass.MC; 210226584Sdim Record *CurRec = &CurMC->Rec; 211226584Sdim 212226584Sdim // Add all of the values in the subclass into the current class. 213288943Sdim for (const auto &SMCVal : SMC->Rec.getValues()) 214288943Sdim if (AddValue(CurRec, SubMultiClass.RefRange.Start, SMCVal)) 215226584Sdim return true; 216226584Sdim 217280031Sdim unsigned newDefStart = CurMC->DefPrototypes.size(); 218226584Sdim 219226584Sdim // Add all of the defs in the subclass into the current multiclass. 220288943Sdim for (const std::unique_ptr<Record> &R : SMC->DefPrototypes) { 221226584Sdim // Clone the def and add it to the current multiclass 222288943Sdim auto NewDef = make_unique<Record>(*R); 223226584Sdim 224226584Sdim // Add all of the values in the superclass into the current def. 225288943Sdim for (const auto &MCVal : CurRec->getValues()) 226288943Sdim if (AddValue(NewDef.get(), SubMultiClass.RefRange.Start, MCVal)) 227226584Sdim return true; 228226584Sdim 229280031Sdim CurMC->DefPrototypes.push_back(std::move(NewDef)); 230226584Sdim } 231226584Sdim 232296417Sdim ArrayRef<Init *> SMCTArgs = SMC->Rec.getTemplateArgs(); 233226584Sdim 234226584Sdim // Ensure that an appropriate number of template arguments are 235226584Sdim // specified. 236226584Sdim if (SMCTArgs.size() < SubMultiClass.TemplateArgs.size()) 237249423Sdim return Error(SubMultiClass.RefRange.Start, 238226584Sdim "More template args specified than expected"); 239226584Sdim 240226584Sdim // Loop over all of the template arguments, setting them to the specified 241226584Sdim // value or leaving them as the default if necessary. 242226584Sdim for (unsigned i = 0, e = SMCTArgs.size(); i != e; ++i) { 243226584Sdim if (i < SubMultiClass.TemplateArgs.size()) { 244226584Sdim // If a value is specified for this template arg, set it in the 245226584Sdim // superclass now. 246249423Sdim if (SetValue(CurRec, SubMultiClass.RefRange.Start, SMCTArgs[i], 247296417Sdim None, SubMultiClass.TemplateArgs[i])) 248226584Sdim return true; 249226584Sdim 250226584Sdim // Resolve it next. 251226584Sdim CurRec->resolveReferencesTo(CurRec->getValue(SMCTArgs[i])); 252226584Sdim 253226584Sdim // Now remove it. 254226584Sdim CurRec->removeValue(SMCTArgs[i]); 255226584Sdim 256226584Sdim // If a value is specified for this template arg, set it in the 257226584Sdim // new defs now. 258280031Sdim for (const auto &Def : 259280031Sdim makeArrayRef(CurMC->DefPrototypes).slice(newDefStart)) { 260280031Sdim if (SetValue(Def.get(), SubMultiClass.RefRange.Start, SMCTArgs[i], 261296417Sdim None, SubMultiClass.TemplateArgs[i])) 262226584Sdim return true; 263226584Sdim 264226584Sdim // Resolve it next. 265226584Sdim Def->resolveReferencesTo(Def->getValue(SMCTArgs[i])); 266226584Sdim 267226584Sdim // Now remove it 268226584Sdim Def->removeValue(SMCTArgs[i]); 269226584Sdim } 270226584Sdim } else if (!CurRec->getValue(SMCTArgs[i])->getValue()->isComplete()) { 271249423Sdim return Error(SubMultiClass.RefRange.Start, 272288943Sdim "Value not specified for template argument #" + 273288943Sdim Twine(i) + " (" + SMCTArgs[i]->getAsUnquotedString() + 274288943Sdim ") of subclass '" + SMC->Rec.getNameInitAsString() + "'!"); 275226584Sdim } 276226584Sdim } 277226584Sdim 278226584Sdim return false; 279226584Sdim} 280226584Sdim 281234353Sdim/// ProcessForeachDefs - Given a record, apply all of the variable 282234353Sdim/// values in all surrounding foreach loops, creating new records for 283234353Sdim/// each combination of values. 284239462Sdimbool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc) { 285239462Sdim if (Loops.empty()) 286239462Sdim return false; 287239462Sdim 288234353Sdim // We want to instantiate a new copy of CurRec for each combination 289234353Sdim // of nested loop iterator values. We don't want top instantiate 290234353Sdim // any copies until we have values for each loop iterator. 291234353Sdim IterSet IterVals; 292239462Sdim return ProcessForeachDefs(CurRec, Loc, IterVals); 293234353Sdim} 294234353Sdim 295234353Sdim/// ProcessForeachDefs - Given a record, a loop and a loop iterator, 296234353Sdim/// apply each of the variable values in this loop and then process 297234353Sdim/// subloops. 298239462Sdimbool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals){ 299239462Sdim // Recursively build a tuple of iterator values. 300239462Sdim if (IterVals.size() != Loops.size()) { 301239462Sdim assert(IterVals.size() < Loops.size()); 302239462Sdim ForeachLoop &CurLoop = Loops[IterVals.size()]; 303243830Sdim ListInit *List = dyn_cast<ListInit>(CurLoop.ListValue); 304276479Sdim if (!List) { 305239462Sdim Error(Loc, "Loop list is not a list"); 306239462Sdim return true; 307239462Sdim } 308234353Sdim 309239462Sdim // Process each value. 310288943Sdim for (unsigned i = 0; i < List->size(); ++i) { 311276479Sdim Init *ItemVal = List->resolveListElementReference(*CurRec, nullptr, i); 312239462Sdim IterVals.push_back(IterRecord(CurLoop.IterVar, ItemVal)); 313239462Sdim if (ProcessForeachDefs(CurRec, Loc, IterVals)) 314239462Sdim return true; 315239462Sdim IterVals.pop_back(); 316239462Sdim } 317239462Sdim return false; 318234353Sdim } 319234353Sdim 320239462Sdim // This is the bottom of the recursion. We have all of the iterator values 321239462Sdim // for this point in the iteration space. Instantiate a new record to 322239462Sdim // reflect this combination of values. 323280031Sdim auto IterRec = make_unique<Record>(*CurRec); 324234353Sdim 325239462Sdim // Set the iterator values now. 326288943Sdim for (IterRecord &IR : IterVals) { 327288943Sdim VarInit *IterVar = IR.IterVar; 328288943Sdim TypedInit *IVal = dyn_cast<TypedInit>(IR.IterValue); 329280031Sdim if (!IVal) 330280031Sdim return Error(Loc, "foreach iterator value is untyped"); 331234353Sdim 332239462Sdim IterRec->addValue(RecordVal(IterVar->getName(), IVal->getType(), false)); 333234353Sdim 334296417Sdim if (SetValue(IterRec.get(), Loc, IterVar->getName(), None, IVal)) 335280031Sdim return Error(Loc, "when instantiating this def"); 336234353Sdim 337239462Sdim // Resolve it next. 338239462Sdim IterRec->resolveReferencesTo(IterRec->getValue(IterVar->getName())); 339234353Sdim 340239462Sdim // Remove it. 341239462Sdim IterRec->removeValue(IterVar->getName()); 342239462Sdim } 343234353Sdim 344239462Sdim if (Records.getDef(IterRec->getNameInitAsString())) { 345276479Sdim // If this record is anonymous, it's no problem, just generate a new name 346280031Sdim if (!IterRec->isAnonymous()) 347280031Sdim return Error(Loc, "def already exists: " +IterRec->getNameInitAsString()); 348280031Sdim 349280031Sdim IterRec->setName(GetNewAnonymousName()); 350239462Sdim } 351234353Sdim 352280031Sdim Record *IterRecSave = IterRec.get(); // Keep a copy before release. 353280031Sdim Records.addDef(std::move(IterRec)); 354280031Sdim IterRecSave->resolveReferences(); 355234353Sdim return false; 356234353Sdim} 357234353Sdim 358226584Sdim//===----------------------------------------------------------------------===// 359226584Sdim// Parser Code 360226584Sdim//===----------------------------------------------------------------------===// 361226584Sdim 362226584Sdim/// isObjectStart - Return true if this is a valid first token for an Object. 363226584Sdimstatic bool isObjectStart(tgtok::TokKind K) { 364226584Sdim return K == tgtok::Class || K == tgtok::Def || 365234353Sdim K == tgtok::Defm || K == tgtok::Let || 366234353Sdim K == tgtok::MultiClass || K == tgtok::Foreach; 367226584Sdim} 368226584Sdim 369276479Sdim/// GetNewAnonymousName - Generate a unique anonymous name that can be used as 370276479Sdim/// an identifier. 371276479Sdimstd::string TGParser::GetNewAnonymousName() { 372288943Sdim return "anonymous_" + utostr(AnonCounter++); 373226584Sdim} 374226584Sdim 375226584Sdim/// ParseObjectName - If an object name is specified, return it. Otherwise, 376249423Sdim/// return 0. 377234353Sdim/// ObjectName ::= Value [ '#' Value ]* 378226584Sdim/// ObjectName ::= /*empty*/ 379226584Sdim/// 380234353SdimInit *TGParser::ParseObjectName(MultiClass *CurMultiClass) { 381234353Sdim switch (Lex.getCode()) { 382234353Sdim case tgtok::colon: 383234353Sdim case tgtok::semi: 384234353Sdim case tgtok::l_brace: 385234353Sdim // These are all of the tokens that can begin an object body. 386234353Sdim // Some of these can also begin values but we disallow those cases 387234353Sdim // because they are unlikely to be useful. 388276479Sdim return nullptr; 389234353Sdim default: 390234353Sdim break; 391234353Sdim } 392226584Sdim 393276479Sdim Record *CurRec = nullptr; 394234353Sdim if (CurMultiClass) 395234353Sdim CurRec = &CurMultiClass->Rec; 396234353Sdim 397276479Sdim RecTy *Type = nullptr; 398234353Sdim if (CurRec) { 399243830Sdim const TypedInit *CurRecName = dyn_cast<TypedInit>(CurRec->getNameInit()); 400234353Sdim if (!CurRecName) { 401234353Sdim TokError("Record name is not typed!"); 402276479Sdim return nullptr; 403234353Sdim } 404234353Sdim Type = CurRecName->getType(); 405234353Sdim } 406234353Sdim 407234353Sdim return ParseValue(CurRec, Type, ParseNameMode); 408226584Sdim} 409226584Sdim 410226584Sdim/// ParseClassID - Parse and resolve a reference to a class name. This returns 411226584Sdim/// null on error. 412226584Sdim/// 413226584Sdim/// ClassID ::= ID 414226584Sdim/// 415226584SdimRecord *TGParser::ParseClassID() { 416226584Sdim if (Lex.getCode() != tgtok::Id) { 417226584Sdim TokError("expected name for ClassID"); 418276479Sdim return nullptr; 419226584Sdim } 420226584Sdim 421226584Sdim Record *Result = Records.getClass(Lex.getCurStrVal()); 422276479Sdim if (!Result) 423226584Sdim TokError("Couldn't find class '" + Lex.getCurStrVal() + "'"); 424226584Sdim 425226584Sdim Lex.Lex(); 426226584Sdim return Result; 427226584Sdim} 428226584Sdim 429226584Sdim/// ParseMultiClassID - Parse and resolve a reference to a multiclass name. 430226584Sdim/// This returns null on error. 431226584Sdim/// 432226584Sdim/// MultiClassID ::= ID 433226584Sdim/// 434226584SdimMultiClass *TGParser::ParseMultiClassID() { 435226584Sdim if (Lex.getCode() != tgtok::Id) { 436249423Sdim TokError("expected name for MultiClassID"); 437276479Sdim return nullptr; 438226584Sdim } 439226584Sdim 440280031Sdim MultiClass *Result = MultiClasses[Lex.getCurStrVal()].get(); 441276479Sdim if (!Result) 442249423Sdim TokError("Couldn't find multiclass '" + Lex.getCurStrVal() + "'"); 443226584Sdim 444226584Sdim Lex.Lex(); 445226584Sdim return Result; 446226584Sdim} 447226584Sdim 448226584Sdim/// ParseSubClassReference - Parse a reference to a subclass or to a templated 449226584Sdim/// subclass. This returns a SubClassRefTy with a null Record* on error. 450226584Sdim/// 451226584Sdim/// SubClassRef ::= ClassID 452226584Sdim/// SubClassRef ::= ClassID '<' ValueList '>' 453226584Sdim/// 454226584SdimSubClassReference TGParser:: 455226584SdimParseSubClassReference(Record *CurRec, bool isDefm) { 456226584Sdim SubClassReference Result; 457249423Sdim Result.RefRange.Start = Lex.getLoc(); 458226584Sdim 459249423Sdim if (isDefm) { 460249423Sdim if (MultiClass *MC = ParseMultiClassID()) 461249423Sdim Result.Rec = &MC->Rec; 462249423Sdim } else { 463226584Sdim Result.Rec = ParseClassID(); 464249423Sdim } 465276479Sdim if (!Result.Rec) return Result; 466226584Sdim 467226584Sdim // If there is no template arg list, we're done. 468249423Sdim if (Lex.getCode() != tgtok::less) { 469249423Sdim Result.RefRange.End = Lex.getLoc(); 470226584Sdim return Result; 471249423Sdim } 472226584Sdim Lex.Lex(); // Eat the '<' 473226584Sdim 474226584Sdim if (Lex.getCode() == tgtok::greater) { 475226584Sdim TokError("subclass reference requires a non-empty list of template values"); 476276479Sdim Result.Rec = nullptr; 477226584Sdim return Result; 478226584Sdim } 479226584Sdim 480226584Sdim Result.TemplateArgs = ParseValueList(CurRec, Result.Rec); 481226584Sdim if (Result.TemplateArgs.empty()) { 482276479Sdim Result.Rec = nullptr; // Error parsing value list. 483226584Sdim return Result; 484226584Sdim } 485226584Sdim 486226584Sdim if (Lex.getCode() != tgtok::greater) { 487226584Sdim TokError("expected '>' in template value list"); 488276479Sdim Result.Rec = nullptr; 489226584Sdim return Result; 490226584Sdim } 491226584Sdim Lex.Lex(); 492249423Sdim Result.RefRange.End = Lex.getLoc(); 493226584Sdim 494226584Sdim return Result; 495226584Sdim} 496226584Sdim 497226584Sdim/// ParseSubMultiClassReference - Parse a reference to a subclass or to a 498226584Sdim/// templated submulticlass. This returns a SubMultiClassRefTy with a null 499226584Sdim/// Record* on error. 500226584Sdim/// 501226584Sdim/// SubMultiClassRef ::= MultiClassID 502226584Sdim/// SubMultiClassRef ::= MultiClassID '<' ValueList '>' 503226584Sdim/// 504226584SdimSubMultiClassReference TGParser:: 505226584SdimParseSubMultiClassReference(MultiClass *CurMC) { 506226584Sdim SubMultiClassReference Result; 507249423Sdim Result.RefRange.Start = Lex.getLoc(); 508226584Sdim 509226584Sdim Result.MC = ParseMultiClassID(); 510276479Sdim if (!Result.MC) return Result; 511226584Sdim 512226584Sdim // If there is no template arg list, we're done. 513249423Sdim if (Lex.getCode() != tgtok::less) { 514249423Sdim Result.RefRange.End = Lex.getLoc(); 515226584Sdim return Result; 516249423Sdim } 517226584Sdim Lex.Lex(); // Eat the '<' 518226584Sdim 519226584Sdim if (Lex.getCode() == tgtok::greater) { 520226584Sdim TokError("subclass reference requires a non-empty list of template values"); 521276479Sdim Result.MC = nullptr; 522226584Sdim return Result; 523226584Sdim } 524226584Sdim 525226584Sdim Result.TemplateArgs = ParseValueList(&CurMC->Rec, &Result.MC->Rec); 526226584Sdim if (Result.TemplateArgs.empty()) { 527276479Sdim Result.MC = nullptr; // Error parsing value list. 528226584Sdim return Result; 529226584Sdim } 530226584Sdim 531226584Sdim if (Lex.getCode() != tgtok::greater) { 532226584Sdim TokError("expected '>' in template value list"); 533276479Sdim Result.MC = nullptr; 534226584Sdim return Result; 535226584Sdim } 536226584Sdim Lex.Lex(); 537249423Sdim Result.RefRange.End = Lex.getLoc(); 538226584Sdim 539226584Sdim return Result; 540226584Sdim} 541226584Sdim 542226584Sdim/// ParseRangePiece - Parse a bit/value range. 543226584Sdim/// RangePiece ::= INTVAL 544226584Sdim/// RangePiece ::= INTVAL '-' INTVAL 545226584Sdim/// RangePiece ::= INTVAL INTVAL 546226584Sdimbool TGParser::ParseRangePiece(std::vector<unsigned> &Ranges) { 547226584Sdim if (Lex.getCode() != tgtok::IntVal) { 548226584Sdim TokError("expected integer or bitrange"); 549226584Sdim return true; 550226584Sdim } 551226584Sdim int64_t Start = Lex.getCurIntVal(); 552226584Sdim int64_t End; 553226584Sdim 554226584Sdim if (Start < 0) 555226584Sdim return TokError("invalid range, cannot be negative"); 556226584Sdim 557226584Sdim switch (Lex.Lex()) { // eat first character. 558226584Sdim default: 559226584Sdim Ranges.push_back(Start); 560226584Sdim return false; 561226584Sdim case tgtok::minus: 562226584Sdim if (Lex.Lex() != tgtok::IntVal) { 563226584Sdim TokError("expected integer value as end of range"); 564226584Sdim return true; 565226584Sdim } 566226584Sdim End = Lex.getCurIntVal(); 567226584Sdim break; 568226584Sdim case tgtok::IntVal: 569226584Sdim End = -Lex.getCurIntVal(); 570226584Sdim break; 571226584Sdim } 572226584Sdim if (End < 0) 573226584Sdim return TokError("invalid range, cannot be negative"); 574226584Sdim Lex.Lex(); 575226584Sdim 576226584Sdim // Add to the range. 577288943Sdim if (Start < End) 578226584Sdim for (; Start <= End; ++Start) 579226584Sdim Ranges.push_back(Start); 580288943Sdim else 581226584Sdim for (; Start >= End; --Start) 582226584Sdim Ranges.push_back(Start); 583226584Sdim return false; 584226584Sdim} 585226584Sdim 586226584Sdim/// ParseRangeList - Parse a list of scalars and ranges into scalar values. 587226584Sdim/// 588226584Sdim/// RangeList ::= RangePiece (',' RangePiece)* 589226584Sdim/// 590226584Sdimstd::vector<unsigned> TGParser::ParseRangeList() { 591226584Sdim std::vector<unsigned> Result; 592226584Sdim 593226584Sdim // Parse the first piece. 594226584Sdim if (ParseRangePiece(Result)) 595226584Sdim return std::vector<unsigned>(); 596226584Sdim while (Lex.getCode() == tgtok::comma) { 597226584Sdim Lex.Lex(); // Eat the comma. 598226584Sdim 599226584Sdim // Parse the next range piece. 600226584Sdim if (ParseRangePiece(Result)) 601226584Sdim return std::vector<unsigned>(); 602226584Sdim } 603226584Sdim return Result; 604226584Sdim} 605226584Sdim 606226584Sdim/// ParseOptionalRangeList - Parse either a range list in <>'s or nothing. 607226584Sdim/// OptionalRangeList ::= '<' RangeList '>' 608226584Sdim/// OptionalRangeList ::= /*empty*/ 609226584Sdimbool TGParser::ParseOptionalRangeList(std::vector<unsigned> &Ranges) { 610226584Sdim if (Lex.getCode() != tgtok::less) 611226584Sdim return false; 612226584Sdim 613226584Sdim SMLoc StartLoc = Lex.getLoc(); 614226584Sdim Lex.Lex(); // eat the '<' 615226584Sdim 616226584Sdim // Parse the range list. 617226584Sdim Ranges = ParseRangeList(); 618226584Sdim if (Ranges.empty()) return true; 619226584Sdim 620226584Sdim if (Lex.getCode() != tgtok::greater) { 621226584Sdim TokError("expected '>' at end of range list"); 622226584Sdim return Error(StartLoc, "to match this '<'"); 623226584Sdim } 624226584Sdim Lex.Lex(); // eat the '>'. 625226584Sdim return false; 626226584Sdim} 627226584Sdim 628226584Sdim/// ParseOptionalBitList - Parse either a bit list in {}'s or nothing. 629226584Sdim/// OptionalBitList ::= '{' RangeList '}' 630226584Sdim/// OptionalBitList ::= /*empty*/ 631226584Sdimbool TGParser::ParseOptionalBitList(std::vector<unsigned> &Ranges) { 632226584Sdim if (Lex.getCode() != tgtok::l_brace) 633226584Sdim return false; 634226584Sdim 635226584Sdim SMLoc StartLoc = Lex.getLoc(); 636226584Sdim Lex.Lex(); // eat the '{' 637226584Sdim 638226584Sdim // Parse the range list. 639226584Sdim Ranges = ParseRangeList(); 640226584Sdim if (Ranges.empty()) return true; 641226584Sdim 642226584Sdim if (Lex.getCode() != tgtok::r_brace) { 643226584Sdim TokError("expected '}' at end of bit list"); 644226584Sdim return Error(StartLoc, "to match this '{'"); 645226584Sdim } 646226584Sdim Lex.Lex(); // eat the '}'. 647226584Sdim return false; 648226584Sdim} 649226584Sdim 650226584Sdim 651226584Sdim/// ParseType - Parse and return a tblgen type. This returns null on error. 652226584Sdim/// 653226584Sdim/// Type ::= STRING // string type 654234353Sdim/// Type ::= CODE // code type 655226584Sdim/// Type ::= BIT // bit type 656226584Sdim/// Type ::= BITS '<' INTVAL '>' // bits<x> type 657226584Sdim/// Type ::= INT // int type 658226584Sdim/// Type ::= LIST '<' Type '>' // list<x> type 659226584Sdim/// Type ::= DAG // dag type 660226584Sdim/// Type ::= ClassID // Record Type 661226584Sdim/// 662226584SdimRecTy *TGParser::ParseType() { 663226584Sdim switch (Lex.getCode()) { 664276479Sdim default: TokError("Unknown token when expecting a type"); return nullptr; 665226584Sdim case tgtok::String: Lex.Lex(); return StringRecTy::get(); 666234353Sdim case tgtok::Code: Lex.Lex(); return StringRecTy::get(); 667226584Sdim case tgtok::Bit: Lex.Lex(); return BitRecTy::get(); 668226584Sdim case tgtok::Int: Lex.Lex(); return IntRecTy::get(); 669226584Sdim case tgtok::Dag: Lex.Lex(); return DagRecTy::get(); 670226584Sdim case tgtok::Id: 671226584Sdim if (Record *R = ParseClassID()) return RecordRecTy::get(R); 672276479Sdim return nullptr; 673226584Sdim case tgtok::Bits: { 674226584Sdim if (Lex.Lex() != tgtok::less) { // Eat 'bits' 675226584Sdim TokError("expected '<' after bits type"); 676276479Sdim return nullptr; 677226584Sdim } 678226584Sdim if (Lex.Lex() != tgtok::IntVal) { // Eat '<' 679226584Sdim TokError("expected integer in bits<n> type"); 680276479Sdim return nullptr; 681226584Sdim } 682226584Sdim uint64_t Val = Lex.getCurIntVal(); 683226584Sdim if (Lex.Lex() != tgtok::greater) { // Eat count. 684226584Sdim TokError("expected '>' at end of bits<n> type"); 685276479Sdim return nullptr; 686226584Sdim } 687226584Sdim Lex.Lex(); // Eat '>' 688226584Sdim return BitsRecTy::get(Val); 689226584Sdim } 690226584Sdim case tgtok::List: { 691226584Sdim if (Lex.Lex() != tgtok::less) { // Eat 'bits' 692226584Sdim TokError("expected '<' after list type"); 693276479Sdim return nullptr; 694226584Sdim } 695226584Sdim Lex.Lex(); // Eat '<' 696226584Sdim RecTy *SubType = ParseType(); 697276479Sdim if (!SubType) return nullptr; 698226584Sdim 699226584Sdim if (Lex.getCode() != tgtok::greater) { 700226584Sdim TokError("expected '>' at end of list<ty> type"); 701276479Sdim return nullptr; 702226584Sdim } 703226584Sdim Lex.Lex(); // Eat '>' 704226584Sdim return ListRecTy::get(SubType); 705226584Sdim } 706226584Sdim } 707226584Sdim} 708226584Sdim 709226584Sdim/// ParseIDValue - This is just like ParseIDValue above, but it assumes the ID 710226584Sdim/// has already been read. 711226584SdimInit *TGParser::ParseIDValue(Record *CurRec, 712234353Sdim const std::string &Name, SMLoc NameLoc, 713234353Sdim IDParseMode Mode) { 714226584Sdim if (CurRec) { 715226584Sdim if (const RecordVal *RV = CurRec->getValue(Name)) 716226584Sdim return VarInit::get(Name, RV->getType()); 717226584Sdim 718234353Sdim Init *TemplateArgName = QualifyName(*CurRec, CurMultiClass, Name, ":"); 719234353Sdim 720226584Sdim if (CurMultiClass) 721234353Sdim TemplateArgName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name, 722234353Sdim "::"); 723226584Sdim 724226584Sdim if (CurRec->isTemplateArg(TemplateArgName)) { 725226584Sdim const RecordVal *RV = CurRec->getValue(TemplateArgName); 726226584Sdim assert(RV && "Template arg doesn't exist??"); 727226584Sdim return VarInit::get(TemplateArgName, RV->getType()); 728226584Sdim } 729226584Sdim } 730226584Sdim 731226584Sdim if (CurMultiClass) { 732234353Sdim Init *MCName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name, 733234353Sdim "::"); 734234353Sdim 735226584Sdim if (CurMultiClass->Rec.isTemplateArg(MCName)) { 736226584Sdim const RecordVal *RV = CurMultiClass->Rec.getValue(MCName); 737226584Sdim assert(RV && "Template arg doesn't exist??"); 738226584Sdim return VarInit::get(MCName, RV->getType()); 739226584Sdim } 740226584Sdim } 741226584Sdim 742234353Sdim // If this is in a foreach loop, make sure it's not a loop iterator 743288943Sdim for (const auto &L : Loops) { 744288943Sdim VarInit *IterVar = dyn_cast<VarInit>(L.IterVar); 745234353Sdim if (IterVar && IterVar->getName() == Name) 746234353Sdim return IterVar; 747234353Sdim } 748234353Sdim 749234353Sdim if (Mode == ParseNameMode) 750234353Sdim return StringInit::get(Name); 751234353Sdim 752226584Sdim if (Record *D = Records.getDef(Name)) 753226584Sdim return DefInit::get(D); 754226584Sdim 755234353Sdim if (Mode == ParseValueMode) { 756234353Sdim Error(NameLoc, "Variable not defined: '" + Name + "'"); 757276479Sdim return nullptr; 758234353Sdim } 759288943Sdim 760234353Sdim return StringInit::get(Name); 761226584Sdim} 762226584Sdim 763226584Sdim/// ParseOperation - Parse an operator. This returns null on error. 764226584Sdim/// 765226584Sdim/// Operation ::= XOperator ['<' Type '>'] '(' Args ')' 766226584Sdim/// 767276479SdimInit *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) { 768226584Sdim switch (Lex.getCode()) { 769226584Sdim default: 770226584Sdim TokError("unknown operation"); 771276479Sdim return nullptr; 772226584Sdim case tgtok::XHead: 773226584Sdim case tgtok::XTail: 774226584Sdim case tgtok::XEmpty: 775226584Sdim case tgtok::XCast: { // Value ::= !unop '(' Value ')' 776226584Sdim UnOpInit::UnaryOp Code; 777276479Sdim RecTy *Type = nullptr; 778226584Sdim 779226584Sdim switch (Lex.getCode()) { 780234353Sdim default: llvm_unreachable("Unhandled code!"); 781226584Sdim case tgtok::XCast: 782226584Sdim Lex.Lex(); // eat the operation 783226584Sdim Code = UnOpInit::CAST; 784226584Sdim 785226584Sdim Type = ParseOperatorType(); 786226584Sdim 787276479Sdim if (!Type) { 788226584Sdim TokError("did not get type for unary operator"); 789276479Sdim return nullptr; 790226584Sdim } 791226584Sdim 792226584Sdim break; 793226584Sdim case tgtok::XHead: 794226584Sdim Lex.Lex(); // eat the operation 795226584Sdim Code = UnOpInit::HEAD; 796226584Sdim break; 797226584Sdim case tgtok::XTail: 798226584Sdim Lex.Lex(); // eat the operation 799226584Sdim Code = UnOpInit::TAIL; 800226584Sdim break; 801226584Sdim case tgtok::XEmpty: 802226584Sdim Lex.Lex(); // eat the operation 803226584Sdim Code = UnOpInit::EMPTY; 804226584Sdim Type = IntRecTy::get(); 805226584Sdim break; 806226584Sdim } 807226584Sdim if (Lex.getCode() != tgtok::l_paren) { 808226584Sdim TokError("expected '(' after unary operator"); 809276479Sdim return nullptr; 810226584Sdim } 811226584Sdim Lex.Lex(); // eat the '(' 812226584Sdim 813226584Sdim Init *LHS = ParseValue(CurRec); 814276479Sdim if (!LHS) return nullptr; 815226584Sdim 816288943Sdim if (Code == UnOpInit::HEAD || 817288943Sdim Code == UnOpInit::TAIL || 818288943Sdim Code == UnOpInit::EMPTY) { 819243830Sdim ListInit *LHSl = dyn_cast<ListInit>(LHS); 820243830Sdim StringInit *LHSs = dyn_cast<StringInit>(LHS); 821243830Sdim TypedInit *LHSt = dyn_cast<TypedInit>(LHS); 822276479Sdim if (!LHSl && !LHSs && !LHSt) { 823226584Sdim TokError("expected list or string type argument in unary operator"); 824276479Sdim return nullptr; 825226584Sdim } 826226584Sdim if (LHSt) { 827243830Sdim ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType()); 828243830Sdim StringRecTy *SType = dyn_cast<StringRecTy>(LHSt->getType()); 829276479Sdim if (!LType && !SType) { 830276479Sdim TokError("expected list or string type argument in unary operator"); 831276479Sdim return nullptr; 832226584Sdim } 833226584Sdim } 834226584Sdim 835288943Sdim if (Code == UnOpInit::HEAD || Code == UnOpInit::TAIL) { 836276479Sdim if (!LHSl && !LHSt) { 837276479Sdim TokError("expected list type argument in unary operator"); 838276479Sdim return nullptr; 839226584Sdim } 840226584Sdim 841288943Sdim if (LHSl && LHSl->empty()) { 842226584Sdim TokError("empty list argument in unary operator"); 843276479Sdim return nullptr; 844226584Sdim } 845226584Sdim if (LHSl) { 846226584Sdim Init *Item = LHSl->getElement(0); 847243830Sdim TypedInit *Itemt = dyn_cast<TypedInit>(Item); 848276479Sdim if (!Itemt) { 849226584Sdim TokError("untyped list element in unary operator"); 850276479Sdim return nullptr; 851226584Sdim } 852288943Sdim Type = (Code == UnOpInit::HEAD) ? Itemt->getType() 853288943Sdim : ListRecTy::get(Itemt->getType()); 854226584Sdim } else { 855226584Sdim assert(LHSt && "expected list type argument in unary operator"); 856243830Sdim ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType()); 857276479Sdim if (!LType) { 858276479Sdim TokError("expected list type argument in unary operator"); 859276479Sdim return nullptr; 860226584Sdim } 861288943Sdim Type = (Code == UnOpInit::HEAD) ? LType->getElementType() : LType; 862226584Sdim } 863226584Sdim } 864226584Sdim } 865226584Sdim 866226584Sdim if (Lex.getCode() != tgtok::r_paren) { 867226584Sdim TokError("expected ')' in unary operator"); 868276479Sdim return nullptr; 869226584Sdim } 870226584Sdim Lex.Lex(); // eat the ')' 871226584Sdim return (UnOpInit::get(Code, LHS, Type))->Fold(CurRec, CurMultiClass); 872226584Sdim } 873226584Sdim 874226584Sdim case tgtok::XConcat: 875249423Sdim case tgtok::XADD: 876280031Sdim case tgtok::XAND: 877226584Sdim case tgtok::XSRA: 878226584Sdim case tgtok::XSRL: 879226584Sdim case tgtok::XSHL: 880226584Sdim case tgtok::XEq: 881276479Sdim case tgtok::XListConcat: 882226584Sdim case tgtok::XStrConcat: { // Value ::= !binop '(' Value ',' Value ')' 883226584Sdim tgtok::TokKind OpTok = Lex.getCode(); 884226584Sdim SMLoc OpLoc = Lex.getLoc(); 885226584Sdim Lex.Lex(); // eat the operation 886226584Sdim 887226584Sdim BinOpInit::BinaryOp Code; 888276479Sdim RecTy *Type = nullptr; 889226584Sdim 890226584Sdim switch (OpTok) { 891234353Sdim default: llvm_unreachable("Unhandled code!"); 892226584Sdim case tgtok::XConcat: Code = BinOpInit::CONCAT;Type = DagRecTy::get(); break; 893249423Sdim case tgtok::XADD: Code = BinOpInit::ADD; Type = IntRecTy::get(); break; 894280031Sdim case tgtok::XAND: Code = BinOpInit::AND; Type = IntRecTy::get(); break; 895226584Sdim case tgtok::XSRA: Code = BinOpInit::SRA; Type = IntRecTy::get(); break; 896226584Sdim case tgtok::XSRL: Code = BinOpInit::SRL; Type = IntRecTy::get(); break; 897226584Sdim case tgtok::XSHL: Code = BinOpInit::SHL; Type = IntRecTy::get(); break; 898226584Sdim case tgtok::XEq: Code = BinOpInit::EQ; Type = BitRecTy::get(); break; 899276479Sdim case tgtok::XListConcat: 900276479Sdim Code = BinOpInit::LISTCONCAT; 901276479Sdim // We don't know the list type until we parse the first argument 902276479Sdim break; 903226584Sdim case tgtok::XStrConcat: 904226584Sdim Code = BinOpInit::STRCONCAT; 905226584Sdim Type = StringRecTy::get(); 906226584Sdim break; 907226584Sdim } 908226584Sdim 909226584Sdim if (Lex.getCode() != tgtok::l_paren) { 910226584Sdim TokError("expected '(' after binary operator"); 911276479Sdim return nullptr; 912226584Sdim } 913226584Sdim Lex.Lex(); // eat the '(' 914226584Sdim 915226584Sdim SmallVector<Init*, 2> InitList; 916226584Sdim 917226584Sdim InitList.push_back(ParseValue(CurRec)); 918276479Sdim if (!InitList.back()) return nullptr; 919226584Sdim 920226584Sdim while (Lex.getCode() == tgtok::comma) { 921226584Sdim Lex.Lex(); // eat the ',' 922226584Sdim 923226584Sdim InitList.push_back(ParseValue(CurRec)); 924276479Sdim if (!InitList.back()) return nullptr; 925226584Sdim } 926226584Sdim 927226584Sdim if (Lex.getCode() != tgtok::r_paren) { 928226584Sdim TokError("expected ')' in operator"); 929276479Sdim return nullptr; 930226584Sdim } 931226584Sdim Lex.Lex(); // eat the ')' 932226584Sdim 933276479Sdim // If we are doing !listconcat, we should know the type by now 934276479Sdim if (OpTok == tgtok::XListConcat) { 935276479Sdim if (VarInit *Arg0 = dyn_cast<VarInit>(InitList[0])) 936276479Sdim Type = Arg0->getType(); 937276479Sdim else if (ListInit *Arg0 = dyn_cast<ListInit>(InitList[0])) 938276479Sdim Type = Arg0->getType(); 939276479Sdim else { 940276479Sdim InitList[0]->dump(); 941276479Sdim Error(OpLoc, "expected a list"); 942276479Sdim return nullptr; 943276479Sdim } 944276479Sdim } 945276479Sdim 946226584Sdim // We allow multiple operands to associative operators like !strconcat as 947226584Sdim // shorthand for nesting them. 948276479Sdim if (Code == BinOpInit::STRCONCAT || Code == BinOpInit::LISTCONCAT) { 949226584Sdim while (InitList.size() > 2) { 950226584Sdim Init *RHS = InitList.pop_back_val(); 951226584Sdim RHS = (BinOpInit::get(Code, InitList.back(), RHS, Type)) 952226584Sdim ->Fold(CurRec, CurMultiClass); 953226584Sdim InitList.back() = RHS; 954226584Sdim } 955226584Sdim } 956226584Sdim 957226584Sdim if (InitList.size() == 2) 958226584Sdim return (BinOpInit::get(Code, InitList[0], InitList[1], Type)) 959226584Sdim ->Fold(CurRec, CurMultiClass); 960226584Sdim 961226584Sdim Error(OpLoc, "expected two operands to operator"); 962276479Sdim return nullptr; 963226584Sdim } 964226584Sdim 965226584Sdim case tgtok::XIf: 966226584Sdim case tgtok::XForEach: 967226584Sdim case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')' 968226584Sdim TernOpInit::TernaryOp Code; 969276479Sdim RecTy *Type = nullptr; 970226584Sdim 971226584Sdim tgtok::TokKind LexCode = Lex.getCode(); 972226584Sdim Lex.Lex(); // eat the operation 973226584Sdim switch (LexCode) { 974234353Sdim default: llvm_unreachable("Unhandled code!"); 975226584Sdim case tgtok::XIf: 976226584Sdim Code = TernOpInit::IF; 977226584Sdim break; 978226584Sdim case tgtok::XForEach: 979226584Sdim Code = TernOpInit::FOREACH; 980226584Sdim break; 981226584Sdim case tgtok::XSubst: 982226584Sdim Code = TernOpInit::SUBST; 983226584Sdim break; 984226584Sdim } 985226584Sdim if (Lex.getCode() != tgtok::l_paren) { 986226584Sdim TokError("expected '(' after ternary operator"); 987276479Sdim return nullptr; 988226584Sdim } 989226584Sdim Lex.Lex(); // eat the '(' 990226584Sdim 991226584Sdim Init *LHS = ParseValue(CurRec); 992276479Sdim if (!LHS) return nullptr; 993226584Sdim 994226584Sdim if (Lex.getCode() != tgtok::comma) { 995226584Sdim TokError("expected ',' in ternary operator"); 996276479Sdim return nullptr; 997226584Sdim } 998226584Sdim Lex.Lex(); // eat the ',' 999226584Sdim 1000276479Sdim Init *MHS = ParseValue(CurRec, ItemType); 1001276479Sdim if (!MHS) 1002276479Sdim return nullptr; 1003226584Sdim 1004226584Sdim if (Lex.getCode() != tgtok::comma) { 1005226584Sdim TokError("expected ',' in ternary operator"); 1006276479Sdim return nullptr; 1007226584Sdim } 1008226584Sdim Lex.Lex(); // eat the ',' 1009226584Sdim 1010276479Sdim Init *RHS = ParseValue(CurRec, ItemType); 1011276479Sdim if (!RHS) 1012276479Sdim return nullptr; 1013226584Sdim 1014226584Sdim if (Lex.getCode() != tgtok::r_paren) { 1015226584Sdim TokError("expected ')' in binary operator"); 1016276479Sdim return nullptr; 1017226584Sdim } 1018226584Sdim Lex.Lex(); // eat the ')' 1019226584Sdim 1020226584Sdim switch (LexCode) { 1021234353Sdim default: llvm_unreachable("Unhandled code!"); 1022226584Sdim case tgtok::XIf: { 1023276479Sdim RecTy *MHSTy = nullptr; 1024276479Sdim RecTy *RHSTy = nullptr; 1025226584Sdim 1026243830Sdim if (TypedInit *MHSt = dyn_cast<TypedInit>(MHS)) 1027243830Sdim MHSTy = MHSt->getType(); 1028243830Sdim if (BitsInit *MHSbits = dyn_cast<BitsInit>(MHS)) 1029243830Sdim MHSTy = BitsRecTy::get(MHSbits->getNumBits()); 1030243830Sdim if (isa<BitInit>(MHS)) 1031243830Sdim MHSTy = BitRecTy::get(); 1032226584Sdim 1033243830Sdim if (TypedInit *RHSt = dyn_cast<TypedInit>(RHS)) 1034226584Sdim RHSTy = RHSt->getType(); 1035243830Sdim if (BitsInit *RHSbits = dyn_cast<BitsInit>(RHS)) 1036243830Sdim RHSTy = BitsRecTy::get(RHSbits->getNumBits()); 1037243830Sdim if (isa<BitInit>(RHS)) 1038243830Sdim RHSTy = BitRecTy::get(); 1039226584Sdim 1040243830Sdim // For UnsetInit, it's typed from the other hand. 1041243830Sdim if (isa<UnsetInit>(MHS)) 1042243830Sdim MHSTy = RHSTy; 1043243830Sdim if (isa<UnsetInit>(RHS)) 1044243830Sdim RHSTy = MHSTy; 1045243830Sdim 1046226584Sdim if (!MHSTy || !RHSTy) { 1047226584Sdim TokError("could not get type for !if"); 1048276479Sdim return nullptr; 1049226584Sdim } 1050226584Sdim 1051226584Sdim if (MHSTy->typeIsConvertibleTo(RHSTy)) { 1052226584Sdim Type = RHSTy; 1053226584Sdim } else if (RHSTy->typeIsConvertibleTo(MHSTy)) { 1054226584Sdim Type = MHSTy; 1055226584Sdim } else { 1056226584Sdim TokError("inconsistent types for !if"); 1057276479Sdim return nullptr; 1058226584Sdim } 1059226584Sdim break; 1060226584Sdim } 1061226584Sdim case tgtok::XForEach: { 1062243830Sdim TypedInit *MHSt = dyn_cast<TypedInit>(MHS); 1063276479Sdim if (!MHSt) { 1064226584Sdim TokError("could not get type for !foreach"); 1065276479Sdim return nullptr; 1066226584Sdim } 1067226584Sdim Type = MHSt->getType(); 1068226584Sdim break; 1069226584Sdim } 1070226584Sdim case tgtok::XSubst: { 1071243830Sdim TypedInit *RHSt = dyn_cast<TypedInit>(RHS); 1072276479Sdim if (!RHSt) { 1073226584Sdim TokError("could not get type for !subst"); 1074276479Sdim return nullptr; 1075226584Sdim } 1076226584Sdim Type = RHSt->getType(); 1077226584Sdim break; 1078226584Sdim } 1079226584Sdim } 1080226584Sdim return (TernOpInit::get(Code, LHS, MHS, RHS, Type))->Fold(CurRec, 1081226584Sdim CurMultiClass); 1082226584Sdim } 1083226584Sdim } 1084226584Sdim} 1085226584Sdim 1086226584Sdim/// ParseOperatorType - Parse a type for an operator. This returns 1087226584Sdim/// null on error. 1088226584Sdim/// 1089226584Sdim/// OperatorType ::= '<' Type '>' 1090226584Sdim/// 1091226584SdimRecTy *TGParser::ParseOperatorType() { 1092276479Sdim RecTy *Type = nullptr; 1093226584Sdim 1094226584Sdim if (Lex.getCode() != tgtok::less) { 1095226584Sdim TokError("expected type name for operator"); 1096276479Sdim return nullptr; 1097226584Sdim } 1098226584Sdim Lex.Lex(); // eat the < 1099226584Sdim 1100226584Sdim Type = ParseType(); 1101226584Sdim 1102276479Sdim if (!Type) { 1103226584Sdim TokError("expected type name for operator"); 1104276479Sdim return nullptr; 1105226584Sdim } 1106226584Sdim 1107226584Sdim if (Lex.getCode() != tgtok::greater) { 1108226584Sdim TokError("expected type name for operator"); 1109276479Sdim return nullptr; 1110226584Sdim } 1111226584Sdim Lex.Lex(); // eat the > 1112226584Sdim 1113226584Sdim return Type; 1114226584Sdim} 1115226584Sdim 1116226584Sdim 1117226584Sdim/// ParseSimpleValue - Parse a tblgen value. This returns null on error. 1118226584Sdim/// 1119226584Sdim/// SimpleValue ::= IDValue 1120226584Sdim/// SimpleValue ::= INTVAL 1121226584Sdim/// SimpleValue ::= STRVAL+ 1122226584Sdim/// SimpleValue ::= CODEFRAGMENT 1123226584Sdim/// SimpleValue ::= '?' 1124226584Sdim/// SimpleValue ::= '{' ValueList '}' 1125226584Sdim/// SimpleValue ::= ID '<' ValueListNE '>' 1126226584Sdim/// SimpleValue ::= '[' ValueList ']' 1127226584Sdim/// SimpleValue ::= '(' IDValue DagArgList ')' 1128226584Sdim/// SimpleValue ::= CONCATTOK '(' Value ',' Value ')' 1129249423Sdim/// SimpleValue ::= ADDTOK '(' Value ',' Value ')' 1130226584Sdim/// SimpleValue ::= SHLTOK '(' Value ',' Value ')' 1131226584Sdim/// SimpleValue ::= SRATOK '(' Value ',' Value ')' 1132226584Sdim/// SimpleValue ::= SRLTOK '(' Value ',' Value ')' 1133276479Sdim/// SimpleValue ::= LISTCONCATTOK '(' Value ',' Value ')' 1134226584Sdim/// SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')' 1135226584Sdim/// 1136234353SdimInit *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, 1137234353Sdim IDParseMode Mode) { 1138276479Sdim Init *R = nullptr; 1139226584Sdim switch (Lex.getCode()) { 1140226584Sdim default: TokError("Unknown token when parsing a value"); break; 1141234353Sdim case tgtok::paste: 1142234353Sdim // This is a leading paste operation. This is deprecated but 1143234353Sdim // still exists in some .td files. Ignore it. 1144234353Sdim Lex.Lex(); // Skip '#'. 1145234353Sdim return ParseSimpleValue(CurRec, ItemType, Mode); 1146226584Sdim case tgtok::IntVal: R = IntInit::get(Lex.getCurIntVal()); Lex.Lex(); break; 1147280031Sdim case tgtok::BinaryIntVal: { 1148280031Sdim auto BinaryVal = Lex.getCurBinaryIntVal(); 1149280031Sdim SmallVector<Init*, 16> Bits(BinaryVal.second); 1150280031Sdim for (unsigned i = 0, e = BinaryVal.second; i != e; ++i) 1151280031Sdim Bits[i] = BitInit::get(BinaryVal.first & (1LL << i)); 1152280031Sdim R = BitsInit::get(Bits); 1153280031Sdim Lex.Lex(); 1154280031Sdim break; 1155280031Sdim } 1156226584Sdim case tgtok::StrVal: { 1157226584Sdim std::string Val = Lex.getCurStrVal(); 1158226584Sdim Lex.Lex(); 1159226584Sdim 1160226584Sdim // Handle multiple consecutive concatenated strings. 1161226584Sdim while (Lex.getCode() == tgtok::StrVal) { 1162226584Sdim Val += Lex.getCurStrVal(); 1163226584Sdim Lex.Lex(); 1164226584Sdim } 1165226584Sdim 1166226584Sdim R = StringInit::get(Val); 1167226584Sdim break; 1168226584Sdim } 1169226584Sdim case tgtok::CodeFragment: 1170234353Sdim R = StringInit::get(Lex.getCurStrVal()); 1171226584Sdim Lex.Lex(); 1172226584Sdim break; 1173226584Sdim case tgtok::question: 1174226584Sdim R = UnsetInit::get(); 1175226584Sdim Lex.Lex(); 1176226584Sdim break; 1177226584Sdim case tgtok::Id: { 1178226584Sdim SMLoc NameLoc = Lex.getLoc(); 1179226584Sdim std::string Name = Lex.getCurStrVal(); 1180226584Sdim if (Lex.Lex() != tgtok::less) // consume the Id. 1181234353Sdim return ParseIDValue(CurRec, Name, NameLoc, Mode); // Value ::= IDValue 1182226584Sdim 1183226584Sdim // Value ::= ID '<' ValueListNE '>' 1184226584Sdim if (Lex.Lex() == tgtok::greater) { 1185226584Sdim TokError("expected non-empty value list"); 1186276479Sdim return nullptr; 1187226584Sdim } 1188226584Sdim 1189226584Sdim // This is a CLASS<initvalslist> expression. This is supposed to synthesize 1190226584Sdim // a new anonymous definition, deriving from CLASS<initvalslist> with no 1191226584Sdim // body. 1192226584Sdim Record *Class = Records.getClass(Name); 1193226584Sdim if (!Class) { 1194226584Sdim Error(NameLoc, "Expected a class name, got '" + Name + "'"); 1195276479Sdim return nullptr; 1196226584Sdim } 1197226584Sdim 1198226584Sdim std::vector<Init*> ValueList = ParseValueList(CurRec, Class); 1199276479Sdim if (ValueList.empty()) return nullptr; 1200226584Sdim 1201226584Sdim if (Lex.getCode() != tgtok::greater) { 1202226584Sdim TokError("expected '>' at end of value list"); 1203276479Sdim return nullptr; 1204226584Sdim } 1205226584Sdim Lex.Lex(); // eat the '>' 1206249423Sdim SMLoc EndLoc = Lex.getLoc(); 1207226584Sdim 1208226584Sdim // Create the new record, set it as CurRec temporarily. 1209280031Sdim auto NewRecOwner = llvm::make_unique<Record>(GetNewAnonymousName(), NameLoc, 1210280031Sdim Records, /*IsAnonymous=*/true); 1211280031Sdim Record *NewRec = NewRecOwner.get(); // Keep a copy since we may release. 1212226584Sdim SubClassReference SCRef; 1213249423Sdim SCRef.RefRange = SMRange(NameLoc, EndLoc); 1214226584Sdim SCRef.Rec = Class; 1215226584Sdim SCRef.TemplateArgs = ValueList; 1216226584Sdim // Add info about the subclass to NewRec. 1217226584Sdim if (AddSubClass(NewRec, SCRef)) 1218276479Sdim return nullptr; 1219280031Sdim 1220276479Sdim if (!CurMultiClass) { 1221276479Sdim NewRec->resolveReferences(); 1222280031Sdim Records.addDef(std::move(NewRecOwner)); 1223276479Sdim } else { 1224280031Sdim // This needs to get resolved once the multiclass template arguments are 1225280031Sdim // known before any use. 1226280031Sdim NewRec->setResolveFirst(true); 1227276479Sdim // Otherwise, we're inside a multiclass, add it to the multiclass. 1228280031Sdim CurMultiClass->DefPrototypes.push_back(std::move(NewRecOwner)); 1229226584Sdim 1230276479Sdim // Copy the template arguments for the multiclass into the def. 1231288943Sdim for (Init *TArg : CurMultiClass->Rec.getTemplateArgs()) { 1232288943Sdim const RecordVal *RV = CurMultiClass->Rec.getValue(TArg); 1233276479Sdim assert(RV && "Template arg doesn't exist?"); 1234276479Sdim NewRec->addValue(*RV); 1235276479Sdim } 1236276479Sdim 1237276479Sdim // We can't return the prototype def here, instead return: 1238276479Sdim // !cast<ItemType>(!strconcat(NAME, AnonName)). 1239276479Sdim const RecordVal *MCNameRV = CurMultiClass->Rec.getValue("NAME"); 1240276479Sdim assert(MCNameRV && "multiclass record must have a NAME"); 1241276479Sdim 1242276479Sdim return UnOpInit::get(UnOpInit::CAST, 1243276479Sdim BinOpInit::get(BinOpInit::STRCONCAT, 1244276479Sdim VarInit::get(MCNameRV->getName(), 1245276479Sdim MCNameRV->getType()), 1246276479Sdim NewRec->getNameInit(), 1247276479Sdim StringRecTy::get()), 1248276479Sdim Class->getDefInit()->getType()); 1249276479Sdim } 1250276479Sdim 1251226584Sdim // The result of the expression is a reference to the new record. 1252226584Sdim return DefInit::get(NewRec); 1253226584Sdim } 1254226584Sdim case tgtok::l_brace: { // Value ::= '{' ValueList '}' 1255226584Sdim SMLoc BraceLoc = Lex.getLoc(); 1256226584Sdim Lex.Lex(); // eat the '{' 1257226584Sdim std::vector<Init*> Vals; 1258226584Sdim 1259226584Sdim if (Lex.getCode() != tgtok::r_brace) { 1260226584Sdim Vals = ParseValueList(CurRec); 1261276479Sdim if (Vals.empty()) return nullptr; 1262226584Sdim } 1263226584Sdim if (Lex.getCode() != tgtok::r_brace) { 1264226584Sdim TokError("expected '}' at end of bit list value"); 1265276479Sdim return nullptr; 1266226584Sdim } 1267226584Sdim Lex.Lex(); // eat the '}' 1268226584Sdim 1269280031Sdim SmallVector<Init *, 16> NewBits; 1270226584Sdim 1271280031Sdim // As we parse { a, b, ... }, 'a' is the highest bit, but we parse it 1272280031Sdim // first. We'll first read everything in to a vector, then we can reverse 1273280031Sdim // it to get the bits in the correct order for the BitsInit value. 1274226584Sdim for (unsigned i = 0, e = Vals.size(); i != e; ++i) { 1275280031Sdim // FIXME: The following two loops would not be duplicated 1276280031Sdim // if the API was a little more orthogonal. 1277280031Sdim 1278280031Sdim // bits<n> values are allowed to initialize n bits. 1279280031Sdim if (BitsInit *BI = dyn_cast<BitsInit>(Vals[i])) { 1280280031Sdim for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) 1281280031Sdim NewBits.push_back(BI->getBit((e - i) - 1)); 1282280031Sdim continue; 1283280031Sdim } 1284280031Sdim // bits<n> can also come from variable initializers. 1285280031Sdim if (VarInit *VI = dyn_cast<VarInit>(Vals[i])) { 1286280031Sdim if (BitsRecTy *BitsRec = dyn_cast<BitsRecTy>(VI->getType())) { 1287280031Sdim for (unsigned i = 0, e = BitsRec->getNumBits(); i != e; ++i) 1288280031Sdim NewBits.push_back(VI->getBit((e - i) - 1)); 1289280031Sdim continue; 1290280031Sdim } 1291280031Sdim // Fallthrough to try convert this to a bit. 1292280031Sdim } 1293280031Sdim // All other values must be convertible to just a single bit. 1294226584Sdim Init *Bit = Vals[i]->convertInitializerTo(BitRecTy::get()); 1295276479Sdim if (!Bit) { 1296288943Sdim Error(BraceLoc, "Element #" + Twine(i) + " (" + Vals[i]->getAsString() + 1297226584Sdim ") is not convertable to a bit"); 1298276479Sdim return nullptr; 1299226584Sdim } 1300280031Sdim NewBits.push_back(Bit); 1301226584Sdim } 1302280031Sdim std::reverse(NewBits.begin(), NewBits.end()); 1303226584Sdim return BitsInit::get(NewBits); 1304226584Sdim } 1305226584Sdim case tgtok::l_square: { // Value ::= '[' ValueList ']' 1306226584Sdim Lex.Lex(); // eat the '[' 1307226584Sdim std::vector<Init*> Vals; 1308226584Sdim 1309276479Sdim RecTy *DeducedEltTy = nullptr; 1310276479Sdim ListRecTy *GivenListTy = nullptr; 1311226584Sdim 1312276479Sdim if (ItemType) { 1313243830Sdim ListRecTy *ListType = dyn_cast<ListRecTy>(ItemType); 1314276479Sdim if (!ListType) { 1315288943Sdim TokError(Twine("Type mismatch for list, expected list type, got ") + 1316288943Sdim ItemType->getAsString()); 1317276479Sdim return nullptr; 1318226584Sdim } 1319226584Sdim GivenListTy = ListType; 1320226584Sdim } 1321226584Sdim 1322226584Sdim if (Lex.getCode() != tgtok::r_square) { 1323276479Sdim Vals = ParseValueList(CurRec, nullptr, 1324276479Sdim GivenListTy ? GivenListTy->getElementType() : nullptr); 1325276479Sdim if (Vals.empty()) return nullptr; 1326226584Sdim } 1327226584Sdim if (Lex.getCode() != tgtok::r_square) { 1328226584Sdim TokError("expected ']' at end of list value"); 1329276479Sdim return nullptr; 1330226584Sdim } 1331226584Sdim Lex.Lex(); // eat the ']' 1332226584Sdim 1333276479Sdim RecTy *GivenEltTy = nullptr; 1334226584Sdim if (Lex.getCode() == tgtok::less) { 1335226584Sdim // Optional list element type 1336226584Sdim Lex.Lex(); // eat the '<' 1337226584Sdim 1338226584Sdim GivenEltTy = ParseType(); 1339276479Sdim if (!GivenEltTy) { 1340226584Sdim // Couldn't parse element type 1341276479Sdim return nullptr; 1342226584Sdim } 1343226584Sdim 1344226584Sdim if (Lex.getCode() != tgtok::greater) { 1345226584Sdim TokError("expected '>' at end of list element type"); 1346276479Sdim return nullptr; 1347226584Sdim } 1348226584Sdim Lex.Lex(); // eat the '>' 1349226584Sdim } 1350226584Sdim 1351226584Sdim // Check elements 1352276479Sdim RecTy *EltTy = nullptr; 1353288943Sdim for (Init *V : Vals) { 1354288943Sdim TypedInit *TArg = dyn_cast<TypedInit>(V); 1355276479Sdim if (!TArg) { 1356226584Sdim TokError("Untyped list element"); 1357276479Sdim return nullptr; 1358226584Sdim } 1359276479Sdim if (EltTy) { 1360226584Sdim EltTy = resolveTypes(EltTy, TArg->getType()); 1361276479Sdim if (!EltTy) { 1362226584Sdim TokError("Incompatible types in list elements"); 1363276479Sdim return nullptr; 1364226584Sdim } 1365226584Sdim } else { 1366226584Sdim EltTy = TArg->getType(); 1367226584Sdim } 1368226584Sdim } 1369226584Sdim 1370276479Sdim if (GivenEltTy) { 1371276479Sdim if (EltTy) { 1372226584Sdim // Verify consistency 1373226584Sdim if (!EltTy->typeIsConvertibleTo(GivenEltTy)) { 1374226584Sdim TokError("Incompatible types in list elements"); 1375276479Sdim return nullptr; 1376226584Sdim } 1377226584Sdim } 1378226584Sdim EltTy = GivenEltTy; 1379226584Sdim } 1380226584Sdim 1381276479Sdim if (!EltTy) { 1382276479Sdim if (!ItemType) { 1383226584Sdim TokError("No type for list"); 1384276479Sdim return nullptr; 1385226584Sdim } 1386226584Sdim DeducedEltTy = GivenListTy->getElementType(); 1387226584Sdim } else { 1388226584Sdim // Make sure the deduced type is compatible with the given type 1389226584Sdim if (GivenListTy) { 1390226584Sdim if (!EltTy->typeIsConvertibleTo(GivenListTy->getElementType())) { 1391226584Sdim TokError("Element type mismatch for list"); 1392276479Sdim return nullptr; 1393226584Sdim } 1394226584Sdim } 1395226584Sdim DeducedEltTy = EltTy; 1396226584Sdim } 1397226584Sdim 1398226584Sdim return ListInit::get(Vals, DeducedEltTy); 1399226584Sdim } 1400226584Sdim case tgtok::l_paren: { // Value ::= '(' IDValue DagArgList ')' 1401226584Sdim Lex.Lex(); // eat the '(' 1402226584Sdim if (Lex.getCode() != tgtok::Id && Lex.getCode() != tgtok::XCast) { 1403226584Sdim TokError("expected identifier in dag init"); 1404276479Sdim return nullptr; 1405226584Sdim } 1406226584Sdim 1407226584Sdim Init *Operator = ParseValue(CurRec); 1408276479Sdim if (!Operator) return nullptr; 1409226584Sdim 1410226584Sdim // If the operator name is present, parse it. 1411226584Sdim std::string OperatorName; 1412226584Sdim if (Lex.getCode() == tgtok::colon) { 1413226584Sdim if (Lex.Lex() != tgtok::VarName) { // eat the ':' 1414226584Sdim TokError("expected variable name in dag operator"); 1415276479Sdim return nullptr; 1416226584Sdim } 1417226584Sdim OperatorName = Lex.getCurStrVal(); 1418226584Sdim Lex.Lex(); // eat the VarName. 1419226584Sdim } 1420226584Sdim 1421226584Sdim std::vector<std::pair<llvm::Init*, std::string> > DagArgs; 1422226584Sdim if (Lex.getCode() != tgtok::r_paren) { 1423226584Sdim DagArgs = ParseDagArgList(CurRec); 1424276479Sdim if (DagArgs.empty()) return nullptr; 1425226584Sdim } 1426226584Sdim 1427226584Sdim if (Lex.getCode() != tgtok::r_paren) { 1428226584Sdim TokError("expected ')' in dag init"); 1429276479Sdim return nullptr; 1430226584Sdim } 1431226584Sdim Lex.Lex(); // eat the ')' 1432226584Sdim 1433226584Sdim return DagInit::get(Operator, OperatorName, DagArgs); 1434226584Sdim } 1435226584Sdim 1436226584Sdim case tgtok::XHead: 1437226584Sdim case tgtok::XTail: 1438226584Sdim case tgtok::XEmpty: 1439226584Sdim case tgtok::XCast: // Value ::= !unop '(' Value ')' 1440226584Sdim case tgtok::XConcat: 1441249423Sdim case tgtok::XADD: 1442280031Sdim case tgtok::XAND: 1443226584Sdim case tgtok::XSRA: 1444226584Sdim case tgtok::XSRL: 1445226584Sdim case tgtok::XSHL: 1446226584Sdim case tgtok::XEq: 1447276479Sdim case tgtok::XListConcat: 1448226584Sdim case tgtok::XStrConcat: // Value ::= !binop '(' Value ',' Value ')' 1449226584Sdim case tgtok::XIf: 1450226584Sdim case tgtok::XForEach: 1451226584Sdim case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')' 1452276479Sdim return ParseOperation(CurRec, ItemType); 1453226584Sdim } 1454226584Sdim } 1455226584Sdim 1456226584Sdim return R; 1457226584Sdim} 1458226584Sdim 1459226584Sdim/// ParseValue - Parse a tblgen value. This returns null on error. 1460226584Sdim/// 1461226584Sdim/// Value ::= SimpleValue ValueSuffix* 1462226584Sdim/// ValueSuffix ::= '{' BitList '}' 1463226584Sdim/// ValueSuffix ::= '[' BitList ']' 1464226584Sdim/// ValueSuffix ::= '.' ID 1465226584Sdim/// 1466234353SdimInit *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) { 1467234353Sdim Init *Result = ParseSimpleValue(CurRec, ItemType, Mode); 1468276479Sdim if (!Result) return nullptr; 1469226584Sdim 1470226584Sdim // Parse the suffixes now if present. 1471226584Sdim while (1) { 1472226584Sdim switch (Lex.getCode()) { 1473226584Sdim default: return Result; 1474226584Sdim case tgtok::l_brace: { 1475234353Sdim if (Mode == ParseNameMode || Mode == ParseForeachMode) 1476234353Sdim // This is the beginning of the object body. 1477234353Sdim return Result; 1478234353Sdim 1479226584Sdim SMLoc CurlyLoc = Lex.getLoc(); 1480226584Sdim Lex.Lex(); // eat the '{' 1481226584Sdim std::vector<unsigned> Ranges = ParseRangeList(); 1482276479Sdim if (Ranges.empty()) return nullptr; 1483226584Sdim 1484226584Sdim // Reverse the bitlist. 1485226584Sdim std::reverse(Ranges.begin(), Ranges.end()); 1486226584Sdim Result = Result->convertInitializerBitRange(Ranges); 1487276479Sdim if (!Result) { 1488226584Sdim Error(CurlyLoc, "Invalid bit range for value"); 1489276479Sdim return nullptr; 1490226584Sdim } 1491226584Sdim 1492226584Sdim // Eat the '}'. 1493226584Sdim if (Lex.getCode() != tgtok::r_brace) { 1494226584Sdim TokError("expected '}' at end of bit range list"); 1495276479Sdim return nullptr; 1496226584Sdim } 1497226584Sdim Lex.Lex(); 1498226584Sdim break; 1499226584Sdim } 1500226584Sdim case tgtok::l_square: { 1501226584Sdim SMLoc SquareLoc = Lex.getLoc(); 1502226584Sdim Lex.Lex(); // eat the '[' 1503226584Sdim std::vector<unsigned> Ranges = ParseRangeList(); 1504276479Sdim if (Ranges.empty()) return nullptr; 1505226584Sdim 1506226584Sdim Result = Result->convertInitListSlice(Ranges); 1507276479Sdim if (!Result) { 1508226584Sdim Error(SquareLoc, "Invalid range for list slice"); 1509276479Sdim return nullptr; 1510226584Sdim } 1511226584Sdim 1512226584Sdim // Eat the ']'. 1513226584Sdim if (Lex.getCode() != tgtok::r_square) { 1514226584Sdim TokError("expected ']' at end of list slice"); 1515276479Sdim return nullptr; 1516226584Sdim } 1517226584Sdim Lex.Lex(); 1518226584Sdim break; 1519226584Sdim } 1520226584Sdim case tgtok::period: 1521226584Sdim if (Lex.Lex() != tgtok::Id) { // eat the . 1522226584Sdim TokError("expected field identifier after '.'"); 1523276479Sdim return nullptr; 1524226584Sdim } 1525226584Sdim if (!Result->getFieldType(Lex.getCurStrVal())) { 1526226584Sdim TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" + 1527226584Sdim Result->getAsString() + "'"); 1528276479Sdim return nullptr; 1529226584Sdim } 1530226584Sdim Result = FieldInit::get(Result, Lex.getCurStrVal()); 1531226584Sdim Lex.Lex(); // eat field name 1532226584Sdim break; 1533234353Sdim 1534234353Sdim case tgtok::paste: 1535234353Sdim SMLoc PasteLoc = Lex.getLoc(); 1536234353Sdim 1537234353Sdim // Create a !strconcat() operation, first casting each operand to 1538234353Sdim // a string if necessary. 1539234353Sdim 1540243830Sdim TypedInit *LHS = dyn_cast<TypedInit>(Result); 1541234353Sdim if (!LHS) { 1542234353Sdim Error(PasteLoc, "LHS of paste is not typed!"); 1543276479Sdim return nullptr; 1544234353Sdim } 1545288943Sdim 1546234353Sdim if (LHS->getType() != StringRecTy::get()) { 1547234353Sdim LHS = UnOpInit::get(UnOpInit::CAST, LHS, StringRecTy::get()); 1548234353Sdim } 1549234353Sdim 1550276479Sdim TypedInit *RHS = nullptr; 1551234353Sdim 1552234353Sdim Lex.Lex(); // Eat the '#'. 1553234353Sdim switch (Lex.getCode()) { 1554234353Sdim case tgtok::colon: 1555234353Sdim case tgtok::semi: 1556234353Sdim case tgtok::l_brace: 1557234353Sdim // These are all of the tokens that can begin an object body. 1558234353Sdim // Some of these can also begin values but we disallow those cases 1559234353Sdim // because they are unlikely to be useful. 1560288943Sdim 1561234353Sdim // Trailing paste, concat with an empty string. 1562234353Sdim RHS = StringInit::get(""); 1563234353Sdim break; 1564234353Sdim 1565234353Sdim default: 1566234353Sdim Init *RHSResult = ParseValue(CurRec, ItemType, ParseNameMode); 1567243830Sdim RHS = dyn_cast<TypedInit>(RHSResult); 1568234353Sdim if (!RHS) { 1569234353Sdim Error(PasteLoc, "RHS of paste is not typed!"); 1570276479Sdim return nullptr; 1571234353Sdim } 1572234353Sdim 1573234353Sdim if (RHS->getType() != StringRecTy::get()) { 1574234353Sdim RHS = UnOpInit::get(UnOpInit::CAST, RHS, StringRecTy::get()); 1575234353Sdim } 1576288943Sdim 1577234353Sdim break; 1578234353Sdim } 1579234353Sdim 1580234353Sdim Result = BinOpInit::get(BinOpInit::STRCONCAT, LHS, RHS, 1581234353Sdim StringRecTy::get())->Fold(CurRec, CurMultiClass); 1582234353Sdim break; 1583226584Sdim } 1584226584Sdim } 1585226584Sdim} 1586226584Sdim 1587226584Sdim/// ParseDagArgList - Parse the argument list for a dag literal expression. 1588226584Sdim/// 1589249423Sdim/// DagArg ::= Value (':' VARNAME)? 1590249423Sdim/// DagArg ::= VARNAME 1591249423Sdim/// DagArgList ::= DagArg 1592249423Sdim/// DagArgList ::= DagArgList ',' DagArg 1593226584Sdimstd::vector<std::pair<llvm::Init*, std::string> > 1594226584SdimTGParser::ParseDagArgList(Record *CurRec) { 1595226584Sdim std::vector<std::pair<llvm::Init*, std::string> > Result; 1596226584Sdim 1597226584Sdim while (1) { 1598249423Sdim // DagArg ::= VARNAME 1599249423Sdim if (Lex.getCode() == tgtok::VarName) { 1600249423Sdim // A missing value is treated like '?'. 1601288943Sdim Result.emplace_back(UnsetInit::get(), Lex.getCurStrVal()); 1602249423Sdim Lex.Lex(); 1603249423Sdim } else { 1604249423Sdim // DagArg ::= Value (':' VARNAME)? 1605249423Sdim Init *Val = ParseValue(CurRec); 1606276479Sdim if (!Val) 1607249423Sdim return std::vector<std::pair<llvm::Init*, std::string> >(); 1608226584Sdim 1609249423Sdim // If the variable name is present, add it. 1610249423Sdim std::string VarName; 1611249423Sdim if (Lex.getCode() == tgtok::colon) { 1612249423Sdim if (Lex.Lex() != tgtok::VarName) { // eat the ':' 1613249423Sdim TokError("expected variable name in dag literal"); 1614249423Sdim return std::vector<std::pair<llvm::Init*, std::string> >(); 1615249423Sdim } 1616249423Sdim VarName = Lex.getCurStrVal(); 1617249423Sdim Lex.Lex(); // eat the VarName. 1618226584Sdim } 1619249423Sdim 1620249423Sdim Result.push_back(std::make_pair(Val, VarName)); 1621226584Sdim } 1622226584Sdim if (Lex.getCode() != tgtok::comma) break; 1623226584Sdim Lex.Lex(); // eat the ',' 1624226584Sdim } 1625226584Sdim 1626226584Sdim return Result; 1627226584Sdim} 1628226584Sdim 1629226584Sdim 1630226584Sdim/// ParseValueList - Parse a comma separated list of values, returning them as a 1631226584Sdim/// vector. Note that this always expects to be able to parse at least one 1632226584Sdim/// value. It returns an empty list if this is not possible. 1633226584Sdim/// 1634226584Sdim/// ValueList ::= Value (',' Value) 1635226584Sdim/// 1636226584Sdimstd::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec, 1637226584Sdim RecTy *EltTy) { 1638226584Sdim std::vector<Init*> Result; 1639226584Sdim RecTy *ItemType = EltTy; 1640226584Sdim unsigned int ArgN = 0; 1641276479Sdim if (ArgsRec && !EltTy) { 1642296417Sdim ArrayRef<Init *> TArgs = ArgsRec->getTemplateArgs(); 1643288943Sdim if (TArgs.empty()) { 1644234353Sdim TokError("template argument provided to non-template class"); 1645234353Sdim return std::vector<Init*>(); 1646234353Sdim } 1647226584Sdim const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]); 1648226584Sdim if (!RV) { 1649226584Sdim errs() << "Cannot find template arg " << ArgN << " (" << TArgs[ArgN] 1650226584Sdim << ")\n"; 1651226584Sdim } 1652226584Sdim assert(RV && "Template argument record not found??"); 1653226584Sdim ItemType = RV->getType(); 1654226584Sdim ++ArgN; 1655226584Sdim } 1656226584Sdim Result.push_back(ParseValue(CurRec, ItemType)); 1657276479Sdim if (!Result.back()) return std::vector<Init*>(); 1658226584Sdim 1659226584Sdim while (Lex.getCode() == tgtok::comma) { 1660226584Sdim Lex.Lex(); // Eat the comma 1661226584Sdim 1662276479Sdim if (ArgsRec && !EltTy) { 1663296417Sdim ArrayRef<Init *> TArgs = ArgsRec->getTemplateArgs(); 1664226584Sdim if (ArgN >= TArgs.size()) { 1665226584Sdim TokError("too many template arguments"); 1666226584Sdim return std::vector<Init*>(); 1667226584Sdim } 1668226584Sdim const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]); 1669226584Sdim assert(RV && "Template argument record not found??"); 1670226584Sdim ItemType = RV->getType(); 1671226584Sdim ++ArgN; 1672226584Sdim } 1673226584Sdim Result.push_back(ParseValue(CurRec, ItemType)); 1674276479Sdim if (!Result.back()) return std::vector<Init*>(); 1675226584Sdim } 1676226584Sdim 1677226584Sdim return Result; 1678226584Sdim} 1679226584Sdim 1680226584Sdim 1681226584Sdim/// ParseDeclaration - Read a declaration, returning the name of field ID, or an 1682226584Sdim/// empty string on error. This can happen in a number of different context's, 1683226584Sdim/// including within a def or in the template args for a def (which which case 1684226584Sdim/// CurRec will be non-null) and within the template args for a multiclass (in 1685226584Sdim/// which case CurRec will be null, but CurMultiClass will be set). This can 1686226584Sdim/// also happen within a def that is within a multiclass, which will set both 1687226584Sdim/// CurRec and CurMultiClass. 1688226584Sdim/// 1689226584Sdim/// Declaration ::= FIELD? Type ID ('=' Value)? 1690226584Sdim/// 1691234353SdimInit *TGParser::ParseDeclaration(Record *CurRec, 1692226584Sdim bool ParsingTemplateArgs) { 1693226584Sdim // Read the field prefix if present. 1694226584Sdim bool HasField = Lex.getCode() == tgtok::Field; 1695226584Sdim if (HasField) Lex.Lex(); 1696226584Sdim 1697226584Sdim RecTy *Type = ParseType(); 1698276479Sdim if (!Type) return nullptr; 1699226584Sdim 1700226584Sdim if (Lex.getCode() != tgtok::Id) { 1701226584Sdim TokError("Expected identifier in declaration"); 1702276479Sdim return nullptr; 1703226584Sdim } 1704226584Sdim 1705226584Sdim SMLoc IdLoc = Lex.getLoc(); 1706234353Sdim Init *DeclName = StringInit::get(Lex.getCurStrVal()); 1707226584Sdim Lex.Lex(); 1708226584Sdim 1709226584Sdim if (ParsingTemplateArgs) { 1710288943Sdim if (CurRec) 1711234353Sdim DeclName = QualifyName(*CurRec, CurMultiClass, DeclName, ":"); 1712288943Sdim else 1713226584Sdim assert(CurMultiClass); 1714226584Sdim if (CurMultiClass) 1715234353Sdim DeclName = QualifyName(CurMultiClass->Rec, CurMultiClass, DeclName, 1716234353Sdim "::"); 1717226584Sdim } 1718226584Sdim 1719226584Sdim // Add the value. 1720226584Sdim if (AddValue(CurRec, IdLoc, RecordVal(DeclName, Type, HasField))) 1721276479Sdim return nullptr; 1722226584Sdim 1723226584Sdim // If a value is present, parse it. 1724226584Sdim if (Lex.getCode() == tgtok::equal) { 1725226584Sdim Lex.Lex(); 1726226584Sdim SMLoc ValLoc = Lex.getLoc(); 1727226584Sdim Init *Val = ParseValue(CurRec, Type); 1728276479Sdim if (!Val || 1729296417Sdim SetValue(CurRec, ValLoc, DeclName, None, Val)) 1730280031Sdim // Return the name, even if an error is thrown. This is so that we can 1731280031Sdim // continue to make some progress, even without the value having been 1732280031Sdim // initialized. 1733280031Sdim return DeclName; 1734226584Sdim } 1735226584Sdim 1736226584Sdim return DeclName; 1737226584Sdim} 1738226584Sdim 1739234353Sdim/// ParseForeachDeclaration - Read a foreach declaration, returning 1740234353Sdim/// the name of the declared object or a NULL Init on error. Return 1741234353Sdim/// the name of the parsed initializer list through ForeachListName. 1742234353Sdim/// 1743239462Sdim/// ForeachDeclaration ::= ID '=' '[' ValueList ']' 1744239462Sdim/// ForeachDeclaration ::= ID '=' '{' RangeList '}' 1745239462Sdim/// ForeachDeclaration ::= ID '=' RangePiece 1746234353Sdim/// 1747239462SdimVarInit *TGParser::ParseForeachDeclaration(ListInit *&ForeachListValue) { 1748234353Sdim if (Lex.getCode() != tgtok::Id) { 1749234353Sdim TokError("Expected identifier in foreach declaration"); 1750276479Sdim return nullptr; 1751234353Sdim } 1752234353Sdim 1753234353Sdim Init *DeclName = StringInit::get(Lex.getCurStrVal()); 1754234353Sdim Lex.Lex(); 1755234353Sdim 1756234353Sdim // If a value is present, parse it. 1757234353Sdim if (Lex.getCode() != tgtok::equal) { 1758234353Sdim TokError("Expected '=' in foreach declaration"); 1759276479Sdim return nullptr; 1760234353Sdim } 1761234353Sdim Lex.Lex(); // Eat the '=' 1762234353Sdim 1763276479Sdim RecTy *IterType = nullptr; 1764239462Sdim std::vector<unsigned> Ranges; 1765234353Sdim 1766239462Sdim switch (Lex.getCode()) { 1767276479Sdim default: TokError("Unknown token when expecting a range list"); return nullptr; 1768239462Sdim case tgtok::l_square: { // '[' ValueList ']' 1769276479Sdim Init *List = ParseSimpleValue(nullptr, nullptr, ParseForeachMode); 1770243830Sdim ForeachListValue = dyn_cast<ListInit>(List); 1771276479Sdim if (!ForeachListValue) { 1772239462Sdim TokError("Expected a Value list"); 1773276479Sdim return nullptr; 1774239462Sdim } 1775239462Sdim RecTy *ValueType = ForeachListValue->getType(); 1776243830Sdim ListRecTy *ListType = dyn_cast<ListRecTy>(ValueType); 1777276479Sdim if (!ListType) { 1778239462Sdim TokError("Value list is not of list type"); 1779276479Sdim return nullptr; 1780239462Sdim } 1781239462Sdim IterType = ListType->getElementType(); 1782239462Sdim break; 1783234353Sdim } 1784234353Sdim 1785239462Sdim case tgtok::IntVal: { // RangePiece. 1786239462Sdim if (ParseRangePiece(Ranges)) 1787276479Sdim return nullptr; 1788239462Sdim break; 1789234353Sdim } 1790234353Sdim 1791239462Sdim case tgtok::l_brace: { // '{' RangeList '}' 1792239462Sdim Lex.Lex(); // eat the '{' 1793239462Sdim Ranges = ParseRangeList(); 1794239462Sdim if (Lex.getCode() != tgtok::r_brace) { 1795239462Sdim TokError("expected '}' at end of bit range list"); 1796276479Sdim return nullptr; 1797239462Sdim } 1798239462Sdim Lex.Lex(); 1799239462Sdim break; 1800239462Sdim } 1801239462Sdim } 1802234353Sdim 1803239462Sdim if (!Ranges.empty()) { 1804239462Sdim assert(!IterType && "Type already initialized?"); 1805239462Sdim IterType = IntRecTy::get(); 1806239462Sdim std::vector<Init*> Values; 1807288943Sdim for (unsigned R : Ranges) 1808288943Sdim Values.push_back(IntInit::get(R)); 1809239462Sdim ForeachListValue = ListInit::get(Values, IterType); 1810239462Sdim } 1811239462Sdim 1812239462Sdim if (!IterType) 1813276479Sdim return nullptr; 1814239462Sdim 1815239462Sdim return VarInit::get(DeclName, IterType); 1816234353Sdim} 1817234353Sdim 1818226584Sdim/// ParseTemplateArgList - Read a template argument list, which is a non-empty 1819226584Sdim/// sequence of template-declarations in <>'s. If CurRec is non-null, these are 1820226584Sdim/// template args for a def, which may or may not be in a multiclass. If null, 1821226584Sdim/// these are the template args for a multiclass. 1822226584Sdim/// 1823226584Sdim/// TemplateArgList ::= '<' Declaration (',' Declaration)* '>' 1824226584Sdim/// 1825226584Sdimbool TGParser::ParseTemplateArgList(Record *CurRec) { 1826226584Sdim assert(Lex.getCode() == tgtok::less && "Not a template arg list!"); 1827226584Sdim Lex.Lex(); // eat the '<' 1828226584Sdim 1829226584Sdim Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->Rec; 1830226584Sdim 1831226584Sdim // Read the first declaration. 1832234353Sdim Init *TemplArg = ParseDeclaration(CurRec, true/*templateargs*/); 1833276479Sdim if (!TemplArg) 1834226584Sdim return true; 1835226584Sdim 1836226584Sdim TheRecToAddTo->addTemplateArg(TemplArg); 1837226584Sdim 1838226584Sdim while (Lex.getCode() == tgtok::comma) { 1839226584Sdim Lex.Lex(); // eat the ',' 1840226584Sdim 1841226584Sdim // Read the following declarations. 1842226584Sdim TemplArg = ParseDeclaration(CurRec, true/*templateargs*/); 1843276479Sdim if (!TemplArg) 1844226584Sdim return true; 1845226584Sdim TheRecToAddTo->addTemplateArg(TemplArg); 1846226584Sdim } 1847226584Sdim 1848226584Sdim if (Lex.getCode() != tgtok::greater) 1849226584Sdim return TokError("expected '>' at end of template argument list"); 1850226584Sdim Lex.Lex(); // eat the '>'. 1851226584Sdim return false; 1852226584Sdim} 1853226584Sdim 1854226584Sdim 1855226584Sdim/// ParseBodyItem - Parse a single item at within the body of a def or class. 1856226584Sdim/// 1857226584Sdim/// BodyItem ::= Declaration ';' 1858226584Sdim/// BodyItem ::= LET ID OptionalBitList '=' Value ';' 1859226584Sdimbool TGParser::ParseBodyItem(Record *CurRec) { 1860226584Sdim if (Lex.getCode() != tgtok::Let) { 1861276479Sdim if (!ParseDeclaration(CurRec, false)) 1862226584Sdim return true; 1863226584Sdim 1864226584Sdim if (Lex.getCode() != tgtok::semi) 1865226584Sdim return TokError("expected ';' after declaration"); 1866226584Sdim Lex.Lex(); 1867226584Sdim return false; 1868226584Sdim } 1869226584Sdim 1870226584Sdim // LET ID OptionalRangeList '=' Value ';' 1871226584Sdim if (Lex.Lex() != tgtok::Id) 1872226584Sdim return TokError("expected field identifier after let"); 1873226584Sdim 1874226584Sdim SMLoc IdLoc = Lex.getLoc(); 1875226584Sdim std::string FieldName = Lex.getCurStrVal(); 1876226584Sdim Lex.Lex(); // eat the field name. 1877226584Sdim 1878226584Sdim std::vector<unsigned> BitList; 1879226584Sdim if (ParseOptionalBitList(BitList)) 1880226584Sdim return true; 1881226584Sdim std::reverse(BitList.begin(), BitList.end()); 1882226584Sdim 1883226584Sdim if (Lex.getCode() != tgtok::equal) 1884226584Sdim return TokError("expected '=' in let expression"); 1885226584Sdim Lex.Lex(); // eat the '='. 1886226584Sdim 1887226584Sdim RecordVal *Field = CurRec->getValue(FieldName); 1888276479Sdim if (!Field) 1889226584Sdim return TokError("Value '" + FieldName + "' unknown!"); 1890226584Sdim 1891226584Sdim RecTy *Type = Field->getType(); 1892226584Sdim 1893226584Sdim Init *Val = ParseValue(CurRec, Type); 1894276479Sdim if (!Val) return true; 1895226584Sdim 1896226584Sdim if (Lex.getCode() != tgtok::semi) 1897226584Sdim return TokError("expected ';' after let expression"); 1898226584Sdim Lex.Lex(); 1899226584Sdim 1900226584Sdim return SetValue(CurRec, IdLoc, FieldName, BitList, Val); 1901226584Sdim} 1902226584Sdim 1903226584Sdim/// ParseBody - Read the body of a class or def. Return true on error, false on 1904226584Sdim/// success. 1905226584Sdim/// 1906226584Sdim/// Body ::= ';' 1907226584Sdim/// Body ::= '{' BodyList '}' 1908226584Sdim/// BodyList BodyItem* 1909226584Sdim/// 1910226584Sdimbool TGParser::ParseBody(Record *CurRec) { 1911226584Sdim // If this is a null definition, just eat the semi and return. 1912226584Sdim if (Lex.getCode() == tgtok::semi) { 1913226584Sdim Lex.Lex(); 1914226584Sdim return false; 1915226584Sdim } 1916226584Sdim 1917226584Sdim if (Lex.getCode() != tgtok::l_brace) 1918226584Sdim return TokError("Expected ';' or '{' to start body"); 1919226584Sdim // Eat the '{'. 1920226584Sdim Lex.Lex(); 1921226584Sdim 1922226584Sdim while (Lex.getCode() != tgtok::r_brace) 1923226584Sdim if (ParseBodyItem(CurRec)) 1924226584Sdim return true; 1925226584Sdim 1926226584Sdim // Eat the '}'. 1927226584Sdim Lex.Lex(); 1928226584Sdim return false; 1929226584Sdim} 1930226584Sdim 1931249423Sdim/// \brief Apply the current let bindings to \a CurRec. 1932249423Sdim/// \returns true on error, false otherwise. 1933249423Sdimbool TGParser::ApplyLetStack(Record *CurRec) { 1934288943Sdim for (std::vector<LetRecord> &LetInfo : LetStack) 1935288943Sdim for (LetRecord &LR : LetInfo) 1936288943Sdim if (SetValue(CurRec, LR.Loc, LR.Name, LR.Bits, LR.Value)) 1937249423Sdim return true; 1938249423Sdim return false; 1939249423Sdim} 1940249423Sdim 1941226584Sdim/// ParseObjectBody - Parse the body of a def or class. This consists of an 1942226584Sdim/// optional ClassList followed by a Body. CurRec is the current def or class 1943226584Sdim/// that is being parsed. 1944226584Sdim/// 1945226584Sdim/// ObjectBody ::= BaseClassList Body 1946226584Sdim/// BaseClassList ::= /*empty*/ 1947226584Sdim/// BaseClassList ::= ':' BaseClassListNE 1948226584Sdim/// BaseClassListNE ::= SubClassRef (',' SubClassRef)* 1949226584Sdim/// 1950226584Sdimbool TGParser::ParseObjectBody(Record *CurRec) { 1951226584Sdim // If there is a baseclass list, read it. 1952226584Sdim if (Lex.getCode() == tgtok::colon) { 1953226584Sdim Lex.Lex(); 1954226584Sdim 1955226584Sdim // Read all of the subclasses. 1956226584Sdim SubClassReference SubClass = ParseSubClassReference(CurRec, false); 1957226584Sdim while (1) { 1958226584Sdim // Check for error. 1959276479Sdim if (!SubClass.Rec) return true; 1960226584Sdim 1961226584Sdim // Add it. 1962226584Sdim if (AddSubClass(CurRec, SubClass)) 1963226584Sdim return true; 1964226584Sdim 1965226584Sdim if (Lex.getCode() != tgtok::comma) break; 1966226584Sdim Lex.Lex(); // eat ','. 1967226584Sdim SubClass = ParseSubClassReference(CurRec, false); 1968226584Sdim } 1969226584Sdim } 1970226584Sdim 1971249423Sdim if (ApplyLetStack(CurRec)) 1972249423Sdim return true; 1973226584Sdim 1974226584Sdim return ParseBody(CurRec); 1975226584Sdim} 1976226584Sdim 1977226584Sdim/// ParseDef - Parse and return a top level or multiclass def, return the record 1978226584Sdim/// corresponding to it. This returns null on error. 1979226584Sdim/// 1980226584Sdim/// DefInst ::= DEF ObjectName ObjectBody 1981226584Sdim/// 1982226584Sdimbool TGParser::ParseDef(MultiClass *CurMultiClass) { 1983226584Sdim SMLoc DefLoc = Lex.getLoc(); 1984226584Sdim assert(Lex.getCode() == tgtok::Def && "Unknown tok"); 1985226584Sdim Lex.Lex(); // Eat the 'def' token. 1986226584Sdim 1987226584Sdim // Parse ObjectName and make a record for it. 1988280031Sdim std::unique_ptr<Record> CurRecOwner; 1989249423Sdim Init *Name = ParseObjectName(CurMultiClass); 1990249423Sdim if (Name) 1991280031Sdim CurRecOwner = make_unique<Record>(Name, DefLoc, Records); 1992249423Sdim else 1993280031Sdim CurRecOwner = llvm::make_unique<Record>(GetNewAnonymousName(), DefLoc, 1994280031Sdim Records, /*IsAnonymous=*/true); 1995280031Sdim Record *CurRec = CurRecOwner.get(); // Keep a copy since we may release. 1996226584Sdim 1997239462Sdim if (!CurMultiClass && Loops.empty()) { 1998226584Sdim // Top-level def definition. 1999226584Sdim 2000226584Sdim // Ensure redefinition doesn't happen. 2001280031Sdim if (Records.getDef(CurRec->getNameInitAsString())) 2002280031Sdim return Error(DefLoc, "def '" + CurRec->getNameInitAsString()+ 2003280031Sdim "' already defined"); 2004280031Sdim Records.addDef(std::move(CurRecOwner)); 2005276479Sdim 2006276479Sdim if (ParseObjectBody(CurRec)) 2007276479Sdim return true; 2008239462Sdim } else if (CurMultiClass) { 2009276479Sdim // Parse the body before adding this prototype to the DefPrototypes vector. 2010276479Sdim // That way implicit definitions will be added to the DefPrototypes vector 2011276479Sdim // before this object, instantiated prior to defs derived from this object, 2012276479Sdim // and this available for indirect name resolution when defs derived from 2013276479Sdim // this object are instantiated. 2014276479Sdim if (ParseObjectBody(CurRec)) 2015276479Sdim return true; 2016276479Sdim 2017226584Sdim // Otherwise, a def inside a multiclass, add it to the multiclass. 2018288943Sdim for (const auto &Proto : CurMultiClass->DefPrototypes) 2019288943Sdim if (Proto->getNameInit() == CurRec->getNameInit()) 2020280031Sdim return Error(DefLoc, "def '" + CurRec->getNameInitAsString() + 2021280031Sdim "' already defined in this multiclass!"); 2022280031Sdim CurMultiClass->DefPrototypes.push_back(std::move(CurRecOwner)); 2023280031Sdim } else if (ParseObjectBody(CurRec)) { 2024226584Sdim return true; 2025280031Sdim } 2026226584Sdim 2027276479Sdim if (!CurMultiClass) // Def's in multiclasses aren't really defs. 2028226584Sdim // See Record::setName(). This resolve step will see any new name 2029226584Sdim // for the def that might have been created when resolving 2030226584Sdim // inheritance, values and arguments above. 2031226584Sdim CurRec->resolveReferences(); 2032226584Sdim 2033226584Sdim // If ObjectBody has template arguments, it's an error. 2034226584Sdim assert(CurRec->getTemplateArgs().empty() && "How'd this get template args?"); 2035226584Sdim 2036226584Sdim if (CurMultiClass) { 2037226584Sdim // Copy the template arguments for the multiclass into the def. 2038288943Sdim for (Init *TArg : CurMultiClass->Rec.getTemplateArgs()) { 2039288943Sdim const RecordVal *RV = CurMultiClass->Rec.getValue(TArg); 2040226584Sdim assert(RV && "Template arg doesn't exist?"); 2041226584Sdim CurRec->addValue(*RV); 2042226584Sdim } 2043226584Sdim } 2044226584Sdim 2045288943Sdim if (ProcessForeachDefs(CurRec, DefLoc)) 2046280031Sdim return Error(DefLoc, "Could not process loops for def" + 2047280031Sdim CurRec->getNameInitAsString()); 2048234353Sdim 2049226584Sdim return false; 2050226584Sdim} 2051226584Sdim 2052234353Sdim/// ParseForeach - Parse a for statement. Return the record corresponding 2053234353Sdim/// to it. This returns true on error. 2054234353Sdim/// 2055234353Sdim/// Foreach ::= FOREACH Declaration IN '{ ObjectList '}' 2056234353Sdim/// Foreach ::= FOREACH Declaration IN Object 2057234353Sdim/// 2058234353Sdimbool TGParser::ParseForeach(MultiClass *CurMultiClass) { 2059234353Sdim assert(Lex.getCode() == tgtok::Foreach && "Unknown tok"); 2060234353Sdim Lex.Lex(); // Eat the 'for' token. 2061234353Sdim 2062234353Sdim // Make a temporary object to record items associated with the for 2063234353Sdim // loop. 2064276479Sdim ListInit *ListValue = nullptr; 2065239462Sdim VarInit *IterName = ParseForeachDeclaration(ListValue); 2066276479Sdim if (!IterName) 2067234353Sdim return TokError("expected declaration in for"); 2068234353Sdim 2069234353Sdim if (Lex.getCode() != tgtok::In) 2070234353Sdim return TokError("Unknown tok"); 2071234353Sdim Lex.Lex(); // Eat the in 2072234353Sdim 2073234353Sdim // Create a loop object and remember it. 2074234353Sdim Loops.push_back(ForeachLoop(IterName, ListValue)); 2075234353Sdim 2076234353Sdim if (Lex.getCode() != tgtok::l_brace) { 2077234353Sdim // FOREACH Declaration IN Object 2078234353Sdim if (ParseObject(CurMultiClass)) 2079234353Sdim return true; 2080288943Sdim } else { 2081234353Sdim SMLoc BraceLoc = Lex.getLoc(); 2082234353Sdim // Otherwise, this is a group foreach. 2083234353Sdim Lex.Lex(); // eat the '{'. 2084234353Sdim 2085234353Sdim // Parse the object list. 2086234353Sdim if (ParseObjectList(CurMultiClass)) 2087234353Sdim return true; 2088234353Sdim 2089234353Sdim if (Lex.getCode() != tgtok::r_brace) { 2090234353Sdim TokError("expected '}' at end of foreach command"); 2091234353Sdim return Error(BraceLoc, "to match this '{'"); 2092234353Sdim } 2093234353Sdim Lex.Lex(); // Eat the } 2094234353Sdim } 2095234353Sdim 2096234353Sdim // We've processed everything in this loop. 2097234353Sdim Loops.pop_back(); 2098234353Sdim 2099234353Sdim return false; 2100234353Sdim} 2101234353Sdim 2102226584Sdim/// ParseClass - Parse a tblgen class definition. 2103226584Sdim/// 2104226584Sdim/// ClassInst ::= CLASS ID TemplateArgList? ObjectBody 2105226584Sdim/// 2106226584Sdimbool TGParser::ParseClass() { 2107226584Sdim assert(Lex.getCode() == tgtok::Class && "Unexpected token!"); 2108226584Sdim Lex.Lex(); 2109226584Sdim 2110226584Sdim if (Lex.getCode() != tgtok::Id) 2111226584Sdim return TokError("expected class name after 'class' keyword"); 2112226584Sdim 2113226584Sdim Record *CurRec = Records.getClass(Lex.getCurStrVal()); 2114226584Sdim if (CurRec) { 2115226584Sdim // If the body was previously defined, this is an error. 2116234353Sdim if (CurRec->getValues().size() > 1 || // Account for NAME. 2117226584Sdim !CurRec->getSuperClasses().empty() || 2118226584Sdim !CurRec->getTemplateArgs().empty()) 2119288943Sdim return TokError("Class '" + CurRec->getNameInitAsString() + 2120288943Sdim "' already defined"); 2121226584Sdim } else { 2122226584Sdim // If this is the first reference to this class, create and add it. 2123280031Sdim auto NewRec = 2124280031Sdim llvm::make_unique<Record>(Lex.getCurStrVal(), Lex.getLoc(), Records); 2125280031Sdim CurRec = NewRec.get(); 2126280031Sdim Records.addClass(std::move(NewRec)); 2127226584Sdim } 2128226584Sdim Lex.Lex(); // eat the name. 2129226584Sdim 2130226584Sdim // If there are template args, parse them. 2131226584Sdim if (Lex.getCode() == tgtok::less) 2132226584Sdim if (ParseTemplateArgList(CurRec)) 2133226584Sdim return true; 2134226584Sdim 2135226584Sdim // Finally, parse the object body. 2136226584Sdim return ParseObjectBody(CurRec); 2137226584Sdim} 2138226584Sdim 2139226584Sdim/// ParseLetList - Parse a non-empty list of assignment expressions into a list 2140226584Sdim/// of LetRecords. 2141226584Sdim/// 2142226584Sdim/// LetList ::= LetItem (',' LetItem)* 2143226584Sdim/// LetItem ::= ID OptionalRangeList '=' Value 2144226584Sdim/// 2145226584Sdimstd::vector<LetRecord> TGParser::ParseLetList() { 2146226584Sdim std::vector<LetRecord> Result; 2147226584Sdim 2148226584Sdim while (1) { 2149226584Sdim if (Lex.getCode() != tgtok::Id) { 2150226584Sdim TokError("expected identifier in let definition"); 2151226584Sdim return std::vector<LetRecord>(); 2152226584Sdim } 2153226584Sdim std::string Name = Lex.getCurStrVal(); 2154226584Sdim SMLoc NameLoc = Lex.getLoc(); 2155226584Sdim Lex.Lex(); // Eat the identifier. 2156226584Sdim 2157226584Sdim // Check for an optional RangeList. 2158226584Sdim std::vector<unsigned> Bits; 2159226584Sdim if (ParseOptionalRangeList(Bits)) 2160226584Sdim return std::vector<LetRecord>(); 2161226584Sdim std::reverse(Bits.begin(), Bits.end()); 2162226584Sdim 2163226584Sdim if (Lex.getCode() != tgtok::equal) { 2164226584Sdim TokError("expected '=' in let expression"); 2165226584Sdim return std::vector<LetRecord>(); 2166226584Sdim } 2167226584Sdim Lex.Lex(); // eat the '='. 2168226584Sdim 2169276479Sdim Init *Val = ParseValue(nullptr); 2170276479Sdim if (!Val) return std::vector<LetRecord>(); 2171226584Sdim 2172226584Sdim // Now that we have everything, add the record. 2173288943Sdim Result.emplace_back(std::move(Name), std::move(Bits), Val, NameLoc); 2174226584Sdim 2175226584Sdim if (Lex.getCode() != tgtok::comma) 2176226584Sdim return Result; 2177226584Sdim Lex.Lex(); // eat the comma. 2178226584Sdim } 2179226584Sdim} 2180226584Sdim 2181226584Sdim/// ParseTopLevelLet - Parse a 'let' at top level. This can be a couple of 2182226584Sdim/// different related productions. This works inside multiclasses too. 2183226584Sdim/// 2184226584Sdim/// Object ::= LET LetList IN '{' ObjectList '}' 2185226584Sdim/// Object ::= LET LetList IN Object 2186226584Sdim/// 2187226584Sdimbool TGParser::ParseTopLevelLet(MultiClass *CurMultiClass) { 2188226584Sdim assert(Lex.getCode() == tgtok::Let && "Unexpected token"); 2189226584Sdim Lex.Lex(); 2190226584Sdim 2191226584Sdim // Add this entry to the let stack. 2192226584Sdim std::vector<LetRecord> LetInfo = ParseLetList(); 2193226584Sdim if (LetInfo.empty()) return true; 2194280031Sdim LetStack.push_back(std::move(LetInfo)); 2195226584Sdim 2196226584Sdim if (Lex.getCode() != tgtok::In) 2197226584Sdim return TokError("expected 'in' at end of top-level 'let'"); 2198226584Sdim Lex.Lex(); 2199226584Sdim 2200226584Sdim // If this is a scalar let, just handle it now 2201226584Sdim if (Lex.getCode() != tgtok::l_brace) { 2202226584Sdim // LET LetList IN Object 2203226584Sdim if (ParseObject(CurMultiClass)) 2204226584Sdim return true; 2205226584Sdim } else { // Object ::= LETCommand '{' ObjectList '}' 2206226584Sdim SMLoc BraceLoc = Lex.getLoc(); 2207226584Sdim // Otherwise, this is a group let. 2208226584Sdim Lex.Lex(); // eat the '{'. 2209226584Sdim 2210226584Sdim // Parse the object list. 2211226584Sdim if (ParseObjectList(CurMultiClass)) 2212226584Sdim return true; 2213226584Sdim 2214226584Sdim if (Lex.getCode() != tgtok::r_brace) { 2215226584Sdim TokError("expected '}' at end of top level let command"); 2216226584Sdim return Error(BraceLoc, "to match this '{'"); 2217226584Sdim } 2218226584Sdim Lex.Lex(); 2219226584Sdim } 2220226584Sdim 2221226584Sdim // Outside this let scope, this let block is not active. 2222226584Sdim LetStack.pop_back(); 2223226584Sdim return false; 2224226584Sdim} 2225226584Sdim 2226226584Sdim/// ParseMultiClass - Parse a multiclass definition. 2227226584Sdim/// 2228226584Sdim/// MultiClassInst ::= MULTICLASS ID TemplateArgList? 2229249423Sdim/// ':' BaseMultiClassList '{' MultiClassObject+ '}' 2230249423Sdim/// MultiClassObject ::= DefInst 2231249423Sdim/// MultiClassObject ::= MultiClassInst 2232249423Sdim/// MultiClassObject ::= DefMInst 2233249423Sdim/// MultiClassObject ::= LETCommand '{' ObjectList '}' 2234249423Sdim/// MultiClassObject ::= LETCommand Object 2235226584Sdim/// 2236226584Sdimbool TGParser::ParseMultiClass() { 2237226584Sdim assert(Lex.getCode() == tgtok::MultiClass && "Unexpected token"); 2238226584Sdim Lex.Lex(); // Eat the multiclass token. 2239226584Sdim 2240226584Sdim if (Lex.getCode() != tgtok::Id) 2241226584Sdim return TokError("expected identifier after multiclass for name"); 2242226584Sdim std::string Name = Lex.getCurStrVal(); 2243226584Sdim 2244280031Sdim auto Result = 2245280031Sdim MultiClasses.insert(std::make_pair(Name, 2246280031Sdim llvm::make_unique<MultiClass>(Name, Lex.getLoc(),Records))); 2247280031Sdim 2248280031Sdim if (!Result.second) 2249226584Sdim return TokError("multiclass '" + Name + "' already defined"); 2250226584Sdim 2251280031Sdim CurMultiClass = Result.first->second.get(); 2252226584Sdim Lex.Lex(); // Eat the identifier. 2253226584Sdim 2254226584Sdim // If there are template args, parse them. 2255226584Sdim if (Lex.getCode() == tgtok::less) 2256276479Sdim if (ParseTemplateArgList(nullptr)) 2257226584Sdim return true; 2258226584Sdim 2259226584Sdim bool inherits = false; 2260226584Sdim 2261226584Sdim // If there are submulticlasses, parse them. 2262226584Sdim if (Lex.getCode() == tgtok::colon) { 2263226584Sdim inherits = true; 2264226584Sdim 2265226584Sdim Lex.Lex(); 2266226584Sdim 2267226584Sdim // Read all of the submulticlasses. 2268226584Sdim SubMultiClassReference SubMultiClass = 2269226584Sdim ParseSubMultiClassReference(CurMultiClass); 2270226584Sdim while (1) { 2271226584Sdim // Check for error. 2272276479Sdim if (!SubMultiClass.MC) return true; 2273226584Sdim 2274226584Sdim // Add it. 2275226584Sdim if (AddSubMultiClass(CurMultiClass, SubMultiClass)) 2276226584Sdim return true; 2277226584Sdim 2278226584Sdim if (Lex.getCode() != tgtok::comma) break; 2279226584Sdim Lex.Lex(); // eat ','. 2280226584Sdim SubMultiClass = ParseSubMultiClassReference(CurMultiClass); 2281226584Sdim } 2282226584Sdim } 2283226584Sdim 2284226584Sdim if (Lex.getCode() != tgtok::l_brace) { 2285226584Sdim if (!inherits) 2286226584Sdim return TokError("expected '{' in multiclass definition"); 2287280031Sdim if (Lex.getCode() != tgtok::semi) 2288226584Sdim return TokError("expected ';' in multiclass definition"); 2289280031Sdim Lex.Lex(); // eat the ';'. 2290226584Sdim } else { 2291226584Sdim if (Lex.Lex() == tgtok::r_brace) // eat the '{'. 2292226584Sdim return TokError("multiclass must contain at least one def"); 2293226584Sdim 2294226584Sdim while (Lex.getCode() != tgtok::r_brace) { 2295226584Sdim switch (Lex.getCode()) { 2296280031Sdim default: 2297280031Sdim return TokError("expected 'let', 'def' or 'defm' in multiclass body"); 2298280031Sdim case tgtok::Let: 2299280031Sdim case tgtok::Def: 2300280031Sdim case tgtok::Defm: 2301280031Sdim case tgtok::Foreach: 2302280031Sdim if (ParseObject(CurMultiClass)) 2303280031Sdim return true; 2304280031Sdim break; 2305226584Sdim } 2306226584Sdim } 2307226584Sdim Lex.Lex(); // eat the '}'. 2308226584Sdim } 2309226584Sdim 2310276479Sdim CurMultiClass = nullptr; 2311226584Sdim return false; 2312226584Sdim} 2313226584Sdim 2314296417SdimRecord *TGParser::InstantiateMulticlassDef(MultiClass &MC, Record *DefProto, 2315296417Sdim Init *&DefmPrefix, 2316296417Sdim SMRange DefmPrefixRange, 2317296417Sdim ArrayRef<Init *> TArgs, 2318296417Sdim std::vector<Init *> &TemplateVals) { 2319234353Sdim // We need to preserve DefProto so it can be reused for later 2320234353Sdim // instantiations, so create a new Record to inherit from it. 2321234353Sdim 2322226584Sdim // Add in the defm name. If the defm prefix is empty, give each 2323226584Sdim // instantiated def a unique name. Otherwise, if "#NAME#" exists in the 2324226584Sdim // name, substitute the prefix for #NAME#. Otherwise, use the defm name 2325226584Sdim // as a prefix. 2326234353Sdim 2327249423Sdim bool IsAnonymous = false; 2328276479Sdim if (!DefmPrefix) { 2329234353Sdim DefmPrefix = StringInit::get(GetNewAnonymousName()); 2330249423Sdim IsAnonymous = true; 2331249423Sdim } 2332234353Sdim 2333234353Sdim Init *DefName = DefProto->getNameInit(); 2334243830Sdim StringInit *DefNameString = dyn_cast<StringInit>(DefName); 2335234353Sdim 2336276479Sdim if (DefNameString) { 2337234353Sdim // We have a fully expanded string so there are no operators to 2338234353Sdim // resolve. We should concatenate the given prefix and name. 2339234353Sdim DefName = 2340234353Sdim BinOpInit::get(BinOpInit::STRCONCAT, 2341234353Sdim UnOpInit::get(UnOpInit::CAST, DefmPrefix, 2342234353Sdim StringRecTy::get())->Fold(DefProto, &MC), 2343234353Sdim DefName, StringRecTy::get())->Fold(DefProto, &MC); 2344226584Sdim } 2345226584Sdim 2346243830Sdim // Make a trail of SMLocs from the multiclass instantiations. 2347249423Sdim SmallVector<SMLoc, 4> Locs(1, DefmPrefixRange.Start); 2348243830Sdim Locs.append(DefProto->getLoc().begin(), DefProto->getLoc().end()); 2349280031Sdim auto CurRec = make_unique<Record>(DefName, Locs, Records, IsAnonymous); 2350226584Sdim 2351226584Sdim SubClassReference Ref; 2352249423Sdim Ref.RefRange = DefmPrefixRange; 2353226584Sdim Ref.Rec = DefProto; 2354280031Sdim AddSubClass(CurRec.get(), Ref); 2355226584Sdim 2356239462Sdim // Set the value for NAME. We don't resolve references to it 'til later, 2357239462Sdim // though, so that uses in nested multiclass names don't get 2358239462Sdim // confused. 2359296417Sdim if (SetValue(CurRec.get(), Ref.RefRange.Start, "NAME", None, DefmPrefix, 2360296417Sdim /*AllowSelfAssignment*/true)) { 2361288943Sdim Error(DefmPrefixRange.Start, "Could not resolve " + 2362288943Sdim CurRec->getNameInitAsString() + ":NAME to '" + 2363288943Sdim DefmPrefix->getAsUnquotedString() + "'"); 2364276479Sdim return nullptr; 2365239462Sdim } 2366239462Sdim 2367239462Sdim // If the DefNameString didn't resolve, we probably have a reference to 2368239462Sdim // NAME and need to replace it. We need to do at least this much greedily, 2369239462Sdim // otherwise nested multiclasses will end up with incorrect NAME expansions. 2370276479Sdim if (!DefNameString) { 2371234353Sdim RecordVal *DefNameRV = CurRec->getValue("NAME"); 2372234353Sdim CurRec->resolveReferencesTo(DefNameRV); 2373234353Sdim } 2374234353Sdim 2375234353Sdim if (!CurMultiClass) { 2376239462Sdim // Now that we're at the top level, resolve all NAME references 2377239462Sdim // in the resultant defs that weren't in the def names themselves. 2378239462Sdim RecordVal *DefNameRV = CurRec->getValue("NAME"); 2379239462Sdim CurRec->resolveReferencesTo(DefNameRV); 2380239462Sdim 2381288943Sdim // Check if the name is a complex pattern. 2382288943Sdim // If so, resolve it. 2383288943Sdim DefName = CurRec->getNameInit(); 2384288943Sdim DefNameString = dyn_cast<StringInit>(DefName); 2385288943Sdim 2386288943Sdim // OK the pattern is more complex than simply using NAME. 2387288943Sdim // Let's use the heavy weaponery. 2388288943Sdim if (!DefNameString) { 2389288943Sdim ResolveMulticlassDefArgs(MC, CurRec.get(), DefmPrefixRange.Start, 2390288943Sdim Lex.getLoc(), TArgs, TemplateVals, 2391288943Sdim false/*Delete args*/); 2392288943Sdim DefName = CurRec->getNameInit(); 2393288943Sdim DefNameString = dyn_cast<StringInit>(DefName); 2394288943Sdim 2395288943Sdim if (!DefNameString) 2396288943Sdim DefName = DefName->convertInitializerTo(StringRecTy::get()); 2397288943Sdim 2398288943Sdim // We ran out of options here... 2399288943Sdim DefNameString = dyn_cast<StringInit>(DefName); 2400288943Sdim if (!DefNameString) { 2401288943Sdim PrintFatalError(CurRec->getLoc()[CurRec->getLoc().size() - 1], 2402288943Sdim DefName->getAsUnquotedString() + " is not a string."); 2403288943Sdim return nullptr; 2404288943Sdim } 2405288943Sdim 2406288943Sdim CurRec->setName(DefName); 2407288943Sdim } 2408288943Sdim 2409239462Sdim // Now that NAME references are resolved and we're at the top level of 2410239462Sdim // any multiclass expansions, add the record to the RecordKeeper. If we are 2411234353Sdim // currently in a multiclass, it means this defm appears inside a 2412234353Sdim // multiclass and its name won't be fully resolvable until we see 2413288943Sdim // the top-level defm. Therefore, we don't add this to the 2414288943Sdim // RecordKeeper at this point. If we did we could get duplicate 2415234353Sdim // defs as more than one probably refers to NAME or some other 2416234353Sdim // common internal placeholder. 2417234353Sdim 2418234353Sdim // Ensure redefinition doesn't happen. 2419234353Sdim if (Records.getDef(CurRec->getNameInitAsString())) { 2420249423Sdim Error(DefmPrefixRange.Start, "def '" + CurRec->getNameInitAsString() + 2421234353Sdim "' already defined, instantiating defm with subdef '" + 2422234353Sdim DefProto->getNameInitAsString() + "'"); 2423276479Sdim return nullptr; 2424234353Sdim } 2425234353Sdim 2426280031Sdim Record *CurRecSave = CurRec.get(); // Keep a copy before we release. 2427280031Sdim Records.addDef(std::move(CurRec)); 2428280031Sdim return CurRecSave; 2429234353Sdim } 2430234353Sdim 2431280031Sdim // FIXME This is bad but the ownership transfer to caller is pretty messy. 2432280031Sdim // The unique_ptr in this function at least protects the exits above. 2433280031Sdim return CurRec.release(); 2434226584Sdim} 2435226584Sdim 2436296417Sdimbool TGParser::ResolveMulticlassDefArgs(MultiClass &MC, Record *CurRec, 2437296417Sdim SMLoc DefmPrefixLoc, SMLoc SubClassLoc, 2438296417Sdim ArrayRef<Init *> TArgs, 2439226584Sdim std::vector<Init *> &TemplateVals, 2440226584Sdim bool DeleteArgs) { 2441226584Sdim // Loop over all of the template arguments, setting them to the specified 2442226584Sdim // value or leaving them as the default if necessary. 2443226584Sdim for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { 2444226584Sdim // Check if a value is specified for this temp-arg. 2445226584Sdim if (i < TemplateVals.size()) { 2446226584Sdim // Set it now. 2447296417Sdim if (SetValue(CurRec, DefmPrefixLoc, TArgs[i], None, TemplateVals[i])) 2448226584Sdim return true; 2449288943Sdim 2450226584Sdim // Resolve it next. 2451226584Sdim CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i])); 2452226584Sdim 2453226584Sdim if (DeleteArgs) 2454226584Sdim // Now remove it. 2455226584Sdim CurRec->removeValue(TArgs[i]); 2456288943Sdim 2457226584Sdim } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) { 2458288943Sdim return Error(SubClassLoc, "value not specified for template argument #" + 2459288943Sdim Twine(i) + " (" + TArgs[i]->getAsUnquotedString() + 2460288943Sdim ") of multiclassclass '" + MC.Rec.getNameInitAsString() + 2461288943Sdim "'"); 2462226584Sdim } 2463226584Sdim } 2464226584Sdim return false; 2465226584Sdim} 2466226584Sdim 2467226584Sdimbool TGParser::ResolveMulticlassDef(MultiClass &MC, 2468226584Sdim Record *CurRec, 2469226584Sdim Record *DefProto, 2470226584Sdim SMLoc DefmPrefixLoc) { 2471226584Sdim // If the mdef is inside a 'let' expression, add to each def. 2472249423Sdim if (ApplyLetStack(CurRec)) 2473249423Sdim return Error(DefmPrefixLoc, "when instantiating this defm"); 2474226584Sdim 2475226584Sdim // Don't create a top level definition for defm inside multiclasses, 2476226584Sdim // instead, only update the prototypes and bind the template args 2477226584Sdim // with the new created definition. 2478249423Sdim if (!CurMultiClass) 2479249423Sdim return false; 2480288943Sdim for (const auto &Proto : CurMultiClass->DefPrototypes) 2481288943Sdim if (Proto->getNameInit() == CurRec->getNameInit()) 2482249423Sdim return Error(DefmPrefixLoc, "defm '" + CurRec->getNameInitAsString() + 2483249423Sdim "' already defined in this multiclass!"); 2484280031Sdim CurMultiClass->DefPrototypes.push_back(std::unique_ptr<Record>(CurRec)); 2485226584Sdim 2486249423Sdim // Copy the template arguments for the multiclass into the new def. 2487288943Sdim for (Init * TA : CurMultiClass->Rec.getTemplateArgs()) { 2488288943Sdim const RecordVal *RV = CurMultiClass->Rec.getValue(TA); 2489249423Sdim assert(RV && "Template arg doesn't exist?"); 2490249423Sdim CurRec->addValue(*RV); 2491226584Sdim } 2492226584Sdim 2493226584Sdim return false; 2494226584Sdim} 2495226584Sdim 2496226584Sdim/// ParseDefm - Parse the instantiation of a multiclass. 2497226584Sdim/// 2498226584Sdim/// DefMInst ::= DEFM ID ':' DefmSubClassRef ';' 2499226584Sdim/// 2500226584Sdimbool TGParser::ParseDefm(MultiClass *CurMultiClass) { 2501226584Sdim assert(Lex.getCode() == tgtok::Defm && "Unexpected token!"); 2502249423Sdim SMLoc DefmLoc = Lex.getLoc(); 2503276479Sdim Init *DefmPrefix = nullptr; 2504234353Sdim 2505226584Sdim if (Lex.Lex() == tgtok::Id) { // eat the defm. 2506234353Sdim DefmPrefix = ParseObjectName(CurMultiClass); 2507226584Sdim } 2508226584Sdim 2509249423Sdim SMLoc DefmPrefixEndLoc = Lex.getLoc(); 2510226584Sdim if (Lex.getCode() != tgtok::colon) 2511226584Sdim return TokError("expected ':' after defm identifier"); 2512226584Sdim 2513226584Sdim // Keep track of the new generated record definitions. 2514226584Sdim std::vector<Record*> NewRecDefs; 2515226584Sdim 2516226584Sdim // This record also inherits from a regular class (non-multiclass)? 2517226584Sdim bool InheritFromClass = false; 2518226584Sdim 2519226584Sdim // eat the colon. 2520226584Sdim Lex.Lex(); 2521226584Sdim 2522226584Sdim SMLoc SubClassLoc = Lex.getLoc(); 2523276479Sdim SubClassReference Ref = ParseSubClassReference(nullptr, true); 2524226584Sdim 2525226584Sdim while (1) { 2526276479Sdim if (!Ref.Rec) return true; 2527226584Sdim 2528226584Sdim // To instantiate a multiclass, we need to first get the multiclass, then 2529226584Sdim // instantiate each def contained in the multiclass with the SubClassRef 2530226584Sdim // template parameters. 2531280031Sdim MultiClass *MC = MultiClasses[Ref.Rec->getName()].get(); 2532226584Sdim assert(MC && "Didn't lookup multiclass correctly?"); 2533226584Sdim std::vector<Init*> &TemplateVals = Ref.TemplateArgs; 2534226584Sdim 2535226584Sdim // Verify that the correct number of template arguments were specified. 2536296417Sdim ArrayRef<Init *> TArgs = MC->Rec.getTemplateArgs(); 2537226584Sdim if (TArgs.size() < TemplateVals.size()) 2538226584Sdim return Error(SubClassLoc, 2539226584Sdim "more template args specified than multiclass expects"); 2540226584Sdim 2541226584Sdim // Loop over all the def's in the multiclass, instantiating each one. 2542288943Sdim for (const std::unique_ptr<Record> &DefProto : MC->DefPrototypes) { 2543288943Sdim // The record name construction goes as follow: 2544288943Sdim // - If the def name is a string, prepend the prefix. 2545288943Sdim // - If the def name is a more complex pattern, use that pattern. 2546288943Sdim // As a result, the record is instanciated before resolving 2547288943Sdim // arguments, as it would make its name a string. 2548288943Sdim Record *CurRec = InstantiateMulticlassDef(*MC, DefProto.get(), DefmPrefix, 2549249423Sdim SMRange(DefmLoc, 2550288943Sdim DefmPrefixEndLoc), 2551288943Sdim TArgs, TemplateVals); 2552234353Sdim if (!CurRec) 2553234353Sdim return true; 2554226584Sdim 2555288943Sdim // Now that the record is instanciated, we can resolve arguments. 2556249423Sdim if (ResolveMulticlassDefArgs(*MC, CurRec, DefmLoc, SubClassLoc, 2557226584Sdim TArgs, TemplateVals, true/*Delete args*/)) 2558226584Sdim return Error(SubClassLoc, "could not instantiate def"); 2559226584Sdim 2560288943Sdim if (ResolveMulticlassDef(*MC, CurRec, DefProto.get(), DefmLoc)) 2561226584Sdim return Error(SubClassLoc, "could not instantiate def"); 2562226584Sdim 2563280031Sdim // Defs that can be used by other definitions should be fully resolved 2564280031Sdim // before any use. 2565280031Sdim if (DefProto->isResolveFirst() && !CurMultiClass) { 2566280031Sdim CurRec->resolveReferences(); 2567280031Sdim CurRec->setResolveFirst(false); 2568280031Sdim } 2569226584Sdim NewRecDefs.push_back(CurRec); 2570226584Sdim } 2571226584Sdim 2572226584Sdim 2573226584Sdim if (Lex.getCode() != tgtok::comma) break; 2574226584Sdim Lex.Lex(); // eat ','. 2575226584Sdim 2576261991Sdim if (Lex.getCode() != tgtok::Id) 2577261991Sdim return TokError("expected identifier"); 2578261991Sdim 2579226584Sdim SubClassLoc = Lex.getLoc(); 2580226584Sdim 2581226584Sdim // A defm can inherit from regular classes (non-multiclass) as 2582226584Sdim // long as they come in the end of the inheritance list. 2583276479Sdim InheritFromClass = (Records.getClass(Lex.getCurStrVal()) != nullptr); 2584226584Sdim 2585226584Sdim if (InheritFromClass) 2586226584Sdim break; 2587226584Sdim 2588276479Sdim Ref = ParseSubClassReference(nullptr, true); 2589226584Sdim } 2590226584Sdim 2591226584Sdim if (InheritFromClass) { 2592226584Sdim // Process all the classes to inherit as if they were part of a 2593226584Sdim // regular 'def' and inherit all record values. 2594276479Sdim SubClassReference SubClass = ParseSubClassReference(nullptr, false); 2595226584Sdim while (1) { 2596226584Sdim // Check for error. 2597276479Sdim if (!SubClass.Rec) return true; 2598226584Sdim 2599226584Sdim // Get the expanded definition prototypes and teach them about 2600226584Sdim // the record values the current class to inherit has 2601288943Sdim for (Record *CurRec : NewRecDefs) { 2602226584Sdim // Add it. 2603226584Sdim if (AddSubClass(CurRec, SubClass)) 2604226584Sdim return true; 2605226584Sdim 2606249423Sdim if (ApplyLetStack(CurRec)) 2607249423Sdim return true; 2608226584Sdim } 2609226584Sdim 2610226584Sdim if (Lex.getCode() != tgtok::comma) break; 2611226584Sdim Lex.Lex(); // eat ','. 2612276479Sdim SubClass = ParseSubClassReference(nullptr, false); 2613226584Sdim } 2614226584Sdim } 2615226584Sdim 2616226584Sdim if (!CurMultiClass) 2617288943Sdim for (Record *CurRec : NewRecDefs) 2618226584Sdim // See Record::setName(). This resolve step will see any new 2619226584Sdim // name for the def that might have been created when resolving 2620226584Sdim // inheritance, values and arguments above. 2621288943Sdim CurRec->resolveReferences(); 2622226584Sdim 2623226584Sdim if (Lex.getCode() != tgtok::semi) 2624226584Sdim return TokError("expected ';' at end of defm"); 2625226584Sdim Lex.Lex(); 2626226584Sdim 2627226584Sdim return false; 2628226584Sdim} 2629226584Sdim 2630226584Sdim/// ParseObject 2631226584Sdim/// Object ::= ClassInst 2632226584Sdim/// Object ::= DefInst 2633226584Sdim/// Object ::= MultiClassInst 2634226584Sdim/// Object ::= DefMInst 2635226584Sdim/// Object ::= LETCommand '{' ObjectList '}' 2636226584Sdim/// Object ::= LETCommand Object 2637226584Sdimbool TGParser::ParseObject(MultiClass *MC) { 2638226584Sdim switch (Lex.getCode()) { 2639226584Sdim default: 2640226584Sdim return TokError("Expected class, def, defm, multiclass or let definition"); 2641226584Sdim case tgtok::Let: return ParseTopLevelLet(MC); 2642226584Sdim case tgtok::Def: return ParseDef(MC); 2643234353Sdim case tgtok::Foreach: return ParseForeach(MC); 2644226584Sdim case tgtok::Defm: return ParseDefm(MC); 2645226584Sdim case tgtok::Class: return ParseClass(); 2646226584Sdim case tgtok::MultiClass: return ParseMultiClass(); 2647226584Sdim } 2648226584Sdim} 2649226584Sdim 2650226584Sdim/// ParseObjectList 2651226584Sdim/// ObjectList :== Object* 2652226584Sdimbool TGParser::ParseObjectList(MultiClass *MC) { 2653226584Sdim while (isObjectStart(Lex.getCode())) { 2654226584Sdim if (ParseObject(MC)) 2655226584Sdim return true; 2656226584Sdim } 2657226584Sdim return false; 2658226584Sdim} 2659226584Sdim 2660226584Sdimbool TGParser::ParseFile() { 2661226584Sdim Lex.Lex(); // Prime the lexer. 2662226584Sdim if (ParseObjectList()) return true; 2663226584Sdim 2664226584Sdim // If we have unread input at the end of the file, report it. 2665226584Sdim if (Lex.getCode() == tgtok::Eof) 2666226584Sdim return false; 2667226584Sdim 2668226584Sdim return TokError("Unexpected input at top level"); 2669226584Sdim} 2670226584Sdim 2671