TGParser.cpp revision 309124
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" 18226584Sdim#include "llvm/TableGen/Record.h" 19226584Sdim#include <algorithm> 20226584Sdimusing namespace llvm; 21226584Sdim 22226584Sdim//===----------------------------------------------------------------------===// 23226584Sdim// Support Code for the Semantic Actions. 24226584Sdim//===----------------------------------------------------------------------===// 25226584Sdim 26226584Sdimnamespace llvm { 27226584Sdimstruct SubClassReference { 28249423Sdim SMRange RefRange; 29226584Sdim Record *Rec; 30226584Sdim std::vector<Init*> TemplateArgs; 31276479Sdim SubClassReference() : Rec(nullptr) {} 32226584Sdim 33276479Sdim bool isInvalid() const { return Rec == nullptr; } 34226584Sdim}; 35226584Sdim 36226584Sdimstruct SubMultiClassReference { 37249423Sdim SMRange RefRange; 38226584Sdim MultiClass *MC; 39226584Sdim std::vector<Init*> TemplateArgs; 40276479Sdim SubMultiClassReference() : MC(nullptr) {} 41226584Sdim 42276479Sdim bool isInvalid() const { return MC == nullptr; } 43226584Sdim void dump() const; 44226584Sdim}; 45226584Sdim 46309124SdimLLVM_DUMP_METHOD void SubMultiClassReference::dump() const { 47226584Sdim errs() << "Multiclass:\n"; 48226584Sdim 49226584Sdim MC->dump(); 50226584Sdim 51226584Sdim errs() << "Template args:\n"; 52288943Sdim for (Init *TA : TemplateArgs) 53288943Sdim TA->dump(); 54226584Sdim} 55226584Sdim 56226584Sdim} // end namespace llvm 57226584Sdim 58226584Sdimbool TGParser::AddValue(Record *CurRec, SMLoc Loc, const RecordVal &RV) { 59276479Sdim if (!CurRec) 60226584Sdim CurRec = &CurMultiClass->Rec; 61226584Sdim 62234353Sdim if (RecordVal *ERV = CurRec->getValue(RV.getNameInit())) { 63226584Sdim // The value already exists in the class, treat this as a set. 64226584Sdim if (ERV->setValue(RV.getValue())) 65226584Sdim return Error(Loc, "New definition of '" + RV.getName() + "' of type '" + 66226584Sdim RV.getType()->getAsString() + "' is incompatible with " + 67226584Sdim "previous definition of type '" + 68226584Sdim ERV->getType()->getAsString() + "'"); 69226584Sdim } else { 70226584Sdim CurRec->addValue(RV); 71226584Sdim } 72226584Sdim return false; 73226584Sdim} 74226584Sdim 75226584Sdim/// SetValue - 76226584Sdim/// Return true on error, false on success. 77234353Sdimbool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName, 78296417Sdim ArrayRef<unsigned> BitList, Init *V, 79296417Sdim bool AllowSelfAssignment) { 80226584Sdim if (!V) return false; 81226584Sdim 82276479Sdim if (!CurRec) CurRec = &CurMultiClass->Rec; 83226584Sdim 84226584Sdim RecordVal *RV = CurRec->getValue(ValName); 85276479Sdim if (!RV) 86288943Sdim return Error(Loc, "Value '" + ValName->getAsUnquotedString() + 87288943Sdim "' unknown!"); 88226584Sdim 89226584Sdim // Do not allow assignments like 'X = X'. This will just cause infinite loops 90226584Sdim // in the resolution machinery. 91226584Sdim if (BitList.empty()) 92243830Sdim if (VarInit *VI = dyn_cast<VarInit>(V)) 93296417Sdim if (VI->getNameInit() == ValName && !AllowSelfAssignment) 94296417Sdim return true; 95226584Sdim 96226584Sdim // If we are assigning to a subset of the bits in the value... then we must be 97226584Sdim // assigning to a field of BitsRecTy, which must have a BitsInit 98226584Sdim // initializer. 99226584Sdim // 100226584Sdim if (!BitList.empty()) { 101243830Sdim BitsInit *CurVal = dyn_cast<BitsInit>(RV->getValue()); 102276479Sdim if (!CurVal) 103288943Sdim return Error(Loc, "Value '" + ValName->getAsUnquotedString() + 104288943Sdim "' is not a bits type"); 105226584Sdim 106226584Sdim // Convert the incoming value to a bits type of the appropriate size... 107226584Sdim Init *BI = V->convertInitializerTo(BitsRecTy::get(BitList.size())); 108288943Sdim if (!BI) 109226584Sdim return Error(Loc, "Initializer is not compatible with bit range"); 110226584Sdim 111226584Sdim // We should have a BitsInit type now. 112288943Sdim BitsInit *BInit = cast<BitsInit>(BI); 113226584Sdim 114226584Sdim SmallVector<Init *, 16> NewBits(CurVal->getNumBits()); 115226584Sdim 116226584Sdim // Loop over bits, assigning values as appropriate. 117226584Sdim for (unsigned i = 0, e = BitList.size(); i != e; ++i) { 118226584Sdim unsigned Bit = BitList[i]; 119226584Sdim if (NewBits[Bit]) 120288943Sdim return Error(Loc, "Cannot set bit #" + Twine(Bit) + " of value '" + 121234353Sdim ValName->getAsUnquotedString() + "' more than once"); 122226584Sdim NewBits[Bit] = BInit->getBit(i); 123226584Sdim } 124226584Sdim 125226584Sdim for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i) 126276479Sdim if (!NewBits[i]) 127226584Sdim NewBits[i] = CurVal->getBit(i); 128226584Sdim 129226584Sdim V = BitsInit::get(NewBits); 130226584Sdim } 131226584Sdim 132280031Sdim if (RV->setValue(V)) { 133280031Sdim std::string InitType = ""; 134288943Sdim if (BitsInit *BI = dyn_cast<BitsInit>(V)) 135280031Sdim InitType = (Twine("' of type bit initializer with length ") + 136280031Sdim Twine(BI->getNumBits())).str(); 137288943Sdim return Error(Loc, "Value '" + ValName->getAsUnquotedString() + 138288943Sdim "' of type '" + RV->getType()->getAsString() + 139288943Sdim "' is incompatible with initializer '" + V->getAsString() + 140288943Sdim InitType + "'"); 141280031Sdim } 142226584Sdim return false; 143226584Sdim} 144226584Sdim 145226584Sdim/// AddSubClass - Add SubClass as a subclass to CurRec, resolving its template 146226584Sdim/// args as SubClass's template arguments. 147226584Sdimbool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) { 148226584Sdim Record *SC = SubClass.Rec; 149226584Sdim // Add all of the values in the subclass into the current class. 150288943Sdim for (const RecordVal &Val : SC->getValues()) 151288943Sdim if (AddValue(CurRec, SubClass.RefRange.Start, Val)) 152226584Sdim return true; 153226584Sdim 154296417Sdim ArrayRef<Init *> TArgs = SC->getTemplateArgs(); 155226584Sdim 156226584Sdim // Ensure that an appropriate number of template arguments are specified. 157226584Sdim if (TArgs.size() < SubClass.TemplateArgs.size()) 158249423Sdim return Error(SubClass.RefRange.Start, 159249423Sdim "More template args specified than expected"); 160226584Sdim 161226584Sdim // Loop over all of the template arguments, setting them to the specified 162226584Sdim // value or leaving them as the default if necessary. 163226584Sdim for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { 164226584Sdim if (i < SubClass.TemplateArgs.size()) { 165226584Sdim // If a value is specified for this template arg, set it now. 166249423Sdim if (SetValue(CurRec, SubClass.RefRange.Start, TArgs[i], 167296417Sdim None, SubClass.TemplateArgs[i])) 168226584Sdim return true; 169226584Sdim 170226584Sdim // Resolve it next. 171226584Sdim CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i])); 172226584Sdim 173226584Sdim // Now remove it. 174226584Sdim CurRec->removeValue(TArgs[i]); 175226584Sdim 176226584Sdim } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) { 177249423Sdim return Error(SubClass.RefRange.Start, 178288943Sdim "Value not specified for template argument #" + 179288943Sdim Twine(i) + " (" + TArgs[i]->getAsUnquotedString() + 180288943Sdim ") of subclass '" + SC->getNameInitAsString() + "'!"); 181226584Sdim } 182226584Sdim } 183226584Sdim 184226584Sdim // Since everything went well, we can now set the "superclass" list for the 185226584Sdim // current record. 186309124Sdim ArrayRef<std::pair<Record *, SMRange>> SCs = SC->getSuperClasses(); 187309124Sdim for (const auto &SCPair : SCs) { 188309124Sdim if (CurRec->isSubClassOf(SCPair.first)) 189249423Sdim return Error(SubClass.RefRange.Start, 190309124Sdim "Already subclass of '" + SCPair.first->getName() + "'!\n"); 191309124Sdim CurRec->addSuperClass(SCPair.first, SCPair.second); 192226584Sdim } 193226584Sdim 194226584Sdim if (CurRec->isSubClassOf(SC)) 195249423Sdim return Error(SubClass.RefRange.Start, 196226584Sdim "Already subclass of '" + SC->getName() + "'!\n"); 197249423Sdim CurRec->addSuperClass(SC, SubClass.RefRange); 198226584Sdim return false; 199226584Sdim} 200226584Sdim 201226584Sdim/// AddSubMultiClass - Add SubMultiClass as a subclass to 202226584Sdim/// CurMC, resolving its template args as SubMultiClass's 203226584Sdim/// template arguments. 204226584Sdimbool TGParser::AddSubMultiClass(MultiClass *CurMC, 205226584Sdim SubMultiClassReference &SubMultiClass) { 206226584Sdim MultiClass *SMC = SubMultiClass.MC; 207226584Sdim Record *CurRec = &CurMC->Rec; 208226584Sdim 209226584Sdim // Add all of the values in the subclass into the current class. 210288943Sdim for (const auto &SMCVal : SMC->Rec.getValues()) 211288943Sdim if (AddValue(CurRec, SubMultiClass.RefRange.Start, SMCVal)) 212226584Sdim return true; 213226584Sdim 214280031Sdim unsigned newDefStart = CurMC->DefPrototypes.size(); 215226584Sdim 216226584Sdim // Add all of the defs in the subclass into the current multiclass. 217288943Sdim for (const std::unique_ptr<Record> &R : SMC->DefPrototypes) { 218226584Sdim // Clone the def and add it to the current multiclass 219288943Sdim auto NewDef = make_unique<Record>(*R); 220226584Sdim 221226584Sdim // Add all of the values in the superclass into the current def. 222288943Sdim for (const auto &MCVal : CurRec->getValues()) 223288943Sdim if (AddValue(NewDef.get(), SubMultiClass.RefRange.Start, MCVal)) 224226584Sdim return true; 225226584Sdim 226280031Sdim CurMC->DefPrototypes.push_back(std::move(NewDef)); 227226584Sdim } 228226584Sdim 229296417Sdim ArrayRef<Init *> SMCTArgs = SMC->Rec.getTemplateArgs(); 230226584Sdim 231226584Sdim // Ensure that an appropriate number of template arguments are 232226584Sdim // specified. 233226584Sdim if (SMCTArgs.size() < SubMultiClass.TemplateArgs.size()) 234249423Sdim return Error(SubMultiClass.RefRange.Start, 235226584Sdim "More template args specified than expected"); 236226584Sdim 237226584Sdim // Loop over all of the template arguments, setting them to the specified 238226584Sdim // value or leaving them as the default if necessary. 239226584Sdim for (unsigned i = 0, e = SMCTArgs.size(); i != e; ++i) { 240226584Sdim if (i < SubMultiClass.TemplateArgs.size()) { 241226584Sdim // If a value is specified for this template arg, set it in the 242226584Sdim // superclass now. 243249423Sdim if (SetValue(CurRec, SubMultiClass.RefRange.Start, SMCTArgs[i], 244296417Sdim None, SubMultiClass.TemplateArgs[i])) 245226584Sdim return true; 246226584Sdim 247226584Sdim // Resolve it next. 248226584Sdim CurRec->resolveReferencesTo(CurRec->getValue(SMCTArgs[i])); 249226584Sdim 250226584Sdim // Now remove it. 251226584Sdim CurRec->removeValue(SMCTArgs[i]); 252226584Sdim 253226584Sdim // If a value is specified for this template arg, set it in the 254226584Sdim // new defs now. 255280031Sdim for (const auto &Def : 256280031Sdim makeArrayRef(CurMC->DefPrototypes).slice(newDefStart)) { 257280031Sdim if (SetValue(Def.get(), SubMultiClass.RefRange.Start, SMCTArgs[i], 258296417Sdim None, SubMultiClass.TemplateArgs[i])) 259226584Sdim return true; 260226584Sdim 261226584Sdim // Resolve it next. 262226584Sdim Def->resolveReferencesTo(Def->getValue(SMCTArgs[i])); 263226584Sdim 264226584Sdim // Now remove it 265226584Sdim Def->removeValue(SMCTArgs[i]); 266226584Sdim } 267226584Sdim } else if (!CurRec->getValue(SMCTArgs[i])->getValue()->isComplete()) { 268249423Sdim return Error(SubMultiClass.RefRange.Start, 269288943Sdim "Value not specified for template argument #" + 270288943Sdim Twine(i) + " (" + SMCTArgs[i]->getAsUnquotedString() + 271288943Sdim ") of subclass '" + SMC->Rec.getNameInitAsString() + "'!"); 272226584Sdim } 273226584Sdim } 274226584Sdim 275226584Sdim return false; 276226584Sdim} 277226584Sdim 278234353Sdim/// ProcessForeachDefs - Given a record, apply all of the variable 279234353Sdim/// values in all surrounding foreach loops, creating new records for 280234353Sdim/// each combination of values. 281239462Sdimbool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc) { 282239462Sdim if (Loops.empty()) 283239462Sdim return false; 284239462Sdim 285234353Sdim // We want to instantiate a new copy of CurRec for each combination 286234353Sdim // of nested loop iterator values. We don't want top instantiate 287234353Sdim // any copies until we have values for each loop iterator. 288234353Sdim IterSet IterVals; 289239462Sdim return ProcessForeachDefs(CurRec, Loc, IterVals); 290234353Sdim} 291234353Sdim 292234353Sdim/// ProcessForeachDefs - Given a record, a loop and a loop iterator, 293234353Sdim/// apply each of the variable values in this loop and then process 294234353Sdim/// subloops. 295239462Sdimbool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals){ 296239462Sdim // Recursively build a tuple of iterator values. 297239462Sdim if (IterVals.size() != Loops.size()) { 298239462Sdim assert(IterVals.size() < Loops.size()); 299239462Sdim ForeachLoop &CurLoop = Loops[IterVals.size()]; 300243830Sdim ListInit *List = dyn_cast<ListInit>(CurLoop.ListValue); 301276479Sdim if (!List) { 302239462Sdim Error(Loc, "Loop list is not a list"); 303239462Sdim return true; 304239462Sdim } 305234353Sdim 306239462Sdim // Process each value. 307288943Sdim for (unsigned i = 0; i < List->size(); ++i) { 308276479Sdim Init *ItemVal = List->resolveListElementReference(*CurRec, nullptr, i); 309239462Sdim IterVals.push_back(IterRecord(CurLoop.IterVar, ItemVal)); 310239462Sdim if (ProcessForeachDefs(CurRec, Loc, IterVals)) 311239462Sdim return true; 312239462Sdim IterVals.pop_back(); 313239462Sdim } 314239462Sdim return false; 315234353Sdim } 316234353Sdim 317239462Sdim // This is the bottom of the recursion. We have all of the iterator values 318239462Sdim // for this point in the iteration space. Instantiate a new record to 319239462Sdim // reflect this combination of values. 320280031Sdim auto IterRec = make_unique<Record>(*CurRec); 321234353Sdim 322239462Sdim // Set the iterator values now. 323288943Sdim for (IterRecord &IR : IterVals) { 324288943Sdim VarInit *IterVar = IR.IterVar; 325288943Sdim TypedInit *IVal = dyn_cast<TypedInit>(IR.IterValue); 326280031Sdim if (!IVal) 327280031Sdim return Error(Loc, "foreach iterator value is untyped"); 328234353Sdim 329239462Sdim IterRec->addValue(RecordVal(IterVar->getName(), IVal->getType(), false)); 330234353Sdim 331296417Sdim if (SetValue(IterRec.get(), Loc, IterVar->getName(), None, IVal)) 332280031Sdim return Error(Loc, "when instantiating this def"); 333234353Sdim 334239462Sdim // Resolve it next. 335239462Sdim IterRec->resolveReferencesTo(IterRec->getValue(IterVar->getName())); 336234353Sdim 337239462Sdim // Remove it. 338239462Sdim IterRec->removeValue(IterVar->getName()); 339239462Sdim } 340234353Sdim 341239462Sdim if (Records.getDef(IterRec->getNameInitAsString())) { 342276479Sdim // If this record is anonymous, it's no problem, just generate a new name 343280031Sdim if (!IterRec->isAnonymous()) 344280031Sdim return Error(Loc, "def already exists: " +IterRec->getNameInitAsString()); 345280031Sdim 346280031Sdim IterRec->setName(GetNewAnonymousName()); 347239462Sdim } 348234353Sdim 349280031Sdim Record *IterRecSave = IterRec.get(); // Keep a copy before release. 350280031Sdim Records.addDef(std::move(IterRec)); 351280031Sdim IterRecSave->resolveReferences(); 352234353Sdim return false; 353234353Sdim} 354234353Sdim 355226584Sdim//===----------------------------------------------------------------------===// 356226584Sdim// Parser Code 357226584Sdim//===----------------------------------------------------------------------===// 358226584Sdim 359226584Sdim/// isObjectStart - Return true if this is a valid first token for an Object. 360226584Sdimstatic bool isObjectStart(tgtok::TokKind K) { 361226584Sdim return K == tgtok::Class || K == tgtok::Def || 362234353Sdim K == tgtok::Defm || K == tgtok::Let || 363234353Sdim K == tgtok::MultiClass || K == tgtok::Foreach; 364226584Sdim} 365226584Sdim 366276479Sdim/// GetNewAnonymousName - Generate a unique anonymous name that can be used as 367276479Sdim/// an identifier. 368276479Sdimstd::string TGParser::GetNewAnonymousName() { 369288943Sdim return "anonymous_" + utostr(AnonCounter++); 370226584Sdim} 371226584Sdim 372226584Sdim/// ParseObjectName - If an object name is specified, return it. Otherwise, 373249423Sdim/// return 0. 374234353Sdim/// ObjectName ::= Value [ '#' Value ]* 375226584Sdim/// ObjectName ::= /*empty*/ 376226584Sdim/// 377234353SdimInit *TGParser::ParseObjectName(MultiClass *CurMultiClass) { 378234353Sdim switch (Lex.getCode()) { 379234353Sdim case tgtok::colon: 380234353Sdim case tgtok::semi: 381234353Sdim case tgtok::l_brace: 382234353Sdim // These are all of the tokens that can begin an object body. 383234353Sdim // Some of these can also begin values but we disallow those cases 384234353Sdim // because they are unlikely to be useful. 385276479Sdim return nullptr; 386234353Sdim default: 387234353Sdim break; 388234353Sdim } 389226584Sdim 390276479Sdim Record *CurRec = nullptr; 391234353Sdim if (CurMultiClass) 392234353Sdim CurRec = &CurMultiClass->Rec; 393234353Sdim 394276479Sdim RecTy *Type = nullptr; 395234353Sdim if (CurRec) { 396243830Sdim const TypedInit *CurRecName = dyn_cast<TypedInit>(CurRec->getNameInit()); 397234353Sdim if (!CurRecName) { 398234353Sdim TokError("Record name is not typed!"); 399276479Sdim return nullptr; 400234353Sdim } 401234353Sdim Type = CurRecName->getType(); 402234353Sdim } 403234353Sdim 404234353Sdim return ParseValue(CurRec, Type, ParseNameMode); 405226584Sdim} 406226584Sdim 407226584Sdim/// ParseClassID - Parse and resolve a reference to a class name. This returns 408226584Sdim/// null on error. 409226584Sdim/// 410226584Sdim/// ClassID ::= ID 411226584Sdim/// 412226584SdimRecord *TGParser::ParseClassID() { 413226584Sdim if (Lex.getCode() != tgtok::Id) { 414226584Sdim TokError("expected name for ClassID"); 415276479Sdim return nullptr; 416226584Sdim } 417226584Sdim 418226584Sdim Record *Result = Records.getClass(Lex.getCurStrVal()); 419276479Sdim if (!Result) 420226584Sdim TokError("Couldn't find class '" + Lex.getCurStrVal() + "'"); 421226584Sdim 422226584Sdim Lex.Lex(); 423226584Sdim return Result; 424226584Sdim} 425226584Sdim 426226584Sdim/// ParseMultiClassID - Parse and resolve a reference to a multiclass name. 427226584Sdim/// This returns null on error. 428226584Sdim/// 429226584Sdim/// MultiClassID ::= ID 430226584Sdim/// 431226584SdimMultiClass *TGParser::ParseMultiClassID() { 432226584Sdim if (Lex.getCode() != tgtok::Id) { 433249423Sdim TokError("expected name for MultiClassID"); 434276479Sdim return nullptr; 435226584Sdim } 436226584Sdim 437280031Sdim MultiClass *Result = MultiClasses[Lex.getCurStrVal()].get(); 438276479Sdim if (!Result) 439249423Sdim TokError("Couldn't find multiclass '" + Lex.getCurStrVal() + "'"); 440226584Sdim 441226584Sdim Lex.Lex(); 442226584Sdim return Result; 443226584Sdim} 444226584Sdim 445226584Sdim/// ParseSubClassReference - Parse a reference to a subclass or to a templated 446226584Sdim/// subclass. This returns a SubClassRefTy with a null Record* on error. 447226584Sdim/// 448226584Sdim/// SubClassRef ::= ClassID 449226584Sdim/// SubClassRef ::= ClassID '<' ValueList '>' 450226584Sdim/// 451226584SdimSubClassReference TGParser:: 452226584SdimParseSubClassReference(Record *CurRec, bool isDefm) { 453226584Sdim SubClassReference Result; 454249423Sdim Result.RefRange.Start = Lex.getLoc(); 455226584Sdim 456249423Sdim if (isDefm) { 457249423Sdim if (MultiClass *MC = ParseMultiClassID()) 458249423Sdim Result.Rec = &MC->Rec; 459249423Sdim } else { 460226584Sdim Result.Rec = ParseClassID(); 461249423Sdim } 462276479Sdim if (!Result.Rec) return Result; 463226584Sdim 464226584Sdim // If there is no template arg list, we're done. 465249423Sdim if (Lex.getCode() != tgtok::less) { 466249423Sdim Result.RefRange.End = Lex.getLoc(); 467226584Sdim return Result; 468249423Sdim } 469226584Sdim Lex.Lex(); // Eat the '<' 470226584Sdim 471226584Sdim if (Lex.getCode() == tgtok::greater) { 472226584Sdim TokError("subclass reference requires a non-empty list of template values"); 473276479Sdim Result.Rec = nullptr; 474226584Sdim return Result; 475226584Sdim } 476226584Sdim 477226584Sdim Result.TemplateArgs = ParseValueList(CurRec, Result.Rec); 478226584Sdim if (Result.TemplateArgs.empty()) { 479276479Sdim Result.Rec = nullptr; // Error parsing value list. 480226584Sdim return Result; 481226584Sdim } 482226584Sdim 483226584Sdim if (Lex.getCode() != tgtok::greater) { 484226584Sdim TokError("expected '>' in template value list"); 485276479Sdim Result.Rec = nullptr; 486226584Sdim return Result; 487226584Sdim } 488226584Sdim Lex.Lex(); 489249423Sdim Result.RefRange.End = Lex.getLoc(); 490226584Sdim 491226584Sdim return Result; 492226584Sdim} 493226584Sdim 494226584Sdim/// ParseSubMultiClassReference - Parse a reference to a subclass or to a 495226584Sdim/// templated submulticlass. This returns a SubMultiClassRefTy with a null 496226584Sdim/// Record* on error. 497226584Sdim/// 498226584Sdim/// SubMultiClassRef ::= MultiClassID 499226584Sdim/// SubMultiClassRef ::= MultiClassID '<' ValueList '>' 500226584Sdim/// 501226584SdimSubMultiClassReference TGParser:: 502226584SdimParseSubMultiClassReference(MultiClass *CurMC) { 503226584Sdim SubMultiClassReference Result; 504249423Sdim Result.RefRange.Start = Lex.getLoc(); 505226584Sdim 506226584Sdim Result.MC = ParseMultiClassID(); 507276479Sdim if (!Result.MC) return Result; 508226584Sdim 509226584Sdim // If there is no template arg list, we're done. 510249423Sdim if (Lex.getCode() != tgtok::less) { 511249423Sdim Result.RefRange.End = Lex.getLoc(); 512226584Sdim return Result; 513249423Sdim } 514226584Sdim Lex.Lex(); // Eat the '<' 515226584Sdim 516226584Sdim if (Lex.getCode() == tgtok::greater) { 517226584Sdim TokError("subclass reference requires a non-empty list of template values"); 518276479Sdim Result.MC = nullptr; 519226584Sdim return Result; 520226584Sdim } 521226584Sdim 522226584Sdim Result.TemplateArgs = ParseValueList(&CurMC->Rec, &Result.MC->Rec); 523226584Sdim if (Result.TemplateArgs.empty()) { 524276479Sdim Result.MC = nullptr; // Error parsing value list. 525226584Sdim return Result; 526226584Sdim } 527226584Sdim 528226584Sdim if (Lex.getCode() != tgtok::greater) { 529226584Sdim TokError("expected '>' in template value list"); 530276479Sdim Result.MC = nullptr; 531226584Sdim return Result; 532226584Sdim } 533226584Sdim Lex.Lex(); 534249423Sdim Result.RefRange.End = Lex.getLoc(); 535226584Sdim 536226584Sdim return Result; 537226584Sdim} 538226584Sdim 539226584Sdim/// ParseRangePiece - Parse a bit/value range. 540226584Sdim/// RangePiece ::= INTVAL 541226584Sdim/// RangePiece ::= INTVAL '-' INTVAL 542226584Sdim/// RangePiece ::= INTVAL INTVAL 543226584Sdimbool TGParser::ParseRangePiece(std::vector<unsigned> &Ranges) { 544226584Sdim if (Lex.getCode() != tgtok::IntVal) { 545226584Sdim TokError("expected integer or bitrange"); 546226584Sdim return true; 547226584Sdim } 548226584Sdim int64_t Start = Lex.getCurIntVal(); 549226584Sdim int64_t End; 550226584Sdim 551226584Sdim if (Start < 0) 552226584Sdim return TokError("invalid range, cannot be negative"); 553226584Sdim 554226584Sdim switch (Lex.Lex()) { // eat first character. 555226584Sdim default: 556226584Sdim Ranges.push_back(Start); 557226584Sdim return false; 558226584Sdim case tgtok::minus: 559226584Sdim if (Lex.Lex() != tgtok::IntVal) { 560226584Sdim TokError("expected integer value as end of range"); 561226584Sdim return true; 562226584Sdim } 563226584Sdim End = Lex.getCurIntVal(); 564226584Sdim break; 565226584Sdim case tgtok::IntVal: 566226584Sdim End = -Lex.getCurIntVal(); 567226584Sdim break; 568226584Sdim } 569226584Sdim if (End < 0) 570226584Sdim return TokError("invalid range, cannot be negative"); 571226584Sdim Lex.Lex(); 572226584Sdim 573226584Sdim // Add to the range. 574288943Sdim if (Start < End) 575226584Sdim for (; Start <= End; ++Start) 576226584Sdim Ranges.push_back(Start); 577288943Sdim else 578226584Sdim for (; Start >= End; --Start) 579226584Sdim Ranges.push_back(Start); 580226584Sdim return false; 581226584Sdim} 582226584Sdim 583226584Sdim/// ParseRangeList - Parse a list of scalars and ranges into scalar values. 584226584Sdim/// 585226584Sdim/// RangeList ::= RangePiece (',' RangePiece)* 586226584Sdim/// 587226584Sdimstd::vector<unsigned> TGParser::ParseRangeList() { 588226584Sdim std::vector<unsigned> Result; 589226584Sdim 590226584Sdim // Parse the first piece. 591226584Sdim if (ParseRangePiece(Result)) 592226584Sdim return std::vector<unsigned>(); 593226584Sdim while (Lex.getCode() == tgtok::comma) { 594226584Sdim Lex.Lex(); // Eat the comma. 595226584Sdim 596226584Sdim // Parse the next range piece. 597226584Sdim if (ParseRangePiece(Result)) 598226584Sdim return std::vector<unsigned>(); 599226584Sdim } 600226584Sdim return Result; 601226584Sdim} 602226584Sdim 603226584Sdim/// ParseOptionalRangeList - Parse either a range list in <>'s or nothing. 604226584Sdim/// OptionalRangeList ::= '<' RangeList '>' 605226584Sdim/// OptionalRangeList ::= /*empty*/ 606226584Sdimbool TGParser::ParseOptionalRangeList(std::vector<unsigned> &Ranges) { 607226584Sdim if (Lex.getCode() != tgtok::less) 608226584Sdim return false; 609226584Sdim 610226584Sdim SMLoc StartLoc = Lex.getLoc(); 611226584Sdim Lex.Lex(); // eat the '<' 612226584Sdim 613226584Sdim // Parse the range list. 614226584Sdim Ranges = ParseRangeList(); 615226584Sdim if (Ranges.empty()) return true; 616226584Sdim 617226584Sdim if (Lex.getCode() != tgtok::greater) { 618226584Sdim TokError("expected '>' at end of range list"); 619226584Sdim return Error(StartLoc, "to match this '<'"); 620226584Sdim } 621226584Sdim Lex.Lex(); // eat the '>'. 622226584Sdim return false; 623226584Sdim} 624226584Sdim 625226584Sdim/// ParseOptionalBitList - Parse either a bit list in {}'s or nothing. 626226584Sdim/// OptionalBitList ::= '{' RangeList '}' 627226584Sdim/// OptionalBitList ::= /*empty*/ 628226584Sdimbool TGParser::ParseOptionalBitList(std::vector<unsigned> &Ranges) { 629226584Sdim if (Lex.getCode() != tgtok::l_brace) 630226584Sdim return false; 631226584Sdim 632226584Sdim SMLoc StartLoc = Lex.getLoc(); 633226584Sdim Lex.Lex(); // eat the '{' 634226584Sdim 635226584Sdim // Parse the range list. 636226584Sdim Ranges = ParseRangeList(); 637226584Sdim if (Ranges.empty()) return true; 638226584Sdim 639226584Sdim if (Lex.getCode() != tgtok::r_brace) { 640226584Sdim TokError("expected '}' at end of bit list"); 641226584Sdim return Error(StartLoc, "to match this '{'"); 642226584Sdim } 643226584Sdim Lex.Lex(); // eat the '}'. 644226584Sdim return false; 645226584Sdim} 646226584Sdim 647226584Sdim 648226584Sdim/// ParseType - Parse and return a tblgen type. This returns null on error. 649226584Sdim/// 650226584Sdim/// Type ::= STRING // string type 651234353Sdim/// Type ::= CODE // code type 652226584Sdim/// Type ::= BIT // bit type 653226584Sdim/// Type ::= BITS '<' INTVAL '>' // bits<x> type 654226584Sdim/// Type ::= INT // int type 655226584Sdim/// Type ::= LIST '<' Type '>' // list<x> type 656226584Sdim/// Type ::= DAG // dag type 657226584Sdim/// Type ::= ClassID // Record Type 658226584Sdim/// 659226584SdimRecTy *TGParser::ParseType() { 660226584Sdim switch (Lex.getCode()) { 661276479Sdim default: TokError("Unknown token when expecting a type"); return nullptr; 662226584Sdim case tgtok::String: Lex.Lex(); return StringRecTy::get(); 663309124Sdim case tgtok::Code: Lex.Lex(); return CodeRecTy::get(); 664226584Sdim case tgtok::Bit: Lex.Lex(); return BitRecTy::get(); 665226584Sdim case tgtok::Int: Lex.Lex(); return IntRecTy::get(); 666226584Sdim case tgtok::Dag: Lex.Lex(); return DagRecTy::get(); 667226584Sdim case tgtok::Id: 668226584Sdim if (Record *R = ParseClassID()) return RecordRecTy::get(R); 669276479Sdim return nullptr; 670226584Sdim case tgtok::Bits: { 671226584Sdim if (Lex.Lex() != tgtok::less) { // Eat 'bits' 672226584Sdim TokError("expected '<' after bits type"); 673276479Sdim return nullptr; 674226584Sdim } 675226584Sdim if (Lex.Lex() != tgtok::IntVal) { // Eat '<' 676226584Sdim TokError("expected integer in bits<n> type"); 677276479Sdim return nullptr; 678226584Sdim } 679226584Sdim uint64_t Val = Lex.getCurIntVal(); 680226584Sdim if (Lex.Lex() != tgtok::greater) { // Eat count. 681226584Sdim TokError("expected '>' at end of bits<n> type"); 682276479Sdim return nullptr; 683226584Sdim } 684226584Sdim Lex.Lex(); // Eat '>' 685226584Sdim return BitsRecTy::get(Val); 686226584Sdim } 687226584Sdim case tgtok::List: { 688226584Sdim if (Lex.Lex() != tgtok::less) { // Eat 'bits' 689226584Sdim TokError("expected '<' after list type"); 690276479Sdim return nullptr; 691226584Sdim } 692226584Sdim Lex.Lex(); // Eat '<' 693226584Sdim RecTy *SubType = ParseType(); 694276479Sdim if (!SubType) return nullptr; 695226584Sdim 696226584Sdim if (Lex.getCode() != tgtok::greater) { 697226584Sdim TokError("expected '>' at end of list<ty> type"); 698276479Sdim return nullptr; 699226584Sdim } 700226584Sdim Lex.Lex(); // Eat '>' 701226584Sdim return ListRecTy::get(SubType); 702226584Sdim } 703226584Sdim } 704226584Sdim} 705226584Sdim 706226584Sdim/// ParseIDValue - This is just like ParseIDValue above, but it assumes the ID 707226584Sdim/// has already been read. 708226584SdimInit *TGParser::ParseIDValue(Record *CurRec, 709234353Sdim const std::string &Name, SMLoc NameLoc, 710234353Sdim IDParseMode Mode) { 711226584Sdim if (CurRec) { 712226584Sdim if (const RecordVal *RV = CurRec->getValue(Name)) 713226584Sdim return VarInit::get(Name, RV->getType()); 714226584Sdim 715234353Sdim Init *TemplateArgName = QualifyName(*CurRec, CurMultiClass, Name, ":"); 716234353Sdim 717226584Sdim if (CurMultiClass) 718234353Sdim TemplateArgName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name, 719234353Sdim "::"); 720226584Sdim 721226584Sdim if (CurRec->isTemplateArg(TemplateArgName)) { 722226584Sdim const RecordVal *RV = CurRec->getValue(TemplateArgName); 723226584Sdim assert(RV && "Template arg doesn't exist??"); 724226584Sdim return VarInit::get(TemplateArgName, RV->getType()); 725226584Sdim } 726226584Sdim } 727226584Sdim 728226584Sdim if (CurMultiClass) { 729234353Sdim Init *MCName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name, 730234353Sdim "::"); 731234353Sdim 732226584Sdim if (CurMultiClass->Rec.isTemplateArg(MCName)) { 733226584Sdim const RecordVal *RV = CurMultiClass->Rec.getValue(MCName); 734226584Sdim assert(RV && "Template arg doesn't exist??"); 735226584Sdim return VarInit::get(MCName, RV->getType()); 736226584Sdim } 737226584Sdim } 738226584Sdim 739234353Sdim // If this is in a foreach loop, make sure it's not a loop iterator 740288943Sdim for (const auto &L : Loops) { 741288943Sdim VarInit *IterVar = dyn_cast<VarInit>(L.IterVar); 742234353Sdim if (IterVar && IterVar->getName() == Name) 743234353Sdim return IterVar; 744234353Sdim } 745234353Sdim 746234353Sdim if (Mode == ParseNameMode) 747234353Sdim return StringInit::get(Name); 748234353Sdim 749226584Sdim if (Record *D = Records.getDef(Name)) 750226584Sdim return DefInit::get(D); 751226584Sdim 752234353Sdim if (Mode == ParseValueMode) { 753234353Sdim Error(NameLoc, "Variable not defined: '" + Name + "'"); 754276479Sdim return nullptr; 755234353Sdim } 756288943Sdim 757234353Sdim return StringInit::get(Name); 758226584Sdim} 759226584Sdim 760226584Sdim/// ParseOperation - Parse an operator. This returns null on error. 761226584Sdim/// 762226584Sdim/// Operation ::= XOperator ['<' Type '>'] '(' Args ')' 763226584Sdim/// 764276479SdimInit *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) { 765226584Sdim switch (Lex.getCode()) { 766226584Sdim default: 767226584Sdim TokError("unknown operation"); 768276479Sdim return nullptr; 769226584Sdim case tgtok::XHead: 770226584Sdim case tgtok::XTail: 771226584Sdim case tgtok::XEmpty: 772226584Sdim case tgtok::XCast: { // Value ::= !unop '(' Value ')' 773226584Sdim UnOpInit::UnaryOp Code; 774276479Sdim RecTy *Type = nullptr; 775226584Sdim 776226584Sdim switch (Lex.getCode()) { 777234353Sdim default: llvm_unreachable("Unhandled code!"); 778226584Sdim case tgtok::XCast: 779226584Sdim Lex.Lex(); // eat the operation 780226584Sdim Code = UnOpInit::CAST; 781226584Sdim 782226584Sdim Type = ParseOperatorType(); 783226584Sdim 784276479Sdim if (!Type) { 785226584Sdim TokError("did not get type for unary operator"); 786276479Sdim return nullptr; 787226584Sdim } 788226584Sdim 789226584Sdim break; 790226584Sdim case tgtok::XHead: 791226584Sdim Lex.Lex(); // eat the operation 792226584Sdim Code = UnOpInit::HEAD; 793226584Sdim break; 794226584Sdim case tgtok::XTail: 795226584Sdim Lex.Lex(); // eat the operation 796226584Sdim Code = UnOpInit::TAIL; 797226584Sdim break; 798226584Sdim case tgtok::XEmpty: 799226584Sdim Lex.Lex(); // eat the operation 800226584Sdim Code = UnOpInit::EMPTY; 801226584Sdim Type = IntRecTy::get(); 802226584Sdim break; 803226584Sdim } 804226584Sdim if (Lex.getCode() != tgtok::l_paren) { 805226584Sdim TokError("expected '(' after unary operator"); 806276479Sdim return nullptr; 807226584Sdim } 808226584Sdim Lex.Lex(); // eat the '(' 809226584Sdim 810226584Sdim Init *LHS = ParseValue(CurRec); 811276479Sdim if (!LHS) return nullptr; 812226584Sdim 813288943Sdim if (Code == UnOpInit::HEAD || 814288943Sdim Code == UnOpInit::TAIL || 815288943Sdim Code == UnOpInit::EMPTY) { 816243830Sdim ListInit *LHSl = dyn_cast<ListInit>(LHS); 817243830Sdim StringInit *LHSs = dyn_cast<StringInit>(LHS); 818243830Sdim TypedInit *LHSt = dyn_cast<TypedInit>(LHS); 819276479Sdim if (!LHSl && !LHSs && !LHSt) { 820226584Sdim TokError("expected list or string type argument in unary operator"); 821276479Sdim return nullptr; 822226584Sdim } 823226584Sdim if (LHSt) { 824243830Sdim ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType()); 825243830Sdim StringRecTy *SType = dyn_cast<StringRecTy>(LHSt->getType()); 826276479Sdim if (!LType && !SType) { 827276479Sdim TokError("expected list or string type argument in unary operator"); 828276479Sdim return nullptr; 829226584Sdim } 830226584Sdim } 831226584Sdim 832288943Sdim if (Code == UnOpInit::HEAD || Code == UnOpInit::TAIL) { 833276479Sdim if (!LHSl && !LHSt) { 834276479Sdim TokError("expected list type argument in unary operator"); 835276479Sdim return nullptr; 836226584Sdim } 837226584Sdim 838288943Sdim if (LHSl && LHSl->empty()) { 839226584Sdim TokError("empty list argument in unary operator"); 840276479Sdim return nullptr; 841226584Sdim } 842226584Sdim if (LHSl) { 843226584Sdim Init *Item = LHSl->getElement(0); 844243830Sdim TypedInit *Itemt = dyn_cast<TypedInit>(Item); 845276479Sdim if (!Itemt) { 846226584Sdim TokError("untyped list element in unary operator"); 847276479Sdim return nullptr; 848226584Sdim } 849288943Sdim Type = (Code == UnOpInit::HEAD) ? Itemt->getType() 850288943Sdim : ListRecTy::get(Itemt->getType()); 851226584Sdim } else { 852226584Sdim assert(LHSt && "expected list type argument in unary operator"); 853243830Sdim ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType()); 854276479Sdim if (!LType) { 855276479Sdim TokError("expected list type argument in unary operator"); 856276479Sdim return nullptr; 857226584Sdim } 858288943Sdim Type = (Code == UnOpInit::HEAD) ? LType->getElementType() : LType; 859226584Sdim } 860226584Sdim } 861226584Sdim } 862226584Sdim 863226584Sdim if (Lex.getCode() != tgtok::r_paren) { 864226584Sdim TokError("expected ')' in unary operator"); 865276479Sdim return nullptr; 866226584Sdim } 867226584Sdim Lex.Lex(); // eat the ')' 868226584Sdim return (UnOpInit::get(Code, LHS, Type))->Fold(CurRec, CurMultiClass); 869226584Sdim } 870226584Sdim 871226584Sdim case tgtok::XConcat: 872249423Sdim case tgtok::XADD: 873280031Sdim case tgtok::XAND: 874226584Sdim case tgtok::XSRA: 875226584Sdim case tgtok::XSRL: 876226584Sdim case tgtok::XSHL: 877226584Sdim case tgtok::XEq: 878276479Sdim case tgtok::XListConcat: 879226584Sdim case tgtok::XStrConcat: { // Value ::= !binop '(' Value ',' Value ')' 880226584Sdim tgtok::TokKind OpTok = Lex.getCode(); 881226584Sdim SMLoc OpLoc = Lex.getLoc(); 882226584Sdim Lex.Lex(); // eat the operation 883226584Sdim 884226584Sdim BinOpInit::BinaryOp Code; 885276479Sdim RecTy *Type = nullptr; 886226584Sdim 887226584Sdim switch (OpTok) { 888234353Sdim default: llvm_unreachable("Unhandled code!"); 889226584Sdim case tgtok::XConcat: Code = BinOpInit::CONCAT;Type = DagRecTy::get(); break; 890249423Sdim case tgtok::XADD: Code = BinOpInit::ADD; Type = IntRecTy::get(); break; 891280031Sdim case tgtok::XAND: Code = BinOpInit::AND; Type = IntRecTy::get(); break; 892226584Sdim case tgtok::XSRA: Code = BinOpInit::SRA; Type = IntRecTy::get(); break; 893226584Sdim case tgtok::XSRL: Code = BinOpInit::SRL; Type = IntRecTy::get(); break; 894226584Sdim case tgtok::XSHL: Code = BinOpInit::SHL; Type = IntRecTy::get(); break; 895226584Sdim case tgtok::XEq: Code = BinOpInit::EQ; Type = BitRecTy::get(); break; 896276479Sdim case tgtok::XListConcat: 897276479Sdim Code = BinOpInit::LISTCONCAT; 898276479Sdim // We don't know the list type until we parse the first argument 899276479Sdim break; 900226584Sdim case tgtok::XStrConcat: 901226584Sdim Code = BinOpInit::STRCONCAT; 902226584Sdim Type = StringRecTy::get(); 903226584Sdim break; 904226584Sdim } 905226584Sdim 906226584Sdim if (Lex.getCode() != tgtok::l_paren) { 907226584Sdim TokError("expected '(' after binary operator"); 908276479Sdim return nullptr; 909226584Sdim } 910226584Sdim Lex.Lex(); // eat the '(' 911226584Sdim 912226584Sdim SmallVector<Init*, 2> InitList; 913226584Sdim 914226584Sdim InitList.push_back(ParseValue(CurRec)); 915276479Sdim if (!InitList.back()) return nullptr; 916226584Sdim 917226584Sdim while (Lex.getCode() == tgtok::comma) { 918226584Sdim Lex.Lex(); // eat the ',' 919226584Sdim 920226584Sdim InitList.push_back(ParseValue(CurRec)); 921276479Sdim if (!InitList.back()) return nullptr; 922226584Sdim } 923226584Sdim 924226584Sdim if (Lex.getCode() != tgtok::r_paren) { 925226584Sdim TokError("expected ')' in operator"); 926276479Sdim return nullptr; 927226584Sdim } 928226584Sdim Lex.Lex(); // eat the ')' 929226584Sdim 930276479Sdim // If we are doing !listconcat, we should know the type by now 931276479Sdim if (OpTok == tgtok::XListConcat) { 932276479Sdim if (VarInit *Arg0 = dyn_cast<VarInit>(InitList[0])) 933276479Sdim Type = Arg0->getType(); 934276479Sdim else if (ListInit *Arg0 = dyn_cast<ListInit>(InitList[0])) 935276479Sdim Type = Arg0->getType(); 936276479Sdim else { 937276479Sdim InitList[0]->dump(); 938276479Sdim Error(OpLoc, "expected a list"); 939276479Sdim return nullptr; 940276479Sdim } 941276479Sdim } 942276479Sdim 943226584Sdim // We allow multiple operands to associative operators like !strconcat as 944226584Sdim // shorthand for nesting them. 945276479Sdim if (Code == BinOpInit::STRCONCAT || Code == BinOpInit::LISTCONCAT) { 946226584Sdim while (InitList.size() > 2) { 947226584Sdim Init *RHS = InitList.pop_back_val(); 948226584Sdim RHS = (BinOpInit::get(Code, InitList.back(), RHS, Type)) 949226584Sdim ->Fold(CurRec, CurMultiClass); 950226584Sdim InitList.back() = RHS; 951226584Sdim } 952226584Sdim } 953226584Sdim 954226584Sdim if (InitList.size() == 2) 955226584Sdim return (BinOpInit::get(Code, InitList[0], InitList[1], Type)) 956226584Sdim ->Fold(CurRec, CurMultiClass); 957226584Sdim 958226584Sdim Error(OpLoc, "expected two operands to operator"); 959276479Sdim return nullptr; 960226584Sdim } 961226584Sdim 962226584Sdim case tgtok::XIf: 963226584Sdim case tgtok::XForEach: 964226584Sdim case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')' 965226584Sdim TernOpInit::TernaryOp Code; 966276479Sdim RecTy *Type = nullptr; 967226584Sdim 968226584Sdim tgtok::TokKind LexCode = Lex.getCode(); 969226584Sdim Lex.Lex(); // eat the operation 970226584Sdim switch (LexCode) { 971234353Sdim default: llvm_unreachable("Unhandled code!"); 972226584Sdim case tgtok::XIf: 973226584Sdim Code = TernOpInit::IF; 974226584Sdim break; 975226584Sdim case tgtok::XForEach: 976226584Sdim Code = TernOpInit::FOREACH; 977226584Sdim break; 978226584Sdim case tgtok::XSubst: 979226584Sdim Code = TernOpInit::SUBST; 980226584Sdim break; 981226584Sdim } 982226584Sdim if (Lex.getCode() != tgtok::l_paren) { 983226584Sdim TokError("expected '(' after ternary operator"); 984276479Sdim return nullptr; 985226584Sdim } 986226584Sdim Lex.Lex(); // eat the '(' 987226584Sdim 988226584Sdim Init *LHS = ParseValue(CurRec); 989276479Sdim if (!LHS) return nullptr; 990226584Sdim 991226584Sdim if (Lex.getCode() != tgtok::comma) { 992226584Sdim TokError("expected ',' in ternary operator"); 993276479Sdim return nullptr; 994226584Sdim } 995226584Sdim Lex.Lex(); // eat the ',' 996226584Sdim 997276479Sdim Init *MHS = ParseValue(CurRec, ItemType); 998276479Sdim if (!MHS) 999276479Sdim return nullptr; 1000226584Sdim 1001226584Sdim if (Lex.getCode() != tgtok::comma) { 1002226584Sdim TokError("expected ',' in ternary operator"); 1003276479Sdim return nullptr; 1004226584Sdim } 1005226584Sdim Lex.Lex(); // eat the ',' 1006226584Sdim 1007276479Sdim Init *RHS = ParseValue(CurRec, ItemType); 1008276479Sdim if (!RHS) 1009276479Sdim return nullptr; 1010226584Sdim 1011226584Sdim if (Lex.getCode() != tgtok::r_paren) { 1012226584Sdim TokError("expected ')' in binary operator"); 1013276479Sdim return nullptr; 1014226584Sdim } 1015226584Sdim Lex.Lex(); // eat the ')' 1016226584Sdim 1017226584Sdim switch (LexCode) { 1018234353Sdim default: llvm_unreachable("Unhandled code!"); 1019226584Sdim case tgtok::XIf: { 1020276479Sdim RecTy *MHSTy = nullptr; 1021276479Sdim RecTy *RHSTy = nullptr; 1022226584Sdim 1023243830Sdim if (TypedInit *MHSt = dyn_cast<TypedInit>(MHS)) 1024243830Sdim MHSTy = MHSt->getType(); 1025243830Sdim if (BitsInit *MHSbits = dyn_cast<BitsInit>(MHS)) 1026243830Sdim MHSTy = BitsRecTy::get(MHSbits->getNumBits()); 1027243830Sdim if (isa<BitInit>(MHS)) 1028243830Sdim MHSTy = BitRecTy::get(); 1029226584Sdim 1030243830Sdim if (TypedInit *RHSt = dyn_cast<TypedInit>(RHS)) 1031226584Sdim RHSTy = RHSt->getType(); 1032243830Sdim if (BitsInit *RHSbits = dyn_cast<BitsInit>(RHS)) 1033243830Sdim RHSTy = BitsRecTy::get(RHSbits->getNumBits()); 1034243830Sdim if (isa<BitInit>(RHS)) 1035243830Sdim RHSTy = BitRecTy::get(); 1036226584Sdim 1037243830Sdim // For UnsetInit, it's typed from the other hand. 1038243830Sdim if (isa<UnsetInit>(MHS)) 1039243830Sdim MHSTy = RHSTy; 1040243830Sdim if (isa<UnsetInit>(RHS)) 1041243830Sdim RHSTy = MHSTy; 1042243830Sdim 1043226584Sdim if (!MHSTy || !RHSTy) { 1044226584Sdim TokError("could not get type for !if"); 1045276479Sdim return nullptr; 1046226584Sdim } 1047226584Sdim 1048226584Sdim if (MHSTy->typeIsConvertibleTo(RHSTy)) { 1049226584Sdim Type = RHSTy; 1050226584Sdim } else if (RHSTy->typeIsConvertibleTo(MHSTy)) { 1051226584Sdim Type = MHSTy; 1052226584Sdim } else { 1053226584Sdim TokError("inconsistent types for !if"); 1054276479Sdim return nullptr; 1055226584Sdim } 1056226584Sdim break; 1057226584Sdim } 1058226584Sdim case tgtok::XForEach: { 1059243830Sdim TypedInit *MHSt = dyn_cast<TypedInit>(MHS); 1060276479Sdim if (!MHSt) { 1061226584Sdim TokError("could not get type for !foreach"); 1062276479Sdim return nullptr; 1063226584Sdim } 1064226584Sdim Type = MHSt->getType(); 1065226584Sdim break; 1066226584Sdim } 1067226584Sdim case tgtok::XSubst: { 1068243830Sdim TypedInit *RHSt = dyn_cast<TypedInit>(RHS); 1069276479Sdim if (!RHSt) { 1070226584Sdim TokError("could not get type for !subst"); 1071276479Sdim return nullptr; 1072226584Sdim } 1073226584Sdim Type = RHSt->getType(); 1074226584Sdim break; 1075226584Sdim } 1076226584Sdim } 1077226584Sdim return (TernOpInit::get(Code, LHS, MHS, RHS, Type))->Fold(CurRec, 1078226584Sdim CurMultiClass); 1079226584Sdim } 1080226584Sdim } 1081226584Sdim} 1082226584Sdim 1083226584Sdim/// ParseOperatorType - Parse a type for an operator. This returns 1084226584Sdim/// null on error. 1085226584Sdim/// 1086226584Sdim/// OperatorType ::= '<' Type '>' 1087226584Sdim/// 1088226584SdimRecTy *TGParser::ParseOperatorType() { 1089276479Sdim RecTy *Type = nullptr; 1090226584Sdim 1091226584Sdim if (Lex.getCode() != tgtok::less) { 1092226584Sdim TokError("expected type name for operator"); 1093276479Sdim return nullptr; 1094226584Sdim } 1095226584Sdim Lex.Lex(); // eat the < 1096226584Sdim 1097226584Sdim Type = ParseType(); 1098226584Sdim 1099276479Sdim if (!Type) { 1100226584Sdim TokError("expected type name for operator"); 1101276479Sdim return nullptr; 1102226584Sdim } 1103226584Sdim 1104226584Sdim if (Lex.getCode() != tgtok::greater) { 1105226584Sdim TokError("expected type name for operator"); 1106276479Sdim return nullptr; 1107226584Sdim } 1108226584Sdim Lex.Lex(); // eat the > 1109226584Sdim 1110226584Sdim return Type; 1111226584Sdim} 1112226584Sdim 1113226584Sdim 1114226584Sdim/// ParseSimpleValue - Parse a tblgen value. This returns null on error. 1115226584Sdim/// 1116226584Sdim/// SimpleValue ::= IDValue 1117226584Sdim/// SimpleValue ::= INTVAL 1118226584Sdim/// SimpleValue ::= STRVAL+ 1119226584Sdim/// SimpleValue ::= CODEFRAGMENT 1120226584Sdim/// SimpleValue ::= '?' 1121226584Sdim/// SimpleValue ::= '{' ValueList '}' 1122226584Sdim/// SimpleValue ::= ID '<' ValueListNE '>' 1123226584Sdim/// SimpleValue ::= '[' ValueList ']' 1124226584Sdim/// SimpleValue ::= '(' IDValue DagArgList ')' 1125226584Sdim/// SimpleValue ::= CONCATTOK '(' Value ',' Value ')' 1126249423Sdim/// SimpleValue ::= ADDTOK '(' Value ',' Value ')' 1127226584Sdim/// SimpleValue ::= SHLTOK '(' Value ',' Value ')' 1128226584Sdim/// SimpleValue ::= SRATOK '(' Value ',' Value ')' 1129226584Sdim/// SimpleValue ::= SRLTOK '(' Value ',' Value ')' 1130276479Sdim/// SimpleValue ::= LISTCONCATTOK '(' Value ',' Value ')' 1131226584Sdim/// SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')' 1132226584Sdim/// 1133234353SdimInit *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, 1134234353Sdim IDParseMode Mode) { 1135276479Sdim Init *R = nullptr; 1136226584Sdim switch (Lex.getCode()) { 1137226584Sdim default: TokError("Unknown token when parsing a value"); break; 1138234353Sdim case tgtok::paste: 1139234353Sdim // This is a leading paste operation. This is deprecated but 1140234353Sdim // still exists in some .td files. Ignore it. 1141234353Sdim Lex.Lex(); // Skip '#'. 1142234353Sdim return ParseSimpleValue(CurRec, ItemType, Mode); 1143226584Sdim case tgtok::IntVal: R = IntInit::get(Lex.getCurIntVal()); Lex.Lex(); break; 1144280031Sdim case tgtok::BinaryIntVal: { 1145280031Sdim auto BinaryVal = Lex.getCurBinaryIntVal(); 1146280031Sdim SmallVector<Init*, 16> Bits(BinaryVal.second); 1147280031Sdim for (unsigned i = 0, e = BinaryVal.second; i != e; ++i) 1148280031Sdim Bits[i] = BitInit::get(BinaryVal.first & (1LL << i)); 1149280031Sdim R = BitsInit::get(Bits); 1150280031Sdim Lex.Lex(); 1151280031Sdim break; 1152280031Sdim } 1153226584Sdim case tgtok::StrVal: { 1154226584Sdim std::string Val = Lex.getCurStrVal(); 1155226584Sdim Lex.Lex(); 1156226584Sdim 1157226584Sdim // Handle multiple consecutive concatenated strings. 1158226584Sdim while (Lex.getCode() == tgtok::StrVal) { 1159226584Sdim Val += Lex.getCurStrVal(); 1160226584Sdim Lex.Lex(); 1161226584Sdim } 1162226584Sdim 1163226584Sdim R = StringInit::get(Val); 1164226584Sdim break; 1165226584Sdim } 1166226584Sdim case tgtok::CodeFragment: 1167309124Sdim R = CodeInit::get(Lex.getCurStrVal()); 1168226584Sdim Lex.Lex(); 1169226584Sdim break; 1170226584Sdim case tgtok::question: 1171226584Sdim R = UnsetInit::get(); 1172226584Sdim Lex.Lex(); 1173226584Sdim break; 1174226584Sdim case tgtok::Id: { 1175226584Sdim SMLoc NameLoc = Lex.getLoc(); 1176226584Sdim std::string Name = Lex.getCurStrVal(); 1177226584Sdim if (Lex.Lex() != tgtok::less) // consume the Id. 1178234353Sdim return ParseIDValue(CurRec, Name, NameLoc, Mode); // Value ::= IDValue 1179226584Sdim 1180226584Sdim // Value ::= ID '<' ValueListNE '>' 1181226584Sdim if (Lex.Lex() == tgtok::greater) { 1182226584Sdim TokError("expected non-empty value list"); 1183276479Sdim return nullptr; 1184226584Sdim } 1185226584Sdim 1186226584Sdim // This is a CLASS<initvalslist> expression. This is supposed to synthesize 1187226584Sdim // a new anonymous definition, deriving from CLASS<initvalslist> with no 1188226584Sdim // body. 1189226584Sdim Record *Class = Records.getClass(Name); 1190226584Sdim if (!Class) { 1191226584Sdim Error(NameLoc, "Expected a class name, got '" + Name + "'"); 1192276479Sdim return nullptr; 1193226584Sdim } 1194226584Sdim 1195226584Sdim std::vector<Init*> ValueList = ParseValueList(CurRec, Class); 1196276479Sdim if (ValueList.empty()) return nullptr; 1197226584Sdim 1198226584Sdim if (Lex.getCode() != tgtok::greater) { 1199226584Sdim TokError("expected '>' at end of value list"); 1200276479Sdim return nullptr; 1201226584Sdim } 1202226584Sdim Lex.Lex(); // eat the '>' 1203249423Sdim SMLoc EndLoc = Lex.getLoc(); 1204226584Sdim 1205226584Sdim // Create the new record, set it as CurRec temporarily. 1206280031Sdim auto NewRecOwner = llvm::make_unique<Record>(GetNewAnonymousName(), NameLoc, 1207280031Sdim Records, /*IsAnonymous=*/true); 1208280031Sdim Record *NewRec = NewRecOwner.get(); // Keep a copy since we may release. 1209226584Sdim SubClassReference SCRef; 1210249423Sdim SCRef.RefRange = SMRange(NameLoc, EndLoc); 1211226584Sdim SCRef.Rec = Class; 1212226584Sdim SCRef.TemplateArgs = ValueList; 1213226584Sdim // Add info about the subclass to NewRec. 1214226584Sdim if (AddSubClass(NewRec, SCRef)) 1215276479Sdim return nullptr; 1216280031Sdim 1217276479Sdim if (!CurMultiClass) { 1218276479Sdim NewRec->resolveReferences(); 1219280031Sdim Records.addDef(std::move(NewRecOwner)); 1220276479Sdim } else { 1221280031Sdim // This needs to get resolved once the multiclass template arguments are 1222280031Sdim // known before any use. 1223280031Sdim NewRec->setResolveFirst(true); 1224276479Sdim // Otherwise, we're inside a multiclass, add it to the multiclass. 1225280031Sdim CurMultiClass->DefPrototypes.push_back(std::move(NewRecOwner)); 1226226584Sdim 1227276479Sdim // Copy the template arguments for the multiclass into the def. 1228288943Sdim for (Init *TArg : CurMultiClass->Rec.getTemplateArgs()) { 1229288943Sdim const RecordVal *RV = CurMultiClass->Rec.getValue(TArg); 1230276479Sdim assert(RV && "Template arg doesn't exist?"); 1231276479Sdim NewRec->addValue(*RV); 1232276479Sdim } 1233276479Sdim 1234276479Sdim // We can't return the prototype def here, instead return: 1235276479Sdim // !cast<ItemType>(!strconcat(NAME, AnonName)). 1236276479Sdim const RecordVal *MCNameRV = CurMultiClass->Rec.getValue("NAME"); 1237276479Sdim assert(MCNameRV && "multiclass record must have a NAME"); 1238276479Sdim 1239276479Sdim return UnOpInit::get(UnOpInit::CAST, 1240276479Sdim BinOpInit::get(BinOpInit::STRCONCAT, 1241276479Sdim VarInit::get(MCNameRV->getName(), 1242276479Sdim MCNameRV->getType()), 1243276479Sdim NewRec->getNameInit(), 1244276479Sdim StringRecTy::get()), 1245276479Sdim Class->getDefInit()->getType()); 1246276479Sdim } 1247276479Sdim 1248226584Sdim // The result of the expression is a reference to the new record. 1249226584Sdim return DefInit::get(NewRec); 1250226584Sdim } 1251226584Sdim case tgtok::l_brace: { // Value ::= '{' ValueList '}' 1252226584Sdim SMLoc BraceLoc = Lex.getLoc(); 1253226584Sdim Lex.Lex(); // eat the '{' 1254226584Sdim std::vector<Init*> Vals; 1255226584Sdim 1256226584Sdim if (Lex.getCode() != tgtok::r_brace) { 1257226584Sdim Vals = ParseValueList(CurRec); 1258276479Sdim if (Vals.empty()) return nullptr; 1259226584Sdim } 1260226584Sdim if (Lex.getCode() != tgtok::r_brace) { 1261226584Sdim TokError("expected '}' at end of bit list value"); 1262276479Sdim return nullptr; 1263226584Sdim } 1264226584Sdim Lex.Lex(); // eat the '}' 1265226584Sdim 1266280031Sdim SmallVector<Init *, 16> NewBits; 1267226584Sdim 1268280031Sdim // As we parse { a, b, ... }, 'a' is the highest bit, but we parse it 1269280031Sdim // first. We'll first read everything in to a vector, then we can reverse 1270280031Sdim // it to get the bits in the correct order for the BitsInit value. 1271226584Sdim for (unsigned i = 0, e = Vals.size(); i != e; ++i) { 1272280031Sdim // FIXME: The following two loops would not be duplicated 1273280031Sdim // if the API was a little more orthogonal. 1274280031Sdim 1275280031Sdim // bits<n> values are allowed to initialize n bits. 1276280031Sdim if (BitsInit *BI = dyn_cast<BitsInit>(Vals[i])) { 1277280031Sdim for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) 1278280031Sdim NewBits.push_back(BI->getBit((e - i) - 1)); 1279280031Sdim continue; 1280280031Sdim } 1281280031Sdim // bits<n> can also come from variable initializers. 1282280031Sdim if (VarInit *VI = dyn_cast<VarInit>(Vals[i])) { 1283280031Sdim if (BitsRecTy *BitsRec = dyn_cast<BitsRecTy>(VI->getType())) { 1284280031Sdim for (unsigned i = 0, e = BitsRec->getNumBits(); i != e; ++i) 1285280031Sdim NewBits.push_back(VI->getBit((e - i) - 1)); 1286280031Sdim continue; 1287280031Sdim } 1288280031Sdim // Fallthrough to try convert this to a bit. 1289280031Sdim } 1290280031Sdim // All other values must be convertible to just a single bit. 1291226584Sdim Init *Bit = Vals[i]->convertInitializerTo(BitRecTy::get()); 1292276479Sdim if (!Bit) { 1293288943Sdim Error(BraceLoc, "Element #" + Twine(i) + " (" + Vals[i]->getAsString() + 1294226584Sdim ") is not convertable to a bit"); 1295276479Sdim return nullptr; 1296226584Sdim } 1297280031Sdim NewBits.push_back(Bit); 1298226584Sdim } 1299280031Sdim std::reverse(NewBits.begin(), NewBits.end()); 1300226584Sdim return BitsInit::get(NewBits); 1301226584Sdim } 1302226584Sdim case tgtok::l_square: { // Value ::= '[' ValueList ']' 1303226584Sdim Lex.Lex(); // eat the '[' 1304226584Sdim std::vector<Init*> Vals; 1305226584Sdim 1306276479Sdim RecTy *DeducedEltTy = nullptr; 1307276479Sdim ListRecTy *GivenListTy = nullptr; 1308226584Sdim 1309276479Sdim if (ItemType) { 1310243830Sdim ListRecTy *ListType = dyn_cast<ListRecTy>(ItemType); 1311276479Sdim if (!ListType) { 1312288943Sdim TokError(Twine("Type mismatch for list, expected list type, got ") + 1313288943Sdim ItemType->getAsString()); 1314276479Sdim return nullptr; 1315226584Sdim } 1316226584Sdim GivenListTy = ListType; 1317226584Sdim } 1318226584Sdim 1319226584Sdim if (Lex.getCode() != tgtok::r_square) { 1320276479Sdim Vals = ParseValueList(CurRec, nullptr, 1321276479Sdim GivenListTy ? GivenListTy->getElementType() : nullptr); 1322276479Sdim if (Vals.empty()) return nullptr; 1323226584Sdim } 1324226584Sdim if (Lex.getCode() != tgtok::r_square) { 1325226584Sdim TokError("expected ']' at end of list value"); 1326276479Sdim return nullptr; 1327226584Sdim } 1328226584Sdim Lex.Lex(); // eat the ']' 1329226584Sdim 1330276479Sdim RecTy *GivenEltTy = nullptr; 1331226584Sdim if (Lex.getCode() == tgtok::less) { 1332226584Sdim // Optional list element type 1333226584Sdim Lex.Lex(); // eat the '<' 1334226584Sdim 1335226584Sdim GivenEltTy = ParseType(); 1336276479Sdim if (!GivenEltTy) { 1337226584Sdim // Couldn't parse element type 1338276479Sdim return nullptr; 1339226584Sdim } 1340226584Sdim 1341226584Sdim if (Lex.getCode() != tgtok::greater) { 1342226584Sdim TokError("expected '>' at end of list element type"); 1343276479Sdim return nullptr; 1344226584Sdim } 1345226584Sdim Lex.Lex(); // eat the '>' 1346226584Sdim } 1347226584Sdim 1348226584Sdim // Check elements 1349276479Sdim RecTy *EltTy = nullptr; 1350288943Sdim for (Init *V : Vals) { 1351288943Sdim TypedInit *TArg = dyn_cast<TypedInit>(V); 1352276479Sdim if (!TArg) { 1353226584Sdim TokError("Untyped list element"); 1354276479Sdim return nullptr; 1355226584Sdim } 1356276479Sdim if (EltTy) { 1357226584Sdim EltTy = resolveTypes(EltTy, TArg->getType()); 1358276479Sdim if (!EltTy) { 1359226584Sdim TokError("Incompatible types in list elements"); 1360276479Sdim return nullptr; 1361226584Sdim } 1362226584Sdim } else { 1363226584Sdim EltTy = TArg->getType(); 1364226584Sdim } 1365226584Sdim } 1366226584Sdim 1367276479Sdim if (GivenEltTy) { 1368276479Sdim if (EltTy) { 1369226584Sdim // Verify consistency 1370226584Sdim if (!EltTy->typeIsConvertibleTo(GivenEltTy)) { 1371226584Sdim TokError("Incompatible types in list elements"); 1372276479Sdim return nullptr; 1373226584Sdim } 1374226584Sdim } 1375226584Sdim EltTy = GivenEltTy; 1376226584Sdim } 1377226584Sdim 1378276479Sdim if (!EltTy) { 1379276479Sdim if (!ItemType) { 1380226584Sdim TokError("No type for list"); 1381276479Sdim return nullptr; 1382226584Sdim } 1383226584Sdim DeducedEltTy = GivenListTy->getElementType(); 1384226584Sdim } else { 1385226584Sdim // Make sure the deduced type is compatible with the given type 1386226584Sdim if (GivenListTy) { 1387226584Sdim if (!EltTy->typeIsConvertibleTo(GivenListTy->getElementType())) { 1388226584Sdim TokError("Element type mismatch for list"); 1389276479Sdim return nullptr; 1390226584Sdim } 1391226584Sdim } 1392226584Sdim DeducedEltTy = EltTy; 1393226584Sdim } 1394226584Sdim 1395226584Sdim return ListInit::get(Vals, DeducedEltTy); 1396226584Sdim } 1397226584Sdim case tgtok::l_paren: { // Value ::= '(' IDValue DagArgList ')' 1398226584Sdim Lex.Lex(); // eat the '(' 1399226584Sdim if (Lex.getCode() != tgtok::Id && Lex.getCode() != tgtok::XCast) { 1400226584Sdim TokError("expected identifier in dag init"); 1401276479Sdim return nullptr; 1402226584Sdim } 1403226584Sdim 1404226584Sdim Init *Operator = ParseValue(CurRec); 1405276479Sdim if (!Operator) return nullptr; 1406226584Sdim 1407226584Sdim // If the operator name is present, parse it. 1408226584Sdim std::string OperatorName; 1409226584Sdim if (Lex.getCode() == tgtok::colon) { 1410226584Sdim if (Lex.Lex() != tgtok::VarName) { // eat the ':' 1411226584Sdim TokError("expected variable name in dag operator"); 1412276479Sdim return nullptr; 1413226584Sdim } 1414226584Sdim OperatorName = Lex.getCurStrVal(); 1415226584Sdim Lex.Lex(); // eat the VarName. 1416226584Sdim } 1417226584Sdim 1418226584Sdim std::vector<std::pair<llvm::Init*, std::string> > DagArgs; 1419226584Sdim if (Lex.getCode() != tgtok::r_paren) { 1420226584Sdim DagArgs = ParseDagArgList(CurRec); 1421276479Sdim if (DagArgs.empty()) return nullptr; 1422226584Sdim } 1423226584Sdim 1424226584Sdim if (Lex.getCode() != tgtok::r_paren) { 1425226584Sdim TokError("expected ')' in dag init"); 1426276479Sdim return nullptr; 1427226584Sdim } 1428226584Sdim Lex.Lex(); // eat the ')' 1429226584Sdim 1430226584Sdim return DagInit::get(Operator, OperatorName, DagArgs); 1431226584Sdim } 1432226584Sdim 1433226584Sdim case tgtok::XHead: 1434226584Sdim case tgtok::XTail: 1435226584Sdim case tgtok::XEmpty: 1436226584Sdim case tgtok::XCast: // Value ::= !unop '(' Value ')' 1437226584Sdim case tgtok::XConcat: 1438249423Sdim case tgtok::XADD: 1439280031Sdim case tgtok::XAND: 1440226584Sdim case tgtok::XSRA: 1441226584Sdim case tgtok::XSRL: 1442226584Sdim case tgtok::XSHL: 1443226584Sdim case tgtok::XEq: 1444276479Sdim case tgtok::XListConcat: 1445226584Sdim case tgtok::XStrConcat: // Value ::= !binop '(' Value ',' Value ')' 1446226584Sdim case tgtok::XIf: 1447226584Sdim case tgtok::XForEach: 1448226584Sdim case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')' 1449276479Sdim return ParseOperation(CurRec, ItemType); 1450226584Sdim } 1451226584Sdim } 1452226584Sdim 1453226584Sdim return R; 1454226584Sdim} 1455226584Sdim 1456226584Sdim/// ParseValue - Parse a tblgen value. This returns null on error. 1457226584Sdim/// 1458226584Sdim/// Value ::= SimpleValue ValueSuffix* 1459226584Sdim/// ValueSuffix ::= '{' BitList '}' 1460226584Sdim/// ValueSuffix ::= '[' BitList ']' 1461226584Sdim/// ValueSuffix ::= '.' ID 1462226584Sdim/// 1463234353SdimInit *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) { 1464234353Sdim Init *Result = ParseSimpleValue(CurRec, ItemType, Mode); 1465276479Sdim if (!Result) return nullptr; 1466226584Sdim 1467226584Sdim // Parse the suffixes now if present. 1468226584Sdim while (1) { 1469226584Sdim switch (Lex.getCode()) { 1470226584Sdim default: return Result; 1471226584Sdim case tgtok::l_brace: { 1472234353Sdim if (Mode == ParseNameMode || Mode == ParseForeachMode) 1473234353Sdim // This is the beginning of the object body. 1474234353Sdim return Result; 1475234353Sdim 1476226584Sdim SMLoc CurlyLoc = Lex.getLoc(); 1477226584Sdim Lex.Lex(); // eat the '{' 1478226584Sdim std::vector<unsigned> Ranges = ParseRangeList(); 1479276479Sdim if (Ranges.empty()) return nullptr; 1480226584Sdim 1481226584Sdim // Reverse the bitlist. 1482226584Sdim std::reverse(Ranges.begin(), Ranges.end()); 1483226584Sdim Result = Result->convertInitializerBitRange(Ranges); 1484276479Sdim if (!Result) { 1485226584Sdim Error(CurlyLoc, "Invalid bit range for value"); 1486276479Sdim return nullptr; 1487226584Sdim } 1488226584Sdim 1489226584Sdim // Eat the '}'. 1490226584Sdim if (Lex.getCode() != tgtok::r_brace) { 1491226584Sdim TokError("expected '}' at end of bit range list"); 1492276479Sdim return nullptr; 1493226584Sdim } 1494226584Sdim Lex.Lex(); 1495226584Sdim break; 1496226584Sdim } 1497226584Sdim case tgtok::l_square: { 1498226584Sdim SMLoc SquareLoc = Lex.getLoc(); 1499226584Sdim Lex.Lex(); // eat the '[' 1500226584Sdim std::vector<unsigned> Ranges = ParseRangeList(); 1501276479Sdim if (Ranges.empty()) return nullptr; 1502226584Sdim 1503226584Sdim Result = Result->convertInitListSlice(Ranges); 1504276479Sdim if (!Result) { 1505226584Sdim Error(SquareLoc, "Invalid range for list slice"); 1506276479Sdim return nullptr; 1507226584Sdim } 1508226584Sdim 1509226584Sdim // Eat the ']'. 1510226584Sdim if (Lex.getCode() != tgtok::r_square) { 1511226584Sdim TokError("expected ']' at end of list slice"); 1512276479Sdim return nullptr; 1513226584Sdim } 1514226584Sdim Lex.Lex(); 1515226584Sdim break; 1516226584Sdim } 1517226584Sdim case tgtok::period: 1518226584Sdim if (Lex.Lex() != tgtok::Id) { // eat the . 1519226584Sdim TokError("expected field identifier after '.'"); 1520276479Sdim return nullptr; 1521226584Sdim } 1522226584Sdim if (!Result->getFieldType(Lex.getCurStrVal())) { 1523226584Sdim TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" + 1524226584Sdim Result->getAsString() + "'"); 1525276479Sdim return nullptr; 1526226584Sdim } 1527226584Sdim Result = FieldInit::get(Result, Lex.getCurStrVal()); 1528226584Sdim Lex.Lex(); // eat field name 1529226584Sdim break; 1530234353Sdim 1531234353Sdim case tgtok::paste: 1532234353Sdim SMLoc PasteLoc = Lex.getLoc(); 1533234353Sdim 1534234353Sdim // Create a !strconcat() operation, first casting each operand to 1535234353Sdim // a string if necessary. 1536234353Sdim 1537243830Sdim TypedInit *LHS = dyn_cast<TypedInit>(Result); 1538234353Sdim if (!LHS) { 1539234353Sdim Error(PasteLoc, "LHS of paste is not typed!"); 1540276479Sdim return nullptr; 1541234353Sdim } 1542288943Sdim 1543234353Sdim if (LHS->getType() != StringRecTy::get()) { 1544234353Sdim LHS = UnOpInit::get(UnOpInit::CAST, LHS, StringRecTy::get()); 1545234353Sdim } 1546234353Sdim 1547276479Sdim TypedInit *RHS = nullptr; 1548234353Sdim 1549234353Sdim Lex.Lex(); // Eat the '#'. 1550234353Sdim switch (Lex.getCode()) { 1551234353Sdim case tgtok::colon: 1552234353Sdim case tgtok::semi: 1553234353Sdim case tgtok::l_brace: 1554234353Sdim // These are all of the tokens that can begin an object body. 1555234353Sdim // Some of these can also begin values but we disallow those cases 1556234353Sdim // because they are unlikely to be useful. 1557288943Sdim 1558234353Sdim // Trailing paste, concat with an empty string. 1559234353Sdim RHS = StringInit::get(""); 1560234353Sdim break; 1561234353Sdim 1562234353Sdim default: 1563234353Sdim Init *RHSResult = ParseValue(CurRec, ItemType, ParseNameMode); 1564243830Sdim RHS = dyn_cast<TypedInit>(RHSResult); 1565234353Sdim if (!RHS) { 1566234353Sdim Error(PasteLoc, "RHS of paste is not typed!"); 1567276479Sdim return nullptr; 1568234353Sdim } 1569234353Sdim 1570234353Sdim if (RHS->getType() != StringRecTy::get()) { 1571234353Sdim RHS = UnOpInit::get(UnOpInit::CAST, RHS, StringRecTy::get()); 1572234353Sdim } 1573288943Sdim 1574234353Sdim break; 1575234353Sdim } 1576234353Sdim 1577234353Sdim Result = BinOpInit::get(BinOpInit::STRCONCAT, LHS, RHS, 1578234353Sdim StringRecTy::get())->Fold(CurRec, CurMultiClass); 1579234353Sdim break; 1580226584Sdim } 1581226584Sdim } 1582226584Sdim} 1583226584Sdim 1584226584Sdim/// ParseDagArgList - Parse the argument list for a dag literal expression. 1585226584Sdim/// 1586249423Sdim/// DagArg ::= Value (':' VARNAME)? 1587249423Sdim/// DagArg ::= VARNAME 1588249423Sdim/// DagArgList ::= DagArg 1589249423Sdim/// DagArgList ::= DagArgList ',' DagArg 1590226584Sdimstd::vector<std::pair<llvm::Init*, std::string> > 1591226584SdimTGParser::ParseDagArgList(Record *CurRec) { 1592226584Sdim std::vector<std::pair<llvm::Init*, std::string> > Result; 1593226584Sdim 1594226584Sdim while (1) { 1595249423Sdim // DagArg ::= VARNAME 1596249423Sdim if (Lex.getCode() == tgtok::VarName) { 1597249423Sdim // A missing value is treated like '?'. 1598288943Sdim Result.emplace_back(UnsetInit::get(), Lex.getCurStrVal()); 1599249423Sdim Lex.Lex(); 1600249423Sdim } else { 1601249423Sdim // DagArg ::= Value (':' VARNAME)? 1602249423Sdim Init *Val = ParseValue(CurRec); 1603276479Sdim if (!Val) 1604249423Sdim return std::vector<std::pair<llvm::Init*, std::string> >(); 1605226584Sdim 1606249423Sdim // If the variable name is present, add it. 1607249423Sdim std::string VarName; 1608249423Sdim if (Lex.getCode() == tgtok::colon) { 1609249423Sdim if (Lex.Lex() != tgtok::VarName) { // eat the ':' 1610249423Sdim TokError("expected variable name in dag literal"); 1611249423Sdim return std::vector<std::pair<llvm::Init*, std::string> >(); 1612249423Sdim } 1613249423Sdim VarName = Lex.getCurStrVal(); 1614249423Sdim Lex.Lex(); // eat the VarName. 1615226584Sdim } 1616249423Sdim 1617249423Sdim Result.push_back(std::make_pair(Val, VarName)); 1618226584Sdim } 1619226584Sdim if (Lex.getCode() != tgtok::comma) break; 1620226584Sdim Lex.Lex(); // eat the ',' 1621226584Sdim } 1622226584Sdim 1623226584Sdim return Result; 1624226584Sdim} 1625226584Sdim 1626226584Sdim 1627226584Sdim/// ParseValueList - Parse a comma separated list of values, returning them as a 1628226584Sdim/// vector. Note that this always expects to be able to parse at least one 1629226584Sdim/// value. It returns an empty list if this is not possible. 1630226584Sdim/// 1631226584Sdim/// ValueList ::= Value (',' Value) 1632226584Sdim/// 1633226584Sdimstd::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec, 1634226584Sdim RecTy *EltTy) { 1635226584Sdim std::vector<Init*> Result; 1636226584Sdim RecTy *ItemType = EltTy; 1637226584Sdim unsigned int ArgN = 0; 1638276479Sdim if (ArgsRec && !EltTy) { 1639296417Sdim ArrayRef<Init *> TArgs = ArgsRec->getTemplateArgs(); 1640288943Sdim if (TArgs.empty()) { 1641234353Sdim TokError("template argument provided to non-template class"); 1642234353Sdim return std::vector<Init*>(); 1643234353Sdim } 1644226584Sdim const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]); 1645226584Sdim if (!RV) { 1646226584Sdim errs() << "Cannot find template arg " << ArgN << " (" << TArgs[ArgN] 1647226584Sdim << ")\n"; 1648226584Sdim } 1649226584Sdim assert(RV && "Template argument record not found??"); 1650226584Sdim ItemType = RV->getType(); 1651226584Sdim ++ArgN; 1652226584Sdim } 1653226584Sdim Result.push_back(ParseValue(CurRec, ItemType)); 1654276479Sdim if (!Result.back()) return std::vector<Init*>(); 1655226584Sdim 1656226584Sdim while (Lex.getCode() == tgtok::comma) { 1657226584Sdim Lex.Lex(); // Eat the comma 1658226584Sdim 1659276479Sdim if (ArgsRec && !EltTy) { 1660296417Sdim ArrayRef<Init *> TArgs = ArgsRec->getTemplateArgs(); 1661226584Sdim if (ArgN >= TArgs.size()) { 1662226584Sdim TokError("too many template arguments"); 1663226584Sdim return std::vector<Init*>(); 1664226584Sdim } 1665226584Sdim const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]); 1666226584Sdim assert(RV && "Template argument record not found??"); 1667226584Sdim ItemType = RV->getType(); 1668226584Sdim ++ArgN; 1669226584Sdim } 1670226584Sdim Result.push_back(ParseValue(CurRec, ItemType)); 1671276479Sdim if (!Result.back()) return std::vector<Init*>(); 1672226584Sdim } 1673226584Sdim 1674226584Sdim return Result; 1675226584Sdim} 1676226584Sdim 1677226584Sdim 1678226584Sdim/// ParseDeclaration - Read a declaration, returning the name of field ID, or an 1679226584Sdim/// empty string on error. This can happen in a number of different context's, 1680226584Sdim/// including within a def or in the template args for a def (which which case 1681226584Sdim/// CurRec will be non-null) and within the template args for a multiclass (in 1682226584Sdim/// which case CurRec will be null, but CurMultiClass will be set). This can 1683226584Sdim/// also happen within a def that is within a multiclass, which will set both 1684226584Sdim/// CurRec and CurMultiClass. 1685226584Sdim/// 1686226584Sdim/// Declaration ::= FIELD? Type ID ('=' Value)? 1687226584Sdim/// 1688234353SdimInit *TGParser::ParseDeclaration(Record *CurRec, 1689226584Sdim bool ParsingTemplateArgs) { 1690226584Sdim // Read the field prefix if present. 1691226584Sdim bool HasField = Lex.getCode() == tgtok::Field; 1692226584Sdim if (HasField) Lex.Lex(); 1693226584Sdim 1694226584Sdim RecTy *Type = ParseType(); 1695276479Sdim if (!Type) return nullptr; 1696226584Sdim 1697226584Sdim if (Lex.getCode() != tgtok::Id) { 1698226584Sdim TokError("Expected identifier in declaration"); 1699276479Sdim return nullptr; 1700226584Sdim } 1701226584Sdim 1702226584Sdim SMLoc IdLoc = Lex.getLoc(); 1703234353Sdim Init *DeclName = StringInit::get(Lex.getCurStrVal()); 1704226584Sdim Lex.Lex(); 1705226584Sdim 1706226584Sdim if (ParsingTemplateArgs) { 1707288943Sdim if (CurRec) 1708234353Sdim DeclName = QualifyName(*CurRec, CurMultiClass, DeclName, ":"); 1709288943Sdim else 1710226584Sdim assert(CurMultiClass); 1711226584Sdim if (CurMultiClass) 1712234353Sdim DeclName = QualifyName(CurMultiClass->Rec, CurMultiClass, DeclName, 1713234353Sdim "::"); 1714226584Sdim } 1715226584Sdim 1716226584Sdim // Add the value. 1717226584Sdim if (AddValue(CurRec, IdLoc, RecordVal(DeclName, Type, HasField))) 1718276479Sdim return nullptr; 1719226584Sdim 1720226584Sdim // If a value is present, parse it. 1721226584Sdim if (Lex.getCode() == tgtok::equal) { 1722226584Sdim Lex.Lex(); 1723226584Sdim SMLoc ValLoc = Lex.getLoc(); 1724226584Sdim Init *Val = ParseValue(CurRec, Type); 1725276479Sdim if (!Val || 1726296417Sdim SetValue(CurRec, ValLoc, DeclName, None, Val)) 1727280031Sdim // Return the name, even if an error is thrown. This is so that we can 1728280031Sdim // continue to make some progress, even without the value having been 1729280031Sdim // initialized. 1730280031Sdim return DeclName; 1731226584Sdim } 1732226584Sdim 1733226584Sdim return DeclName; 1734226584Sdim} 1735226584Sdim 1736234353Sdim/// ParseForeachDeclaration - Read a foreach declaration, returning 1737234353Sdim/// the name of the declared object or a NULL Init on error. Return 1738234353Sdim/// the name of the parsed initializer list through ForeachListName. 1739234353Sdim/// 1740239462Sdim/// ForeachDeclaration ::= ID '=' '[' ValueList ']' 1741239462Sdim/// ForeachDeclaration ::= ID '=' '{' RangeList '}' 1742239462Sdim/// ForeachDeclaration ::= ID '=' RangePiece 1743234353Sdim/// 1744239462SdimVarInit *TGParser::ParseForeachDeclaration(ListInit *&ForeachListValue) { 1745234353Sdim if (Lex.getCode() != tgtok::Id) { 1746234353Sdim TokError("Expected identifier in foreach declaration"); 1747276479Sdim return nullptr; 1748234353Sdim } 1749234353Sdim 1750234353Sdim Init *DeclName = StringInit::get(Lex.getCurStrVal()); 1751234353Sdim Lex.Lex(); 1752234353Sdim 1753234353Sdim // If a value is present, parse it. 1754234353Sdim if (Lex.getCode() != tgtok::equal) { 1755234353Sdim TokError("Expected '=' in foreach declaration"); 1756276479Sdim return nullptr; 1757234353Sdim } 1758234353Sdim Lex.Lex(); // Eat the '=' 1759234353Sdim 1760276479Sdim RecTy *IterType = nullptr; 1761239462Sdim std::vector<unsigned> Ranges; 1762234353Sdim 1763239462Sdim switch (Lex.getCode()) { 1764276479Sdim default: TokError("Unknown token when expecting a range list"); return nullptr; 1765239462Sdim case tgtok::l_square: { // '[' ValueList ']' 1766276479Sdim Init *List = ParseSimpleValue(nullptr, nullptr, ParseForeachMode); 1767243830Sdim ForeachListValue = dyn_cast<ListInit>(List); 1768276479Sdim if (!ForeachListValue) { 1769239462Sdim TokError("Expected a Value list"); 1770276479Sdim return nullptr; 1771239462Sdim } 1772239462Sdim RecTy *ValueType = ForeachListValue->getType(); 1773243830Sdim ListRecTy *ListType = dyn_cast<ListRecTy>(ValueType); 1774276479Sdim if (!ListType) { 1775239462Sdim TokError("Value list is not of list type"); 1776276479Sdim return nullptr; 1777239462Sdim } 1778239462Sdim IterType = ListType->getElementType(); 1779239462Sdim break; 1780234353Sdim } 1781234353Sdim 1782239462Sdim case tgtok::IntVal: { // RangePiece. 1783239462Sdim if (ParseRangePiece(Ranges)) 1784276479Sdim return nullptr; 1785239462Sdim break; 1786234353Sdim } 1787234353Sdim 1788239462Sdim case tgtok::l_brace: { // '{' RangeList '}' 1789239462Sdim Lex.Lex(); // eat the '{' 1790239462Sdim Ranges = ParseRangeList(); 1791239462Sdim if (Lex.getCode() != tgtok::r_brace) { 1792239462Sdim TokError("expected '}' at end of bit range list"); 1793276479Sdim return nullptr; 1794239462Sdim } 1795239462Sdim Lex.Lex(); 1796239462Sdim break; 1797239462Sdim } 1798239462Sdim } 1799234353Sdim 1800239462Sdim if (!Ranges.empty()) { 1801239462Sdim assert(!IterType && "Type already initialized?"); 1802239462Sdim IterType = IntRecTy::get(); 1803239462Sdim std::vector<Init*> Values; 1804288943Sdim for (unsigned R : Ranges) 1805288943Sdim Values.push_back(IntInit::get(R)); 1806239462Sdim ForeachListValue = ListInit::get(Values, IterType); 1807239462Sdim } 1808239462Sdim 1809239462Sdim if (!IterType) 1810276479Sdim return nullptr; 1811239462Sdim 1812239462Sdim return VarInit::get(DeclName, IterType); 1813234353Sdim} 1814234353Sdim 1815226584Sdim/// ParseTemplateArgList - Read a template argument list, which is a non-empty 1816226584Sdim/// sequence of template-declarations in <>'s. If CurRec is non-null, these are 1817226584Sdim/// template args for a def, which may or may not be in a multiclass. If null, 1818226584Sdim/// these are the template args for a multiclass. 1819226584Sdim/// 1820226584Sdim/// TemplateArgList ::= '<' Declaration (',' Declaration)* '>' 1821226584Sdim/// 1822226584Sdimbool TGParser::ParseTemplateArgList(Record *CurRec) { 1823226584Sdim assert(Lex.getCode() == tgtok::less && "Not a template arg list!"); 1824226584Sdim Lex.Lex(); // eat the '<' 1825226584Sdim 1826226584Sdim Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->Rec; 1827226584Sdim 1828226584Sdim // Read the first declaration. 1829234353Sdim Init *TemplArg = ParseDeclaration(CurRec, true/*templateargs*/); 1830276479Sdim if (!TemplArg) 1831226584Sdim return true; 1832226584Sdim 1833226584Sdim TheRecToAddTo->addTemplateArg(TemplArg); 1834226584Sdim 1835226584Sdim while (Lex.getCode() == tgtok::comma) { 1836226584Sdim Lex.Lex(); // eat the ',' 1837226584Sdim 1838226584Sdim // Read the following declarations. 1839226584Sdim TemplArg = ParseDeclaration(CurRec, true/*templateargs*/); 1840276479Sdim if (!TemplArg) 1841226584Sdim return true; 1842226584Sdim TheRecToAddTo->addTemplateArg(TemplArg); 1843226584Sdim } 1844226584Sdim 1845226584Sdim if (Lex.getCode() != tgtok::greater) 1846226584Sdim return TokError("expected '>' at end of template argument list"); 1847226584Sdim Lex.Lex(); // eat the '>'. 1848226584Sdim return false; 1849226584Sdim} 1850226584Sdim 1851226584Sdim 1852226584Sdim/// ParseBodyItem - Parse a single item at within the body of a def or class. 1853226584Sdim/// 1854226584Sdim/// BodyItem ::= Declaration ';' 1855226584Sdim/// BodyItem ::= LET ID OptionalBitList '=' Value ';' 1856226584Sdimbool TGParser::ParseBodyItem(Record *CurRec) { 1857226584Sdim if (Lex.getCode() != tgtok::Let) { 1858276479Sdim if (!ParseDeclaration(CurRec, false)) 1859226584Sdim return true; 1860226584Sdim 1861226584Sdim if (Lex.getCode() != tgtok::semi) 1862226584Sdim return TokError("expected ';' after declaration"); 1863226584Sdim Lex.Lex(); 1864226584Sdim return false; 1865226584Sdim } 1866226584Sdim 1867226584Sdim // LET ID OptionalRangeList '=' Value ';' 1868226584Sdim if (Lex.Lex() != tgtok::Id) 1869226584Sdim return TokError("expected field identifier after let"); 1870226584Sdim 1871226584Sdim SMLoc IdLoc = Lex.getLoc(); 1872226584Sdim std::string FieldName = Lex.getCurStrVal(); 1873226584Sdim Lex.Lex(); // eat the field name. 1874226584Sdim 1875226584Sdim std::vector<unsigned> BitList; 1876226584Sdim if (ParseOptionalBitList(BitList)) 1877226584Sdim return true; 1878226584Sdim std::reverse(BitList.begin(), BitList.end()); 1879226584Sdim 1880226584Sdim if (Lex.getCode() != tgtok::equal) 1881226584Sdim return TokError("expected '=' in let expression"); 1882226584Sdim Lex.Lex(); // eat the '='. 1883226584Sdim 1884226584Sdim RecordVal *Field = CurRec->getValue(FieldName); 1885276479Sdim if (!Field) 1886226584Sdim return TokError("Value '" + FieldName + "' unknown!"); 1887226584Sdim 1888226584Sdim RecTy *Type = Field->getType(); 1889226584Sdim 1890226584Sdim Init *Val = ParseValue(CurRec, Type); 1891276479Sdim if (!Val) return true; 1892226584Sdim 1893226584Sdim if (Lex.getCode() != tgtok::semi) 1894226584Sdim return TokError("expected ';' after let expression"); 1895226584Sdim Lex.Lex(); 1896226584Sdim 1897226584Sdim return SetValue(CurRec, IdLoc, FieldName, BitList, Val); 1898226584Sdim} 1899226584Sdim 1900226584Sdim/// ParseBody - Read the body of a class or def. Return true on error, false on 1901226584Sdim/// success. 1902226584Sdim/// 1903226584Sdim/// Body ::= ';' 1904226584Sdim/// Body ::= '{' BodyList '}' 1905226584Sdim/// BodyList BodyItem* 1906226584Sdim/// 1907226584Sdimbool TGParser::ParseBody(Record *CurRec) { 1908226584Sdim // If this is a null definition, just eat the semi and return. 1909226584Sdim if (Lex.getCode() == tgtok::semi) { 1910226584Sdim Lex.Lex(); 1911226584Sdim return false; 1912226584Sdim } 1913226584Sdim 1914226584Sdim if (Lex.getCode() != tgtok::l_brace) 1915226584Sdim return TokError("Expected ';' or '{' to start body"); 1916226584Sdim // Eat the '{'. 1917226584Sdim Lex.Lex(); 1918226584Sdim 1919226584Sdim while (Lex.getCode() != tgtok::r_brace) 1920226584Sdim if (ParseBodyItem(CurRec)) 1921226584Sdim return true; 1922226584Sdim 1923226584Sdim // Eat the '}'. 1924226584Sdim Lex.Lex(); 1925226584Sdim return false; 1926226584Sdim} 1927226584Sdim 1928249423Sdim/// \brief Apply the current let bindings to \a CurRec. 1929249423Sdim/// \returns true on error, false otherwise. 1930249423Sdimbool TGParser::ApplyLetStack(Record *CurRec) { 1931288943Sdim for (std::vector<LetRecord> &LetInfo : LetStack) 1932288943Sdim for (LetRecord &LR : LetInfo) 1933288943Sdim if (SetValue(CurRec, LR.Loc, LR.Name, LR.Bits, LR.Value)) 1934249423Sdim return true; 1935249423Sdim return false; 1936249423Sdim} 1937249423Sdim 1938226584Sdim/// ParseObjectBody - Parse the body of a def or class. This consists of an 1939226584Sdim/// optional ClassList followed by a Body. CurRec is the current def or class 1940226584Sdim/// that is being parsed. 1941226584Sdim/// 1942226584Sdim/// ObjectBody ::= BaseClassList Body 1943226584Sdim/// BaseClassList ::= /*empty*/ 1944226584Sdim/// BaseClassList ::= ':' BaseClassListNE 1945226584Sdim/// BaseClassListNE ::= SubClassRef (',' SubClassRef)* 1946226584Sdim/// 1947226584Sdimbool TGParser::ParseObjectBody(Record *CurRec) { 1948226584Sdim // If there is a baseclass list, read it. 1949226584Sdim if (Lex.getCode() == tgtok::colon) { 1950226584Sdim Lex.Lex(); 1951226584Sdim 1952226584Sdim // Read all of the subclasses. 1953226584Sdim SubClassReference SubClass = ParseSubClassReference(CurRec, false); 1954226584Sdim while (1) { 1955226584Sdim // Check for error. 1956276479Sdim if (!SubClass.Rec) return true; 1957226584Sdim 1958226584Sdim // Add it. 1959226584Sdim if (AddSubClass(CurRec, SubClass)) 1960226584Sdim return true; 1961226584Sdim 1962226584Sdim if (Lex.getCode() != tgtok::comma) break; 1963226584Sdim Lex.Lex(); // eat ','. 1964226584Sdim SubClass = ParseSubClassReference(CurRec, false); 1965226584Sdim } 1966226584Sdim } 1967226584Sdim 1968249423Sdim if (ApplyLetStack(CurRec)) 1969249423Sdim return true; 1970226584Sdim 1971226584Sdim return ParseBody(CurRec); 1972226584Sdim} 1973226584Sdim 1974226584Sdim/// ParseDef - Parse and return a top level or multiclass def, return the record 1975226584Sdim/// corresponding to it. This returns null on error. 1976226584Sdim/// 1977226584Sdim/// DefInst ::= DEF ObjectName ObjectBody 1978226584Sdim/// 1979226584Sdimbool TGParser::ParseDef(MultiClass *CurMultiClass) { 1980226584Sdim SMLoc DefLoc = Lex.getLoc(); 1981226584Sdim assert(Lex.getCode() == tgtok::Def && "Unknown tok"); 1982226584Sdim Lex.Lex(); // Eat the 'def' token. 1983226584Sdim 1984226584Sdim // Parse ObjectName and make a record for it. 1985280031Sdim std::unique_ptr<Record> CurRecOwner; 1986249423Sdim Init *Name = ParseObjectName(CurMultiClass); 1987249423Sdim if (Name) 1988280031Sdim CurRecOwner = make_unique<Record>(Name, DefLoc, Records); 1989249423Sdim else 1990280031Sdim CurRecOwner = llvm::make_unique<Record>(GetNewAnonymousName(), DefLoc, 1991280031Sdim Records, /*IsAnonymous=*/true); 1992280031Sdim Record *CurRec = CurRecOwner.get(); // Keep a copy since we may release. 1993226584Sdim 1994239462Sdim if (!CurMultiClass && Loops.empty()) { 1995226584Sdim // Top-level def definition. 1996226584Sdim 1997226584Sdim // Ensure redefinition doesn't happen. 1998280031Sdim if (Records.getDef(CurRec->getNameInitAsString())) 1999280031Sdim return Error(DefLoc, "def '" + CurRec->getNameInitAsString()+ 2000280031Sdim "' already defined"); 2001280031Sdim Records.addDef(std::move(CurRecOwner)); 2002276479Sdim 2003276479Sdim if (ParseObjectBody(CurRec)) 2004276479Sdim return true; 2005239462Sdim } else if (CurMultiClass) { 2006276479Sdim // Parse the body before adding this prototype to the DefPrototypes vector. 2007276479Sdim // That way implicit definitions will be added to the DefPrototypes vector 2008276479Sdim // before this object, instantiated prior to defs derived from this object, 2009276479Sdim // and this available for indirect name resolution when defs derived from 2010276479Sdim // this object are instantiated. 2011276479Sdim if (ParseObjectBody(CurRec)) 2012276479Sdim return true; 2013276479Sdim 2014226584Sdim // Otherwise, a def inside a multiclass, add it to the multiclass. 2015288943Sdim for (const auto &Proto : CurMultiClass->DefPrototypes) 2016288943Sdim if (Proto->getNameInit() == CurRec->getNameInit()) 2017280031Sdim return Error(DefLoc, "def '" + CurRec->getNameInitAsString() + 2018280031Sdim "' already defined in this multiclass!"); 2019280031Sdim CurMultiClass->DefPrototypes.push_back(std::move(CurRecOwner)); 2020280031Sdim } else if (ParseObjectBody(CurRec)) { 2021226584Sdim return true; 2022280031Sdim } 2023226584Sdim 2024276479Sdim if (!CurMultiClass) // Def's in multiclasses aren't really defs. 2025226584Sdim // See Record::setName(). This resolve step will see any new name 2026226584Sdim // for the def that might have been created when resolving 2027226584Sdim // inheritance, values and arguments above. 2028226584Sdim CurRec->resolveReferences(); 2029226584Sdim 2030226584Sdim // If ObjectBody has template arguments, it's an error. 2031226584Sdim assert(CurRec->getTemplateArgs().empty() && "How'd this get template args?"); 2032226584Sdim 2033226584Sdim if (CurMultiClass) { 2034226584Sdim // Copy the template arguments for the multiclass into the def. 2035288943Sdim for (Init *TArg : CurMultiClass->Rec.getTemplateArgs()) { 2036288943Sdim const RecordVal *RV = CurMultiClass->Rec.getValue(TArg); 2037226584Sdim assert(RV && "Template arg doesn't exist?"); 2038226584Sdim CurRec->addValue(*RV); 2039226584Sdim } 2040226584Sdim } 2041226584Sdim 2042288943Sdim if (ProcessForeachDefs(CurRec, DefLoc)) 2043280031Sdim return Error(DefLoc, "Could not process loops for def" + 2044280031Sdim CurRec->getNameInitAsString()); 2045234353Sdim 2046226584Sdim return false; 2047226584Sdim} 2048226584Sdim 2049234353Sdim/// ParseForeach - Parse a for statement. Return the record corresponding 2050234353Sdim/// to it. This returns true on error. 2051234353Sdim/// 2052234353Sdim/// Foreach ::= FOREACH Declaration IN '{ ObjectList '}' 2053234353Sdim/// Foreach ::= FOREACH Declaration IN Object 2054234353Sdim/// 2055234353Sdimbool TGParser::ParseForeach(MultiClass *CurMultiClass) { 2056234353Sdim assert(Lex.getCode() == tgtok::Foreach && "Unknown tok"); 2057234353Sdim Lex.Lex(); // Eat the 'for' token. 2058234353Sdim 2059234353Sdim // Make a temporary object to record items associated with the for 2060234353Sdim // loop. 2061276479Sdim ListInit *ListValue = nullptr; 2062239462Sdim VarInit *IterName = ParseForeachDeclaration(ListValue); 2063276479Sdim if (!IterName) 2064234353Sdim return TokError("expected declaration in for"); 2065234353Sdim 2066234353Sdim if (Lex.getCode() != tgtok::In) 2067234353Sdim return TokError("Unknown tok"); 2068234353Sdim Lex.Lex(); // Eat the in 2069234353Sdim 2070234353Sdim // Create a loop object and remember it. 2071234353Sdim Loops.push_back(ForeachLoop(IterName, ListValue)); 2072234353Sdim 2073234353Sdim if (Lex.getCode() != tgtok::l_brace) { 2074234353Sdim // FOREACH Declaration IN Object 2075234353Sdim if (ParseObject(CurMultiClass)) 2076234353Sdim return true; 2077288943Sdim } else { 2078234353Sdim SMLoc BraceLoc = Lex.getLoc(); 2079234353Sdim // Otherwise, this is a group foreach. 2080234353Sdim Lex.Lex(); // eat the '{'. 2081234353Sdim 2082234353Sdim // Parse the object list. 2083234353Sdim if (ParseObjectList(CurMultiClass)) 2084234353Sdim return true; 2085234353Sdim 2086234353Sdim if (Lex.getCode() != tgtok::r_brace) { 2087234353Sdim TokError("expected '}' at end of foreach command"); 2088234353Sdim return Error(BraceLoc, "to match this '{'"); 2089234353Sdim } 2090234353Sdim Lex.Lex(); // Eat the } 2091234353Sdim } 2092234353Sdim 2093234353Sdim // We've processed everything in this loop. 2094234353Sdim Loops.pop_back(); 2095234353Sdim 2096234353Sdim return false; 2097234353Sdim} 2098234353Sdim 2099226584Sdim/// ParseClass - Parse a tblgen class definition. 2100226584Sdim/// 2101226584Sdim/// ClassInst ::= CLASS ID TemplateArgList? ObjectBody 2102226584Sdim/// 2103226584Sdimbool TGParser::ParseClass() { 2104226584Sdim assert(Lex.getCode() == tgtok::Class && "Unexpected token!"); 2105226584Sdim Lex.Lex(); 2106226584Sdim 2107226584Sdim if (Lex.getCode() != tgtok::Id) 2108226584Sdim return TokError("expected class name after 'class' keyword"); 2109226584Sdim 2110226584Sdim Record *CurRec = Records.getClass(Lex.getCurStrVal()); 2111226584Sdim if (CurRec) { 2112226584Sdim // If the body was previously defined, this is an error. 2113234353Sdim if (CurRec->getValues().size() > 1 || // Account for NAME. 2114226584Sdim !CurRec->getSuperClasses().empty() || 2115226584Sdim !CurRec->getTemplateArgs().empty()) 2116288943Sdim return TokError("Class '" + CurRec->getNameInitAsString() + 2117288943Sdim "' already defined"); 2118226584Sdim } else { 2119226584Sdim // If this is the first reference to this class, create and add it. 2120280031Sdim auto NewRec = 2121280031Sdim llvm::make_unique<Record>(Lex.getCurStrVal(), Lex.getLoc(), Records); 2122280031Sdim CurRec = NewRec.get(); 2123280031Sdim Records.addClass(std::move(NewRec)); 2124226584Sdim } 2125226584Sdim Lex.Lex(); // eat the name. 2126226584Sdim 2127226584Sdim // If there are template args, parse them. 2128226584Sdim if (Lex.getCode() == tgtok::less) 2129226584Sdim if (ParseTemplateArgList(CurRec)) 2130226584Sdim return true; 2131226584Sdim 2132226584Sdim // Finally, parse the object body. 2133226584Sdim return ParseObjectBody(CurRec); 2134226584Sdim} 2135226584Sdim 2136226584Sdim/// ParseLetList - Parse a non-empty list of assignment expressions into a list 2137226584Sdim/// of LetRecords. 2138226584Sdim/// 2139226584Sdim/// LetList ::= LetItem (',' LetItem)* 2140226584Sdim/// LetItem ::= ID OptionalRangeList '=' Value 2141226584Sdim/// 2142226584Sdimstd::vector<LetRecord> TGParser::ParseLetList() { 2143226584Sdim std::vector<LetRecord> Result; 2144226584Sdim 2145226584Sdim while (1) { 2146226584Sdim if (Lex.getCode() != tgtok::Id) { 2147226584Sdim TokError("expected identifier in let definition"); 2148226584Sdim return std::vector<LetRecord>(); 2149226584Sdim } 2150226584Sdim std::string Name = Lex.getCurStrVal(); 2151226584Sdim SMLoc NameLoc = Lex.getLoc(); 2152226584Sdim Lex.Lex(); // Eat the identifier. 2153226584Sdim 2154226584Sdim // Check for an optional RangeList. 2155226584Sdim std::vector<unsigned> Bits; 2156226584Sdim if (ParseOptionalRangeList(Bits)) 2157226584Sdim return std::vector<LetRecord>(); 2158226584Sdim std::reverse(Bits.begin(), Bits.end()); 2159226584Sdim 2160226584Sdim if (Lex.getCode() != tgtok::equal) { 2161226584Sdim TokError("expected '=' in let expression"); 2162226584Sdim return std::vector<LetRecord>(); 2163226584Sdim } 2164226584Sdim Lex.Lex(); // eat the '='. 2165226584Sdim 2166276479Sdim Init *Val = ParseValue(nullptr); 2167276479Sdim if (!Val) return std::vector<LetRecord>(); 2168226584Sdim 2169226584Sdim // Now that we have everything, add the record. 2170288943Sdim Result.emplace_back(std::move(Name), std::move(Bits), Val, NameLoc); 2171226584Sdim 2172226584Sdim if (Lex.getCode() != tgtok::comma) 2173226584Sdim return Result; 2174226584Sdim Lex.Lex(); // eat the comma. 2175226584Sdim } 2176226584Sdim} 2177226584Sdim 2178226584Sdim/// ParseTopLevelLet - Parse a 'let' at top level. This can be a couple of 2179226584Sdim/// different related productions. This works inside multiclasses too. 2180226584Sdim/// 2181226584Sdim/// Object ::= LET LetList IN '{' ObjectList '}' 2182226584Sdim/// Object ::= LET LetList IN Object 2183226584Sdim/// 2184226584Sdimbool TGParser::ParseTopLevelLet(MultiClass *CurMultiClass) { 2185226584Sdim assert(Lex.getCode() == tgtok::Let && "Unexpected token"); 2186226584Sdim Lex.Lex(); 2187226584Sdim 2188226584Sdim // Add this entry to the let stack. 2189226584Sdim std::vector<LetRecord> LetInfo = ParseLetList(); 2190226584Sdim if (LetInfo.empty()) return true; 2191280031Sdim LetStack.push_back(std::move(LetInfo)); 2192226584Sdim 2193226584Sdim if (Lex.getCode() != tgtok::In) 2194226584Sdim return TokError("expected 'in' at end of top-level 'let'"); 2195226584Sdim Lex.Lex(); 2196226584Sdim 2197226584Sdim // If this is a scalar let, just handle it now 2198226584Sdim if (Lex.getCode() != tgtok::l_brace) { 2199226584Sdim // LET LetList IN Object 2200226584Sdim if (ParseObject(CurMultiClass)) 2201226584Sdim return true; 2202226584Sdim } else { // Object ::= LETCommand '{' ObjectList '}' 2203226584Sdim SMLoc BraceLoc = Lex.getLoc(); 2204226584Sdim // Otherwise, this is a group let. 2205226584Sdim Lex.Lex(); // eat the '{'. 2206226584Sdim 2207226584Sdim // Parse the object list. 2208226584Sdim if (ParseObjectList(CurMultiClass)) 2209226584Sdim return true; 2210226584Sdim 2211226584Sdim if (Lex.getCode() != tgtok::r_brace) { 2212226584Sdim TokError("expected '}' at end of top level let command"); 2213226584Sdim return Error(BraceLoc, "to match this '{'"); 2214226584Sdim } 2215226584Sdim Lex.Lex(); 2216226584Sdim } 2217226584Sdim 2218226584Sdim // Outside this let scope, this let block is not active. 2219226584Sdim LetStack.pop_back(); 2220226584Sdim return false; 2221226584Sdim} 2222226584Sdim 2223226584Sdim/// ParseMultiClass - Parse a multiclass definition. 2224226584Sdim/// 2225226584Sdim/// MultiClassInst ::= MULTICLASS ID TemplateArgList? 2226249423Sdim/// ':' BaseMultiClassList '{' MultiClassObject+ '}' 2227249423Sdim/// MultiClassObject ::= DefInst 2228249423Sdim/// MultiClassObject ::= MultiClassInst 2229249423Sdim/// MultiClassObject ::= DefMInst 2230249423Sdim/// MultiClassObject ::= LETCommand '{' ObjectList '}' 2231249423Sdim/// MultiClassObject ::= LETCommand Object 2232226584Sdim/// 2233226584Sdimbool TGParser::ParseMultiClass() { 2234226584Sdim assert(Lex.getCode() == tgtok::MultiClass && "Unexpected token"); 2235226584Sdim Lex.Lex(); // Eat the multiclass token. 2236226584Sdim 2237226584Sdim if (Lex.getCode() != tgtok::Id) 2238226584Sdim return TokError("expected identifier after multiclass for name"); 2239226584Sdim std::string Name = Lex.getCurStrVal(); 2240226584Sdim 2241280031Sdim auto Result = 2242280031Sdim MultiClasses.insert(std::make_pair(Name, 2243280031Sdim llvm::make_unique<MultiClass>(Name, Lex.getLoc(),Records))); 2244280031Sdim 2245280031Sdim if (!Result.second) 2246226584Sdim return TokError("multiclass '" + Name + "' already defined"); 2247226584Sdim 2248280031Sdim CurMultiClass = Result.first->second.get(); 2249226584Sdim Lex.Lex(); // Eat the identifier. 2250226584Sdim 2251226584Sdim // If there are template args, parse them. 2252226584Sdim if (Lex.getCode() == tgtok::less) 2253276479Sdim if (ParseTemplateArgList(nullptr)) 2254226584Sdim return true; 2255226584Sdim 2256226584Sdim bool inherits = false; 2257226584Sdim 2258226584Sdim // If there are submulticlasses, parse them. 2259226584Sdim if (Lex.getCode() == tgtok::colon) { 2260226584Sdim inherits = true; 2261226584Sdim 2262226584Sdim Lex.Lex(); 2263226584Sdim 2264226584Sdim // Read all of the submulticlasses. 2265226584Sdim SubMultiClassReference SubMultiClass = 2266226584Sdim ParseSubMultiClassReference(CurMultiClass); 2267226584Sdim while (1) { 2268226584Sdim // Check for error. 2269276479Sdim if (!SubMultiClass.MC) return true; 2270226584Sdim 2271226584Sdim // Add it. 2272226584Sdim if (AddSubMultiClass(CurMultiClass, SubMultiClass)) 2273226584Sdim return true; 2274226584Sdim 2275226584Sdim if (Lex.getCode() != tgtok::comma) break; 2276226584Sdim Lex.Lex(); // eat ','. 2277226584Sdim SubMultiClass = ParseSubMultiClassReference(CurMultiClass); 2278226584Sdim } 2279226584Sdim } 2280226584Sdim 2281226584Sdim if (Lex.getCode() != tgtok::l_brace) { 2282226584Sdim if (!inherits) 2283226584Sdim return TokError("expected '{' in multiclass definition"); 2284280031Sdim if (Lex.getCode() != tgtok::semi) 2285226584Sdim return TokError("expected ';' in multiclass definition"); 2286280031Sdim Lex.Lex(); // eat the ';'. 2287226584Sdim } else { 2288226584Sdim if (Lex.Lex() == tgtok::r_brace) // eat the '{'. 2289226584Sdim return TokError("multiclass must contain at least one def"); 2290226584Sdim 2291226584Sdim while (Lex.getCode() != tgtok::r_brace) { 2292226584Sdim switch (Lex.getCode()) { 2293280031Sdim default: 2294280031Sdim return TokError("expected 'let', 'def' or 'defm' in multiclass body"); 2295280031Sdim case tgtok::Let: 2296280031Sdim case tgtok::Def: 2297280031Sdim case tgtok::Defm: 2298280031Sdim case tgtok::Foreach: 2299280031Sdim if (ParseObject(CurMultiClass)) 2300280031Sdim return true; 2301280031Sdim break; 2302226584Sdim } 2303226584Sdim } 2304226584Sdim Lex.Lex(); // eat the '}'. 2305226584Sdim } 2306226584Sdim 2307276479Sdim CurMultiClass = nullptr; 2308226584Sdim return false; 2309226584Sdim} 2310226584Sdim 2311296417SdimRecord *TGParser::InstantiateMulticlassDef(MultiClass &MC, Record *DefProto, 2312296417Sdim Init *&DefmPrefix, 2313296417Sdim SMRange DefmPrefixRange, 2314296417Sdim ArrayRef<Init *> TArgs, 2315296417Sdim std::vector<Init *> &TemplateVals) { 2316234353Sdim // We need to preserve DefProto so it can be reused for later 2317234353Sdim // instantiations, so create a new Record to inherit from it. 2318234353Sdim 2319226584Sdim // Add in the defm name. If the defm prefix is empty, give each 2320226584Sdim // instantiated def a unique name. Otherwise, if "#NAME#" exists in the 2321226584Sdim // name, substitute the prefix for #NAME#. Otherwise, use the defm name 2322226584Sdim // as a prefix. 2323234353Sdim 2324249423Sdim bool IsAnonymous = false; 2325276479Sdim if (!DefmPrefix) { 2326234353Sdim DefmPrefix = StringInit::get(GetNewAnonymousName()); 2327249423Sdim IsAnonymous = true; 2328249423Sdim } 2329234353Sdim 2330234353Sdim Init *DefName = DefProto->getNameInit(); 2331243830Sdim StringInit *DefNameString = dyn_cast<StringInit>(DefName); 2332234353Sdim 2333276479Sdim if (DefNameString) { 2334234353Sdim // We have a fully expanded string so there are no operators to 2335234353Sdim // resolve. We should concatenate the given prefix and name. 2336234353Sdim DefName = 2337234353Sdim BinOpInit::get(BinOpInit::STRCONCAT, 2338234353Sdim UnOpInit::get(UnOpInit::CAST, DefmPrefix, 2339234353Sdim StringRecTy::get())->Fold(DefProto, &MC), 2340234353Sdim DefName, StringRecTy::get())->Fold(DefProto, &MC); 2341226584Sdim } 2342226584Sdim 2343243830Sdim // Make a trail of SMLocs from the multiclass instantiations. 2344249423Sdim SmallVector<SMLoc, 4> Locs(1, DefmPrefixRange.Start); 2345243830Sdim Locs.append(DefProto->getLoc().begin(), DefProto->getLoc().end()); 2346280031Sdim auto CurRec = make_unique<Record>(DefName, Locs, Records, IsAnonymous); 2347226584Sdim 2348226584Sdim SubClassReference Ref; 2349249423Sdim Ref.RefRange = DefmPrefixRange; 2350226584Sdim Ref.Rec = DefProto; 2351280031Sdim AddSubClass(CurRec.get(), Ref); 2352226584Sdim 2353239462Sdim // Set the value for NAME. We don't resolve references to it 'til later, 2354239462Sdim // though, so that uses in nested multiclass names don't get 2355239462Sdim // confused. 2356296417Sdim if (SetValue(CurRec.get(), Ref.RefRange.Start, "NAME", None, DefmPrefix, 2357296417Sdim /*AllowSelfAssignment*/true)) { 2358288943Sdim Error(DefmPrefixRange.Start, "Could not resolve " + 2359288943Sdim CurRec->getNameInitAsString() + ":NAME to '" + 2360288943Sdim DefmPrefix->getAsUnquotedString() + "'"); 2361276479Sdim return nullptr; 2362239462Sdim } 2363239462Sdim 2364239462Sdim // If the DefNameString didn't resolve, we probably have a reference to 2365239462Sdim // NAME and need to replace it. We need to do at least this much greedily, 2366239462Sdim // otherwise nested multiclasses will end up with incorrect NAME expansions. 2367276479Sdim if (!DefNameString) { 2368234353Sdim RecordVal *DefNameRV = CurRec->getValue("NAME"); 2369234353Sdim CurRec->resolveReferencesTo(DefNameRV); 2370234353Sdim } 2371234353Sdim 2372234353Sdim if (!CurMultiClass) { 2373239462Sdim // Now that we're at the top level, resolve all NAME references 2374239462Sdim // in the resultant defs that weren't in the def names themselves. 2375239462Sdim RecordVal *DefNameRV = CurRec->getValue("NAME"); 2376239462Sdim CurRec->resolveReferencesTo(DefNameRV); 2377239462Sdim 2378288943Sdim // Check if the name is a complex pattern. 2379288943Sdim // If so, resolve it. 2380288943Sdim DefName = CurRec->getNameInit(); 2381288943Sdim DefNameString = dyn_cast<StringInit>(DefName); 2382288943Sdim 2383288943Sdim // OK the pattern is more complex than simply using NAME. 2384288943Sdim // Let's use the heavy weaponery. 2385288943Sdim if (!DefNameString) { 2386288943Sdim ResolveMulticlassDefArgs(MC, CurRec.get(), DefmPrefixRange.Start, 2387288943Sdim Lex.getLoc(), TArgs, TemplateVals, 2388288943Sdim false/*Delete args*/); 2389288943Sdim DefName = CurRec->getNameInit(); 2390288943Sdim DefNameString = dyn_cast<StringInit>(DefName); 2391288943Sdim 2392288943Sdim if (!DefNameString) 2393288943Sdim DefName = DefName->convertInitializerTo(StringRecTy::get()); 2394288943Sdim 2395288943Sdim // We ran out of options here... 2396288943Sdim DefNameString = dyn_cast<StringInit>(DefName); 2397288943Sdim if (!DefNameString) { 2398288943Sdim PrintFatalError(CurRec->getLoc()[CurRec->getLoc().size() - 1], 2399288943Sdim DefName->getAsUnquotedString() + " is not a string."); 2400288943Sdim return nullptr; 2401288943Sdim } 2402288943Sdim 2403288943Sdim CurRec->setName(DefName); 2404288943Sdim } 2405288943Sdim 2406239462Sdim // Now that NAME references are resolved and we're at the top level of 2407239462Sdim // any multiclass expansions, add the record to the RecordKeeper. If we are 2408234353Sdim // currently in a multiclass, it means this defm appears inside a 2409234353Sdim // multiclass and its name won't be fully resolvable until we see 2410288943Sdim // the top-level defm. Therefore, we don't add this to the 2411288943Sdim // RecordKeeper at this point. If we did we could get duplicate 2412234353Sdim // defs as more than one probably refers to NAME or some other 2413234353Sdim // common internal placeholder. 2414234353Sdim 2415234353Sdim // Ensure redefinition doesn't happen. 2416234353Sdim if (Records.getDef(CurRec->getNameInitAsString())) { 2417249423Sdim Error(DefmPrefixRange.Start, "def '" + CurRec->getNameInitAsString() + 2418234353Sdim "' already defined, instantiating defm with subdef '" + 2419234353Sdim DefProto->getNameInitAsString() + "'"); 2420276479Sdim return nullptr; 2421234353Sdim } 2422234353Sdim 2423280031Sdim Record *CurRecSave = CurRec.get(); // Keep a copy before we release. 2424280031Sdim Records.addDef(std::move(CurRec)); 2425280031Sdim return CurRecSave; 2426234353Sdim } 2427234353Sdim 2428280031Sdim // FIXME This is bad but the ownership transfer to caller is pretty messy. 2429280031Sdim // The unique_ptr in this function at least protects the exits above. 2430280031Sdim return CurRec.release(); 2431226584Sdim} 2432226584Sdim 2433296417Sdimbool TGParser::ResolveMulticlassDefArgs(MultiClass &MC, Record *CurRec, 2434296417Sdim SMLoc DefmPrefixLoc, SMLoc SubClassLoc, 2435296417Sdim ArrayRef<Init *> TArgs, 2436226584Sdim std::vector<Init *> &TemplateVals, 2437226584Sdim bool DeleteArgs) { 2438226584Sdim // Loop over all of the template arguments, setting them to the specified 2439226584Sdim // value or leaving them as the default if necessary. 2440226584Sdim for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { 2441226584Sdim // Check if a value is specified for this temp-arg. 2442226584Sdim if (i < TemplateVals.size()) { 2443226584Sdim // Set it now. 2444296417Sdim if (SetValue(CurRec, DefmPrefixLoc, TArgs[i], None, TemplateVals[i])) 2445226584Sdim return true; 2446288943Sdim 2447226584Sdim // Resolve it next. 2448226584Sdim CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i])); 2449226584Sdim 2450226584Sdim if (DeleteArgs) 2451226584Sdim // Now remove it. 2452226584Sdim CurRec->removeValue(TArgs[i]); 2453288943Sdim 2454226584Sdim } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) { 2455288943Sdim return Error(SubClassLoc, "value not specified for template argument #" + 2456288943Sdim Twine(i) + " (" + TArgs[i]->getAsUnquotedString() + 2457288943Sdim ") of multiclassclass '" + MC.Rec.getNameInitAsString() + 2458288943Sdim "'"); 2459226584Sdim } 2460226584Sdim } 2461226584Sdim return false; 2462226584Sdim} 2463226584Sdim 2464226584Sdimbool TGParser::ResolveMulticlassDef(MultiClass &MC, 2465226584Sdim Record *CurRec, 2466226584Sdim Record *DefProto, 2467226584Sdim SMLoc DefmPrefixLoc) { 2468226584Sdim // If the mdef is inside a 'let' expression, add to each def. 2469249423Sdim if (ApplyLetStack(CurRec)) 2470249423Sdim return Error(DefmPrefixLoc, "when instantiating this defm"); 2471226584Sdim 2472226584Sdim // Don't create a top level definition for defm inside multiclasses, 2473226584Sdim // instead, only update the prototypes and bind the template args 2474226584Sdim // with the new created definition. 2475249423Sdim if (!CurMultiClass) 2476249423Sdim return false; 2477288943Sdim for (const auto &Proto : CurMultiClass->DefPrototypes) 2478288943Sdim if (Proto->getNameInit() == CurRec->getNameInit()) 2479249423Sdim return Error(DefmPrefixLoc, "defm '" + CurRec->getNameInitAsString() + 2480249423Sdim "' already defined in this multiclass!"); 2481280031Sdim CurMultiClass->DefPrototypes.push_back(std::unique_ptr<Record>(CurRec)); 2482226584Sdim 2483249423Sdim // Copy the template arguments for the multiclass into the new def. 2484288943Sdim for (Init * TA : CurMultiClass->Rec.getTemplateArgs()) { 2485288943Sdim const RecordVal *RV = CurMultiClass->Rec.getValue(TA); 2486249423Sdim assert(RV && "Template arg doesn't exist?"); 2487249423Sdim CurRec->addValue(*RV); 2488226584Sdim } 2489226584Sdim 2490226584Sdim return false; 2491226584Sdim} 2492226584Sdim 2493226584Sdim/// ParseDefm - Parse the instantiation of a multiclass. 2494226584Sdim/// 2495226584Sdim/// DefMInst ::= DEFM ID ':' DefmSubClassRef ';' 2496226584Sdim/// 2497226584Sdimbool TGParser::ParseDefm(MultiClass *CurMultiClass) { 2498226584Sdim assert(Lex.getCode() == tgtok::Defm && "Unexpected token!"); 2499249423Sdim SMLoc DefmLoc = Lex.getLoc(); 2500276479Sdim Init *DefmPrefix = nullptr; 2501234353Sdim 2502226584Sdim if (Lex.Lex() == tgtok::Id) { // eat the defm. 2503234353Sdim DefmPrefix = ParseObjectName(CurMultiClass); 2504226584Sdim } 2505226584Sdim 2506249423Sdim SMLoc DefmPrefixEndLoc = Lex.getLoc(); 2507226584Sdim if (Lex.getCode() != tgtok::colon) 2508226584Sdim return TokError("expected ':' after defm identifier"); 2509226584Sdim 2510226584Sdim // Keep track of the new generated record definitions. 2511226584Sdim std::vector<Record*> NewRecDefs; 2512226584Sdim 2513226584Sdim // This record also inherits from a regular class (non-multiclass)? 2514226584Sdim bool InheritFromClass = false; 2515226584Sdim 2516226584Sdim // eat the colon. 2517226584Sdim Lex.Lex(); 2518226584Sdim 2519226584Sdim SMLoc SubClassLoc = Lex.getLoc(); 2520276479Sdim SubClassReference Ref = ParseSubClassReference(nullptr, true); 2521226584Sdim 2522226584Sdim while (1) { 2523276479Sdim if (!Ref.Rec) return true; 2524226584Sdim 2525226584Sdim // To instantiate a multiclass, we need to first get the multiclass, then 2526226584Sdim // instantiate each def contained in the multiclass with the SubClassRef 2527226584Sdim // template parameters. 2528280031Sdim MultiClass *MC = MultiClasses[Ref.Rec->getName()].get(); 2529226584Sdim assert(MC && "Didn't lookup multiclass correctly?"); 2530226584Sdim std::vector<Init*> &TemplateVals = Ref.TemplateArgs; 2531226584Sdim 2532226584Sdim // Verify that the correct number of template arguments were specified. 2533296417Sdim ArrayRef<Init *> TArgs = MC->Rec.getTemplateArgs(); 2534226584Sdim if (TArgs.size() < TemplateVals.size()) 2535226584Sdim return Error(SubClassLoc, 2536226584Sdim "more template args specified than multiclass expects"); 2537226584Sdim 2538226584Sdim // Loop over all the def's in the multiclass, instantiating each one. 2539288943Sdim for (const std::unique_ptr<Record> &DefProto : MC->DefPrototypes) { 2540288943Sdim // The record name construction goes as follow: 2541288943Sdim // - If the def name is a string, prepend the prefix. 2542288943Sdim // - If the def name is a more complex pattern, use that pattern. 2543309124Sdim // As a result, the record is instantiated before resolving 2544288943Sdim // arguments, as it would make its name a string. 2545288943Sdim Record *CurRec = InstantiateMulticlassDef(*MC, DefProto.get(), DefmPrefix, 2546249423Sdim SMRange(DefmLoc, 2547288943Sdim DefmPrefixEndLoc), 2548288943Sdim TArgs, TemplateVals); 2549234353Sdim if (!CurRec) 2550234353Sdim return true; 2551226584Sdim 2552309124Sdim // Now that the record is instantiated, we can resolve arguments. 2553249423Sdim if (ResolveMulticlassDefArgs(*MC, CurRec, DefmLoc, SubClassLoc, 2554226584Sdim TArgs, TemplateVals, true/*Delete args*/)) 2555226584Sdim return Error(SubClassLoc, "could not instantiate def"); 2556226584Sdim 2557288943Sdim if (ResolveMulticlassDef(*MC, CurRec, DefProto.get(), DefmLoc)) 2558226584Sdim return Error(SubClassLoc, "could not instantiate def"); 2559226584Sdim 2560280031Sdim // Defs that can be used by other definitions should be fully resolved 2561280031Sdim // before any use. 2562280031Sdim if (DefProto->isResolveFirst() && !CurMultiClass) { 2563280031Sdim CurRec->resolveReferences(); 2564280031Sdim CurRec->setResolveFirst(false); 2565280031Sdim } 2566226584Sdim NewRecDefs.push_back(CurRec); 2567226584Sdim } 2568226584Sdim 2569226584Sdim 2570226584Sdim if (Lex.getCode() != tgtok::comma) break; 2571226584Sdim Lex.Lex(); // eat ','. 2572226584Sdim 2573261991Sdim if (Lex.getCode() != tgtok::Id) 2574261991Sdim return TokError("expected identifier"); 2575261991Sdim 2576226584Sdim SubClassLoc = Lex.getLoc(); 2577226584Sdim 2578226584Sdim // A defm can inherit from regular classes (non-multiclass) as 2579226584Sdim // long as they come in the end of the inheritance list. 2580276479Sdim InheritFromClass = (Records.getClass(Lex.getCurStrVal()) != nullptr); 2581226584Sdim 2582226584Sdim if (InheritFromClass) 2583226584Sdim break; 2584226584Sdim 2585276479Sdim Ref = ParseSubClassReference(nullptr, true); 2586226584Sdim } 2587226584Sdim 2588226584Sdim if (InheritFromClass) { 2589226584Sdim // Process all the classes to inherit as if they were part of a 2590226584Sdim // regular 'def' and inherit all record values. 2591276479Sdim SubClassReference SubClass = ParseSubClassReference(nullptr, false); 2592226584Sdim while (1) { 2593226584Sdim // Check for error. 2594276479Sdim if (!SubClass.Rec) return true; 2595226584Sdim 2596226584Sdim // Get the expanded definition prototypes and teach them about 2597226584Sdim // the record values the current class to inherit has 2598288943Sdim for (Record *CurRec : NewRecDefs) { 2599226584Sdim // Add it. 2600226584Sdim if (AddSubClass(CurRec, SubClass)) 2601226584Sdim return true; 2602226584Sdim 2603249423Sdim if (ApplyLetStack(CurRec)) 2604249423Sdim return true; 2605226584Sdim } 2606226584Sdim 2607226584Sdim if (Lex.getCode() != tgtok::comma) break; 2608226584Sdim Lex.Lex(); // eat ','. 2609276479Sdim SubClass = ParseSubClassReference(nullptr, false); 2610226584Sdim } 2611226584Sdim } 2612226584Sdim 2613226584Sdim if (!CurMultiClass) 2614288943Sdim for (Record *CurRec : NewRecDefs) 2615226584Sdim // See Record::setName(). This resolve step will see any new 2616226584Sdim // name for the def that might have been created when resolving 2617226584Sdim // inheritance, values and arguments above. 2618288943Sdim CurRec->resolveReferences(); 2619226584Sdim 2620226584Sdim if (Lex.getCode() != tgtok::semi) 2621226584Sdim return TokError("expected ';' at end of defm"); 2622226584Sdim Lex.Lex(); 2623226584Sdim 2624226584Sdim return false; 2625226584Sdim} 2626226584Sdim 2627226584Sdim/// ParseObject 2628226584Sdim/// Object ::= ClassInst 2629226584Sdim/// Object ::= DefInst 2630226584Sdim/// Object ::= MultiClassInst 2631226584Sdim/// Object ::= DefMInst 2632226584Sdim/// Object ::= LETCommand '{' ObjectList '}' 2633226584Sdim/// Object ::= LETCommand Object 2634226584Sdimbool TGParser::ParseObject(MultiClass *MC) { 2635226584Sdim switch (Lex.getCode()) { 2636226584Sdim default: 2637226584Sdim return TokError("Expected class, def, defm, multiclass or let definition"); 2638226584Sdim case tgtok::Let: return ParseTopLevelLet(MC); 2639226584Sdim case tgtok::Def: return ParseDef(MC); 2640234353Sdim case tgtok::Foreach: return ParseForeach(MC); 2641226584Sdim case tgtok::Defm: return ParseDefm(MC); 2642226584Sdim case tgtok::Class: return ParseClass(); 2643226584Sdim case tgtok::MultiClass: return ParseMultiClass(); 2644226584Sdim } 2645226584Sdim} 2646226584Sdim 2647226584Sdim/// ParseObjectList 2648226584Sdim/// ObjectList :== Object* 2649226584Sdimbool TGParser::ParseObjectList(MultiClass *MC) { 2650226584Sdim while (isObjectStart(Lex.getCode())) { 2651226584Sdim if (ParseObject(MC)) 2652226584Sdim return true; 2653226584Sdim } 2654226584Sdim return false; 2655226584Sdim} 2656226584Sdim 2657226584Sdimbool TGParser::ParseFile() { 2658226584Sdim Lex.Lex(); // Prime the lexer. 2659226584Sdim if (ParseObjectList()) return true; 2660226584Sdim 2661226584Sdim // If we have unread input at the end of the file, report it. 2662226584Sdim if (Lex.getCode() == tgtok::Eof) 2663226584Sdim return false; 2664226584Sdim 2665226584Sdim return TokError("Unexpected input at top level"); 2666226584Sdim} 2667226584Sdim 2668