xref: /aosp_15_r20/external/llvm/lib/TableGen/TGParser.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- TGParser.cpp - Parser for TableGen Files ---------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // Implement the Parser for TableGen.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker 
14*9880d681SAndroid Build Coastguard Worker #include "TGParser.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallVector.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringExtras.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/TableGen/Record.h"
19*9880d681SAndroid Build Coastguard Worker #include <algorithm>
20*9880d681SAndroid Build Coastguard Worker using namespace llvm;
21*9880d681SAndroid Build Coastguard Worker 
22*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
23*9880d681SAndroid Build Coastguard Worker // Support Code for the Semantic Actions.
24*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
25*9880d681SAndroid Build Coastguard Worker 
26*9880d681SAndroid Build Coastguard Worker namespace llvm {
27*9880d681SAndroid Build Coastguard Worker struct SubClassReference {
28*9880d681SAndroid Build Coastguard Worker   SMRange RefRange;
29*9880d681SAndroid Build Coastguard Worker   Record *Rec;
30*9880d681SAndroid Build Coastguard Worker   std::vector<Init*> TemplateArgs;
SubClassReferencellvm::SubClassReference31*9880d681SAndroid Build Coastguard Worker   SubClassReference() : Rec(nullptr) {}
32*9880d681SAndroid Build Coastguard Worker 
isInvalidllvm::SubClassReference33*9880d681SAndroid Build Coastguard Worker   bool isInvalid() const { return Rec == nullptr; }
34*9880d681SAndroid Build Coastguard Worker };
35*9880d681SAndroid Build Coastguard Worker 
36*9880d681SAndroid Build Coastguard Worker struct SubMultiClassReference {
37*9880d681SAndroid Build Coastguard Worker   SMRange RefRange;
38*9880d681SAndroid Build Coastguard Worker   MultiClass *MC;
39*9880d681SAndroid Build Coastguard Worker   std::vector<Init*> TemplateArgs;
SubMultiClassReferencellvm::SubMultiClassReference40*9880d681SAndroid Build Coastguard Worker   SubMultiClassReference() : MC(nullptr) {}
41*9880d681SAndroid Build Coastguard Worker 
isInvalidllvm::SubMultiClassReference42*9880d681SAndroid Build Coastguard Worker   bool isInvalid() const { return MC == nullptr; }
43*9880d681SAndroid Build Coastguard Worker   void dump() const;
44*9880d681SAndroid Build Coastguard Worker };
45*9880d681SAndroid Build Coastguard Worker 
dump() const46*9880d681SAndroid Build Coastguard Worker LLVM_DUMP_METHOD void SubMultiClassReference::dump() const {
47*9880d681SAndroid Build Coastguard Worker   errs() << "Multiclass:\n";
48*9880d681SAndroid Build Coastguard Worker 
49*9880d681SAndroid Build Coastguard Worker   MC->dump();
50*9880d681SAndroid Build Coastguard Worker 
51*9880d681SAndroid Build Coastguard Worker   errs() << "Template args:\n";
52*9880d681SAndroid Build Coastguard Worker   for (Init *TA : TemplateArgs)
53*9880d681SAndroid Build Coastguard Worker     TA->dump();
54*9880d681SAndroid Build Coastguard Worker }
55*9880d681SAndroid Build Coastguard Worker 
56*9880d681SAndroid Build Coastguard Worker } // end namespace llvm
57*9880d681SAndroid Build Coastguard Worker 
AddValue(Record * CurRec,SMLoc Loc,const RecordVal & RV)58*9880d681SAndroid Build Coastguard Worker bool TGParser::AddValue(Record *CurRec, SMLoc Loc, const RecordVal &RV) {
59*9880d681SAndroid Build Coastguard Worker   if (!CurRec)
60*9880d681SAndroid Build Coastguard Worker     CurRec = &CurMultiClass->Rec;
61*9880d681SAndroid Build Coastguard Worker 
62*9880d681SAndroid Build Coastguard Worker   if (RecordVal *ERV = CurRec->getValue(RV.getNameInit())) {
63*9880d681SAndroid Build Coastguard Worker     // The value already exists in the class, treat this as a set.
64*9880d681SAndroid Build Coastguard Worker     if (ERV->setValue(RV.getValue()))
65*9880d681SAndroid Build Coastguard Worker       return Error(Loc, "New definition of '" + RV.getName() + "' of type '" +
66*9880d681SAndroid Build Coastguard Worker                    RV.getType()->getAsString() + "' is incompatible with " +
67*9880d681SAndroid Build Coastguard Worker                    "previous definition of type '" +
68*9880d681SAndroid Build Coastguard Worker                    ERV->getType()->getAsString() + "'");
69*9880d681SAndroid Build Coastguard Worker   } else {
70*9880d681SAndroid Build Coastguard Worker     CurRec->addValue(RV);
71*9880d681SAndroid Build Coastguard Worker   }
72*9880d681SAndroid Build Coastguard Worker   return false;
73*9880d681SAndroid Build Coastguard Worker }
74*9880d681SAndroid Build Coastguard Worker 
75*9880d681SAndroid Build Coastguard Worker /// SetValue -
76*9880d681SAndroid Build Coastguard Worker /// Return true on error, false on success.
SetValue(Record * CurRec,SMLoc Loc,Init * ValName,ArrayRef<unsigned> BitList,Init * V,bool AllowSelfAssignment)77*9880d681SAndroid Build Coastguard Worker bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName,
78*9880d681SAndroid Build Coastguard Worker                         ArrayRef<unsigned> BitList, Init *V,
79*9880d681SAndroid Build Coastguard Worker                         bool AllowSelfAssignment) {
80*9880d681SAndroid Build Coastguard Worker   if (!V) return false;
81*9880d681SAndroid Build Coastguard Worker 
82*9880d681SAndroid Build Coastguard Worker   if (!CurRec) CurRec = &CurMultiClass->Rec;
83*9880d681SAndroid Build Coastguard Worker 
84*9880d681SAndroid Build Coastguard Worker   RecordVal *RV = CurRec->getValue(ValName);
85*9880d681SAndroid Build Coastguard Worker   if (!RV)
86*9880d681SAndroid Build Coastguard Worker     return Error(Loc, "Value '" + ValName->getAsUnquotedString() +
87*9880d681SAndroid Build Coastguard Worker                  "' unknown!");
88*9880d681SAndroid Build Coastguard Worker 
89*9880d681SAndroid Build Coastguard Worker   // Do not allow assignments like 'X = X'.  This will just cause infinite loops
90*9880d681SAndroid Build Coastguard Worker   // in the resolution machinery.
91*9880d681SAndroid Build Coastguard Worker   if (BitList.empty())
92*9880d681SAndroid Build Coastguard Worker     if (VarInit *VI = dyn_cast<VarInit>(V))
93*9880d681SAndroid Build Coastguard Worker       if (VI->getNameInit() == ValName && !AllowSelfAssignment)
94*9880d681SAndroid Build Coastguard Worker         return true;
95*9880d681SAndroid Build Coastguard Worker 
96*9880d681SAndroid Build Coastguard Worker   // If we are assigning to a subset of the bits in the value... then we must be
97*9880d681SAndroid Build Coastguard Worker   // assigning to a field of BitsRecTy, which must have a BitsInit
98*9880d681SAndroid Build Coastguard Worker   // initializer.
99*9880d681SAndroid Build Coastguard Worker   //
100*9880d681SAndroid Build Coastguard Worker   if (!BitList.empty()) {
101*9880d681SAndroid Build Coastguard Worker     BitsInit *CurVal = dyn_cast<BitsInit>(RV->getValue());
102*9880d681SAndroid Build Coastguard Worker     if (!CurVal)
103*9880d681SAndroid Build Coastguard Worker       return Error(Loc, "Value '" + ValName->getAsUnquotedString() +
104*9880d681SAndroid Build Coastguard Worker                    "' is not a bits type");
105*9880d681SAndroid Build Coastguard Worker 
106*9880d681SAndroid Build Coastguard Worker     // Convert the incoming value to a bits type of the appropriate size...
107*9880d681SAndroid Build Coastguard Worker     Init *BI = V->convertInitializerTo(BitsRecTy::get(BitList.size()));
108*9880d681SAndroid Build Coastguard Worker     if (!BI)
109*9880d681SAndroid Build Coastguard Worker       return Error(Loc, "Initializer is not compatible with bit range");
110*9880d681SAndroid Build Coastguard Worker 
111*9880d681SAndroid Build Coastguard Worker     // We should have a BitsInit type now.
112*9880d681SAndroid Build Coastguard Worker     BitsInit *BInit = cast<BitsInit>(BI);
113*9880d681SAndroid Build Coastguard Worker 
114*9880d681SAndroid Build Coastguard Worker     SmallVector<Init *, 16> NewBits(CurVal->getNumBits());
115*9880d681SAndroid Build Coastguard Worker 
116*9880d681SAndroid Build Coastguard Worker     // Loop over bits, assigning values as appropriate.
117*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, e = BitList.size(); i != e; ++i) {
118*9880d681SAndroid Build Coastguard Worker       unsigned Bit = BitList[i];
119*9880d681SAndroid Build Coastguard Worker       if (NewBits[Bit])
120*9880d681SAndroid Build Coastguard Worker         return Error(Loc, "Cannot set bit #" + Twine(Bit) + " of value '" +
121*9880d681SAndroid Build Coastguard Worker                      ValName->getAsUnquotedString() + "' more than once");
122*9880d681SAndroid Build Coastguard Worker       NewBits[Bit] = BInit->getBit(i);
123*9880d681SAndroid Build Coastguard Worker     }
124*9880d681SAndroid Build Coastguard Worker 
125*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i)
126*9880d681SAndroid Build Coastguard Worker       if (!NewBits[i])
127*9880d681SAndroid Build Coastguard Worker         NewBits[i] = CurVal->getBit(i);
128*9880d681SAndroid Build Coastguard Worker 
129*9880d681SAndroid Build Coastguard Worker     V = BitsInit::get(NewBits);
130*9880d681SAndroid Build Coastguard Worker   }
131*9880d681SAndroid Build Coastguard Worker 
132*9880d681SAndroid Build Coastguard Worker   if (RV->setValue(V)) {
133*9880d681SAndroid Build Coastguard Worker     std::string InitType = "";
134*9880d681SAndroid Build Coastguard Worker     if (BitsInit *BI = dyn_cast<BitsInit>(V))
135*9880d681SAndroid Build Coastguard Worker       InitType = (Twine("' of type bit initializer with length ") +
136*9880d681SAndroid Build Coastguard Worker                   Twine(BI->getNumBits())).str();
137*9880d681SAndroid Build Coastguard Worker     return Error(Loc, "Value '" + ValName->getAsUnquotedString() +
138*9880d681SAndroid Build Coastguard Worker                  "' of type '" + RV->getType()->getAsString() +
139*9880d681SAndroid Build Coastguard Worker                  "' is incompatible with initializer '" + V->getAsString() +
140*9880d681SAndroid Build Coastguard Worker                  InitType + "'");
141*9880d681SAndroid Build Coastguard Worker   }
142*9880d681SAndroid Build Coastguard Worker   return false;
143*9880d681SAndroid Build Coastguard Worker }
144*9880d681SAndroid Build Coastguard Worker 
145*9880d681SAndroid Build Coastguard Worker /// AddSubClass - Add SubClass as a subclass to CurRec, resolving its template
146*9880d681SAndroid Build Coastguard Worker /// args as SubClass's template arguments.
AddSubClass(Record * CurRec,SubClassReference & SubClass)147*9880d681SAndroid Build Coastguard Worker bool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) {
148*9880d681SAndroid Build Coastguard Worker   Record *SC = SubClass.Rec;
149*9880d681SAndroid Build Coastguard Worker   // Add all of the values in the subclass into the current class.
150*9880d681SAndroid Build Coastguard Worker   for (const RecordVal &Val : SC->getValues())
151*9880d681SAndroid Build Coastguard Worker     if (AddValue(CurRec, SubClass.RefRange.Start, Val))
152*9880d681SAndroid Build Coastguard Worker       return true;
153*9880d681SAndroid Build Coastguard Worker 
154*9880d681SAndroid Build Coastguard Worker   ArrayRef<Init *> TArgs = SC->getTemplateArgs();
155*9880d681SAndroid Build Coastguard Worker 
156*9880d681SAndroid Build Coastguard Worker   // Ensure that an appropriate number of template arguments are specified.
157*9880d681SAndroid Build Coastguard Worker   if (TArgs.size() < SubClass.TemplateArgs.size())
158*9880d681SAndroid Build Coastguard Worker     return Error(SubClass.RefRange.Start,
159*9880d681SAndroid Build Coastguard Worker                  "More template args specified than expected");
160*9880d681SAndroid Build Coastguard Worker 
161*9880d681SAndroid Build Coastguard Worker   // Loop over all of the template arguments, setting them to the specified
162*9880d681SAndroid Build Coastguard Worker   // value or leaving them as the default if necessary.
163*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
164*9880d681SAndroid Build Coastguard Worker     if (i < SubClass.TemplateArgs.size()) {
165*9880d681SAndroid Build Coastguard Worker       // If a value is specified for this template arg, set it now.
166*9880d681SAndroid Build Coastguard Worker       if (SetValue(CurRec, SubClass.RefRange.Start, TArgs[i],
167*9880d681SAndroid Build Coastguard Worker                    None, SubClass.TemplateArgs[i]))
168*9880d681SAndroid Build Coastguard Worker         return true;
169*9880d681SAndroid Build Coastguard Worker 
170*9880d681SAndroid Build Coastguard Worker       // Resolve it next.
171*9880d681SAndroid Build Coastguard Worker       CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i]));
172*9880d681SAndroid Build Coastguard Worker 
173*9880d681SAndroid Build Coastguard Worker       // Now remove it.
174*9880d681SAndroid Build Coastguard Worker       CurRec->removeValue(TArgs[i]);
175*9880d681SAndroid Build Coastguard Worker 
176*9880d681SAndroid Build Coastguard Worker     } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
177*9880d681SAndroid Build Coastguard Worker       return Error(SubClass.RefRange.Start,
178*9880d681SAndroid Build Coastguard Worker                    "Value not specified for template argument #" +
179*9880d681SAndroid Build Coastguard Worker                    Twine(i) + " (" + TArgs[i]->getAsUnquotedString() +
180*9880d681SAndroid Build Coastguard Worker                    ") of subclass '" + SC->getNameInitAsString() + "'!");
181*9880d681SAndroid Build Coastguard Worker     }
182*9880d681SAndroid Build Coastguard Worker   }
183*9880d681SAndroid Build Coastguard Worker 
184*9880d681SAndroid Build Coastguard Worker   // Since everything went well, we can now set the "superclass" list for the
185*9880d681SAndroid Build Coastguard Worker   // current record.
186*9880d681SAndroid Build Coastguard Worker   ArrayRef<std::pair<Record *, SMRange>> SCs = SC->getSuperClasses();
187*9880d681SAndroid Build Coastguard Worker   for (const auto &SCPair : SCs) {
188*9880d681SAndroid Build Coastguard Worker     if (CurRec->isSubClassOf(SCPair.first))
189*9880d681SAndroid Build Coastguard Worker       return Error(SubClass.RefRange.Start,
190*9880d681SAndroid Build Coastguard Worker                    "Already subclass of '" + SCPair.first->getName() + "'!\n");
191*9880d681SAndroid Build Coastguard Worker     CurRec->addSuperClass(SCPair.first, SCPair.second);
192*9880d681SAndroid Build Coastguard Worker   }
193*9880d681SAndroid Build Coastguard Worker 
194*9880d681SAndroid Build Coastguard Worker   if (CurRec->isSubClassOf(SC))
195*9880d681SAndroid Build Coastguard Worker     return Error(SubClass.RefRange.Start,
196*9880d681SAndroid Build Coastguard Worker                  "Already subclass of '" + SC->getName() + "'!\n");
197*9880d681SAndroid Build Coastguard Worker   CurRec->addSuperClass(SC, SubClass.RefRange);
198*9880d681SAndroid Build Coastguard Worker   return false;
199*9880d681SAndroid Build Coastguard Worker }
200*9880d681SAndroid Build Coastguard Worker 
201*9880d681SAndroid Build Coastguard Worker /// AddSubMultiClass - Add SubMultiClass as a subclass to
202*9880d681SAndroid Build Coastguard Worker /// CurMC, resolving its template args as SubMultiClass's
203*9880d681SAndroid Build Coastguard Worker /// template arguments.
AddSubMultiClass(MultiClass * CurMC,SubMultiClassReference & SubMultiClass)204*9880d681SAndroid Build Coastguard Worker bool TGParser::AddSubMultiClass(MultiClass *CurMC,
205*9880d681SAndroid Build Coastguard Worker                                 SubMultiClassReference &SubMultiClass) {
206*9880d681SAndroid Build Coastguard Worker   MultiClass *SMC = SubMultiClass.MC;
207*9880d681SAndroid Build Coastguard Worker   Record *CurRec = &CurMC->Rec;
208*9880d681SAndroid Build Coastguard Worker 
209*9880d681SAndroid Build Coastguard Worker   // Add all of the values in the subclass into the current class.
210*9880d681SAndroid Build Coastguard Worker   for (const auto &SMCVal : SMC->Rec.getValues())
211*9880d681SAndroid Build Coastguard Worker     if (AddValue(CurRec, SubMultiClass.RefRange.Start, SMCVal))
212*9880d681SAndroid Build Coastguard Worker       return true;
213*9880d681SAndroid Build Coastguard Worker 
214*9880d681SAndroid Build Coastguard Worker   unsigned newDefStart = CurMC->DefPrototypes.size();
215*9880d681SAndroid Build Coastguard Worker 
216*9880d681SAndroid Build Coastguard Worker   // Add all of the defs in the subclass into the current multiclass.
217*9880d681SAndroid Build Coastguard Worker   for (const std::unique_ptr<Record> &R : SMC->DefPrototypes) {
218*9880d681SAndroid Build Coastguard Worker     // Clone the def and add it to the current multiclass
219*9880d681SAndroid Build Coastguard Worker     auto NewDef = make_unique<Record>(*R);
220*9880d681SAndroid Build Coastguard Worker 
221*9880d681SAndroid Build Coastguard Worker     // Add all of the values in the superclass into the current def.
222*9880d681SAndroid Build Coastguard Worker     for (const auto &MCVal : CurRec->getValues())
223*9880d681SAndroid Build Coastguard Worker       if (AddValue(NewDef.get(), SubMultiClass.RefRange.Start, MCVal))
224*9880d681SAndroid Build Coastguard Worker         return true;
225*9880d681SAndroid Build Coastguard Worker 
226*9880d681SAndroid Build Coastguard Worker     CurMC->DefPrototypes.push_back(std::move(NewDef));
227*9880d681SAndroid Build Coastguard Worker   }
228*9880d681SAndroid Build Coastguard Worker 
229*9880d681SAndroid Build Coastguard Worker   ArrayRef<Init *> SMCTArgs = SMC->Rec.getTemplateArgs();
230*9880d681SAndroid Build Coastguard Worker 
231*9880d681SAndroid Build Coastguard Worker   // Ensure that an appropriate number of template arguments are
232*9880d681SAndroid Build Coastguard Worker   // specified.
233*9880d681SAndroid Build Coastguard Worker   if (SMCTArgs.size() < SubMultiClass.TemplateArgs.size())
234*9880d681SAndroid Build Coastguard Worker     return Error(SubMultiClass.RefRange.Start,
235*9880d681SAndroid Build Coastguard Worker                  "More template args specified than expected");
236*9880d681SAndroid Build Coastguard Worker 
237*9880d681SAndroid Build Coastguard Worker   // Loop over all of the template arguments, setting them to the specified
238*9880d681SAndroid Build Coastguard Worker   // value or leaving them as the default if necessary.
239*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = SMCTArgs.size(); i != e; ++i) {
240*9880d681SAndroid Build Coastguard Worker     if (i < SubMultiClass.TemplateArgs.size()) {
241*9880d681SAndroid Build Coastguard Worker       // If a value is specified for this template arg, set it in the
242*9880d681SAndroid Build Coastguard Worker       // superclass now.
243*9880d681SAndroid Build Coastguard Worker       if (SetValue(CurRec, SubMultiClass.RefRange.Start, SMCTArgs[i],
244*9880d681SAndroid Build Coastguard Worker                    None, SubMultiClass.TemplateArgs[i]))
245*9880d681SAndroid Build Coastguard Worker         return true;
246*9880d681SAndroid Build Coastguard Worker 
247*9880d681SAndroid Build Coastguard Worker       // Resolve it next.
248*9880d681SAndroid Build Coastguard Worker       CurRec->resolveReferencesTo(CurRec->getValue(SMCTArgs[i]));
249*9880d681SAndroid Build Coastguard Worker 
250*9880d681SAndroid Build Coastguard Worker       // Now remove it.
251*9880d681SAndroid Build Coastguard Worker       CurRec->removeValue(SMCTArgs[i]);
252*9880d681SAndroid Build Coastguard Worker 
253*9880d681SAndroid Build Coastguard Worker       // If a value is specified for this template arg, set it in the
254*9880d681SAndroid Build Coastguard Worker       // new defs now.
255*9880d681SAndroid Build Coastguard Worker       for (const auto &Def :
256*9880d681SAndroid Build Coastguard Worker              makeArrayRef(CurMC->DefPrototypes).slice(newDefStart)) {
257*9880d681SAndroid Build Coastguard Worker         if (SetValue(Def.get(), SubMultiClass.RefRange.Start, SMCTArgs[i],
258*9880d681SAndroid Build Coastguard Worker                      None, SubMultiClass.TemplateArgs[i]))
259*9880d681SAndroid Build Coastguard Worker           return true;
260*9880d681SAndroid Build Coastguard Worker 
261*9880d681SAndroid Build Coastguard Worker         // Resolve it next.
262*9880d681SAndroid Build Coastguard Worker         Def->resolveReferencesTo(Def->getValue(SMCTArgs[i]));
263*9880d681SAndroid Build Coastguard Worker 
264*9880d681SAndroid Build Coastguard Worker         // Now remove it
265*9880d681SAndroid Build Coastguard Worker         Def->removeValue(SMCTArgs[i]);
266*9880d681SAndroid Build Coastguard Worker       }
267*9880d681SAndroid Build Coastguard Worker     } else if (!CurRec->getValue(SMCTArgs[i])->getValue()->isComplete()) {
268*9880d681SAndroid Build Coastguard Worker       return Error(SubMultiClass.RefRange.Start,
269*9880d681SAndroid Build Coastguard Worker                    "Value not specified for template argument #" +
270*9880d681SAndroid Build Coastguard Worker                    Twine(i) + " (" + SMCTArgs[i]->getAsUnquotedString() +
271*9880d681SAndroid Build Coastguard Worker                    ") of subclass '" + SMC->Rec.getNameInitAsString() + "'!");
272*9880d681SAndroid Build Coastguard Worker     }
273*9880d681SAndroid Build Coastguard Worker   }
274*9880d681SAndroid Build Coastguard Worker 
275*9880d681SAndroid Build Coastguard Worker   return false;
276*9880d681SAndroid Build Coastguard Worker }
277*9880d681SAndroid Build Coastguard Worker 
278*9880d681SAndroid Build Coastguard Worker /// ProcessForeachDefs - Given a record, apply all of the variable
279*9880d681SAndroid Build Coastguard Worker /// values in all surrounding foreach loops, creating new records for
280*9880d681SAndroid Build Coastguard Worker /// each combination of values.
ProcessForeachDefs(Record * CurRec,SMLoc Loc)281*9880d681SAndroid Build Coastguard Worker bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc) {
282*9880d681SAndroid Build Coastguard Worker   if (Loops.empty())
283*9880d681SAndroid Build Coastguard Worker     return false;
284*9880d681SAndroid Build Coastguard Worker 
285*9880d681SAndroid Build Coastguard Worker   // We want to instantiate a new copy of CurRec for each combination
286*9880d681SAndroid Build Coastguard Worker   // of nested loop iterator values.  We don't want top instantiate
287*9880d681SAndroid Build Coastguard Worker   // any copies until we have values for each loop iterator.
288*9880d681SAndroid Build Coastguard Worker   IterSet IterVals;
289*9880d681SAndroid Build Coastguard Worker   return ProcessForeachDefs(CurRec, Loc, IterVals);
290*9880d681SAndroid Build Coastguard Worker }
291*9880d681SAndroid Build Coastguard Worker 
292*9880d681SAndroid Build Coastguard Worker /// ProcessForeachDefs - Given a record, a loop and a loop iterator,
293*9880d681SAndroid Build Coastguard Worker /// apply each of the variable values in this loop and then process
294*9880d681SAndroid Build Coastguard Worker /// subloops.
ProcessForeachDefs(Record * CurRec,SMLoc Loc,IterSet & IterVals)295*9880d681SAndroid Build Coastguard Worker bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals){
296*9880d681SAndroid Build Coastguard Worker   // Recursively build a tuple of iterator values.
297*9880d681SAndroid Build Coastguard Worker   if (IterVals.size() != Loops.size()) {
298*9880d681SAndroid Build Coastguard Worker     assert(IterVals.size() < Loops.size());
299*9880d681SAndroid Build Coastguard Worker     ForeachLoop &CurLoop = Loops[IterVals.size()];
300*9880d681SAndroid Build Coastguard Worker     ListInit *List = dyn_cast<ListInit>(CurLoop.ListValue);
301*9880d681SAndroid Build Coastguard Worker     if (!List) {
302*9880d681SAndroid Build Coastguard Worker       Error(Loc, "Loop list is not a list");
303*9880d681SAndroid Build Coastguard Worker       return true;
304*9880d681SAndroid Build Coastguard Worker     }
305*9880d681SAndroid Build Coastguard Worker 
306*9880d681SAndroid Build Coastguard Worker     // Process each value.
307*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0; i < List->size(); ++i) {
308*9880d681SAndroid Build Coastguard Worker       Init *ItemVal = List->resolveListElementReference(*CurRec, nullptr, i);
309*9880d681SAndroid Build Coastguard Worker       IterVals.push_back(IterRecord(CurLoop.IterVar, ItemVal));
310*9880d681SAndroid Build Coastguard Worker       if (ProcessForeachDefs(CurRec, Loc, IterVals))
311*9880d681SAndroid Build Coastguard Worker         return true;
312*9880d681SAndroid Build Coastguard Worker       IterVals.pop_back();
313*9880d681SAndroid Build Coastguard Worker     }
314*9880d681SAndroid Build Coastguard Worker     return false;
315*9880d681SAndroid Build Coastguard Worker   }
316*9880d681SAndroid Build Coastguard Worker 
317*9880d681SAndroid Build Coastguard Worker   // This is the bottom of the recursion. We have all of the iterator values
318*9880d681SAndroid Build Coastguard Worker   // for this point in the iteration space.  Instantiate a new record to
319*9880d681SAndroid Build Coastguard Worker   // reflect this combination of values.
320*9880d681SAndroid Build Coastguard Worker   auto IterRec = make_unique<Record>(*CurRec);
321*9880d681SAndroid Build Coastguard Worker 
322*9880d681SAndroid Build Coastguard Worker   // Set the iterator values now.
323*9880d681SAndroid Build Coastguard Worker   for (IterRecord &IR : IterVals) {
324*9880d681SAndroid Build Coastguard Worker     VarInit *IterVar = IR.IterVar;
325*9880d681SAndroid Build Coastguard Worker     TypedInit *IVal = dyn_cast<TypedInit>(IR.IterValue);
326*9880d681SAndroid Build Coastguard Worker     if (!IVal)
327*9880d681SAndroid Build Coastguard Worker       return Error(Loc, "foreach iterator value is untyped");
328*9880d681SAndroid Build Coastguard Worker 
329*9880d681SAndroid Build Coastguard Worker     IterRec->addValue(RecordVal(IterVar->getName(), IVal->getType(), false));
330*9880d681SAndroid Build Coastguard Worker 
331*9880d681SAndroid Build Coastguard Worker     if (SetValue(IterRec.get(), Loc, IterVar->getName(), None, IVal))
332*9880d681SAndroid Build Coastguard Worker       return Error(Loc, "when instantiating this def");
333*9880d681SAndroid Build Coastguard Worker 
334*9880d681SAndroid Build Coastguard Worker     // Resolve it next.
335*9880d681SAndroid Build Coastguard Worker     IterRec->resolveReferencesTo(IterRec->getValue(IterVar->getName()));
336*9880d681SAndroid Build Coastguard Worker 
337*9880d681SAndroid Build Coastguard Worker     // Remove it.
338*9880d681SAndroid Build Coastguard Worker     IterRec->removeValue(IterVar->getName());
339*9880d681SAndroid Build Coastguard Worker   }
340*9880d681SAndroid Build Coastguard Worker 
341*9880d681SAndroid Build Coastguard Worker   if (Records.getDef(IterRec->getNameInitAsString())) {
342*9880d681SAndroid Build Coastguard Worker     // If this record is anonymous, it's no problem, just generate a new name
343*9880d681SAndroid Build Coastguard Worker     if (!IterRec->isAnonymous())
344*9880d681SAndroid Build Coastguard Worker       return Error(Loc, "def already exists: " +IterRec->getNameInitAsString());
345*9880d681SAndroid Build Coastguard Worker 
346*9880d681SAndroid Build Coastguard Worker     IterRec->setName(GetNewAnonymousName());
347*9880d681SAndroid Build Coastguard Worker   }
348*9880d681SAndroid Build Coastguard Worker 
349*9880d681SAndroid Build Coastguard Worker   Record *IterRecSave = IterRec.get(); // Keep a copy before release.
350*9880d681SAndroid Build Coastguard Worker   Records.addDef(std::move(IterRec));
351*9880d681SAndroid Build Coastguard Worker   IterRecSave->resolveReferences();
352*9880d681SAndroid Build Coastguard Worker   return false;
353*9880d681SAndroid Build Coastguard Worker }
354*9880d681SAndroid Build Coastguard Worker 
355*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
356*9880d681SAndroid Build Coastguard Worker // Parser Code
357*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
358*9880d681SAndroid Build Coastguard Worker 
359*9880d681SAndroid Build Coastguard Worker /// isObjectStart - Return true if this is a valid first token for an Object.
isObjectStart(tgtok::TokKind K)360*9880d681SAndroid Build Coastguard Worker static bool isObjectStart(tgtok::TokKind K) {
361*9880d681SAndroid Build Coastguard Worker   return K == tgtok::Class || K == tgtok::Def ||
362*9880d681SAndroid Build Coastguard Worker          K == tgtok::Defm || K == tgtok::Let ||
363*9880d681SAndroid Build Coastguard Worker          K == tgtok::MultiClass || K == tgtok::Foreach;
364*9880d681SAndroid Build Coastguard Worker }
365*9880d681SAndroid Build Coastguard Worker 
366*9880d681SAndroid Build Coastguard Worker /// GetNewAnonymousName - Generate a unique anonymous name that can be used as
367*9880d681SAndroid Build Coastguard Worker /// an identifier.
GetNewAnonymousName()368*9880d681SAndroid Build Coastguard Worker std::string TGParser::GetNewAnonymousName() {
369*9880d681SAndroid Build Coastguard Worker   return "anonymous_" + utostr(AnonCounter++);
370*9880d681SAndroid Build Coastguard Worker }
371*9880d681SAndroid Build Coastguard Worker 
372*9880d681SAndroid Build Coastguard Worker /// ParseObjectName - If an object name is specified, return it.  Otherwise,
373*9880d681SAndroid Build Coastguard Worker /// return 0.
374*9880d681SAndroid Build Coastguard Worker ///   ObjectName ::= Value [ '#' Value ]*
375*9880d681SAndroid Build Coastguard Worker ///   ObjectName ::= /*empty*/
376*9880d681SAndroid Build Coastguard Worker ///
ParseObjectName(MultiClass * CurMultiClass)377*9880d681SAndroid Build Coastguard Worker Init *TGParser::ParseObjectName(MultiClass *CurMultiClass) {
378*9880d681SAndroid Build Coastguard Worker   switch (Lex.getCode()) {
379*9880d681SAndroid Build Coastguard Worker   case tgtok::colon:
380*9880d681SAndroid Build Coastguard Worker   case tgtok::semi:
381*9880d681SAndroid Build Coastguard Worker   case tgtok::l_brace:
382*9880d681SAndroid Build Coastguard Worker     // These are all of the tokens that can begin an object body.
383*9880d681SAndroid Build Coastguard Worker     // Some of these can also begin values but we disallow those cases
384*9880d681SAndroid Build Coastguard Worker     // because they are unlikely to be useful.
385*9880d681SAndroid Build Coastguard Worker     return nullptr;
386*9880d681SAndroid Build Coastguard Worker   default:
387*9880d681SAndroid Build Coastguard Worker     break;
388*9880d681SAndroid Build Coastguard Worker   }
389*9880d681SAndroid Build Coastguard Worker 
390*9880d681SAndroid Build Coastguard Worker   Record *CurRec = nullptr;
391*9880d681SAndroid Build Coastguard Worker   if (CurMultiClass)
392*9880d681SAndroid Build Coastguard Worker     CurRec = &CurMultiClass->Rec;
393*9880d681SAndroid Build Coastguard Worker 
394*9880d681SAndroid Build Coastguard Worker   RecTy *Type = nullptr;
395*9880d681SAndroid Build Coastguard Worker   if (CurRec) {
396*9880d681SAndroid Build Coastguard Worker     const TypedInit *CurRecName = dyn_cast<TypedInit>(CurRec->getNameInit());
397*9880d681SAndroid Build Coastguard Worker     if (!CurRecName) {
398*9880d681SAndroid Build Coastguard Worker       TokError("Record name is not typed!");
399*9880d681SAndroid Build Coastguard Worker       return nullptr;
400*9880d681SAndroid Build Coastguard Worker     }
401*9880d681SAndroid Build Coastguard Worker     Type = CurRecName->getType();
402*9880d681SAndroid Build Coastguard Worker   }
403*9880d681SAndroid Build Coastguard Worker 
404*9880d681SAndroid Build Coastguard Worker   return ParseValue(CurRec, Type, ParseNameMode);
405*9880d681SAndroid Build Coastguard Worker }
406*9880d681SAndroid Build Coastguard Worker 
407*9880d681SAndroid Build Coastguard Worker /// ParseClassID - Parse and resolve a reference to a class name.  This returns
408*9880d681SAndroid Build Coastguard Worker /// null on error.
409*9880d681SAndroid Build Coastguard Worker ///
410*9880d681SAndroid Build Coastguard Worker ///    ClassID ::= ID
411*9880d681SAndroid Build Coastguard Worker ///
ParseClassID()412*9880d681SAndroid Build Coastguard Worker Record *TGParser::ParseClassID() {
413*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::Id) {
414*9880d681SAndroid Build Coastguard Worker     TokError("expected name for ClassID");
415*9880d681SAndroid Build Coastguard Worker     return nullptr;
416*9880d681SAndroid Build Coastguard Worker   }
417*9880d681SAndroid Build Coastguard Worker 
418*9880d681SAndroid Build Coastguard Worker   Record *Result = Records.getClass(Lex.getCurStrVal());
419*9880d681SAndroid Build Coastguard Worker   if (!Result)
420*9880d681SAndroid Build Coastguard Worker     TokError("Couldn't find class '" + Lex.getCurStrVal() + "'");
421*9880d681SAndroid Build Coastguard Worker 
422*9880d681SAndroid Build Coastguard Worker   Lex.Lex();
423*9880d681SAndroid Build Coastguard Worker   return Result;
424*9880d681SAndroid Build Coastguard Worker }
425*9880d681SAndroid Build Coastguard Worker 
426*9880d681SAndroid Build Coastguard Worker /// ParseMultiClassID - Parse and resolve a reference to a multiclass name.
427*9880d681SAndroid Build Coastguard Worker /// This returns null on error.
428*9880d681SAndroid Build Coastguard Worker ///
429*9880d681SAndroid Build Coastguard Worker ///    MultiClassID ::= ID
430*9880d681SAndroid Build Coastguard Worker ///
ParseMultiClassID()431*9880d681SAndroid Build Coastguard Worker MultiClass *TGParser::ParseMultiClassID() {
432*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::Id) {
433*9880d681SAndroid Build Coastguard Worker     TokError("expected name for MultiClassID");
434*9880d681SAndroid Build Coastguard Worker     return nullptr;
435*9880d681SAndroid Build Coastguard Worker   }
436*9880d681SAndroid Build Coastguard Worker 
437*9880d681SAndroid Build Coastguard Worker   MultiClass *Result = MultiClasses[Lex.getCurStrVal()].get();
438*9880d681SAndroid Build Coastguard Worker   if (!Result)
439*9880d681SAndroid Build Coastguard Worker     TokError("Couldn't find multiclass '" + Lex.getCurStrVal() + "'");
440*9880d681SAndroid Build Coastguard Worker 
441*9880d681SAndroid Build Coastguard Worker   Lex.Lex();
442*9880d681SAndroid Build Coastguard Worker   return Result;
443*9880d681SAndroid Build Coastguard Worker }
444*9880d681SAndroid Build Coastguard Worker 
445*9880d681SAndroid Build Coastguard Worker /// ParseSubClassReference - Parse a reference to a subclass or to a templated
446*9880d681SAndroid Build Coastguard Worker /// subclass.  This returns a SubClassRefTy with a null Record* on error.
447*9880d681SAndroid Build Coastguard Worker ///
448*9880d681SAndroid Build Coastguard Worker ///  SubClassRef ::= ClassID
449*9880d681SAndroid Build Coastguard Worker ///  SubClassRef ::= ClassID '<' ValueList '>'
450*9880d681SAndroid Build Coastguard Worker ///
451*9880d681SAndroid Build Coastguard Worker SubClassReference TGParser::
ParseSubClassReference(Record * CurRec,bool isDefm)452*9880d681SAndroid Build Coastguard Worker ParseSubClassReference(Record *CurRec, bool isDefm) {
453*9880d681SAndroid Build Coastguard Worker   SubClassReference Result;
454*9880d681SAndroid Build Coastguard Worker   Result.RefRange.Start = Lex.getLoc();
455*9880d681SAndroid Build Coastguard Worker 
456*9880d681SAndroid Build Coastguard Worker   if (isDefm) {
457*9880d681SAndroid Build Coastguard Worker     if (MultiClass *MC = ParseMultiClassID())
458*9880d681SAndroid Build Coastguard Worker       Result.Rec = &MC->Rec;
459*9880d681SAndroid Build Coastguard Worker   } else {
460*9880d681SAndroid Build Coastguard Worker     Result.Rec = ParseClassID();
461*9880d681SAndroid Build Coastguard Worker   }
462*9880d681SAndroid Build Coastguard Worker   if (!Result.Rec) return Result;
463*9880d681SAndroid Build Coastguard Worker 
464*9880d681SAndroid Build Coastguard Worker   // If there is no template arg list, we're done.
465*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::less) {
466*9880d681SAndroid Build Coastguard Worker     Result.RefRange.End = Lex.getLoc();
467*9880d681SAndroid Build Coastguard Worker     return Result;
468*9880d681SAndroid Build Coastguard Worker   }
469*9880d681SAndroid Build Coastguard Worker   Lex.Lex();  // Eat the '<'
470*9880d681SAndroid Build Coastguard Worker 
471*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() == tgtok::greater) {
472*9880d681SAndroid Build Coastguard Worker     TokError("subclass reference requires a non-empty list of template values");
473*9880d681SAndroid Build Coastguard Worker     Result.Rec = nullptr;
474*9880d681SAndroid Build Coastguard Worker     return Result;
475*9880d681SAndroid Build Coastguard Worker   }
476*9880d681SAndroid Build Coastguard Worker 
477*9880d681SAndroid Build Coastguard Worker   Result.TemplateArgs = ParseValueList(CurRec, Result.Rec);
478*9880d681SAndroid Build Coastguard Worker   if (Result.TemplateArgs.empty()) {
479*9880d681SAndroid Build Coastguard Worker     Result.Rec = nullptr;   // Error parsing value list.
480*9880d681SAndroid Build Coastguard Worker     return Result;
481*9880d681SAndroid Build Coastguard Worker   }
482*9880d681SAndroid Build Coastguard Worker 
483*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::greater) {
484*9880d681SAndroid Build Coastguard Worker     TokError("expected '>' in template value list");
485*9880d681SAndroid Build Coastguard Worker     Result.Rec = nullptr;
486*9880d681SAndroid Build Coastguard Worker     return Result;
487*9880d681SAndroid Build Coastguard Worker   }
488*9880d681SAndroid Build Coastguard Worker   Lex.Lex();
489*9880d681SAndroid Build Coastguard Worker   Result.RefRange.End = Lex.getLoc();
490*9880d681SAndroid Build Coastguard Worker 
491*9880d681SAndroid Build Coastguard Worker   return Result;
492*9880d681SAndroid Build Coastguard Worker }
493*9880d681SAndroid Build Coastguard Worker 
494*9880d681SAndroid Build Coastguard Worker /// ParseSubMultiClassReference - Parse a reference to a subclass or to a
495*9880d681SAndroid Build Coastguard Worker /// templated submulticlass.  This returns a SubMultiClassRefTy with a null
496*9880d681SAndroid Build Coastguard Worker /// Record* on error.
497*9880d681SAndroid Build Coastguard Worker ///
498*9880d681SAndroid Build Coastguard Worker ///  SubMultiClassRef ::= MultiClassID
499*9880d681SAndroid Build Coastguard Worker ///  SubMultiClassRef ::= MultiClassID '<' ValueList '>'
500*9880d681SAndroid Build Coastguard Worker ///
501*9880d681SAndroid Build Coastguard Worker SubMultiClassReference TGParser::
ParseSubMultiClassReference(MultiClass * CurMC)502*9880d681SAndroid Build Coastguard Worker ParseSubMultiClassReference(MultiClass *CurMC) {
503*9880d681SAndroid Build Coastguard Worker   SubMultiClassReference Result;
504*9880d681SAndroid Build Coastguard Worker   Result.RefRange.Start = Lex.getLoc();
505*9880d681SAndroid Build Coastguard Worker 
506*9880d681SAndroid Build Coastguard Worker   Result.MC = ParseMultiClassID();
507*9880d681SAndroid Build Coastguard Worker   if (!Result.MC) return Result;
508*9880d681SAndroid Build Coastguard Worker 
509*9880d681SAndroid Build Coastguard Worker   // If there is no template arg list, we're done.
510*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::less) {
511*9880d681SAndroid Build Coastguard Worker     Result.RefRange.End = Lex.getLoc();
512*9880d681SAndroid Build Coastguard Worker     return Result;
513*9880d681SAndroid Build Coastguard Worker   }
514*9880d681SAndroid Build Coastguard Worker   Lex.Lex();  // Eat the '<'
515*9880d681SAndroid Build Coastguard Worker 
516*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() == tgtok::greater) {
517*9880d681SAndroid Build Coastguard Worker     TokError("subclass reference requires a non-empty list of template values");
518*9880d681SAndroid Build Coastguard Worker     Result.MC = nullptr;
519*9880d681SAndroid Build Coastguard Worker     return Result;
520*9880d681SAndroid Build Coastguard Worker   }
521*9880d681SAndroid Build Coastguard Worker 
522*9880d681SAndroid Build Coastguard Worker   Result.TemplateArgs = ParseValueList(&CurMC->Rec, &Result.MC->Rec);
523*9880d681SAndroid Build Coastguard Worker   if (Result.TemplateArgs.empty()) {
524*9880d681SAndroid Build Coastguard Worker     Result.MC = nullptr;   // Error parsing value list.
525*9880d681SAndroid Build Coastguard Worker     return Result;
526*9880d681SAndroid Build Coastguard Worker   }
527*9880d681SAndroid Build Coastguard Worker 
528*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::greater) {
529*9880d681SAndroid Build Coastguard Worker     TokError("expected '>' in template value list");
530*9880d681SAndroid Build Coastguard Worker     Result.MC = nullptr;
531*9880d681SAndroid Build Coastguard Worker     return Result;
532*9880d681SAndroid Build Coastguard Worker   }
533*9880d681SAndroid Build Coastguard Worker   Lex.Lex();
534*9880d681SAndroid Build Coastguard Worker   Result.RefRange.End = Lex.getLoc();
535*9880d681SAndroid Build Coastguard Worker 
536*9880d681SAndroid Build Coastguard Worker   return Result;
537*9880d681SAndroid Build Coastguard Worker }
538*9880d681SAndroid Build Coastguard Worker 
539*9880d681SAndroid Build Coastguard Worker /// ParseRangePiece - Parse a bit/value range.
540*9880d681SAndroid Build Coastguard Worker ///   RangePiece ::= INTVAL
541*9880d681SAndroid Build Coastguard Worker ///   RangePiece ::= INTVAL '-' INTVAL
542*9880d681SAndroid Build Coastguard Worker ///   RangePiece ::= INTVAL INTVAL
ParseRangePiece(std::vector<unsigned> & Ranges)543*9880d681SAndroid Build Coastguard Worker bool TGParser::ParseRangePiece(std::vector<unsigned> &Ranges) {
544*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::IntVal) {
545*9880d681SAndroid Build Coastguard Worker     TokError("expected integer or bitrange");
546*9880d681SAndroid Build Coastguard Worker     return true;
547*9880d681SAndroid Build Coastguard Worker   }
548*9880d681SAndroid Build Coastguard Worker   int64_t Start = Lex.getCurIntVal();
549*9880d681SAndroid Build Coastguard Worker   int64_t End;
550*9880d681SAndroid Build Coastguard Worker 
551*9880d681SAndroid Build Coastguard Worker   if (Start < 0)
552*9880d681SAndroid Build Coastguard Worker     return TokError("invalid range, cannot be negative");
553*9880d681SAndroid Build Coastguard Worker 
554*9880d681SAndroid Build Coastguard Worker   switch (Lex.Lex()) {  // eat first character.
555*9880d681SAndroid Build Coastguard Worker   default:
556*9880d681SAndroid Build Coastguard Worker     Ranges.push_back(Start);
557*9880d681SAndroid Build Coastguard Worker     return false;
558*9880d681SAndroid Build Coastguard Worker   case tgtok::minus:
559*9880d681SAndroid Build Coastguard Worker     if (Lex.Lex() != tgtok::IntVal) {
560*9880d681SAndroid Build Coastguard Worker       TokError("expected integer value as end of range");
561*9880d681SAndroid Build Coastguard Worker       return true;
562*9880d681SAndroid Build Coastguard Worker     }
563*9880d681SAndroid Build Coastguard Worker     End = Lex.getCurIntVal();
564*9880d681SAndroid Build Coastguard Worker     break;
565*9880d681SAndroid Build Coastguard Worker   case tgtok::IntVal:
566*9880d681SAndroid Build Coastguard Worker     End = -Lex.getCurIntVal();
567*9880d681SAndroid Build Coastguard Worker     break;
568*9880d681SAndroid Build Coastguard Worker   }
569*9880d681SAndroid Build Coastguard Worker   if (End < 0)
570*9880d681SAndroid Build Coastguard Worker     return TokError("invalid range, cannot be negative");
571*9880d681SAndroid Build Coastguard Worker   Lex.Lex();
572*9880d681SAndroid Build Coastguard Worker 
573*9880d681SAndroid Build Coastguard Worker   // Add to the range.
574*9880d681SAndroid Build Coastguard Worker   if (Start < End)
575*9880d681SAndroid Build Coastguard Worker     for (; Start <= End; ++Start)
576*9880d681SAndroid Build Coastguard Worker       Ranges.push_back(Start);
577*9880d681SAndroid Build Coastguard Worker   else
578*9880d681SAndroid Build Coastguard Worker     for (; Start >= End; --Start)
579*9880d681SAndroid Build Coastguard Worker       Ranges.push_back(Start);
580*9880d681SAndroid Build Coastguard Worker   return false;
581*9880d681SAndroid Build Coastguard Worker }
582*9880d681SAndroid Build Coastguard Worker 
583*9880d681SAndroid Build Coastguard Worker /// ParseRangeList - Parse a list of scalars and ranges into scalar values.
584*9880d681SAndroid Build Coastguard Worker ///
585*9880d681SAndroid Build Coastguard Worker ///   RangeList ::= RangePiece (',' RangePiece)*
586*9880d681SAndroid Build Coastguard Worker ///
ParseRangeList()587*9880d681SAndroid Build Coastguard Worker std::vector<unsigned> TGParser::ParseRangeList() {
588*9880d681SAndroid Build Coastguard Worker   std::vector<unsigned> Result;
589*9880d681SAndroid Build Coastguard Worker 
590*9880d681SAndroid Build Coastguard Worker   // Parse the first piece.
591*9880d681SAndroid Build Coastguard Worker   if (ParseRangePiece(Result))
592*9880d681SAndroid Build Coastguard Worker     return std::vector<unsigned>();
593*9880d681SAndroid Build Coastguard Worker   while (Lex.getCode() == tgtok::comma) {
594*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // Eat the comma.
595*9880d681SAndroid Build Coastguard Worker 
596*9880d681SAndroid Build Coastguard Worker     // Parse the next range piece.
597*9880d681SAndroid Build Coastguard Worker     if (ParseRangePiece(Result))
598*9880d681SAndroid Build Coastguard Worker       return std::vector<unsigned>();
599*9880d681SAndroid Build Coastguard Worker   }
600*9880d681SAndroid Build Coastguard Worker   return Result;
601*9880d681SAndroid Build Coastguard Worker }
602*9880d681SAndroid Build Coastguard Worker 
603*9880d681SAndroid Build Coastguard Worker /// ParseOptionalRangeList - Parse either a range list in <>'s or nothing.
604*9880d681SAndroid Build Coastguard Worker ///   OptionalRangeList ::= '<' RangeList '>'
605*9880d681SAndroid Build Coastguard Worker ///   OptionalRangeList ::= /*empty*/
ParseOptionalRangeList(std::vector<unsigned> & Ranges)606*9880d681SAndroid Build Coastguard Worker bool TGParser::ParseOptionalRangeList(std::vector<unsigned> &Ranges) {
607*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::less)
608*9880d681SAndroid Build Coastguard Worker     return false;
609*9880d681SAndroid Build Coastguard Worker 
610*9880d681SAndroid Build Coastguard Worker   SMLoc StartLoc = Lex.getLoc();
611*9880d681SAndroid Build Coastguard Worker   Lex.Lex(); // eat the '<'
612*9880d681SAndroid Build Coastguard Worker 
613*9880d681SAndroid Build Coastguard Worker   // Parse the range list.
614*9880d681SAndroid Build Coastguard Worker   Ranges = ParseRangeList();
615*9880d681SAndroid Build Coastguard Worker   if (Ranges.empty()) return true;
616*9880d681SAndroid Build Coastguard Worker 
617*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::greater) {
618*9880d681SAndroid Build Coastguard Worker     TokError("expected '>' at end of range list");
619*9880d681SAndroid Build Coastguard Worker     return Error(StartLoc, "to match this '<'");
620*9880d681SAndroid Build Coastguard Worker   }
621*9880d681SAndroid Build Coastguard Worker   Lex.Lex();   // eat the '>'.
622*9880d681SAndroid Build Coastguard Worker   return false;
623*9880d681SAndroid Build Coastguard Worker }
624*9880d681SAndroid Build Coastguard Worker 
625*9880d681SAndroid Build Coastguard Worker /// ParseOptionalBitList - Parse either a bit list in {}'s or nothing.
626*9880d681SAndroid Build Coastguard Worker ///   OptionalBitList ::= '{' RangeList '}'
627*9880d681SAndroid Build Coastguard Worker ///   OptionalBitList ::= /*empty*/
ParseOptionalBitList(std::vector<unsigned> & Ranges)628*9880d681SAndroid Build Coastguard Worker bool TGParser::ParseOptionalBitList(std::vector<unsigned> &Ranges) {
629*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::l_brace)
630*9880d681SAndroid Build Coastguard Worker     return false;
631*9880d681SAndroid Build Coastguard Worker 
632*9880d681SAndroid Build Coastguard Worker   SMLoc StartLoc = Lex.getLoc();
633*9880d681SAndroid Build Coastguard Worker   Lex.Lex(); // eat the '{'
634*9880d681SAndroid Build Coastguard Worker 
635*9880d681SAndroid Build Coastguard Worker   // Parse the range list.
636*9880d681SAndroid Build Coastguard Worker   Ranges = ParseRangeList();
637*9880d681SAndroid Build Coastguard Worker   if (Ranges.empty()) return true;
638*9880d681SAndroid Build Coastguard Worker 
639*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::r_brace) {
640*9880d681SAndroid Build Coastguard Worker     TokError("expected '}' at end of bit list");
641*9880d681SAndroid Build Coastguard Worker     return Error(StartLoc, "to match this '{'");
642*9880d681SAndroid Build Coastguard Worker   }
643*9880d681SAndroid Build Coastguard Worker   Lex.Lex();   // eat the '}'.
644*9880d681SAndroid Build Coastguard Worker   return false;
645*9880d681SAndroid Build Coastguard Worker }
646*9880d681SAndroid Build Coastguard Worker 
647*9880d681SAndroid Build Coastguard Worker 
648*9880d681SAndroid Build Coastguard Worker /// ParseType - Parse and return a tblgen type.  This returns null on error.
649*9880d681SAndroid Build Coastguard Worker ///
650*9880d681SAndroid Build Coastguard Worker ///   Type ::= STRING                       // string type
651*9880d681SAndroid Build Coastguard Worker ///   Type ::= CODE                         // code type
652*9880d681SAndroid Build Coastguard Worker ///   Type ::= BIT                          // bit type
653*9880d681SAndroid Build Coastguard Worker ///   Type ::= BITS '<' INTVAL '>'          // bits<x> type
654*9880d681SAndroid Build Coastguard Worker ///   Type ::= INT                          // int type
655*9880d681SAndroid Build Coastguard Worker ///   Type ::= LIST '<' Type '>'            // list<x> type
656*9880d681SAndroid Build Coastguard Worker ///   Type ::= DAG                          // dag type
657*9880d681SAndroid Build Coastguard Worker ///   Type ::= ClassID                      // Record Type
658*9880d681SAndroid Build Coastguard Worker ///
ParseType()659*9880d681SAndroid Build Coastguard Worker RecTy *TGParser::ParseType() {
660*9880d681SAndroid Build Coastguard Worker   switch (Lex.getCode()) {
661*9880d681SAndroid Build Coastguard Worker   default: TokError("Unknown token when expecting a type"); return nullptr;
662*9880d681SAndroid Build Coastguard Worker   case tgtok::String: Lex.Lex(); return StringRecTy::get();
663*9880d681SAndroid Build Coastguard Worker   case tgtok::Code:   Lex.Lex(); return CodeRecTy::get();
664*9880d681SAndroid Build Coastguard Worker   case tgtok::Bit:    Lex.Lex(); return BitRecTy::get();
665*9880d681SAndroid Build Coastguard Worker   case tgtok::Int:    Lex.Lex(); return IntRecTy::get();
666*9880d681SAndroid Build Coastguard Worker   case tgtok::Dag:    Lex.Lex(); return DagRecTy::get();
667*9880d681SAndroid Build Coastguard Worker   case tgtok::Id:
668*9880d681SAndroid Build Coastguard Worker     if (Record *R = ParseClassID()) return RecordRecTy::get(R);
669*9880d681SAndroid Build Coastguard Worker     return nullptr;
670*9880d681SAndroid Build Coastguard Worker   case tgtok::Bits: {
671*9880d681SAndroid Build Coastguard Worker     if (Lex.Lex() != tgtok::less) { // Eat 'bits'
672*9880d681SAndroid Build Coastguard Worker       TokError("expected '<' after bits type");
673*9880d681SAndroid Build Coastguard Worker       return nullptr;
674*9880d681SAndroid Build Coastguard Worker     }
675*9880d681SAndroid Build Coastguard Worker     if (Lex.Lex() != tgtok::IntVal) {  // Eat '<'
676*9880d681SAndroid Build Coastguard Worker       TokError("expected integer in bits<n> type");
677*9880d681SAndroid Build Coastguard Worker       return nullptr;
678*9880d681SAndroid Build Coastguard Worker     }
679*9880d681SAndroid Build Coastguard Worker     uint64_t Val = Lex.getCurIntVal();
680*9880d681SAndroid Build Coastguard Worker     if (Lex.Lex() != tgtok::greater) {  // Eat count.
681*9880d681SAndroid Build Coastguard Worker       TokError("expected '>' at end of bits<n> type");
682*9880d681SAndroid Build Coastguard Worker       return nullptr;
683*9880d681SAndroid Build Coastguard Worker     }
684*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // Eat '>'
685*9880d681SAndroid Build Coastguard Worker     return BitsRecTy::get(Val);
686*9880d681SAndroid Build Coastguard Worker   }
687*9880d681SAndroid Build Coastguard Worker   case tgtok::List: {
688*9880d681SAndroid Build Coastguard Worker     if (Lex.Lex() != tgtok::less) { // Eat 'bits'
689*9880d681SAndroid Build Coastguard Worker       TokError("expected '<' after list type");
690*9880d681SAndroid Build Coastguard Worker       return nullptr;
691*9880d681SAndroid Build Coastguard Worker     }
692*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // Eat '<'
693*9880d681SAndroid Build Coastguard Worker     RecTy *SubType = ParseType();
694*9880d681SAndroid Build Coastguard Worker     if (!SubType) return nullptr;
695*9880d681SAndroid Build Coastguard Worker 
696*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::greater) {
697*9880d681SAndroid Build Coastguard Worker       TokError("expected '>' at end of list<ty> type");
698*9880d681SAndroid Build Coastguard Worker       return nullptr;
699*9880d681SAndroid Build Coastguard Worker     }
700*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // Eat '>'
701*9880d681SAndroid Build Coastguard Worker     return ListRecTy::get(SubType);
702*9880d681SAndroid Build Coastguard Worker   }
703*9880d681SAndroid Build Coastguard Worker   }
704*9880d681SAndroid Build Coastguard Worker }
705*9880d681SAndroid Build Coastguard Worker 
706*9880d681SAndroid Build Coastguard Worker /// ParseIDValue - This is just like ParseIDValue above, but it assumes the ID
707*9880d681SAndroid Build Coastguard Worker /// has already been read.
ParseIDValue(Record * CurRec,const std::string & Name,SMLoc NameLoc,IDParseMode Mode)708*9880d681SAndroid Build Coastguard Worker Init *TGParser::ParseIDValue(Record *CurRec,
709*9880d681SAndroid Build Coastguard Worker                              const std::string &Name, SMLoc NameLoc,
710*9880d681SAndroid Build Coastguard Worker                              IDParseMode Mode) {
711*9880d681SAndroid Build Coastguard Worker   if (CurRec) {
712*9880d681SAndroid Build Coastguard Worker     if (const RecordVal *RV = CurRec->getValue(Name))
713*9880d681SAndroid Build Coastguard Worker       return VarInit::get(Name, RV->getType());
714*9880d681SAndroid Build Coastguard Worker 
715*9880d681SAndroid Build Coastguard Worker     Init *TemplateArgName = QualifyName(*CurRec, CurMultiClass, Name, ":");
716*9880d681SAndroid Build Coastguard Worker 
717*9880d681SAndroid Build Coastguard Worker     if (CurMultiClass)
718*9880d681SAndroid Build Coastguard Worker       TemplateArgName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name,
719*9880d681SAndroid Build Coastguard Worker                                     "::");
720*9880d681SAndroid Build Coastguard Worker 
721*9880d681SAndroid Build Coastguard Worker     if (CurRec->isTemplateArg(TemplateArgName)) {
722*9880d681SAndroid Build Coastguard Worker       const RecordVal *RV = CurRec->getValue(TemplateArgName);
723*9880d681SAndroid Build Coastguard Worker       assert(RV && "Template arg doesn't exist??");
724*9880d681SAndroid Build Coastguard Worker       return VarInit::get(TemplateArgName, RV->getType());
725*9880d681SAndroid Build Coastguard Worker     }
726*9880d681SAndroid Build Coastguard Worker   }
727*9880d681SAndroid Build Coastguard Worker 
728*9880d681SAndroid Build Coastguard Worker   if (CurMultiClass) {
729*9880d681SAndroid Build Coastguard Worker     Init *MCName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name,
730*9880d681SAndroid Build Coastguard Worker                                "::");
731*9880d681SAndroid Build Coastguard Worker 
732*9880d681SAndroid Build Coastguard Worker     if (CurMultiClass->Rec.isTemplateArg(MCName)) {
733*9880d681SAndroid Build Coastguard Worker       const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
734*9880d681SAndroid Build Coastguard Worker       assert(RV && "Template arg doesn't exist??");
735*9880d681SAndroid Build Coastguard Worker       return VarInit::get(MCName, RV->getType());
736*9880d681SAndroid Build Coastguard Worker     }
737*9880d681SAndroid Build Coastguard Worker   }
738*9880d681SAndroid Build Coastguard Worker 
739*9880d681SAndroid Build Coastguard Worker   // If this is in a foreach loop, make sure it's not a loop iterator
740*9880d681SAndroid Build Coastguard Worker   for (const auto &L : Loops) {
741*9880d681SAndroid Build Coastguard Worker     VarInit *IterVar = dyn_cast<VarInit>(L.IterVar);
742*9880d681SAndroid Build Coastguard Worker     if (IterVar && IterVar->getName() == Name)
743*9880d681SAndroid Build Coastguard Worker       return IterVar;
744*9880d681SAndroid Build Coastguard Worker   }
745*9880d681SAndroid Build Coastguard Worker 
746*9880d681SAndroid Build Coastguard Worker   if (Mode == ParseNameMode)
747*9880d681SAndroid Build Coastguard Worker     return StringInit::get(Name);
748*9880d681SAndroid Build Coastguard Worker 
749*9880d681SAndroid Build Coastguard Worker   if (Record *D = Records.getDef(Name))
750*9880d681SAndroid Build Coastguard Worker     return DefInit::get(D);
751*9880d681SAndroid Build Coastguard Worker 
752*9880d681SAndroid Build Coastguard Worker   if (Mode == ParseValueMode) {
753*9880d681SAndroid Build Coastguard Worker     Error(NameLoc, "Variable not defined: '" + Name + "'");
754*9880d681SAndroid Build Coastguard Worker     return nullptr;
755*9880d681SAndroid Build Coastguard Worker   }
756*9880d681SAndroid Build Coastguard Worker 
757*9880d681SAndroid Build Coastguard Worker   return StringInit::get(Name);
758*9880d681SAndroid Build Coastguard Worker }
759*9880d681SAndroid Build Coastguard Worker 
760*9880d681SAndroid Build Coastguard Worker /// ParseOperation - Parse an operator.  This returns null on error.
761*9880d681SAndroid Build Coastguard Worker ///
762*9880d681SAndroid Build Coastguard Worker /// Operation ::= XOperator ['<' Type '>'] '(' Args ')'
763*9880d681SAndroid Build Coastguard Worker ///
ParseOperation(Record * CurRec,RecTy * ItemType)764*9880d681SAndroid Build Coastguard Worker Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
765*9880d681SAndroid Build Coastguard Worker   switch (Lex.getCode()) {
766*9880d681SAndroid Build Coastguard Worker   default:
767*9880d681SAndroid Build Coastguard Worker     TokError("unknown operation");
768*9880d681SAndroid Build Coastguard Worker     return nullptr;
769*9880d681SAndroid Build Coastguard Worker   case tgtok::XHead:
770*9880d681SAndroid Build Coastguard Worker   case tgtok::XTail:
771*9880d681SAndroid Build Coastguard Worker   case tgtok::XEmpty:
772*9880d681SAndroid Build Coastguard Worker   case tgtok::XCast: {  // Value ::= !unop '(' Value ')'
773*9880d681SAndroid Build Coastguard Worker     UnOpInit::UnaryOp Code;
774*9880d681SAndroid Build Coastguard Worker     RecTy *Type = nullptr;
775*9880d681SAndroid Build Coastguard Worker 
776*9880d681SAndroid Build Coastguard Worker     switch (Lex.getCode()) {
777*9880d681SAndroid Build Coastguard Worker     default: llvm_unreachable("Unhandled code!");
778*9880d681SAndroid Build Coastguard Worker     case tgtok::XCast:
779*9880d681SAndroid Build Coastguard Worker       Lex.Lex();  // eat the operation
780*9880d681SAndroid Build Coastguard Worker       Code = UnOpInit::CAST;
781*9880d681SAndroid Build Coastguard Worker 
782*9880d681SAndroid Build Coastguard Worker       Type = ParseOperatorType();
783*9880d681SAndroid Build Coastguard Worker 
784*9880d681SAndroid Build Coastguard Worker       if (!Type) {
785*9880d681SAndroid Build Coastguard Worker         TokError("did not get type for unary operator");
786*9880d681SAndroid Build Coastguard Worker         return nullptr;
787*9880d681SAndroid Build Coastguard Worker       }
788*9880d681SAndroid Build Coastguard Worker 
789*9880d681SAndroid Build Coastguard Worker       break;
790*9880d681SAndroid Build Coastguard Worker     case tgtok::XHead:
791*9880d681SAndroid Build Coastguard Worker       Lex.Lex();  // eat the operation
792*9880d681SAndroid Build Coastguard Worker       Code = UnOpInit::HEAD;
793*9880d681SAndroid Build Coastguard Worker       break;
794*9880d681SAndroid Build Coastguard Worker     case tgtok::XTail:
795*9880d681SAndroid Build Coastguard Worker       Lex.Lex();  // eat the operation
796*9880d681SAndroid Build Coastguard Worker       Code = UnOpInit::TAIL;
797*9880d681SAndroid Build Coastguard Worker       break;
798*9880d681SAndroid Build Coastguard Worker     case tgtok::XEmpty:
799*9880d681SAndroid Build Coastguard Worker       Lex.Lex();  // eat the operation
800*9880d681SAndroid Build Coastguard Worker       Code = UnOpInit::EMPTY;
801*9880d681SAndroid Build Coastguard Worker       Type = IntRecTy::get();
802*9880d681SAndroid Build Coastguard Worker       break;
803*9880d681SAndroid Build Coastguard Worker     }
804*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::l_paren) {
805*9880d681SAndroid Build Coastguard Worker       TokError("expected '(' after unary operator");
806*9880d681SAndroid Build Coastguard Worker       return nullptr;
807*9880d681SAndroid Build Coastguard Worker     }
808*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // eat the '('
809*9880d681SAndroid Build Coastguard Worker 
810*9880d681SAndroid Build Coastguard Worker     Init *LHS = ParseValue(CurRec);
811*9880d681SAndroid Build Coastguard Worker     if (!LHS) return nullptr;
812*9880d681SAndroid Build Coastguard Worker 
813*9880d681SAndroid Build Coastguard Worker     if (Code == UnOpInit::HEAD ||
814*9880d681SAndroid Build Coastguard Worker         Code == UnOpInit::TAIL ||
815*9880d681SAndroid Build Coastguard Worker         Code == UnOpInit::EMPTY) {
816*9880d681SAndroid Build Coastguard Worker       ListInit *LHSl = dyn_cast<ListInit>(LHS);
817*9880d681SAndroid Build Coastguard Worker       StringInit *LHSs = dyn_cast<StringInit>(LHS);
818*9880d681SAndroid Build Coastguard Worker       TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
819*9880d681SAndroid Build Coastguard Worker       if (!LHSl && !LHSs && !LHSt) {
820*9880d681SAndroid Build Coastguard Worker         TokError("expected list or string type argument in unary operator");
821*9880d681SAndroid Build Coastguard Worker         return nullptr;
822*9880d681SAndroid Build Coastguard Worker       }
823*9880d681SAndroid Build Coastguard Worker       if (LHSt) {
824*9880d681SAndroid Build Coastguard Worker         ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType());
825*9880d681SAndroid Build Coastguard Worker         StringRecTy *SType = dyn_cast<StringRecTy>(LHSt->getType());
826*9880d681SAndroid Build Coastguard Worker         if (!LType && !SType) {
827*9880d681SAndroid Build Coastguard Worker           TokError("expected list or string type argument in unary operator");
828*9880d681SAndroid Build Coastguard Worker           return nullptr;
829*9880d681SAndroid Build Coastguard Worker         }
830*9880d681SAndroid Build Coastguard Worker       }
831*9880d681SAndroid Build Coastguard Worker 
832*9880d681SAndroid Build Coastguard Worker       if (Code == UnOpInit::HEAD || Code == UnOpInit::TAIL) {
833*9880d681SAndroid Build Coastguard Worker         if (!LHSl && !LHSt) {
834*9880d681SAndroid Build Coastguard Worker           TokError("expected list type argument in unary operator");
835*9880d681SAndroid Build Coastguard Worker           return nullptr;
836*9880d681SAndroid Build Coastguard Worker         }
837*9880d681SAndroid Build Coastguard Worker 
838*9880d681SAndroid Build Coastguard Worker         if (LHSl && LHSl->empty()) {
839*9880d681SAndroid Build Coastguard Worker           TokError("empty list argument in unary operator");
840*9880d681SAndroid Build Coastguard Worker           return nullptr;
841*9880d681SAndroid Build Coastguard Worker         }
842*9880d681SAndroid Build Coastguard Worker         if (LHSl) {
843*9880d681SAndroid Build Coastguard Worker           Init *Item = LHSl->getElement(0);
844*9880d681SAndroid Build Coastguard Worker           TypedInit *Itemt = dyn_cast<TypedInit>(Item);
845*9880d681SAndroid Build Coastguard Worker           if (!Itemt) {
846*9880d681SAndroid Build Coastguard Worker             TokError("untyped list element in unary operator");
847*9880d681SAndroid Build Coastguard Worker             return nullptr;
848*9880d681SAndroid Build Coastguard Worker           }
849*9880d681SAndroid Build Coastguard Worker           Type = (Code == UnOpInit::HEAD) ? Itemt->getType()
850*9880d681SAndroid Build Coastguard Worker                                           : ListRecTy::get(Itemt->getType());
851*9880d681SAndroid Build Coastguard Worker         } else {
852*9880d681SAndroid Build Coastguard Worker           assert(LHSt && "expected list type argument in unary operator");
853*9880d681SAndroid Build Coastguard Worker           ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType());
854*9880d681SAndroid Build Coastguard Worker           if (!LType) {
855*9880d681SAndroid Build Coastguard Worker             TokError("expected list type argument in unary operator");
856*9880d681SAndroid Build Coastguard Worker             return nullptr;
857*9880d681SAndroid Build Coastguard Worker           }
858*9880d681SAndroid Build Coastguard Worker           Type = (Code == UnOpInit::HEAD) ? LType->getElementType() : LType;
859*9880d681SAndroid Build Coastguard Worker         }
860*9880d681SAndroid Build Coastguard Worker       }
861*9880d681SAndroid Build Coastguard Worker     }
862*9880d681SAndroid Build Coastguard Worker 
863*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::r_paren) {
864*9880d681SAndroid Build Coastguard Worker       TokError("expected ')' in unary operator");
865*9880d681SAndroid Build Coastguard Worker       return nullptr;
866*9880d681SAndroid Build Coastguard Worker     }
867*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // eat the ')'
868*9880d681SAndroid Build Coastguard Worker     return (UnOpInit::get(Code, LHS, Type))->Fold(CurRec, CurMultiClass);
869*9880d681SAndroid Build Coastguard Worker   }
870*9880d681SAndroid Build Coastguard Worker 
871*9880d681SAndroid Build Coastguard Worker   case tgtok::XConcat:
872*9880d681SAndroid Build Coastguard Worker   case tgtok::XADD:
873*9880d681SAndroid Build Coastguard Worker   case tgtok::XAND:
874*9880d681SAndroid Build Coastguard Worker   case tgtok::XSRA:
875*9880d681SAndroid Build Coastguard Worker   case tgtok::XSRL:
876*9880d681SAndroid Build Coastguard Worker   case tgtok::XSHL:
877*9880d681SAndroid Build Coastguard Worker   case tgtok::XEq:
878*9880d681SAndroid Build Coastguard Worker   case tgtok::XListConcat:
879*9880d681SAndroid Build Coastguard Worker   case tgtok::XStrConcat: {  // Value ::= !binop '(' Value ',' Value ')'
880*9880d681SAndroid Build Coastguard Worker     tgtok::TokKind OpTok = Lex.getCode();
881*9880d681SAndroid Build Coastguard Worker     SMLoc OpLoc = Lex.getLoc();
882*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // eat the operation
883*9880d681SAndroid Build Coastguard Worker 
884*9880d681SAndroid Build Coastguard Worker     BinOpInit::BinaryOp Code;
885*9880d681SAndroid Build Coastguard Worker     RecTy *Type = nullptr;
886*9880d681SAndroid Build Coastguard Worker 
887*9880d681SAndroid Build Coastguard Worker     switch (OpTok) {
888*9880d681SAndroid Build Coastguard Worker     default: llvm_unreachable("Unhandled code!");
889*9880d681SAndroid Build Coastguard Worker     case tgtok::XConcat: Code = BinOpInit::CONCAT;Type = DagRecTy::get(); break;
890*9880d681SAndroid Build Coastguard Worker     case tgtok::XADD:    Code = BinOpInit::ADD;   Type = IntRecTy::get(); break;
891*9880d681SAndroid Build Coastguard Worker     case tgtok::XAND:    Code = BinOpInit::AND;   Type = IntRecTy::get(); break;
892*9880d681SAndroid Build Coastguard Worker     case tgtok::XSRA:    Code = BinOpInit::SRA;   Type = IntRecTy::get(); break;
893*9880d681SAndroid Build Coastguard Worker     case tgtok::XSRL:    Code = BinOpInit::SRL;   Type = IntRecTy::get(); break;
894*9880d681SAndroid Build Coastguard Worker     case tgtok::XSHL:    Code = BinOpInit::SHL;   Type = IntRecTy::get(); break;
895*9880d681SAndroid Build Coastguard Worker     case tgtok::XEq:     Code = BinOpInit::EQ;    Type = BitRecTy::get(); break;
896*9880d681SAndroid Build Coastguard Worker     case tgtok::XListConcat:
897*9880d681SAndroid Build Coastguard Worker       Code = BinOpInit::LISTCONCAT;
898*9880d681SAndroid Build Coastguard Worker       // We don't know the list type until we parse the first argument
899*9880d681SAndroid Build Coastguard Worker       break;
900*9880d681SAndroid Build Coastguard Worker     case tgtok::XStrConcat:
901*9880d681SAndroid Build Coastguard Worker       Code = BinOpInit::STRCONCAT;
902*9880d681SAndroid Build Coastguard Worker       Type = StringRecTy::get();
903*9880d681SAndroid Build Coastguard Worker       break;
904*9880d681SAndroid Build Coastguard Worker     }
905*9880d681SAndroid Build Coastguard Worker 
906*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::l_paren) {
907*9880d681SAndroid Build Coastguard Worker       TokError("expected '(' after binary operator");
908*9880d681SAndroid Build Coastguard Worker       return nullptr;
909*9880d681SAndroid Build Coastguard Worker     }
910*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // eat the '('
911*9880d681SAndroid Build Coastguard Worker 
912*9880d681SAndroid Build Coastguard Worker     SmallVector<Init*, 2> InitList;
913*9880d681SAndroid Build Coastguard Worker 
914*9880d681SAndroid Build Coastguard Worker     InitList.push_back(ParseValue(CurRec));
915*9880d681SAndroid Build Coastguard Worker     if (!InitList.back()) return nullptr;
916*9880d681SAndroid Build Coastguard Worker 
917*9880d681SAndroid Build Coastguard Worker     while (Lex.getCode() == tgtok::comma) {
918*9880d681SAndroid Build Coastguard Worker       Lex.Lex();  // eat the ','
919*9880d681SAndroid Build Coastguard Worker 
920*9880d681SAndroid Build Coastguard Worker       InitList.push_back(ParseValue(CurRec));
921*9880d681SAndroid Build Coastguard Worker       if (!InitList.back()) return nullptr;
922*9880d681SAndroid Build Coastguard Worker     }
923*9880d681SAndroid Build Coastguard Worker 
924*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::r_paren) {
925*9880d681SAndroid Build Coastguard Worker       TokError("expected ')' in operator");
926*9880d681SAndroid Build Coastguard Worker       return nullptr;
927*9880d681SAndroid Build Coastguard Worker     }
928*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // eat the ')'
929*9880d681SAndroid Build Coastguard Worker 
930*9880d681SAndroid Build Coastguard Worker     // If we are doing !listconcat, we should know the type by now
931*9880d681SAndroid Build Coastguard Worker     if (OpTok == tgtok::XListConcat) {
932*9880d681SAndroid Build Coastguard Worker       if (VarInit *Arg0 = dyn_cast<VarInit>(InitList[0]))
933*9880d681SAndroid Build Coastguard Worker         Type = Arg0->getType();
934*9880d681SAndroid Build Coastguard Worker       else if (ListInit *Arg0 = dyn_cast<ListInit>(InitList[0]))
935*9880d681SAndroid Build Coastguard Worker         Type = Arg0->getType();
936*9880d681SAndroid Build Coastguard Worker       else {
937*9880d681SAndroid Build Coastguard Worker         InitList[0]->dump();
938*9880d681SAndroid Build Coastguard Worker         Error(OpLoc, "expected a list");
939*9880d681SAndroid Build Coastguard Worker         return nullptr;
940*9880d681SAndroid Build Coastguard Worker       }
941*9880d681SAndroid Build Coastguard Worker     }
942*9880d681SAndroid Build Coastguard Worker 
943*9880d681SAndroid Build Coastguard Worker     // We allow multiple operands to associative operators like !strconcat as
944*9880d681SAndroid Build Coastguard Worker     // shorthand for nesting them.
945*9880d681SAndroid Build Coastguard Worker     if (Code == BinOpInit::STRCONCAT || Code == BinOpInit::LISTCONCAT) {
946*9880d681SAndroid Build Coastguard Worker       while (InitList.size() > 2) {
947*9880d681SAndroid Build Coastguard Worker         Init *RHS = InitList.pop_back_val();
948*9880d681SAndroid Build Coastguard Worker         RHS = (BinOpInit::get(Code, InitList.back(), RHS, Type))
949*9880d681SAndroid Build Coastguard Worker                            ->Fold(CurRec, CurMultiClass);
950*9880d681SAndroid Build Coastguard Worker         InitList.back() = RHS;
951*9880d681SAndroid Build Coastguard Worker       }
952*9880d681SAndroid Build Coastguard Worker     }
953*9880d681SAndroid Build Coastguard Worker 
954*9880d681SAndroid Build Coastguard Worker     if (InitList.size() == 2)
955*9880d681SAndroid Build Coastguard Worker       return (BinOpInit::get(Code, InitList[0], InitList[1], Type))
956*9880d681SAndroid Build Coastguard Worker         ->Fold(CurRec, CurMultiClass);
957*9880d681SAndroid Build Coastguard Worker 
958*9880d681SAndroid Build Coastguard Worker     Error(OpLoc, "expected two operands to operator");
959*9880d681SAndroid Build Coastguard Worker     return nullptr;
960*9880d681SAndroid Build Coastguard Worker   }
961*9880d681SAndroid Build Coastguard Worker 
962*9880d681SAndroid Build Coastguard Worker   case tgtok::XIf:
963*9880d681SAndroid Build Coastguard Worker   case tgtok::XForEach:
964*9880d681SAndroid Build Coastguard Worker   case tgtok::XSubst: {  // Value ::= !ternop '(' Value ',' Value ',' Value ')'
965*9880d681SAndroid Build Coastguard Worker     TernOpInit::TernaryOp Code;
966*9880d681SAndroid Build Coastguard Worker     RecTy *Type = nullptr;
967*9880d681SAndroid Build Coastguard Worker 
968*9880d681SAndroid Build Coastguard Worker     tgtok::TokKind LexCode = Lex.getCode();
969*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // eat the operation
970*9880d681SAndroid Build Coastguard Worker     switch (LexCode) {
971*9880d681SAndroid Build Coastguard Worker     default: llvm_unreachable("Unhandled code!");
972*9880d681SAndroid Build Coastguard Worker     case tgtok::XIf:
973*9880d681SAndroid Build Coastguard Worker       Code = TernOpInit::IF;
974*9880d681SAndroid Build Coastguard Worker       break;
975*9880d681SAndroid Build Coastguard Worker     case tgtok::XForEach:
976*9880d681SAndroid Build Coastguard Worker       Code = TernOpInit::FOREACH;
977*9880d681SAndroid Build Coastguard Worker       break;
978*9880d681SAndroid Build Coastguard Worker     case tgtok::XSubst:
979*9880d681SAndroid Build Coastguard Worker       Code = TernOpInit::SUBST;
980*9880d681SAndroid Build Coastguard Worker       break;
981*9880d681SAndroid Build Coastguard Worker     }
982*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::l_paren) {
983*9880d681SAndroid Build Coastguard Worker       TokError("expected '(' after ternary operator");
984*9880d681SAndroid Build Coastguard Worker       return nullptr;
985*9880d681SAndroid Build Coastguard Worker     }
986*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // eat the '('
987*9880d681SAndroid Build Coastguard Worker 
988*9880d681SAndroid Build Coastguard Worker     Init *LHS = ParseValue(CurRec);
989*9880d681SAndroid Build Coastguard Worker     if (!LHS) return nullptr;
990*9880d681SAndroid Build Coastguard Worker 
991*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::comma) {
992*9880d681SAndroid Build Coastguard Worker       TokError("expected ',' in ternary operator");
993*9880d681SAndroid Build Coastguard Worker       return nullptr;
994*9880d681SAndroid Build Coastguard Worker     }
995*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // eat the ','
996*9880d681SAndroid Build Coastguard Worker 
997*9880d681SAndroid Build Coastguard Worker     Init *MHS = ParseValue(CurRec, ItemType);
998*9880d681SAndroid Build Coastguard Worker     if (!MHS)
999*9880d681SAndroid Build Coastguard Worker       return nullptr;
1000*9880d681SAndroid Build Coastguard Worker 
1001*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::comma) {
1002*9880d681SAndroid Build Coastguard Worker       TokError("expected ',' in ternary operator");
1003*9880d681SAndroid Build Coastguard Worker       return nullptr;
1004*9880d681SAndroid Build Coastguard Worker     }
1005*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // eat the ','
1006*9880d681SAndroid Build Coastguard Worker 
1007*9880d681SAndroid Build Coastguard Worker     Init *RHS = ParseValue(CurRec, ItemType);
1008*9880d681SAndroid Build Coastguard Worker     if (!RHS)
1009*9880d681SAndroid Build Coastguard Worker       return nullptr;
1010*9880d681SAndroid Build Coastguard Worker 
1011*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::r_paren) {
1012*9880d681SAndroid Build Coastguard Worker       TokError("expected ')' in binary operator");
1013*9880d681SAndroid Build Coastguard Worker       return nullptr;
1014*9880d681SAndroid Build Coastguard Worker     }
1015*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // eat the ')'
1016*9880d681SAndroid Build Coastguard Worker 
1017*9880d681SAndroid Build Coastguard Worker     switch (LexCode) {
1018*9880d681SAndroid Build Coastguard Worker     default: llvm_unreachable("Unhandled code!");
1019*9880d681SAndroid Build Coastguard Worker     case tgtok::XIf: {
1020*9880d681SAndroid Build Coastguard Worker       RecTy *MHSTy = nullptr;
1021*9880d681SAndroid Build Coastguard Worker       RecTy *RHSTy = nullptr;
1022*9880d681SAndroid Build Coastguard Worker 
1023*9880d681SAndroid Build Coastguard Worker       if (TypedInit *MHSt = dyn_cast<TypedInit>(MHS))
1024*9880d681SAndroid Build Coastguard Worker         MHSTy = MHSt->getType();
1025*9880d681SAndroid Build Coastguard Worker       if (BitsInit *MHSbits = dyn_cast<BitsInit>(MHS))
1026*9880d681SAndroid Build Coastguard Worker         MHSTy = BitsRecTy::get(MHSbits->getNumBits());
1027*9880d681SAndroid Build Coastguard Worker       if (isa<BitInit>(MHS))
1028*9880d681SAndroid Build Coastguard Worker         MHSTy = BitRecTy::get();
1029*9880d681SAndroid Build Coastguard Worker 
1030*9880d681SAndroid Build Coastguard Worker       if (TypedInit *RHSt = dyn_cast<TypedInit>(RHS))
1031*9880d681SAndroid Build Coastguard Worker         RHSTy = RHSt->getType();
1032*9880d681SAndroid Build Coastguard Worker       if (BitsInit *RHSbits = dyn_cast<BitsInit>(RHS))
1033*9880d681SAndroid Build Coastguard Worker         RHSTy = BitsRecTy::get(RHSbits->getNumBits());
1034*9880d681SAndroid Build Coastguard Worker       if (isa<BitInit>(RHS))
1035*9880d681SAndroid Build Coastguard Worker         RHSTy = BitRecTy::get();
1036*9880d681SAndroid Build Coastguard Worker 
1037*9880d681SAndroid Build Coastguard Worker       // For UnsetInit, it's typed from the other hand.
1038*9880d681SAndroid Build Coastguard Worker       if (isa<UnsetInit>(MHS))
1039*9880d681SAndroid Build Coastguard Worker         MHSTy = RHSTy;
1040*9880d681SAndroid Build Coastguard Worker       if (isa<UnsetInit>(RHS))
1041*9880d681SAndroid Build Coastguard Worker         RHSTy = MHSTy;
1042*9880d681SAndroid Build Coastguard Worker 
1043*9880d681SAndroid Build Coastguard Worker       if (!MHSTy || !RHSTy) {
1044*9880d681SAndroid Build Coastguard Worker         TokError("could not get type for !if");
1045*9880d681SAndroid Build Coastguard Worker         return nullptr;
1046*9880d681SAndroid Build Coastguard Worker       }
1047*9880d681SAndroid Build Coastguard Worker 
1048*9880d681SAndroid Build Coastguard Worker       if (MHSTy->typeIsConvertibleTo(RHSTy)) {
1049*9880d681SAndroid Build Coastguard Worker         Type = RHSTy;
1050*9880d681SAndroid Build Coastguard Worker       } else if (RHSTy->typeIsConvertibleTo(MHSTy)) {
1051*9880d681SAndroid Build Coastguard Worker         Type = MHSTy;
1052*9880d681SAndroid Build Coastguard Worker       } else {
1053*9880d681SAndroid Build Coastguard Worker         TokError("inconsistent types for !if");
1054*9880d681SAndroid Build Coastguard Worker         return nullptr;
1055*9880d681SAndroid Build Coastguard Worker       }
1056*9880d681SAndroid Build Coastguard Worker       break;
1057*9880d681SAndroid Build Coastguard Worker     }
1058*9880d681SAndroid Build Coastguard Worker     case tgtok::XForEach: {
1059*9880d681SAndroid Build Coastguard Worker       TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
1060*9880d681SAndroid Build Coastguard Worker       if (!MHSt) {
1061*9880d681SAndroid Build Coastguard Worker         TokError("could not get type for !foreach");
1062*9880d681SAndroid Build Coastguard Worker         return nullptr;
1063*9880d681SAndroid Build Coastguard Worker       }
1064*9880d681SAndroid Build Coastguard Worker       Type = MHSt->getType();
1065*9880d681SAndroid Build Coastguard Worker       break;
1066*9880d681SAndroid Build Coastguard Worker     }
1067*9880d681SAndroid Build Coastguard Worker     case tgtok::XSubst: {
1068*9880d681SAndroid Build Coastguard Worker       TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
1069*9880d681SAndroid Build Coastguard Worker       if (!RHSt) {
1070*9880d681SAndroid Build Coastguard Worker         TokError("could not get type for !subst");
1071*9880d681SAndroid Build Coastguard Worker         return nullptr;
1072*9880d681SAndroid Build Coastguard Worker       }
1073*9880d681SAndroid Build Coastguard Worker       Type = RHSt->getType();
1074*9880d681SAndroid Build Coastguard Worker       break;
1075*9880d681SAndroid Build Coastguard Worker     }
1076*9880d681SAndroid Build Coastguard Worker     }
1077*9880d681SAndroid Build Coastguard Worker     return (TernOpInit::get(Code, LHS, MHS, RHS, Type))->Fold(CurRec,
1078*9880d681SAndroid Build Coastguard Worker                                                              CurMultiClass);
1079*9880d681SAndroid Build Coastguard Worker   }
1080*9880d681SAndroid Build Coastguard Worker   }
1081*9880d681SAndroid Build Coastguard Worker }
1082*9880d681SAndroid Build Coastguard Worker 
1083*9880d681SAndroid Build Coastguard Worker /// ParseOperatorType - Parse a type for an operator.  This returns
1084*9880d681SAndroid Build Coastguard Worker /// null on error.
1085*9880d681SAndroid Build Coastguard Worker ///
1086*9880d681SAndroid Build Coastguard Worker /// OperatorType ::= '<' Type '>'
1087*9880d681SAndroid Build Coastguard Worker ///
ParseOperatorType()1088*9880d681SAndroid Build Coastguard Worker RecTy *TGParser::ParseOperatorType() {
1089*9880d681SAndroid Build Coastguard Worker   RecTy *Type = nullptr;
1090*9880d681SAndroid Build Coastguard Worker 
1091*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::less) {
1092*9880d681SAndroid Build Coastguard Worker     TokError("expected type name for operator");
1093*9880d681SAndroid Build Coastguard Worker     return nullptr;
1094*9880d681SAndroid Build Coastguard Worker   }
1095*9880d681SAndroid Build Coastguard Worker   Lex.Lex();  // eat the <
1096*9880d681SAndroid Build Coastguard Worker 
1097*9880d681SAndroid Build Coastguard Worker   Type = ParseType();
1098*9880d681SAndroid Build Coastguard Worker 
1099*9880d681SAndroid Build Coastguard Worker   if (!Type) {
1100*9880d681SAndroid Build Coastguard Worker     TokError("expected type name for operator");
1101*9880d681SAndroid Build Coastguard Worker     return nullptr;
1102*9880d681SAndroid Build Coastguard Worker   }
1103*9880d681SAndroid Build Coastguard Worker 
1104*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::greater) {
1105*9880d681SAndroid Build Coastguard Worker     TokError("expected type name for operator");
1106*9880d681SAndroid Build Coastguard Worker     return nullptr;
1107*9880d681SAndroid Build Coastguard Worker   }
1108*9880d681SAndroid Build Coastguard Worker   Lex.Lex();  // eat the >
1109*9880d681SAndroid Build Coastguard Worker 
1110*9880d681SAndroid Build Coastguard Worker   return Type;
1111*9880d681SAndroid Build Coastguard Worker }
1112*9880d681SAndroid Build Coastguard Worker 
1113*9880d681SAndroid Build Coastguard Worker 
1114*9880d681SAndroid Build Coastguard Worker /// ParseSimpleValue - Parse a tblgen value.  This returns null on error.
1115*9880d681SAndroid Build Coastguard Worker ///
1116*9880d681SAndroid Build Coastguard Worker ///   SimpleValue ::= IDValue
1117*9880d681SAndroid Build Coastguard Worker ///   SimpleValue ::= INTVAL
1118*9880d681SAndroid Build Coastguard Worker ///   SimpleValue ::= STRVAL+
1119*9880d681SAndroid Build Coastguard Worker ///   SimpleValue ::= CODEFRAGMENT
1120*9880d681SAndroid Build Coastguard Worker ///   SimpleValue ::= '?'
1121*9880d681SAndroid Build Coastguard Worker ///   SimpleValue ::= '{' ValueList '}'
1122*9880d681SAndroid Build Coastguard Worker ///   SimpleValue ::= ID '<' ValueListNE '>'
1123*9880d681SAndroid Build Coastguard Worker ///   SimpleValue ::= '[' ValueList ']'
1124*9880d681SAndroid Build Coastguard Worker ///   SimpleValue ::= '(' IDValue DagArgList ')'
1125*9880d681SAndroid Build Coastguard Worker ///   SimpleValue ::= CONCATTOK '(' Value ',' Value ')'
1126*9880d681SAndroid Build Coastguard Worker ///   SimpleValue ::= ADDTOK '(' Value ',' Value ')'
1127*9880d681SAndroid Build Coastguard Worker ///   SimpleValue ::= SHLTOK '(' Value ',' Value ')'
1128*9880d681SAndroid Build Coastguard Worker ///   SimpleValue ::= SRATOK '(' Value ',' Value ')'
1129*9880d681SAndroid Build Coastguard Worker ///   SimpleValue ::= SRLTOK '(' Value ',' Value ')'
1130*9880d681SAndroid Build Coastguard Worker ///   SimpleValue ::= LISTCONCATTOK '(' Value ',' Value ')'
1131*9880d681SAndroid Build Coastguard Worker ///   SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')'
1132*9880d681SAndroid Build Coastguard Worker ///
ParseSimpleValue(Record * CurRec,RecTy * ItemType,IDParseMode Mode)1133*9880d681SAndroid Build Coastguard Worker Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
1134*9880d681SAndroid Build Coastguard Worker                                  IDParseMode Mode) {
1135*9880d681SAndroid Build Coastguard Worker   Init *R = nullptr;
1136*9880d681SAndroid Build Coastguard Worker   switch (Lex.getCode()) {
1137*9880d681SAndroid Build Coastguard Worker   default: TokError("Unknown token when parsing a value"); break;
1138*9880d681SAndroid Build Coastguard Worker   case tgtok::paste:
1139*9880d681SAndroid Build Coastguard Worker     // This is a leading paste operation.  This is deprecated but
1140*9880d681SAndroid Build Coastguard Worker     // still exists in some .td files.  Ignore it.
1141*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // Skip '#'.
1142*9880d681SAndroid Build Coastguard Worker     return ParseSimpleValue(CurRec, ItemType, Mode);
1143*9880d681SAndroid Build Coastguard Worker   case tgtok::IntVal: R = IntInit::get(Lex.getCurIntVal()); Lex.Lex(); break;
1144*9880d681SAndroid Build Coastguard Worker   case tgtok::BinaryIntVal: {
1145*9880d681SAndroid Build Coastguard Worker     auto BinaryVal = Lex.getCurBinaryIntVal();
1146*9880d681SAndroid Build Coastguard Worker     SmallVector<Init*, 16> Bits(BinaryVal.second);
1147*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, e = BinaryVal.second; i != e; ++i)
1148*9880d681SAndroid Build Coastguard Worker       Bits[i] = BitInit::get(BinaryVal.first & (1LL << i));
1149*9880d681SAndroid Build Coastguard Worker     R = BitsInit::get(Bits);
1150*9880d681SAndroid Build Coastguard Worker     Lex.Lex();
1151*9880d681SAndroid Build Coastguard Worker     break;
1152*9880d681SAndroid Build Coastguard Worker   }
1153*9880d681SAndroid Build Coastguard Worker   case tgtok::StrVal: {
1154*9880d681SAndroid Build Coastguard Worker     std::string Val = Lex.getCurStrVal();
1155*9880d681SAndroid Build Coastguard Worker     Lex.Lex();
1156*9880d681SAndroid Build Coastguard Worker 
1157*9880d681SAndroid Build Coastguard Worker     // Handle multiple consecutive concatenated strings.
1158*9880d681SAndroid Build Coastguard Worker     while (Lex.getCode() == tgtok::StrVal) {
1159*9880d681SAndroid Build Coastguard Worker       Val += Lex.getCurStrVal();
1160*9880d681SAndroid Build Coastguard Worker       Lex.Lex();
1161*9880d681SAndroid Build Coastguard Worker     }
1162*9880d681SAndroid Build Coastguard Worker 
1163*9880d681SAndroid Build Coastguard Worker     R = StringInit::get(Val);
1164*9880d681SAndroid Build Coastguard Worker     break;
1165*9880d681SAndroid Build Coastguard Worker   }
1166*9880d681SAndroid Build Coastguard Worker   case tgtok::CodeFragment:
1167*9880d681SAndroid Build Coastguard Worker     R = CodeInit::get(Lex.getCurStrVal());
1168*9880d681SAndroid Build Coastguard Worker     Lex.Lex();
1169*9880d681SAndroid Build Coastguard Worker     break;
1170*9880d681SAndroid Build Coastguard Worker   case tgtok::question:
1171*9880d681SAndroid Build Coastguard Worker     R = UnsetInit::get();
1172*9880d681SAndroid Build Coastguard Worker     Lex.Lex();
1173*9880d681SAndroid Build Coastguard Worker     break;
1174*9880d681SAndroid Build Coastguard Worker   case tgtok::Id: {
1175*9880d681SAndroid Build Coastguard Worker     SMLoc NameLoc = Lex.getLoc();
1176*9880d681SAndroid Build Coastguard Worker     std::string Name = Lex.getCurStrVal();
1177*9880d681SAndroid Build Coastguard Worker     if (Lex.Lex() != tgtok::less)  // consume the Id.
1178*9880d681SAndroid Build Coastguard Worker       return ParseIDValue(CurRec, Name, NameLoc, Mode);    // Value ::= IDValue
1179*9880d681SAndroid Build Coastguard Worker 
1180*9880d681SAndroid Build Coastguard Worker     // Value ::= ID '<' ValueListNE '>'
1181*9880d681SAndroid Build Coastguard Worker     if (Lex.Lex() == tgtok::greater) {
1182*9880d681SAndroid Build Coastguard Worker       TokError("expected non-empty value list");
1183*9880d681SAndroid Build Coastguard Worker       return nullptr;
1184*9880d681SAndroid Build Coastguard Worker     }
1185*9880d681SAndroid Build Coastguard Worker 
1186*9880d681SAndroid Build Coastguard Worker     // This is a CLASS<initvalslist> expression.  This is supposed to synthesize
1187*9880d681SAndroid Build Coastguard Worker     // a new anonymous definition, deriving from CLASS<initvalslist> with no
1188*9880d681SAndroid Build Coastguard Worker     // body.
1189*9880d681SAndroid Build Coastguard Worker     Record *Class = Records.getClass(Name);
1190*9880d681SAndroid Build Coastguard Worker     if (!Class) {
1191*9880d681SAndroid Build Coastguard Worker       Error(NameLoc, "Expected a class name, got '" + Name + "'");
1192*9880d681SAndroid Build Coastguard Worker       return nullptr;
1193*9880d681SAndroid Build Coastguard Worker     }
1194*9880d681SAndroid Build Coastguard Worker 
1195*9880d681SAndroid Build Coastguard Worker     std::vector<Init*> ValueList = ParseValueList(CurRec, Class);
1196*9880d681SAndroid Build Coastguard Worker     if (ValueList.empty()) return nullptr;
1197*9880d681SAndroid Build Coastguard Worker 
1198*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::greater) {
1199*9880d681SAndroid Build Coastguard Worker       TokError("expected '>' at end of value list");
1200*9880d681SAndroid Build Coastguard Worker       return nullptr;
1201*9880d681SAndroid Build Coastguard Worker     }
1202*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // eat the '>'
1203*9880d681SAndroid Build Coastguard Worker     SMLoc EndLoc = Lex.getLoc();
1204*9880d681SAndroid Build Coastguard Worker 
1205*9880d681SAndroid Build Coastguard Worker     // Create the new record, set it as CurRec temporarily.
1206*9880d681SAndroid Build Coastguard Worker     auto NewRecOwner = llvm::make_unique<Record>(GetNewAnonymousName(), NameLoc,
1207*9880d681SAndroid Build Coastguard Worker                                                  Records, /*IsAnonymous=*/true);
1208*9880d681SAndroid Build Coastguard Worker     Record *NewRec = NewRecOwner.get(); // Keep a copy since we may release.
1209*9880d681SAndroid Build Coastguard Worker     SubClassReference SCRef;
1210*9880d681SAndroid Build Coastguard Worker     SCRef.RefRange = SMRange(NameLoc, EndLoc);
1211*9880d681SAndroid Build Coastguard Worker     SCRef.Rec = Class;
1212*9880d681SAndroid Build Coastguard Worker     SCRef.TemplateArgs = ValueList;
1213*9880d681SAndroid Build Coastguard Worker     // Add info about the subclass to NewRec.
1214*9880d681SAndroid Build Coastguard Worker     if (AddSubClass(NewRec, SCRef))
1215*9880d681SAndroid Build Coastguard Worker       return nullptr;
1216*9880d681SAndroid Build Coastguard Worker 
1217*9880d681SAndroid Build Coastguard Worker     if (!CurMultiClass) {
1218*9880d681SAndroid Build Coastguard Worker       NewRec->resolveReferences();
1219*9880d681SAndroid Build Coastguard Worker       Records.addDef(std::move(NewRecOwner));
1220*9880d681SAndroid Build Coastguard Worker     } else {
1221*9880d681SAndroid Build Coastguard Worker       // This needs to get resolved once the multiclass template arguments are
1222*9880d681SAndroid Build Coastguard Worker       // known before any use.
1223*9880d681SAndroid Build Coastguard Worker       NewRec->setResolveFirst(true);
1224*9880d681SAndroid Build Coastguard Worker       // Otherwise, we're inside a multiclass, add it to the multiclass.
1225*9880d681SAndroid Build Coastguard Worker       CurMultiClass->DefPrototypes.push_back(std::move(NewRecOwner));
1226*9880d681SAndroid Build Coastguard Worker 
1227*9880d681SAndroid Build Coastguard Worker       // Copy the template arguments for the multiclass into the def.
1228*9880d681SAndroid Build Coastguard Worker       for (Init *TArg : CurMultiClass->Rec.getTemplateArgs()) {
1229*9880d681SAndroid Build Coastguard Worker         const RecordVal *RV = CurMultiClass->Rec.getValue(TArg);
1230*9880d681SAndroid Build Coastguard Worker         assert(RV && "Template arg doesn't exist?");
1231*9880d681SAndroid Build Coastguard Worker         NewRec->addValue(*RV);
1232*9880d681SAndroid Build Coastguard Worker       }
1233*9880d681SAndroid Build Coastguard Worker 
1234*9880d681SAndroid Build Coastguard Worker       // We can't return the prototype def here, instead return:
1235*9880d681SAndroid Build Coastguard Worker       // !cast<ItemType>(!strconcat(NAME, AnonName)).
1236*9880d681SAndroid Build Coastguard Worker       const RecordVal *MCNameRV = CurMultiClass->Rec.getValue("NAME");
1237*9880d681SAndroid Build Coastguard Worker       assert(MCNameRV && "multiclass record must have a NAME");
1238*9880d681SAndroid Build Coastguard Worker 
1239*9880d681SAndroid Build Coastguard Worker       return UnOpInit::get(UnOpInit::CAST,
1240*9880d681SAndroid Build Coastguard Worker                            BinOpInit::get(BinOpInit::STRCONCAT,
1241*9880d681SAndroid Build Coastguard Worker                                           VarInit::get(MCNameRV->getName(),
1242*9880d681SAndroid Build Coastguard Worker                                                        MCNameRV->getType()),
1243*9880d681SAndroid Build Coastguard Worker                                           NewRec->getNameInit(),
1244*9880d681SAndroid Build Coastguard Worker                                           StringRecTy::get()),
1245*9880d681SAndroid Build Coastguard Worker                            Class->getDefInit()->getType());
1246*9880d681SAndroid Build Coastguard Worker     }
1247*9880d681SAndroid Build Coastguard Worker 
1248*9880d681SAndroid Build Coastguard Worker     // The result of the expression is a reference to the new record.
1249*9880d681SAndroid Build Coastguard Worker     return DefInit::get(NewRec);
1250*9880d681SAndroid Build Coastguard Worker   }
1251*9880d681SAndroid Build Coastguard Worker   case tgtok::l_brace: {           // Value ::= '{' ValueList '}'
1252*9880d681SAndroid Build Coastguard Worker     SMLoc BraceLoc = Lex.getLoc();
1253*9880d681SAndroid Build Coastguard Worker     Lex.Lex(); // eat the '{'
1254*9880d681SAndroid Build Coastguard Worker     std::vector<Init*> Vals;
1255*9880d681SAndroid Build Coastguard Worker 
1256*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::r_brace) {
1257*9880d681SAndroid Build Coastguard Worker       Vals = ParseValueList(CurRec);
1258*9880d681SAndroid Build Coastguard Worker       if (Vals.empty()) return nullptr;
1259*9880d681SAndroid Build Coastguard Worker     }
1260*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::r_brace) {
1261*9880d681SAndroid Build Coastguard Worker       TokError("expected '}' at end of bit list value");
1262*9880d681SAndroid Build Coastguard Worker       return nullptr;
1263*9880d681SAndroid Build Coastguard Worker     }
1264*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // eat the '}'
1265*9880d681SAndroid Build Coastguard Worker 
1266*9880d681SAndroid Build Coastguard Worker     SmallVector<Init *, 16> NewBits;
1267*9880d681SAndroid Build Coastguard Worker 
1268*9880d681SAndroid Build Coastguard Worker     // As we parse { a, b, ... }, 'a' is the highest bit, but we parse it
1269*9880d681SAndroid Build Coastguard Worker     // first.  We'll first read everything in to a vector, then we can reverse
1270*9880d681SAndroid Build Coastguard Worker     // it to get the bits in the correct order for the BitsInit value.
1271*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
1272*9880d681SAndroid Build Coastguard Worker       // FIXME: The following two loops would not be duplicated
1273*9880d681SAndroid Build Coastguard Worker       //        if the API was a little more orthogonal.
1274*9880d681SAndroid Build Coastguard Worker 
1275*9880d681SAndroid Build Coastguard Worker       // bits<n> values are allowed to initialize n bits.
1276*9880d681SAndroid Build Coastguard Worker       if (BitsInit *BI = dyn_cast<BitsInit>(Vals[i])) {
1277*9880d681SAndroid Build Coastguard Worker         for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
1278*9880d681SAndroid Build Coastguard Worker           NewBits.push_back(BI->getBit((e - i) - 1));
1279*9880d681SAndroid Build Coastguard Worker         continue;
1280*9880d681SAndroid Build Coastguard Worker       }
1281*9880d681SAndroid Build Coastguard Worker       // bits<n> can also come from variable initializers.
1282*9880d681SAndroid Build Coastguard Worker       if (VarInit *VI = dyn_cast<VarInit>(Vals[i])) {
1283*9880d681SAndroid Build Coastguard Worker         if (BitsRecTy *BitsRec = dyn_cast<BitsRecTy>(VI->getType())) {
1284*9880d681SAndroid Build Coastguard Worker           for (unsigned i = 0, e = BitsRec->getNumBits(); i != e; ++i)
1285*9880d681SAndroid Build Coastguard Worker             NewBits.push_back(VI->getBit((e - i) - 1));
1286*9880d681SAndroid Build Coastguard Worker           continue;
1287*9880d681SAndroid Build Coastguard Worker         }
1288*9880d681SAndroid Build Coastguard Worker         // Fallthrough to try convert this to a bit.
1289*9880d681SAndroid Build Coastguard Worker       }
1290*9880d681SAndroid Build Coastguard Worker       // All other values must be convertible to just a single bit.
1291*9880d681SAndroid Build Coastguard Worker       Init *Bit = Vals[i]->convertInitializerTo(BitRecTy::get());
1292*9880d681SAndroid Build Coastguard Worker       if (!Bit) {
1293*9880d681SAndroid Build Coastguard Worker         Error(BraceLoc, "Element #" + Twine(i) + " (" + Vals[i]->getAsString() +
1294*9880d681SAndroid Build Coastguard Worker               ") is not convertable to a bit");
1295*9880d681SAndroid Build Coastguard Worker         return nullptr;
1296*9880d681SAndroid Build Coastguard Worker       }
1297*9880d681SAndroid Build Coastguard Worker       NewBits.push_back(Bit);
1298*9880d681SAndroid Build Coastguard Worker     }
1299*9880d681SAndroid Build Coastguard Worker     std::reverse(NewBits.begin(), NewBits.end());
1300*9880d681SAndroid Build Coastguard Worker     return BitsInit::get(NewBits);
1301*9880d681SAndroid Build Coastguard Worker   }
1302*9880d681SAndroid Build Coastguard Worker   case tgtok::l_square: {          // Value ::= '[' ValueList ']'
1303*9880d681SAndroid Build Coastguard Worker     Lex.Lex(); // eat the '['
1304*9880d681SAndroid Build Coastguard Worker     std::vector<Init*> Vals;
1305*9880d681SAndroid Build Coastguard Worker 
1306*9880d681SAndroid Build Coastguard Worker     RecTy *DeducedEltTy = nullptr;
1307*9880d681SAndroid Build Coastguard Worker     ListRecTy *GivenListTy = nullptr;
1308*9880d681SAndroid Build Coastguard Worker 
1309*9880d681SAndroid Build Coastguard Worker     if (ItemType) {
1310*9880d681SAndroid Build Coastguard Worker       ListRecTy *ListType = dyn_cast<ListRecTy>(ItemType);
1311*9880d681SAndroid Build Coastguard Worker       if (!ListType) {
1312*9880d681SAndroid Build Coastguard Worker         TokError(Twine("Type mismatch for list, expected list type, got ") +
1313*9880d681SAndroid Build Coastguard Worker                  ItemType->getAsString());
1314*9880d681SAndroid Build Coastguard Worker         return nullptr;
1315*9880d681SAndroid Build Coastguard Worker       }
1316*9880d681SAndroid Build Coastguard Worker       GivenListTy = ListType;
1317*9880d681SAndroid Build Coastguard Worker     }
1318*9880d681SAndroid Build Coastguard Worker 
1319*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::r_square) {
1320*9880d681SAndroid Build Coastguard Worker       Vals = ParseValueList(CurRec, nullptr,
1321*9880d681SAndroid Build Coastguard Worker                             GivenListTy ? GivenListTy->getElementType() : nullptr);
1322*9880d681SAndroid Build Coastguard Worker       if (Vals.empty()) return nullptr;
1323*9880d681SAndroid Build Coastguard Worker     }
1324*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::r_square) {
1325*9880d681SAndroid Build Coastguard Worker       TokError("expected ']' at end of list value");
1326*9880d681SAndroid Build Coastguard Worker       return nullptr;
1327*9880d681SAndroid Build Coastguard Worker     }
1328*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // eat the ']'
1329*9880d681SAndroid Build Coastguard Worker 
1330*9880d681SAndroid Build Coastguard Worker     RecTy *GivenEltTy = nullptr;
1331*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() == tgtok::less) {
1332*9880d681SAndroid Build Coastguard Worker       // Optional list element type
1333*9880d681SAndroid Build Coastguard Worker       Lex.Lex();  // eat the '<'
1334*9880d681SAndroid Build Coastguard Worker 
1335*9880d681SAndroid Build Coastguard Worker       GivenEltTy = ParseType();
1336*9880d681SAndroid Build Coastguard Worker       if (!GivenEltTy) {
1337*9880d681SAndroid Build Coastguard Worker         // Couldn't parse element type
1338*9880d681SAndroid Build Coastguard Worker         return nullptr;
1339*9880d681SAndroid Build Coastguard Worker       }
1340*9880d681SAndroid Build Coastguard Worker 
1341*9880d681SAndroid Build Coastguard Worker       if (Lex.getCode() != tgtok::greater) {
1342*9880d681SAndroid Build Coastguard Worker         TokError("expected '>' at end of list element type");
1343*9880d681SAndroid Build Coastguard Worker         return nullptr;
1344*9880d681SAndroid Build Coastguard Worker       }
1345*9880d681SAndroid Build Coastguard Worker       Lex.Lex();  // eat the '>'
1346*9880d681SAndroid Build Coastguard Worker     }
1347*9880d681SAndroid Build Coastguard Worker 
1348*9880d681SAndroid Build Coastguard Worker     // Check elements
1349*9880d681SAndroid Build Coastguard Worker     RecTy *EltTy = nullptr;
1350*9880d681SAndroid Build Coastguard Worker     for (Init *V : Vals) {
1351*9880d681SAndroid Build Coastguard Worker       TypedInit *TArg = dyn_cast<TypedInit>(V);
1352*9880d681SAndroid Build Coastguard Worker       if (!TArg) {
1353*9880d681SAndroid Build Coastguard Worker         TokError("Untyped list element");
1354*9880d681SAndroid Build Coastguard Worker         return nullptr;
1355*9880d681SAndroid Build Coastguard Worker       }
1356*9880d681SAndroid Build Coastguard Worker       if (EltTy) {
1357*9880d681SAndroid Build Coastguard Worker         EltTy = resolveTypes(EltTy, TArg->getType());
1358*9880d681SAndroid Build Coastguard Worker         if (!EltTy) {
1359*9880d681SAndroid Build Coastguard Worker           TokError("Incompatible types in list elements");
1360*9880d681SAndroid Build Coastguard Worker           return nullptr;
1361*9880d681SAndroid Build Coastguard Worker         }
1362*9880d681SAndroid Build Coastguard Worker       } else {
1363*9880d681SAndroid Build Coastguard Worker         EltTy = TArg->getType();
1364*9880d681SAndroid Build Coastguard Worker       }
1365*9880d681SAndroid Build Coastguard Worker     }
1366*9880d681SAndroid Build Coastguard Worker 
1367*9880d681SAndroid Build Coastguard Worker     if (GivenEltTy) {
1368*9880d681SAndroid Build Coastguard Worker       if (EltTy) {
1369*9880d681SAndroid Build Coastguard Worker         // Verify consistency
1370*9880d681SAndroid Build Coastguard Worker         if (!EltTy->typeIsConvertibleTo(GivenEltTy)) {
1371*9880d681SAndroid Build Coastguard Worker           TokError("Incompatible types in list elements");
1372*9880d681SAndroid Build Coastguard Worker           return nullptr;
1373*9880d681SAndroid Build Coastguard Worker         }
1374*9880d681SAndroid Build Coastguard Worker       }
1375*9880d681SAndroid Build Coastguard Worker       EltTy = GivenEltTy;
1376*9880d681SAndroid Build Coastguard Worker     }
1377*9880d681SAndroid Build Coastguard Worker 
1378*9880d681SAndroid Build Coastguard Worker     if (!EltTy) {
1379*9880d681SAndroid Build Coastguard Worker       if (!ItemType) {
1380*9880d681SAndroid Build Coastguard Worker         TokError("No type for list");
1381*9880d681SAndroid Build Coastguard Worker         return nullptr;
1382*9880d681SAndroid Build Coastguard Worker       }
1383*9880d681SAndroid Build Coastguard Worker       DeducedEltTy = GivenListTy->getElementType();
1384*9880d681SAndroid Build Coastguard Worker     } else {
1385*9880d681SAndroid Build Coastguard Worker       // Make sure the deduced type is compatible with the given type
1386*9880d681SAndroid Build Coastguard Worker       if (GivenListTy) {
1387*9880d681SAndroid Build Coastguard Worker         if (!EltTy->typeIsConvertibleTo(GivenListTy->getElementType())) {
1388*9880d681SAndroid Build Coastguard Worker           TokError("Element type mismatch for list");
1389*9880d681SAndroid Build Coastguard Worker           return nullptr;
1390*9880d681SAndroid Build Coastguard Worker         }
1391*9880d681SAndroid Build Coastguard Worker       }
1392*9880d681SAndroid Build Coastguard Worker       DeducedEltTy = EltTy;
1393*9880d681SAndroid Build Coastguard Worker     }
1394*9880d681SAndroid Build Coastguard Worker 
1395*9880d681SAndroid Build Coastguard Worker     return ListInit::get(Vals, DeducedEltTy);
1396*9880d681SAndroid Build Coastguard Worker   }
1397*9880d681SAndroid Build Coastguard Worker   case tgtok::l_paren: {         // Value ::= '(' IDValue DagArgList ')'
1398*9880d681SAndroid Build Coastguard Worker     Lex.Lex();   // eat the '('
1399*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::Id && Lex.getCode() != tgtok::XCast) {
1400*9880d681SAndroid Build Coastguard Worker       TokError("expected identifier in dag init");
1401*9880d681SAndroid Build Coastguard Worker       return nullptr;
1402*9880d681SAndroid Build Coastguard Worker     }
1403*9880d681SAndroid Build Coastguard Worker 
1404*9880d681SAndroid Build Coastguard Worker     Init *Operator = ParseValue(CurRec);
1405*9880d681SAndroid Build Coastguard Worker     if (!Operator) return nullptr;
1406*9880d681SAndroid Build Coastguard Worker 
1407*9880d681SAndroid Build Coastguard Worker     // If the operator name is present, parse it.
1408*9880d681SAndroid Build Coastguard Worker     std::string OperatorName;
1409*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() == tgtok::colon) {
1410*9880d681SAndroid Build Coastguard Worker       if (Lex.Lex() != tgtok::VarName) { // eat the ':'
1411*9880d681SAndroid Build Coastguard Worker         TokError("expected variable name in dag operator");
1412*9880d681SAndroid Build Coastguard Worker         return nullptr;
1413*9880d681SAndroid Build Coastguard Worker       }
1414*9880d681SAndroid Build Coastguard Worker       OperatorName = Lex.getCurStrVal();
1415*9880d681SAndroid Build Coastguard Worker       Lex.Lex();  // eat the VarName.
1416*9880d681SAndroid Build Coastguard Worker     }
1417*9880d681SAndroid Build Coastguard Worker 
1418*9880d681SAndroid Build Coastguard Worker     std::vector<std::pair<llvm::Init*, std::string> > DagArgs;
1419*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::r_paren) {
1420*9880d681SAndroid Build Coastguard Worker       DagArgs = ParseDagArgList(CurRec);
1421*9880d681SAndroid Build Coastguard Worker       if (DagArgs.empty()) return nullptr;
1422*9880d681SAndroid Build Coastguard Worker     }
1423*9880d681SAndroid Build Coastguard Worker 
1424*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::r_paren) {
1425*9880d681SAndroid Build Coastguard Worker       TokError("expected ')' in dag init");
1426*9880d681SAndroid Build Coastguard Worker       return nullptr;
1427*9880d681SAndroid Build Coastguard Worker     }
1428*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // eat the ')'
1429*9880d681SAndroid Build Coastguard Worker 
1430*9880d681SAndroid Build Coastguard Worker     return DagInit::get(Operator, OperatorName, DagArgs);
1431*9880d681SAndroid Build Coastguard Worker   }
1432*9880d681SAndroid Build Coastguard Worker 
1433*9880d681SAndroid Build Coastguard Worker   case tgtok::XHead:
1434*9880d681SAndroid Build Coastguard Worker   case tgtok::XTail:
1435*9880d681SAndroid Build Coastguard Worker   case tgtok::XEmpty:
1436*9880d681SAndroid Build Coastguard Worker   case tgtok::XCast:  // Value ::= !unop '(' Value ')'
1437*9880d681SAndroid Build Coastguard Worker   case tgtok::XConcat:
1438*9880d681SAndroid Build Coastguard Worker   case tgtok::XADD:
1439*9880d681SAndroid Build Coastguard Worker   case tgtok::XAND:
1440*9880d681SAndroid Build Coastguard Worker   case tgtok::XSRA:
1441*9880d681SAndroid Build Coastguard Worker   case tgtok::XSRL:
1442*9880d681SAndroid Build Coastguard Worker   case tgtok::XSHL:
1443*9880d681SAndroid Build Coastguard Worker   case tgtok::XEq:
1444*9880d681SAndroid Build Coastguard Worker   case tgtok::XListConcat:
1445*9880d681SAndroid Build Coastguard Worker   case tgtok::XStrConcat:   // Value ::= !binop '(' Value ',' Value ')'
1446*9880d681SAndroid Build Coastguard Worker   case tgtok::XIf:
1447*9880d681SAndroid Build Coastguard Worker   case tgtok::XForEach:
1448*9880d681SAndroid Build Coastguard Worker   case tgtok::XSubst: {  // Value ::= !ternop '(' Value ',' Value ',' Value ')'
1449*9880d681SAndroid Build Coastguard Worker     return ParseOperation(CurRec, ItemType);
1450*9880d681SAndroid Build Coastguard Worker   }
1451*9880d681SAndroid Build Coastguard Worker   }
1452*9880d681SAndroid Build Coastguard Worker 
1453*9880d681SAndroid Build Coastguard Worker   return R;
1454*9880d681SAndroid Build Coastguard Worker }
1455*9880d681SAndroid Build Coastguard Worker 
1456*9880d681SAndroid Build Coastguard Worker /// ParseValue - Parse a tblgen value.  This returns null on error.
1457*9880d681SAndroid Build Coastguard Worker ///
1458*9880d681SAndroid Build Coastguard Worker ///   Value       ::= SimpleValue ValueSuffix*
1459*9880d681SAndroid Build Coastguard Worker ///   ValueSuffix ::= '{' BitList '}'
1460*9880d681SAndroid Build Coastguard Worker ///   ValueSuffix ::= '[' BitList ']'
1461*9880d681SAndroid Build Coastguard Worker ///   ValueSuffix ::= '.' ID
1462*9880d681SAndroid Build Coastguard Worker ///
ParseValue(Record * CurRec,RecTy * ItemType,IDParseMode Mode)1463*9880d681SAndroid Build Coastguard Worker Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
1464*9880d681SAndroid Build Coastguard Worker   Init *Result = ParseSimpleValue(CurRec, ItemType, Mode);
1465*9880d681SAndroid Build Coastguard Worker   if (!Result) return nullptr;
1466*9880d681SAndroid Build Coastguard Worker 
1467*9880d681SAndroid Build Coastguard Worker   // Parse the suffixes now if present.
1468*9880d681SAndroid Build Coastguard Worker   while (1) {
1469*9880d681SAndroid Build Coastguard Worker     switch (Lex.getCode()) {
1470*9880d681SAndroid Build Coastguard Worker     default: return Result;
1471*9880d681SAndroid Build Coastguard Worker     case tgtok::l_brace: {
1472*9880d681SAndroid Build Coastguard Worker       if (Mode == ParseNameMode || Mode == ParseForeachMode)
1473*9880d681SAndroid Build Coastguard Worker         // This is the beginning of the object body.
1474*9880d681SAndroid Build Coastguard Worker         return Result;
1475*9880d681SAndroid Build Coastguard Worker 
1476*9880d681SAndroid Build Coastguard Worker       SMLoc CurlyLoc = Lex.getLoc();
1477*9880d681SAndroid Build Coastguard Worker       Lex.Lex(); // eat the '{'
1478*9880d681SAndroid Build Coastguard Worker       std::vector<unsigned> Ranges = ParseRangeList();
1479*9880d681SAndroid Build Coastguard Worker       if (Ranges.empty()) return nullptr;
1480*9880d681SAndroid Build Coastguard Worker 
1481*9880d681SAndroid Build Coastguard Worker       // Reverse the bitlist.
1482*9880d681SAndroid Build Coastguard Worker       std::reverse(Ranges.begin(), Ranges.end());
1483*9880d681SAndroid Build Coastguard Worker       Result = Result->convertInitializerBitRange(Ranges);
1484*9880d681SAndroid Build Coastguard Worker       if (!Result) {
1485*9880d681SAndroid Build Coastguard Worker         Error(CurlyLoc, "Invalid bit range for value");
1486*9880d681SAndroid Build Coastguard Worker         return nullptr;
1487*9880d681SAndroid Build Coastguard Worker       }
1488*9880d681SAndroid Build Coastguard Worker 
1489*9880d681SAndroid Build Coastguard Worker       // Eat the '}'.
1490*9880d681SAndroid Build Coastguard Worker       if (Lex.getCode() != tgtok::r_brace) {
1491*9880d681SAndroid Build Coastguard Worker         TokError("expected '}' at end of bit range list");
1492*9880d681SAndroid Build Coastguard Worker         return nullptr;
1493*9880d681SAndroid Build Coastguard Worker       }
1494*9880d681SAndroid Build Coastguard Worker       Lex.Lex();
1495*9880d681SAndroid Build Coastguard Worker       break;
1496*9880d681SAndroid Build Coastguard Worker     }
1497*9880d681SAndroid Build Coastguard Worker     case tgtok::l_square: {
1498*9880d681SAndroid Build Coastguard Worker       SMLoc SquareLoc = Lex.getLoc();
1499*9880d681SAndroid Build Coastguard Worker       Lex.Lex(); // eat the '['
1500*9880d681SAndroid Build Coastguard Worker       std::vector<unsigned> Ranges = ParseRangeList();
1501*9880d681SAndroid Build Coastguard Worker       if (Ranges.empty()) return nullptr;
1502*9880d681SAndroid Build Coastguard Worker 
1503*9880d681SAndroid Build Coastguard Worker       Result = Result->convertInitListSlice(Ranges);
1504*9880d681SAndroid Build Coastguard Worker       if (!Result) {
1505*9880d681SAndroid Build Coastguard Worker         Error(SquareLoc, "Invalid range for list slice");
1506*9880d681SAndroid Build Coastguard Worker         return nullptr;
1507*9880d681SAndroid Build Coastguard Worker       }
1508*9880d681SAndroid Build Coastguard Worker 
1509*9880d681SAndroid Build Coastguard Worker       // Eat the ']'.
1510*9880d681SAndroid Build Coastguard Worker       if (Lex.getCode() != tgtok::r_square) {
1511*9880d681SAndroid Build Coastguard Worker         TokError("expected ']' at end of list slice");
1512*9880d681SAndroid Build Coastguard Worker         return nullptr;
1513*9880d681SAndroid Build Coastguard Worker       }
1514*9880d681SAndroid Build Coastguard Worker       Lex.Lex();
1515*9880d681SAndroid Build Coastguard Worker       break;
1516*9880d681SAndroid Build Coastguard Worker     }
1517*9880d681SAndroid Build Coastguard Worker     case tgtok::period:
1518*9880d681SAndroid Build Coastguard Worker       if (Lex.Lex() != tgtok::Id) {  // eat the .
1519*9880d681SAndroid Build Coastguard Worker         TokError("expected field identifier after '.'");
1520*9880d681SAndroid Build Coastguard Worker         return nullptr;
1521*9880d681SAndroid Build Coastguard Worker       }
1522*9880d681SAndroid Build Coastguard Worker       if (!Result->getFieldType(Lex.getCurStrVal())) {
1523*9880d681SAndroid Build Coastguard Worker         TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" +
1524*9880d681SAndroid Build Coastguard Worker                  Result->getAsString() + "'");
1525*9880d681SAndroid Build Coastguard Worker         return nullptr;
1526*9880d681SAndroid Build Coastguard Worker       }
1527*9880d681SAndroid Build Coastguard Worker       Result = FieldInit::get(Result, Lex.getCurStrVal());
1528*9880d681SAndroid Build Coastguard Worker       Lex.Lex();  // eat field name
1529*9880d681SAndroid Build Coastguard Worker       break;
1530*9880d681SAndroid Build Coastguard Worker 
1531*9880d681SAndroid Build Coastguard Worker     case tgtok::paste:
1532*9880d681SAndroid Build Coastguard Worker       SMLoc PasteLoc = Lex.getLoc();
1533*9880d681SAndroid Build Coastguard Worker 
1534*9880d681SAndroid Build Coastguard Worker       // Create a !strconcat() operation, first casting each operand to
1535*9880d681SAndroid Build Coastguard Worker       // a string if necessary.
1536*9880d681SAndroid Build Coastguard Worker 
1537*9880d681SAndroid Build Coastguard Worker       TypedInit *LHS = dyn_cast<TypedInit>(Result);
1538*9880d681SAndroid Build Coastguard Worker       if (!LHS) {
1539*9880d681SAndroid Build Coastguard Worker         Error(PasteLoc, "LHS of paste is not typed!");
1540*9880d681SAndroid Build Coastguard Worker         return nullptr;
1541*9880d681SAndroid Build Coastguard Worker       }
1542*9880d681SAndroid Build Coastguard Worker 
1543*9880d681SAndroid Build Coastguard Worker       if (LHS->getType() != StringRecTy::get()) {
1544*9880d681SAndroid Build Coastguard Worker         LHS = UnOpInit::get(UnOpInit::CAST, LHS, StringRecTy::get());
1545*9880d681SAndroid Build Coastguard Worker       }
1546*9880d681SAndroid Build Coastguard Worker 
1547*9880d681SAndroid Build Coastguard Worker       TypedInit *RHS = nullptr;
1548*9880d681SAndroid Build Coastguard Worker 
1549*9880d681SAndroid Build Coastguard Worker       Lex.Lex();  // Eat the '#'.
1550*9880d681SAndroid Build Coastguard Worker       switch (Lex.getCode()) {
1551*9880d681SAndroid Build Coastguard Worker       case tgtok::colon:
1552*9880d681SAndroid Build Coastguard Worker       case tgtok::semi:
1553*9880d681SAndroid Build Coastguard Worker       case tgtok::l_brace:
1554*9880d681SAndroid Build Coastguard Worker         // These are all of the tokens that can begin an object body.
1555*9880d681SAndroid Build Coastguard Worker         // Some of these can also begin values but we disallow those cases
1556*9880d681SAndroid Build Coastguard Worker         // because they are unlikely to be useful.
1557*9880d681SAndroid Build Coastguard Worker 
1558*9880d681SAndroid Build Coastguard Worker         // Trailing paste, concat with an empty string.
1559*9880d681SAndroid Build Coastguard Worker         RHS = StringInit::get("");
1560*9880d681SAndroid Build Coastguard Worker         break;
1561*9880d681SAndroid Build Coastguard Worker 
1562*9880d681SAndroid Build Coastguard Worker       default:
1563*9880d681SAndroid Build Coastguard Worker         Init *RHSResult = ParseValue(CurRec, ItemType, ParseNameMode);
1564*9880d681SAndroid Build Coastguard Worker         RHS = dyn_cast<TypedInit>(RHSResult);
1565*9880d681SAndroid Build Coastguard Worker         if (!RHS) {
1566*9880d681SAndroid Build Coastguard Worker           Error(PasteLoc, "RHS of paste is not typed!");
1567*9880d681SAndroid Build Coastguard Worker           return nullptr;
1568*9880d681SAndroid Build Coastguard Worker         }
1569*9880d681SAndroid Build Coastguard Worker 
1570*9880d681SAndroid Build Coastguard Worker         if (RHS->getType() != StringRecTy::get()) {
1571*9880d681SAndroid Build Coastguard Worker           RHS = UnOpInit::get(UnOpInit::CAST, RHS, StringRecTy::get());
1572*9880d681SAndroid Build Coastguard Worker         }
1573*9880d681SAndroid Build Coastguard Worker 
1574*9880d681SAndroid Build Coastguard Worker         break;
1575*9880d681SAndroid Build Coastguard Worker       }
1576*9880d681SAndroid Build Coastguard Worker 
1577*9880d681SAndroid Build Coastguard Worker       Result = BinOpInit::get(BinOpInit::STRCONCAT, LHS, RHS,
1578*9880d681SAndroid Build Coastguard Worker                               StringRecTy::get())->Fold(CurRec, CurMultiClass);
1579*9880d681SAndroid Build Coastguard Worker       break;
1580*9880d681SAndroid Build Coastguard Worker     }
1581*9880d681SAndroid Build Coastguard Worker   }
1582*9880d681SAndroid Build Coastguard Worker }
1583*9880d681SAndroid Build Coastguard Worker 
1584*9880d681SAndroid Build Coastguard Worker /// ParseDagArgList - Parse the argument list for a dag literal expression.
1585*9880d681SAndroid Build Coastguard Worker ///
1586*9880d681SAndroid Build Coastguard Worker ///    DagArg     ::= Value (':' VARNAME)?
1587*9880d681SAndroid Build Coastguard Worker ///    DagArg     ::= VARNAME
1588*9880d681SAndroid Build Coastguard Worker ///    DagArgList ::= DagArg
1589*9880d681SAndroid Build Coastguard Worker ///    DagArgList ::= DagArgList ',' DagArg
1590*9880d681SAndroid Build Coastguard Worker std::vector<std::pair<llvm::Init*, std::string> >
ParseDagArgList(Record * CurRec)1591*9880d681SAndroid Build Coastguard Worker TGParser::ParseDagArgList(Record *CurRec) {
1592*9880d681SAndroid Build Coastguard Worker   std::vector<std::pair<llvm::Init*, std::string> > Result;
1593*9880d681SAndroid Build Coastguard Worker 
1594*9880d681SAndroid Build Coastguard Worker   while (1) {
1595*9880d681SAndroid Build Coastguard Worker     // DagArg ::= VARNAME
1596*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() == tgtok::VarName) {
1597*9880d681SAndroid Build Coastguard Worker       // A missing value is treated like '?'.
1598*9880d681SAndroid Build Coastguard Worker       Result.emplace_back(UnsetInit::get(), Lex.getCurStrVal());
1599*9880d681SAndroid Build Coastguard Worker       Lex.Lex();
1600*9880d681SAndroid Build Coastguard Worker     } else {
1601*9880d681SAndroid Build Coastguard Worker       // DagArg ::= Value (':' VARNAME)?
1602*9880d681SAndroid Build Coastguard Worker       Init *Val = ParseValue(CurRec);
1603*9880d681SAndroid Build Coastguard Worker       if (!Val)
1604*9880d681SAndroid Build Coastguard Worker         return std::vector<std::pair<llvm::Init*, std::string> >();
1605*9880d681SAndroid Build Coastguard Worker 
1606*9880d681SAndroid Build Coastguard Worker       // If the variable name is present, add it.
1607*9880d681SAndroid Build Coastguard Worker       std::string VarName;
1608*9880d681SAndroid Build Coastguard Worker       if (Lex.getCode() == tgtok::colon) {
1609*9880d681SAndroid Build Coastguard Worker         if (Lex.Lex() != tgtok::VarName) { // eat the ':'
1610*9880d681SAndroid Build Coastguard Worker           TokError("expected variable name in dag literal");
1611*9880d681SAndroid Build Coastguard Worker           return std::vector<std::pair<llvm::Init*, std::string> >();
1612*9880d681SAndroid Build Coastguard Worker         }
1613*9880d681SAndroid Build Coastguard Worker         VarName = Lex.getCurStrVal();
1614*9880d681SAndroid Build Coastguard Worker         Lex.Lex();  // eat the VarName.
1615*9880d681SAndroid Build Coastguard Worker       }
1616*9880d681SAndroid Build Coastguard Worker 
1617*9880d681SAndroid Build Coastguard Worker       Result.push_back(std::make_pair(Val, VarName));
1618*9880d681SAndroid Build Coastguard Worker     }
1619*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::comma) break;
1620*9880d681SAndroid Build Coastguard Worker     Lex.Lex(); // eat the ','
1621*9880d681SAndroid Build Coastguard Worker   }
1622*9880d681SAndroid Build Coastguard Worker 
1623*9880d681SAndroid Build Coastguard Worker   return Result;
1624*9880d681SAndroid Build Coastguard Worker }
1625*9880d681SAndroid Build Coastguard Worker 
1626*9880d681SAndroid Build Coastguard Worker 
1627*9880d681SAndroid Build Coastguard Worker /// ParseValueList - Parse a comma separated list of values, returning them as a
1628*9880d681SAndroid Build Coastguard Worker /// vector.  Note that this always expects to be able to parse at least one
1629*9880d681SAndroid Build Coastguard Worker /// value.  It returns an empty list if this is not possible.
1630*9880d681SAndroid Build Coastguard Worker ///
1631*9880d681SAndroid Build Coastguard Worker ///   ValueList ::= Value (',' Value)
1632*9880d681SAndroid Build Coastguard Worker ///
ParseValueList(Record * CurRec,Record * ArgsRec,RecTy * EltTy)1633*9880d681SAndroid Build Coastguard Worker std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec,
1634*9880d681SAndroid Build Coastguard Worker                                             RecTy *EltTy) {
1635*9880d681SAndroid Build Coastguard Worker   std::vector<Init*> Result;
1636*9880d681SAndroid Build Coastguard Worker   RecTy *ItemType = EltTy;
1637*9880d681SAndroid Build Coastguard Worker   unsigned int ArgN = 0;
1638*9880d681SAndroid Build Coastguard Worker   if (ArgsRec && !EltTy) {
1639*9880d681SAndroid Build Coastguard Worker     ArrayRef<Init *> TArgs = ArgsRec->getTemplateArgs();
1640*9880d681SAndroid Build Coastguard Worker     if (TArgs.empty()) {
1641*9880d681SAndroid Build Coastguard Worker       TokError("template argument provided to non-template class");
1642*9880d681SAndroid Build Coastguard Worker       return std::vector<Init*>();
1643*9880d681SAndroid Build Coastguard Worker     }
1644*9880d681SAndroid Build Coastguard Worker     const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]);
1645*9880d681SAndroid Build Coastguard Worker     if (!RV) {
1646*9880d681SAndroid Build Coastguard Worker       errs() << "Cannot find template arg " << ArgN << " (" << TArgs[ArgN]
1647*9880d681SAndroid Build Coastguard Worker         << ")\n";
1648*9880d681SAndroid Build Coastguard Worker     }
1649*9880d681SAndroid Build Coastguard Worker     assert(RV && "Template argument record not found??");
1650*9880d681SAndroid Build Coastguard Worker     ItemType = RV->getType();
1651*9880d681SAndroid Build Coastguard Worker     ++ArgN;
1652*9880d681SAndroid Build Coastguard Worker   }
1653*9880d681SAndroid Build Coastguard Worker   Result.push_back(ParseValue(CurRec, ItemType));
1654*9880d681SAndroid Build Coastguard Worker   if (!Result.back()) return std::vector<Init*>();
1655*9880d681SAndroid Build Coastguard Worker 
1656*9880d681SAndroid Build Coastguard Worker   while (Lex.getCode() == tgtok::comma) {
1657*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // Eat the comma
1658*9880d681SAndroid Build Coastguard Worker 
1659*9880d681SAndroid Build Coastguard Worker     if (ArgsRec && !EltTy) {
1660*9880d681SAndroid Build Coastguard Worker       ArrayRef<Init *> TArgs = ArgsRec->getTemplateArgs();
1661*9880d681SAndroid Build Coastguard Worker       if (ArgN >= TArgs.size()) {
1662*9880d681SAndroid Build Coastguard Worker         TokError("too many template arguments");
1663*9880d681SAndroid Build Coastguard Worker         return std::vector<Init*>();
1664*9880d681SAndroid Build Coastguard Worker       }
1665*9880d681SAndroid Build Coastguard Worker       const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]);
1666*9880d681SAndroid Build Coastguard Worker       assert(RV && "Template argument record not found??");
1667*9880d681SAndroid Build Coastguard Worker       ItemType = RV->getType();
1668*9880d681SAndroid Build Coastguard Worker       ++ArgN;
1669*9880d681SAndroid Build Coastguard Worker     }
1670*9880d681SAndroid Build Coastguard Worker     Result.push_back(ParseValue(CurRec, ItemType));
1671*9880d681SAndroid Build Coastguard Worker     if (!Result.back()) return std::vector<Init*>();
1672*9880d681SAndroid Build Coastguard Worker   }
1673*9880d681SAndroid Build Coastguard Worker 
1674*9880d681SAndroid Build Coastguard Worker   return Result;
1675*9880d681SAndroid Build Coastguard Worker }
1676*9880d681SAndroid Build Coastguard Worker 
1677*9880d681SAndroid Build Coastguard Worker 
1678*9880d681SAndroid Build Coastguard Worker /// ParseDeclaration - Read a declaration, returning the name of field ID, or an
1679*9880d681SAndroid Build Coastguard Worker /// empty string on error.  This can happen in a number of different context's,
1680*9880d681SAndroid Build Coastguard Worker /// including within a def or in the template args for a def (which which case
1681*9880d681SAndroid Build Coastguard Worker /// CurRec will be non-null) and within the template args for a multiclass (in
1682*9880d681SAndroid Build Coastguard Worker /// which case CurRec will be null, but CurMultiClass will be set).  This can
1683*9880d681SAndroid Build Coastguard Worker /// also happen within a def that is within a multiclass, which will set both
1684*9880d681SAndroid Build Coastguard Worker /// CurRec and CurMultiClass.
1685*9880d681SAndroid Build Coastguard Worker ///
1686*9880d681SAndroid Build Coastguard Worker ///  Declaration ::= FIELD? Type ID ('=' Value)?
1687*9880d681SAndroid Build Coastguard Worker ///
ParseDeclaration(Record * CurRec,bool ParsingTemplateArgs)1688*9880d681SAndroid Build Coastguard Worker Init *TGParser::ParseDeclaration(Record *CurRec,
1689*9880d681SAndroid Build Coastguard Worker                                        bool ParsingTemplateArgs) {
1690*9880d681SAndroid Build Coastguard Worker   // Read the field prefix if present.
1691*9880d681SAndroid Build Coastguard Worker   bool HasField = Lex.getCode() == tgtok::Field;
1692*9880d681SAndroid Build Coastguard Worker   if (HasField) Lex.Lex();
1693*9880d681SAndroid Build Coastguard Worker 
1694*9880d681SAndroid Build Coastguard Worker   RecTy *Type = ParseType();
1695*9880d681SAndroid Build Coastguard Worker   if (!Type) return nullptr;
1696*9880d681SAndroid Build Coastguard Worker 
1697*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::Id) {
1698*9880d681SAndroid Build Coastguard Worker     TokError("Expected identifier in declaration");
1699*9880d681SAndroid Build Coastguard Worker     return nullptr;
1700*9880d681SAndroid Build Coastguard Worker   }
1701*9880d681SAndroid Build Coastguard Worker 
1702*9880d681SAndroid Build Coastguard Worker   SMLoc IdLoc = Lex.getLoc();
1703*9880d681SAndroid Build Coastguard Worker   Init *DeclName = StringInit::get(Lex.getCurStrVal());
1704*9880d681SAndroid Build Coastguard Worker   Lex.Lex();
1705*9880d681SAndroid Build Coastguard Worker 
1706*9880d681SAndroid Build Coastguard Worker   if (ParsingTemplateArgs) {
1707*9880d681SAndroid Build Coastguard Worker     if (CurRec)
1708*9880d681SAndroid Build Coastguard Worker       DeclName = QualifyName(*CurRec, CurMultiClass, DeclName, ":");
1709*9880d681SAndroid Build Coastguard Worker     else
1710*9880d681SAndroid Build Coastguard Worker       assert(CurMultiClass);
1711*9880d681SAndroid Build Coastguard Worker     if (CurMultiClass)
1712*9880d681SAndroid Build Coastguard Worker       DeclName = QualifyName(CurMultiClass->Rec, CurMultiClass, DeclName,
1713*9880d681SAndroid Build Coastguard Worker                              "::");
1714*9880d681SAndroid Build Coastguard Worker   }
1715*9880d681SAndroid Build Coastguard Worker 
1716*9880d681SAndroid Build Coastguard Worker   // Add the value.
1717*9880d681SAndroid Build Coastguard Worker   if (AddValue(CurRec, IdLoc, RecordVal(DeclName, Type, HasField)))
1718*9880d681SAndroid Build Coastguard Worker     return nullptr;
1719*9880d681SAndroid Build Coastguard Worker 
1720*9880d681SAndroid Build Coastguard Worker   // If a value is present, parse it.
1721*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() == tgtok::equal) {
1722*9880d681SAndroid Build Coastguard Worker     Lex.Lex();
1723*9880d681SAndroid Build Coastguard Worker     SMLoc ValLoc = Lex.getLoc();
1724*9880d681SAndroid Build Coastguard Worker     Init *Val = ParseValue(CurRec, Type);
1725*9880d681SAndroid Build Coastguard Worker     if (!Val ||
1726*9880d681SAndroid Build Coastguard Worker         SetValue(CurRec, ValLoc, DeclName, None, Val))
1727*9880d681SAndroid Build Coastguard Worker       // Return the name, even if an error is thrown.  This is so that we can
1728*9880d681SAndroid Build Coastguard Worker       // continue to make some progress, even without the value having been
1729*9880d681SAndroid Build Coastguard Worker       // initialized.
1730*9880d681SAndroid Build Coastguard Worker       return DeclName;
1731*9880d681SAndroid Build Coastguard Worker   }
1732*9880d681SAndroid Build Coastguard Worker 
1733*9880d681SAndroid Build Coastguard Worker   return DeclName;
1734*9880d681SAndroid Build Coastguard Worker }
1735*9880d681SAndroid Build Coastguard Worker 
1736*9880d681SAndroid Build Coastguard Worker /// ParseForeachDeclaration - Read a foreach declaration, returning
1737*9880d681SAndroid Build Coastguard Worker /// the name of the declared object or a NULL Init on error.  Return
1738*9880d681SAndroid Build Coastguard Worker /// the name of the parsed initializer list through ForeachListName.
1739*9880d681SAndroid Build Coastguard Worker ///
1740*9880d681SAndroid Build Coastguard Worker ///  ForeachDeclaration ::= ID '=' '[' ValueList ']'
1741*9880d681SAndroid Build Coastguard Worker ///  ForeachDeclaration ::= ID '=' '{' RangeList '}'
1742*9880d681SAndroid Build Coastguard Worker ///  ForeachDeclaration ::= ID '=' RangePiece
1743*9880d681SAndroid Build Coastguard Worker ///
ParseForeachDeclaration(ListInit * & ForeachListValue)1744*9880d681SAndroid Build Coastguard Worker VarInit *TGParser::ParseForeachDeclaration(ListInit *&ForeachListValue) {
1745*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::Id) {
1746*9880d681SAndroid Build Coastguard Worker     TokError("Expected identifier in foreach declaration");
1747*9880d681SAndroid Build Coastguard Worker     return nullptr;
1748*9880d681SAndroid Build Coastguard Worker   }
1749*9880d681SAndroid Build Coastguard Worker 
1750*9880d681SAndroid Build Coastguard Worker   Init *DeclName = StringInit::get(Lex.getCurStrVal());
1751*9880d681SAndroid Build Coastguard Worker   Lex.Lex();
1752*9880d681SAndroid Build Coastguard Worker 
1753*9880d681SAndroid Build Coastguard Worker   // If a value is present, parse it.
1754*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::equal) {
1755*9880d681SAndroid Build Coastguard Worker     TokError("Expected '=' in foreach declaration");
1756*9880d681SAndroid Build Coastguard Worker     return nullptr;
1757*9880d681SAndroid Build Coastguard Worker   }
1758*9880d681SAndroid Build Coastguard Worker   Lex.Lex();  // Eat the '='
1759*9880d681SAndroid Build Coastguard Worker 
1760*9880d681SAndroid Build Coastguard Worker   RecTy *IterType = nullptr;
1761*9880d681SAndroid Build Coastguard Worker   std::vector<unsigned> Ranges;
1762*9880d681SAndroid Build Coastguard Worker 
1763*9880d681SAndroid Build Coastguard Worker   switch (Lex.getCode()) {
1764*9880d681SAndroid Build Coastguard Worker   default: TokError("Unknown token when expecting a range list"); return nullptr;
1765*9880d681SAndroid Build Coastguard Worker   case tgtok::l_square: { // '[' ValueList ']'
1766*9880d681SAndroid Build Coastguard Worker     Init *List = ParseSimpleValue(nullptr, nullptr, ParseForeachMode);
1767*9880d681SAndroid Build Coastguard Worker     ForeachListValue = dyn_cast<ListInit>(List);
1768*9880d681SAndroid Build Coastguard Worker     if (!ForeachListValue) {
1769*9880d681SAndroid Build Coastguard Worker       TokError("Expected a Value list");
1770*9880d681SAndroid Build Coastguard Worker       return nullptr;
1771*9880d681SAndroid Build Coastguard Worker     }
1772*9880d681SAndroid Build Coastguard Worker     RecTy *ValueType = ForeachListValue->getType();
1773*9880d681SAndroid Build Coastguard Worker     ListRecTy *ListType = dyn_cast<ListRecTy>(ValueType);
1774*9880d681SAndroid Build Coastguard Worker     if (!ListType) {
1775*9880d681SAndroid Build Coastguard Worker       TokError("Value list is not of list type");
1776*9880d681SAndroid Build Coastguard Worker       return nullptr;
1777*9880d681SAndroid Build Coastguard Worker     }
1778*9880d681SAndroid Build Coastguard Worker     IterType = ListType->getElementType();
1779*9880d681SAndroid Build Coastguard Worker     break;
1780*9880d681SAndroid Build Coastguard Worker   }
1781*9880d681SAndroid Build Coastguard Worker 
1782*9880d681SAndroid Build Coastguard Worker   case tgtok::IntVal: { // RangePiece.
1783*9880d681SAndroid Build Coastguard Worker     if (ParseRangePiece(Ranges))
1784*9880d681SAndroid Build Coastguard Worker       return nullptr;
1785*9880d681SAndroid Build Coastguard Worker     break;
1786*9880d681SAndroid Build Coastguard Worker   }
1787*9880d681SAndroid Build Coastguard Worker 
1788*9880d681SAndroid Build Coastguard Worker   case tgtok::l_brace: { // '{' RangeList '}'
1789*9880d681SAndroid Build Coastguard Worker     Lex.Lex(); // eat the '{'
1790*9880d681SAndroid Build Coastguard Worker     Ranges = ParseRangeList();
1791*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::r_brace) {
1792*9880d681SAndroid Build Coastguard Worker       TokError("expected '}' at end of bit range list");
1793*9880d681SAndroid Build Coastguard Worker       return nullptr;
1794*9880d681SAndroid Build Coastguard Worker     }
1795*9880d681SAndroid Build Coastguard Worker     Lex.Lex();
1796*9880d681SAndroid Build Coastguard Worker     break;
1797*9880d681SAndroid Build Coastguard Worker   }
1798*9880d681SAndroid Build Coastguard Worker   }
1799*9880d681SAndroid Build Coastguard Worker 
1800*9880d681SAndroid Build Coastguard Worker   if (!Ranges.empty()) {
1801*9880d681SAndroid Build Coastguard Worker     assert(!IterType && "Type already initialized?");
1802*9880d681SAndroid Build Coastguard Worker     IterType = IntRecTy::get();
1803*9880d681SAndroid Build Coastguard Worker     std::vector<Init*> Values;
1804*9880d681SAndroid Build Coastguard Worker     for (unsigned R : Ranges)
1805*9880d681SAndroid Build Coastguard Worker       Values.push_back(IntInit::get(R));
1806*9880d681SAndroid Build Coastguard Worker     ForeachListValue = ListInit::get(Values, IterType);
1807*9880d681SAndroid Build Coastguard Worker   }
1808*9880d681SAndroid Build Coastguard Worker 
1809*9880d681SAndroid Build Coastguard Worker   if (!IterType)
1810*9880d681SAndroid Build Coastguard Worker     return nullptr;
1811*9880d681SAndroid Build Coastguard Worker 
1812*9880d681SAndroid Build Coastguard Worker   return VarInit::get(DeclName, IterType);
1813*9880d681SAndroid Build Coastguard Worker }
1814*9880d681SAndroid Build Coastguard Worker 
1815*9880d681SAndroid Build Coastguard Worker /// ParseTemplateArgList - Read a template argument list, which is a non-empty
1816*9880d681SAndroid Build Coastguard Worker /// sequence of template-declarations in <>'s.  If CurRec is non-null, these are
1817*9880d681SAndroid Build Coastguard Worker /// template args for a def, which may or may not be in a multiclass.  If null,
1818*9880d681SAndroid Build Coastguard Worker /// these are the template args for a multiclass.
1819*9880d681SAndroid Build Coastguard Worker ///
1820*9880d681SAndroid Build Coastguard Worker ///    TemplateArgList ::= '<' Declaration (',' Declaration)* '>'
1821*9880d681SAndroid Build Coastguard Worker ///
ParseTemplateArgList(Record * CurRec)1822*9880d681SAndroid Build Coastguard Worker bool TGParser::ParseTemplateArgList(Record *CurRec) {
1823*9880d681SAndroid Build Coastguard Worker   assert(Lex.getCode() == tgtok::less && "Not a template arg list!");
1824*9880d681SAndroid Build Coastguard Worker   Lex.Lex(); // eat the '<'
1825*9880d681SAndroid Build Coastguard Worker 
1826*9880d681SAndroid Build Coastguard Worker   Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->Rec;
1827*9880d681SAndroid Build Coastguard Worker 
1828*9880d681SAndroid Build Coastguard Worker   // Read the first declaration.
1829*9880d681SAndroid Build Coastguard Worker   Init *TemplArg = ParseDeclaration(CurRec, true/*templateargs*/);
1830*9880d681SAndroid Build Coastguard Worker   if (!TemplArg)
1831*9880d681SAndroid Build Coastguard Worker     return true;
1832*9880d681SAndroid Build Coastguard Worker 
1833*9880d681SAndroid Build Coastguard Worker   TheRecToAddTo->addTemplateArg(TemplArg);
1834*9880d681SAndroid Build Coastguard Worker 
1835*9880d681SAndroid Build Coastguard Worker   while (Lex.getCode() == tgtok::comma) {
1836*9880d681SAndroid Build Coastguard Worker     Lex.Lex(); // eat the ','
1837*9880d681SAndroid Build Coastguard Worker 
1838*9880d681SAndroid Build Coastguard Worker     // Read the following declarations.
1839*9880d681SAndroid Build Coastguard Worker     TemplArg = ParseDeclaration(CurRec, true/*templateargs*/);
1840*9880d681SAndroid Build Coastguard Worker     if (!TemplArg)
1841*9880d681SAndroid Build Coastguard Worker       return true;
1842*9880d681SAndroid Build Coastguard Worker     TheRecToAddTo->addTemplateArg(TemplArg);
1843*9880d681SAndroid Build Coastguard Worker   }
1844*9880d681SAndroid Build Coastguard Worker 
1845*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::greater)
1846*9880d681SAndroid Build Coastguard Worker     return TokError("expected '>' at end of template argument list");
1847*9880d681SAndroid Build Coastguard Worker   Lex.Lex(); // eat the '>'.
1848*9880d681SAndroid Build Coastguard Worker   return false;
1849*9880d681SAndroid Build Coastguard Worker }
1850*9880d681SAndroid Build Coastguard Worker 
1851*9880d681SAndroid Build Coastguard Worker 
1852*9880d681SAndroid Build Coastguard Worker /// ParseBodyItem - Parse a single item at within the body of a def or class.
1853*9880d681SAndroid Build Coastguard Worker ///
1854*9880d681SAndroid Build Coastguard Worker ///   BodyItem ::= Declaration ';'
1855*9880d681SAndroid Build Coastguard Worker ///   BodyItem ::= LET ID OptionalBitList '=' Value ';'
ParseBodyItem(Record * CurRec)1856*9880d681SAndroid Build Coastguard Worker bool TGParser::ParseBodyItem(Record *CurRec) {
1857*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::Let) {
1858*9880d681SAndroid Build Coastguard Worker     if (!ParseDeclaration(CurRec, false))
1859*9880d681SAndroid Build Coastguard Worker       return true;
1860*9880d681SAndroid Build Coastguard Worker 
1861*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::semi)
1862*9880d681SAndroid Build Coastguard Worker       return TokError("expected ';' after declaration");
1863*9880d681SAndroid Build Coastguard Worker     Lex.Lex();
1864*9880d681SAndroid Build Coastguard Worker     return false;
1865*9880d681SAndroid Build Coastguard Worker   }
1866*9880d681SAndroid Build Coastguard Worker 
1867*9880d681SAndroid Build Coastguard Worker   // LET ID OptionalRangeList '=' Value ';'
1868*9880d681SAndroid Build Coastguard Worker   if (Lex.Lex() != tgtok::Id)
1869*9880d681SAndroid Build Coastguard Worker     return TokError("expected field identifier after let");
1870*9880d681SAndroid Build Coastguard Worker 
1871*9880d681SAndroid Build Coastguard Worker   SMLoc IdLoc = Lex.getLoc();
1872*9880d681SAndroid Build Coastguard Worker   std::string FieldName = Lex.getCurStrVal();
1873*9880d681SAndroid Build Coastguard Worker   Lex.Lex();  // eat the field name.
1874*9880d681SAndroid Build Coastguard Worker 
1875*9880d681SAndroid Build Coastguard Worker   std::vector<unsigned> BitList;
1876*9880d681SAndroid Build Coastguard Worker   if (ParseOptionalBitList(BitList))
1877*9880d681SAndroid Build Coastguard Worker     return true;
1878*9880d681SAndroid Build Coastguard Worker   std::reverse(BitList.begin(), BitList.end());
1879*9880d681SAndroid Build Coastguard Worker 
1880*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::equal)
1881*9880d681SAndroid Build Coastguard Worker     return TokError("expected '=' in let expression");
1882*9880d681SAndroid Build Coastguard Worker   Lex.Lex();  // eat the '='.
1883*9880d681SAndroid Build Coastguard Worker 
1884*9880d681SAndroid Build Coastguard Worker   RecordVal *Field = CurRec->getValue(FieldName);
1885*9880d681SAndroid Build Coastguard Worker   if (!Field)
1886*9880d681SAndroid Build Coastguard Worker     return TokError("Value '" + FieldName + "' unknown!");
1887*9880d681SAndroid Build Coastguard Worker 
1888*9880d681SAndroid Build Coastguard Worker   RecTy *Type = Field->getType();
1889*9880d681SAndroid Build Coastguard Worker 
1890*9880d681SAndroid Build Coastguard Worker   Init *Val = ParseValue(CurRec, Type);
1891*9880d681SAndroid Build Coastguard Worker   if (!Val) return true;
1892*9880d681SAndroid Build Coastguard Worker 
1893*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::semi)
1894*9880d681SAndroid Build Coastguard Worker     return TokError("expected ';' after let expression");
1895*9880d681SAndroid Build Coastguard Worker   Lex.Lex();
1896*9880d681SAndroid Build Coastguard Worker 
1897*9880d681SAndroid Build Coastguard Worker   return SetValue(CurRec, IdLoc, FieldName, BitList, Val);
1898*9880d681SAndroid Build Coastguard Worker }
1899*9880d681SAndroid Build Coastguard Worker 
1900*9880d681SAndroid Build Coastguard Worker /// ParseBody - Read the body of a class or def.  Return true on error, false on
1901*9880d681SAndroid Build Coastguard Worker /// success.
1902*9880d681SAndroid Build Coastguard Worker ///
1903*9880d681SAndroid Build Coastguard Worker ///   Body     ::= ';'
1904*9880d681SAndroid Build Coastguard Worker ///   Body     ::= '{' BodyList '}'
1905*9880d681SAndroid Build Coastguard Worker ///   BodyList BodyItem*
1906*9880d681SAndroid Build Coastguard Worker ///
ParseBody(Record * CurRec)1907*9880d681SAndroid Build Coastguard Worker bool TGParser::ParseBody(Record *CurRec) {
1908*9880d681SAndroid Build Coastguard Worker   // If this is a null definition, just eat the semi and return.
1909*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() == tgtok::semi) {
1910*9880d681SAndroid Build Coastguard Worker     Lex.Lex();
1911*9880d681SAndroid Build Coastguard Worker     return false;
1912*9880d681SAndroid Build Coastguard Worker   }
1913*9880d681SAndroid Build Coastguard Worker 
1914*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::l_brace)
1915*9880d681SAndroid Build Coastguard Worker     return TokError("Expected ';' or '{' to start body");
1916*9880d681SAndroid Build Coastguard Worker   // Eat the '{'.
1917*9880d681SAndroid Build Coastguard Worker   Lex.Lex();
1918*9880d681SAndroid Build Coastguard Worker 
1919*9880d681SAndroid Build Coastguard Worker   while (Lex.getCode() != tgtok::r_brace)
1920*9880d681SAndroid Build Coastguard Worker     if (ParseBodyItem(CurRec))
1921*9880d681SAndroid Build Coastguard Worker       return true;
1922*9880d681SAndroid Build Coastguard Worker 
1923*9880d681SAndroid Build Coastguard Worker   // Eat the '}'.
1924*9880d681SAndroid Build Coastguard Worker   Lex.Lex();
1925*9880d681SAndroid Build Coastguard Worker   return false;
1926*9880d681SAndroid Build Coastguard Worker }
1927*9880d681SAndroid Build Coastguard Worker 
1928*9880d681SAndroid Build Coastguard Worker /// \brief Apply the current let bindings to \a CurRec.
1929*9880d681SAndroid Build Coastguard Worker /// \returns true on error, false otherwise.
ApplyLetStack(Record * CurRec)1930*9880d681SAndroid Build Coastguard Worker bool TGParser::ApplyLetStack(Record *CurRec) {
1931*9880d681SAndroid Build Coastguard Worker   for (std::vector<LetRecord> &LetInfo : LetStack)
1932*9880d681SAndroid Build Coastguard Worker     for (LetRecord &LR : LetInfo)
1933*9880d681SAndroid Build Coastguard Worker       if (SetValue(CurRec, LR.Loc, LR.Name, LR.Bits, LR.Value))
1934*9880d681SAndroid Build Coastguard Worker         return true;
1935*9880d681SAndroid Build Coastguard Worker   return false;
1936*9880d681SAndroid Build Coastguard Worker }
1937*9880d681SAndroid Build Coastguard Worker 
1938*9880d681SAndroid Build Coastguard Worker /// ParseObjectBody - Parse the body of a def or class.  This consists of an
1939*9880d681SAndroid Build Coastguard Worker /// optional ClassList followed by a Body.  CurRec is the current def or class
1940*9880d681SAndroid Build Coastguard Worker /// that is being parsed.
1941*9880d681SAndroid Build Coastguard Worker ///
1942*9880d681SAndroid Build Coastguard Worker ///   ObjectBody      ::= BaseClassList Body
1943*9880d681SAndroid Build Coastguard Worker ///   BaseClassList   ::= /*empty*/
1944*9880d681SAndroid Build Coastguard Worker ///   BaseClassList   ::= ':' BaseClassListNE
1945*9880d681SAndroid Build Coastguard Worker ///   BaseClassListNE ::= SubClassRef (',' SubClassRef)*
1946*9880d681SAndroid Build Coastguard Worker ///
ParseObjectBody(Record * CurRec)1947*9880d681SAndroid Build Coastguard Worker bool TGParser::ParseObjectBody(Record *CurRec) {
1948*9880d681SAndroid Build Coastguard Worker   // If there is a baseclass list, read it.
1949*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() == tgtok::colon) {
1950*9880d681SAndroid Build Coastguard Worker     Lex.Lex();
1951*9880d681SAndroid Build Coastguard Worker 
1952*9880d681SAndroid Build Coastguard Worker     // Read all of the subclasses.
1953*9880d681SAndroid Build Coastguard Worker     SubClassReference SubClass = ParseSubClassReference(CurRec, false);
1954*9880d681SAndroid Build Coastguard Worker     while (1) {
1955*9880d681SAndroid Build Coastguard Worker       // Check for error.
1956*9880d681SAndroid Build Coastguard Worker       if (!SubClass.Rec) return true;
1957*9880d681SAndroid Build Coastguard Worker 
1958*9880d681SAndroid Build Coastguard Worker       // Add it.
1959*9880d681SAndroid Build Coastguard Worker       if (AddSubClass(CurRec, SubClass))
1960*9880d681SAndroid Build Coastguard Worker         return true;
1961*9880d681SAndroid Build Coastguard Worker 
1962*9880d681SAndroid Build Coastguard Worker       if (Lex.getCode() != tgtok::comma) break;
1963*9880d681SAndroid Build Coastguard Worker       Lex.Lex(); // eat ','.
1964*9880d681SAndroid Build Coastguard Worker       SubClass = ParseSubClassReference(CurRec, false);
1965*9880d681SAndroid Build Coastguard Worker     }
1966*9880d681SAndroid Build Coastguard Worker   }
1967*9880d681SAndroid Build Coastguard Worker 
1968*9880d681SAndroid Build Coastguard Worker   if (ApplyLetStack(CurRec))
1969*9880d681SAndroid Build Coastguard Worker     return true;
1970*9880d681SAndroid Build Coastguard Worker 
1971*9880d681SAndroid Build Coastguard Worker   return ParseBody(CurRec);
1972*9880d681SAndroid Build Coastguard Worker }
1973*9880d681SAndroid Build Coastguard Worker 
1974*9880d681SAndroid Build Coastguard Worker /// ParseDef - Parse and return a top level or multiclass def, return the record
1975*9880d681SAndroid Build Coastguard Worker /// corresponding to it.  This returns null on error.
1976*9880d681SAndroid Build Coastguard Worker ///
1977*9880d681SAndroid Build Coastguard Worker ///   DefInst ::= DEF ObjectName ObjectBody
1978*9880d681SAndroid Build Coastguard Worker ///
ParseDef(MultiClass * CurMultiClass)1979*9880d681SAndroid Build Coastguard Worker bool TGParser::ParseDef(MultiClass *CurMultiClass) {
1980*9880d681SAndroid Build Coastguard Worker   SMLoc DefLoc = Lex.getLoc();
1981*9880d681SAndroid Build Coastguard Worker   assert(Lex.getCode() == tgtok::Def && "Unknown tok");
1982*9880d681SAndroid Build Coastguard Worker   Lex.Lex();  // Eat the 'def' token.
1983*9880d681SAndroid Build Coastguard Worker 
1984*9880d681SAndroid Build Coastguard Worker   // Parse ObjectName and make a record for it.
1985*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<Record> CurRecOwner;
1986*9880d681SAndroid Build Coastguard Worker   Init *Name = ParseObjectName(CurMultiClass);
1987*9880d681SAndroid Build Coastguard Worker   if (Name)
1988*9880d681SAndroid Build Coastguard Worker     CurRecOwner = make_unique<Record>(Name, DefLoc, Records);
1989*9880d681SAndroid Build Coastguard Worker   else
1990*9880d681SAndroid Build Coastguard Worker     CurRecOwner = llvm::make_unique<Record>(GetNewAnonymousName(), DefLoc,
1991*9880d681SAndroid Build Coastguard Worker                                             Records, /*IsAnonymous=*/true);
1992*9880d681SAndroid Build Coastguard Worker   Record *CurRec = CurRecOwner.get(); // Keep a copy since we may release.
1993*9880d681SAndroid Build Coastguard Worker 
1994*9880d681SAndroid Build Coastguard Worker   if (!CurMultiClass && Loops.empty()) {
1995*9880d681SAndroid Build Coastguard Worker     // Top-level def definition.
1996*9880d681SAndroid Build Coastguard Worker 
1997*9880d681SAndroid Build Coastguard Worker     // Ensure redefinition doesn't happen.
1998*9880d681SAndroid Build Coastguard Worker     if (Records.getDef(CurRec->getNameInitAsString()))
1999*9880d681SAndroid Build Coastguard Worker       return Error(DefLoc, "def '" + CurRec->getNameInitAsString()+
2000*9880d681SAndroid Build Coastguard Worker                    "' already defined");
2001*9880d681SAndroid Build Coastguard Worker     Records.addDef(std::move(CurRecOwner));
2002*9880d681SAndroid Build Coastguard Worker 
2003*9880d681SAndroid Build Coastguard Worker     if (ParseObjectBody(CurRec))
2004*9880d681SAndroid Build Coastguard Worker       return true;
2005*9880d681SAndroid Build Coastguard Worker   } else if (CurMultiClass) {
2006*9880d681SAndroid Build Coastguard Worker     // Parse the body before adding this prototype to the DefPrototypes vector.
2007*9880d681SAndroid Build Coastguard Worker     // That way implicit definitions will be added to the DefPrototypes vector
2008*9880d681SAndroid Build Coastguard Worker     // before this object, instantiated prior to defs derived from this object,
2009*9880d681SAndroid Build Coastguard Worker     // and this available for indirect name resolution when defs derived from
2010*9880d681SAndroid Build Coastguard Worker     // this object are instantiated.
2011*9880d681SAndroid Build Coastguard Worker     if (ParseObjectBody(CurRec))
2012*9880d681SAndroid Build Coastguard Worker       return true;
2013*9880d681SAndroid Build Coastguard Worker 
2014*9880d681SAndroid Build Coastguard Worker     // Otherwise, a def inside a multiclass, add it to the multiclass.
2015*9880d681SAndroid Build Coastguard Worker     for (const auto &Proto : CurMultiClass->DefPrototypes)
2016*9880d681SAndroid Build Coastguard Worker       if (Proto->getNameInit() == CurRec->getNameInit())
2017*9880d681SAndroid Build Coastguard Worker         return Error(DefLoc, "def '" + CurRec->getNameInitAsString() +
2018*9880d681SAndroid Build Coastguard Worker                      "' already defined in this multiclass!");
2019*9880d681SAndroid Build Coastguard Worker     CurMultiClass->DefPrototypes.push_back(std::move(CurRecOwner));
2020*9880d681SAndroid Build Coastguard Worker   } else if (ParseObjectBody(CurRec)) {
2021*9880d681SAndroid Build Coastguard Worker     return true;
2022*9880d681SAndroid Build Coastguard Worker   }
2023*9880d681SAndroid Build Coastguard Worker 
2024*9880d681SAndroid Build Coastguard Worker   if (!CurMultiClass)  // Def's in multiclasses aren't really defs.
2025*9880d681SAndroid Build Coastguard Worker     // See Record::setName().  This resolve step will see any new name
2026*9880d681SAndroid Build Coastguard Worker     // for the def that might have been created when resolving
2027*9880d681SAndroid Build Coastguard Worker     // inheritance, values and arguments above.
2028*9880d681SAndroid Build Coastguard Worker     CurRec->resolveReferences();
2029*9880d681SAndroid Build Coastguard Worker 
2030*9880d681SAndroid Build Coastguard Worker   // If ObjectBody has template arguments, it's an error.
2031*9880d681SAndroid Build Coastguard Worker   assert(CurRec->getTemplateArgs().empty() && "How'd this get template args?");
2032*9880d681SAndroid Build Coastguard Worker 
2033*9880d681SAndroid Build Coastguard Worker   if (CurMultiClass) {
2034*9880d681SAndroid Build Coastguard Worker     // Copy the template arguments for the multiclass into the def.
2035*9880d681SAndroid Build Coastguard Worker     for (Init *TArg : CurMultiClass->Rec.getTemplateArgs()) {
2036*9880d681SAndroid Build Coastguard Worker       const RecordVal *RV = CurMultiClass->Rec.getValue(TArg);
2037*9880d681SAndroid Build Coastguard Worker       assert(RV && "Template arg doesn't exist?");
2038*9880d681SAndroid Build Coastguard Worker       CurRec->addValue(*RV);
2039*9880d681SAndroid Build Coastguard Worker     }
2040*9880d681SAndroid Build Coastguard Worker   }
2041*9880d681SAndroid Build Coastguard Worker 
2042*9880d681SAndroid Build Coastguard Worker   if (ProcessForeachDefs(CurRec, DefLoc))
2043*9880d681SAndroid Build Coastguard Worker     return Error(DefLoc, "Could not process loops for def" +
2044*9880d681SAndroid Build Coastguard Worker                  CurRec->getNameInitAsString());
2045*9880d681SAndroid Build Coastguard Worker 
2046*9880d681SAndroid Build Coastguard Worker   return false;
2047*9880d681SAndroid Build Coastguard Worker }
2048*9880d681SAndroid Build Coastguard Worker 
2049*9880d681SAndroid Build Coastguard Worker /// ParseForeach - Parse a for statement.  Return the record corresponding
2050*9880d681SAndroid Build Coastguard Worker /// to it.  This returns true on error.
2051*9880d681SAndroid Build Coastguard Worker ///
2052*9880d681SAndroid Build Coastguard Worker ///   Foreach ::= FOREACH Declaration IN '{ ObjectList '}'
2053*9880d681SAndroid Build Coastguard Worker ///   Foreach ::= FOREACH Declaration IN Object
2054*9880d681SAndroid Build Coastguard Worker ///
ParseForeach(MultiClass * CurMultiClass)2055*9880d681SAndroid Build Coastguard Worker bool TGParser::ParseForeach(MultiClass *CurMultiClass) {
2056*9880d681SAndroid Build Coastguard Worker   assert(Lex.getCode() == tgtok::Foreach && "Unknown tok");
2057*9880d681SAndroid Build Coastguard Worker   Lex.Lex();  // Eat the 'for' token.
2058*9880d681SAndroid Build Coastguard Worker 
2059*9880d681SAndroid Build Coastguard Worker   // Make a temporary object to record items associated with the for
2060*9880d681SAndroid Build Coastguard Worker   // loop.
2061*9880d681SAndroid Build Coastguard Worker   ListInit *ListValue = nullptr;
2062*9880d681SAndroid Build Coastguard Worker   VarInit *IterName = ParseForeachDeclaration(ListValue);
2063*9880d681SAndroid Build Coastguard Worker   if (!IterName)
2064*9880d681SAndroid Build Coastguard Worker     return TokError("expected declaration in for");
2065*9880d681SAndroid Build Coastguard Worker 
2066*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::In)
2067*9880d681SAndroid Build Coastguard Worker     return TokError("Unknown tok");
2068*9880d681SAndroid Build Coastguard Worker   Lex.Lex();  // Eat the in
2069*9880d681SAndroid Build Coastguard Worker 
2070*9880d681SAndroid Build Coastguard Worker   // Create a loop object and remember it.
2071*9880d681SAndroid Build Coastguard Worker   Loops.push_back(ForeachLoop(IterName, ListValue));
2072*9880d681SAndroid Build Coastguard Worker 
2073*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::l_brace) {
2074*9880d681SAndroid Build Coastguard Worker     // FOREACH Declaration IN Object
2075*9880d681SAndroid Build Coastguard Worker     if (ParseObject(CurMultiClass))
2076*9880d681SAndroid Build Coastguard Worker       return true;
2077*9880d681SAndroid Build Coastguard Worker   } else {
2078*9880d681SAndroid Build Coastguard Worker     SMLoc BraceLoc = Lex.getLoc();
2079*9880d681SAndroid Build Coastguard Worker     // Otherwise, this is a group foreach.
2080*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // eat the '{'.
2081*9880d681SAndroid Build Coastguard Worker 
2082*9880d681SAndroid Build Coastguard Worker     // Parse the object list.
2083*9880d681SAndroid Build Coastguard Worker     if (ParseObjectList(CurMultiClass))
2084*9880d681SAndroid Build Coastguard Worker       return true;
2085*9880d681SAndroid Build Coastguard Worker 
2086*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::r_brace) {
2087*9880d681SAndroid Build Coastguard Worker       TokError("expected '}' at end of foreach command");
2088*9880d681SAndroid Build Coastguard Worker       return Error(BraceLoc, "to match this '{'");
2089*9880d681SAndroid Build Coastguard Worker     }
2090*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // Eat the }
2091*9880d681SAndroid Build Coastguard Worker   }
2092*9880d681SAndroid Build Coastguard Worker 
2093*9880d681SAndroid Build Coastguard Worker   // We've processed everything in this loop.
2094*9880d681SAndroid Build Coastguard Worker   Loops.pop_back();
2095*9880d681SAndroid Build Coastguard Worker 
2096*9880d681SAndroid Build Coastguard Worker   return false;
2097*9880d681SAndroid Build Coastguard Worker }
2098*9880d681SAndroid Build Coastguard Worker 
2099*9880d681SAndroid Build Coastguard Worker /// ParseClass - Parse a tblgen class definition.
2100*9880d681SAndroid Build Coastguard Worker ///
2101*9880d681SAndroid Build Coastguard Worker ///   ClassInst ::= CLASS ID TemplateArgList? ObjectBody
2102*9880d681SAndroid Build Coastguard Worker ///
ParseClass()2103*9880d681SAndroid Build Coastguard Worker bool TGParser::ParseClass() {
2104*9880d681SAndroid Build Coastguard Worker   assert(Lex.getCode() == tgtok::Class && "Unexpected token!");
2105*9880d681SAndroid Build Coastguard Worker   Lex.Lex();
2106*9880d681SAndroid Build Coastguard Worker 
2107*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::Id)
2108*9880d681SAndroid Build Coastguard Worker     return TokError("expected class name after 'class' keyword");
2109*9880d681SAndroid Build Coastguard Worker 
2110*9880d681SAndroid Build Coastguard Worker   Record *CurRec = Records.getClass(Lex.getCurStrVal());
2111*9880d681SAndroid Build Coastguard Worker   if (CurRec) {
2112*9880d681SAndroid Build Coastguard Worker     // If the body was previously defined, this is an error.
2113*9880d681SAndroid Build Coastguard Worker     if (CurRec->getValues().size() > 1 ||  // Account for NAME.
2114*9880d681SAndroid Build Coastguard Worker         !CurRec->getSuperClasses().empty() ||
2115*9880d681SAndroid Build Coastguard Worker         !CurRec->getTemplateArgs().empty())
2116*9880d681SAndroid Build Coastguard Worker       return TokError("Class '" + CurRec->getNameInitAsString() +
2117*9880d681SAndroid Build Coastguard Worker                       "' already defined");
2118*9880d681SAndroid Build Coastguard Worker   } else {
2119*9880d681SAndroid Build Coastguard Worker     // If this is the first reference to this class, create and add it.
2120*9880d681SAndroid Build Coastguard Worker     auto NewRec =
2121*9880d681SAndroid Build Coastguard Worker         llvm::make_unique<Record>(Lex.getCurStrVal(), Lex.getLoc(), Records);
2122*9880d681SAndroid Build Coastguard Worker     CurRec = NewRec.get();
2123*9880d681SAndroid Build Coastguard Worker     Records.addClass(std::move(NewRec));
2124*9880d681SAndroid Build Coastguard Worker   }
2125*9880d681SAndroid Build Coastguard Worker   Lex.Lex(); // eat the name.
2126*9880d681SAndroid Build Coastguard Worker 
2127*9880d681SAndroid Build Coastguard Worker   // If there are template args, parse them.
2128*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() == tgtok::less)
2129*9880d681SAndroid Build Coastguard Worker     if (ParseTemplateArgList(CurRec))
2130*9880d681SAndroid Build Coastguard Worker       return true;
2131*9880d681SAndroid Build Coastguard Worker 
2132*9880d681SAndroid Build Coastguard Worker   // Finally, parse the object body.
2133*9880d681SAndroid Build Coastguard Worker   return ParseObjectBody(CurRec);
2134*9880d681SAndroid Build Coastguard Worker }
2135*9880d681SAndroid Build Coastguard Worker 
2136*9880d681SAndroid Build Coastguard Worker /// ParseLetList - Parse a non-empty list of assignment expressions into a list
2137*9880d681SAndroid Build Coastguard Worker /// of LetRecords.
2138*9880d681SAndroid Build Coastguard Worker ///
2139*9880d681SAndroid Build Coastguard Worker ///   LetList ::= LetItem (',' LetItem)*
2140*9880d681SAndroid Build Coastguard Worker ///   LetItem ::= ID OptionalRangeList '=' Value
2141*9880d681SAndroid Build Coastguard Worker ///
ParseLetList()2142*9880d681SAndroid Build Coastguard Worker std::vector<LetRecord> TGParser::ParseLetList() {
2143*9880d681SAndroid Build Coastguard Worker   std::vector<LetRecord> Result;
2144*9880d681SAndroid Build Coastguard Worker 
2145*9880d681SAndroid Build Coastguard Worker   while (1) {
2146*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::Id) {
2147*9880d681SAndroid Build Coastguard Worker       TokError("expected identifier in let definition");
2148*9880d681SAndroid Build Coastguard Worker       return std::vector<LetRecord>();
2149*9880d681SAndroid Build Coastguard Worker     }
2150*9880d681SAndroid Build Coastguard Worker     std::string Name = Lex.getCurStrVal();
2151*9880d681SAndroid Build Coastguard Worker     SMLoc NameLoc = Lex.getLoc();
2152*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // Eat the identifier.
2153*9880d681SAndroid Build Coastguard Worker 
2154*9880d681SAndroid Build Coastguard Worker     // Check for an optional RangeList.
2155*9880d681SAndroid Build Coastguard Worker     std::vector<unsigned> Bits;
2156*9880d681SAndroid Build Coastguard Worker     if (ParseOptionalRangeList(Bits))
2157*9880d681SAndroid Build Coastguard Worker       return std::vector<LetRecord>();
2158*9880d681SAndroid Build Coastguard Worker     std::reverse(Bits.begin(), Bits.end());
2159*9880d681SAndroid Build Coastguard Worker 
2160*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::equal) {
2161*9880d681SAndroid Build Coastguard Worker       TokError("expected '=' in let expression");
2162*9880d681SAndroid Build Coastguard Worker       return std::vector<LetRecord>();
2163*9880d681SAndroid Build Coastguard Worker     }
2164*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // eat the '='.
2165*9880d681SAndroid Build Coastguard Worker 
2166*9880d681SAndroid Build Coastguard Worker     Init *Val = ParseValue(nullptr);
2167*9880d681SAndroid Build Coastguard Worker     if (!Val) return std::vector<LetRecord>();
2168*9880d681SAndroid Build Coastguard Worker 
2169*9880d681SAndroid Build Coastguard Worker     // Now that we have everything, add the record.
2170*9880d681SAndroid Build Coastguard Worker     Result.emplace_back(std::move(Name), std::move(Bits), Val, NameLoc);
2171*9880d681SAndroid Build Coastguard Worker 
2172*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::comma)
2173*9880d681SAndroid Build Coastguard Worker       return Result;
2174*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // eat the comma.
2175*9880d681SAndroid Build Coastguard Worker   }
2176*9880d681SAndroid Build Coastguard Worker }
2177*9880d681SAndroid Build Coastguard Worker 
2178*9880d681SAndroid Build Coastguard Worker /// ParseTopLevelLet - Parse a 'let' at top level.  This can be a couple of
2179*9880d681SAndroid Build Coastguard Worker /// different related productions. This works inside multiclasses too.
2180*9880d681SAndroid Build Coastguard Worker ///
2181*9880d681SAndroid Build Coastguard Worker ///   Object ::= LET LetList IN '{' ObjectList '}'
2182*9880d681SAndroid Build Coastguard Worker ///   Object ::= LET LetList IN Object
2183*9880d681SAndroid Build Coastguard Worker ///
ParseTopLevelLet(MultiClass * CurMultiClass)2184*9880d681SAndroid Build Coastguard Worker bool TGParser::ParseTopLevelLet(MultiClass *CurMultiClass) {
2185*9880d681SAndroid Build Coastguard Worker   assert(Lex.getCode() == tgtok::Let && "Unexpected token");
2186*9880d681SAndroid Build Coastguard Worker   Lex.Lex();
2187*9880d681SAndroid Build Coastguard Worker 
2188*9880d681SAndroid Build Coastguard Worker   // Add this entry to the let stack.
2189*9880d681SAndroid Build Coastguard Worker   std::vector<LetRecord> LetInfo = ParseLetList();
2190*9880d681SAndroid Build Coastguard Worker   if (LetInfo.empty()) return true;
2191*9880d681SAndroid Build Coastguard Worker   LetStack.push_back(std::move(LetInfo));
2192*9880d681SAndroid Build Coastguard Worker 
2193*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::In)
2194*9880d681SAndroid Build Coastguard Worker     return TokError("expected 'in' at end of top-level 'let'");
2195*9880d681SAndroid Build Coastguard Worker   Lex.Lex();
2196*9880d681SAndroid Build Coastguard Worker 
2197*9880d681SAndroid Build Coastguard Worker   // If this is a scalar let, just handle it now
2198*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::l_brace) {
2199*9880d681SAndroid Build Coastguard Worker     // LET LetList IN Object
2200*9880d681SAndroid Build Coastguard Worker     if (ParseObject(CurMultiClass))
2201*9880d681SAndroid Build Coastguard Worker       return true;
2202*9880d681SAndroid Build Coastguard Worker   } else {   // Object ::= LETCommand '{' ObjectList '}'
2203*9880d681SAndroid Build Coastguard Worker     SMLoc BraceLoc = Lex.getLoc();
2204*9880d681SAndroid Build Coastguard Worker     // Otherwise, this is a group let.
2205*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // eat the '{'.
2206*9880d681SAndroid Build Coastguard Worker 
2207*9880d681SAndroid Build Coastguard Worker     // Parse the object list.
2208*9880d681SAndroid Build Coastguard Worker     if (ParseObjectList(CurMultiClass))
2209*9880d681SAndroid Build Coastguard Worker       return true;
2210*9880d681SAndroid Build Coastguard Worker 
2211*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::r_brace) {
2212*9880d681SAndroid Build Coastguard Worker       TokError("expected '}' at end of top level let command");
2213*9880d681SAndroid Build Coastguard Worker       return Error(BraceLoc, "to match this '{'");
2214*9880d681SAndroid Build Coastguard Worker     }
2215*9880d681SAndroid Build Coastguard Worker     Lex.Lex();
2216*9880d681SAndroid Build Coastguard Worker   }
2217*9880d681SAndroid Build Coastguard Worker 
2218*9880d681SAndroid Build Coastguard Worker   // Outside this let scope, this let block is not active.
2219*9880d681SAndroid Build Coastguard Worker   LetStack.pop_back();
2220*9880d681SAndroid Build Coastguard Worker   return false;
2221*9880d681SAndroid Build Coastguard Worker }
2222*9880d681SAndroid Build Coastguard Worker 
2223*9880d681SAndroid Build Coastguard Worker /// ParseMultiClass - Parse a multiclass definition.
2224*9880d681SAndroid Build Coastguard Worker ///
2225*9880d681SAndroid Build Coastguard Worker ///  MultiClassInst ::= MULTICLASS ID TemplateArgList?
2226*9880d681SAndroid Build Coastguard Worker ///                     ':' BaseMultiClassList '{' MultiClassObject+ '}'
2227*9880d681SAndroid Build Coastguard Worker ///  MultiClassObject ::= DefInst
2228*9880d681SAndroid Build Coastguard Worker ///  MultiClassObject ::= MultiClassInst
2229*9880d681SAndroid Build Coastguard Worker ///  MultiClassObject ::= DefMInst
2230*9880d681SAndroid Build Coastguard Worker ///  MultiClassObject ::= LETCommand '{' ObjectList '}'
2231*9880d681SAndroid Build Coastguard Worker ///  MultiClassObject ::= LETCommand Object
2232*9880d681SAndroid Build Coastguard Worker ///
ParseMultiClass()2233*9880d681SAndroid Build Coastguard Worker bool TGParser::ParseMultiClass() {
2234*9880d681SAndroid Build Coastguard Worker   assert(Lex.getCode() == tgtok::MultiClass && "Unexpected token");
2235*9880d681SAndroid Build Coastguard Worker   Lex.Lex();  // Eat the multiclass token.
2236*9880d681SAndroid Build Coastguard Worker 
2237*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::Id)
2238*9880d681SAndroid Build Coastguard Worker     return TokError("expected identifier after multiclass for name");
2239*9880d681SAndroid Build Coastguard Worker   std::string Name = Lex.getCurStrVal();
2240*9880d681SAndroid Build Coastguard Worker 
2241*9880d681SAndroid Build Coastguard Worker   auto Result =
2242*9880d681SAndroid Build Coastguard Worker     MultiClasses.insert(std::make_pair(Name,
2243*9880d681SAndroid Build Coastguard Worker                     llvm::make_unique<MultiClass>(Name, Lex.getLoc(),Records)));
2244*9880d681SAndroid Build Coastguard Worker 
2245*9880d681SAndroid Build Coastguard Worker   if (!Result.second)
2246*9880d681SAndroid Build Coastguard Worker     return TokError("multiclass '" + Name + "' already defined");
2247*9880d681SAndroid Build Coastguard Worker 
2248*9880d681SAndroid Build Coastguard Worker   CurMultiClass = Result.first->second.get();
2249*9880d681SAndroid Build Coastguard Worker   Lex.Lex();  // Eat the identifier.
2250*9880d681SAndroid Build Coastguard Worker 
2251*9880d681SAndroid Build Coastguard Worker   // If there are template args, parse them.
2252*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() == tgtok::less)
2253*9880d681SAndroid Build Coastguard Worker     if (ParseTemplateArgList(nullptr))
2254*9880d681SAndroid Build Coastguard Worker       return true;
2255*9880d681SAndroid Build Coastguard Worker 
2256*9880d681SAndroid Build Coastguard Worker   bool inherits = false;
2257*9880d681SAndroid Build Coastguard Worker 
2258*9880d681SAndroid Build Coastguard Worker   // If there are submulticlasses, parse them.
2259*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() == tgtok::colon) {
2260*9880d681SAndroid Build Coastguard Worker     inherits = true;
2261*9880d681SAndroid Build Coastguard Worker 
2262*9880d681SAndroid Build Coastguard Worker     Lex.Lex();
2263*9880d681SAndroid Build Coastguard Worker 
2264*9880d681SAndroid Build Coastguard Worker     // Read all of the submulticlasses.
2265*9880d681SAndroid Build Coastguard Worker     SubMultiClassReference SubMultiClass =
2266*9880d681SAndroid Build Coastguard Worker       ParseSubMultiClassReference(CurMultiClass);
2267*9880d681SAndroid Build Coastguard Worker     while (1) {
2268*9880d681SAndroid Build Coastguard Worker       // Check for error.
2269*9880d681SAndroid Build Coastguard Worker       if (!SubMultiClass.MC) return true;
2270*9880d681SAndroid Build Coastguard Worker 
2271*9880d681SAndroid Build Coastguard Worker       // Add it.
2272*9880d681SAndroid Build Coastguard Worker       if (AddSubMultiClass(CurMultiClass, SubMultiClass))
2273*9880d681SAndroid Build Coastguard Worker         return true;
2274*9880d681SAndroid Build Coastguard Worker 
2275*9880d681SAndroid Build Coastguard Worker       if (Lex.getCode() != tgtok::comma) break;
2276*9880d681SAndroid Build Coastguard Worker       Lex.Lex(); // eat ','.
2277*9880d681SAndroid Build Coastguard Worker       SubMultiClass = ParseSubMultiClassReference(CurMultiClass);
2278*9880d681SAndroid Build Coastguard Worker     }
2279*9880d681SAndroid Build Coastguard Worker   }
2280*9880d681SAndroid Build Coastguard Worker 
2281*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::l_brace) {
2282*9880d681SAndroid Build Coastguard Worker     if (!inherits)
2283*9880d681SAndroid Build Coastguard Worker       return TokError("expected '{' in multiclass definition");
2284*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::semi)
2285*9880d681SAndroid Build Coastguard Worker       return TokError("expected ';' in multiclass definition");
2286*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // eat the ';'.
2287*9880d681SAndroid Build Coastguard Worker   } else {
2288*9880d681SAndroid Build Coastguard Worker     if (Lex.Lex() == tgtok::r_brace)  // eat the '{'.
2289*9880d681SAndroid Build Coastguard Worker       return TokError("multiclass must contain at least one def");
2290*9880d681SAndroid Build Coastguard Worker 
2291*9880d681SAndroid Build Coastguard Worker     while (Lex.getCode() != tgtok::r_brace) {
2292*9880d681SAndroid Build Coastguard Worker       switch (Lex.getCode()) {
2293*9880d681SAndroid Build Coastguard Worker       default:
2294*9880d681SAndroid Build Coastguard Worker         return TokError("expected 'let', 'def' or 'defm' in multiclass body");
2295*9880d681SAndroid Build Coastguard Worker       case tgtok::Let:
2296*9880d681SAndroid Build Coastguard Worker       case tgtok::Def:
2297*9880d681SAndroid Build Coastguard Worker       case tgtok::Defm:
2298*9880d681SAndroid Build Coastguard Worker       case tgtok::Foreach:
2299*9880d681SAndroid Build Coastguard Worker         if (ParseObject(CurMultiClass))
2300*9880d681SAndroid Build Coastguard Worker           return true;
2301*9880d681SAndroid Build Coastguard Worker         break;
2302*9880d681SAndroid Build Coastguard Worker       }
2303*9880d681SAndroid Build Coastguard Worker     }
2304*9880d681SAndroid Build Coastguard Worker     Lex.Lex();  // eat the '}'.
2305*9880d681SAndroid Build Coastguard Worker   }
2306*9880d681SAndroid Build Coastguard Worker 
2307*9880d681SAndroid Build Coastguard Worker   CurMultiClass = nullptr;
2308*9880d681SAndroid Build Coastguard Worker   return false;
2309*9880d681SAndroid Build Coastguard Worker }
2310*9880d681SAndroid Build Coastguard Worker 
InstantiateMulticlassDef(MultiClass & MC,Record * DefProto,Init * & DefmPrefix,SMRange DefmPrefixRange,ArrayRef<Init * > TArgs,std::vector<Init * > & TemplateVals)2311*9880d681SAndroid Build Coastguard Worker Record *TGParser::InstantiateMulticlassDef(MultiClass &MC, Record *DefProto,
2312*9880d681SAndroid Build Coastguard Worker                                            Init *&DefmPrefix,
2313*9880d681SAndroid Build Coastguard Worker                                            SMRange DefmPrefixRange,
2314*9880d681SAndroid Build Coastguard Worker                                            ArrayRef<Init *> TArgs,
2315*9880d681SAndroid Build Coastguard Worker                                            std::vector<Init *> &TemplateVals) {
2316*9880d681SAndroid Build Coastguard Worker   // We need to preserve DefProto so it can be reused for later
2317*9880d681SAndroid Build Coastguard Worker   // instantiations, so create a new Record to inherit from it.
2318*9880d681SAndroid Build Coastguard Worker 
2319*9880d681SAndroid Build Coastguard Worker   // Add in the defm name.  If the defm prefix is empty, give each
2320*9880d681SAndroid Build Coastguard Worker   // instantiated def a unique name.  Otherwise, if "#NAME#" exists in the
2321*9880d681SAndroid Build Coastguard Worker   // name, substitute the prefix for #NAME#.  Otherwise, use the defm name
2322*9880d681SAndroid Build Coastguard Worker   // as a prefix.
2323*9880d681SAndroid Build Coastguard Worker 
2324*9880d681SAndroid Build Coastguard Worker   bool IsAnonymous = false;
2325*9880d681SAndroid Build Coastguard Worker   if (!DefmPrefix) {
2326*9880d681SAndroid Build Coastguard Worker     DefmPrefix = StringInit::get(GetNewAnonymousName());
2327*9880d681SAndroid Build Coastguard Worker     IsAnonymous = true;
2328*9880d681SAndroid Build Coastguard Worker   }
2329*9880d681SAndroid Build Coastguard Worker 
2330*9880d681SAndroid Build Coastguard Worker   Init *DefName = DefProto->getNameInit();
2331*9880d681SAndroid Build Coastguard Worker   StringInit *DefNameString = dyn_cast<StringInit>(DefName);
2332*9880d681SAndroid Build Coastguard Worker 
2333*9880d681SAndroid Build Coastguard Worker   if (DefNameString) {
2334*9880d681SAndroid Build Coastguard Worker     // We have a fully expanded string so there are no operators to
2335*9880d681SAndroid Build Coastguard Worker     // resolve.  We should concatenate the given prefix and name.
2336*9880d681SAndroid Build Coastguard Worker     DefName =
2337*9880d681SAndroid Build Coastguard Worker       BinOpInit::get(BinOpInit::STRCONCAT,
2338*9880d681SAndroid Build Coastguard Worker                      UnOpInit::get(UnOpInit::CAST, DefmPrefix,
2339*9880d681SAndroid Build Coastguard Worker                                    StringRecTy::get())->Fold(DefProto, &MC),
2340*9880d681SAndroid Build Coastguard Worker                      DefName, StringRecTy::get())->Fold(DefProto, &MC);
2341*9880d681SAndroid Build Coastguard Worker   }
2342*9880d681SAndroid Build Coastguard Worker 
2343*9880d681SAndroid Build Coastguard Worker   // Make a trail of SMLocs from the multiclass instantiations.
2344*9880d681SAndroid Build Coastguard Worker   SmallVector<SMLoc, 4> Locs(1, DefmPrefixRange.Start);
2345*9880d681SAndroid Build Coastguard Worker   Locs.append(DefProto->getLoc().begin(), DefProto->getLoc().end());
2346*9880d681SAndroid Build Coastguard Worker   auto CurRec = make_unique<Record>(DefName, Locs, Records, IsAnonymous);
2347*9880d681SAndroid Build Coastguard Worker 
2348*9880d681SAndroid Build Coastguard Worker   SubClassReference Ref;
2349*9880d681SAndroid Build Coastguard Worker   Ref.RefRange = DefmPrefixRange;
2350*9880d681SAndroid Build Coastguard Worker   Ref.Rec = DefProto;
2351*9880d681SAndroid Build Coastguard Worker   AddSubClass(CurRec.get(), Ref);
2352*9880d681SAndroid Build Coastguard Worker 
2353*9880d681SAndroid Build Coastguard Worker   // Set the value for NAME. We don't resolve references to it 'til later,
2354*9880d681SAndroid Build Coastguard Worker   // though, so that uses in nested multiclass names don't get
2355*9880d681SAndroid Build Coastguard Worker   // confused.
2356*9880d681SAndroid Build Coastguard Worker   if (SetValue(CurRec.get(), Ref.RefRange.Start, "NAME", None, DefmPrefix,
2357*9880d681SAndroid Build Coastguard Worker                /*AllowSelfAssignment*/true)) {
2358*9880d681SAndroid Build Coastguard Worker     Error(DefmPrefixRange.Start, "Could not resolve " +
2359*9880d681SAndroid Build Coastguard Worker           CurRec->getNameInitAsString() + ":NAME to '" +
2360*9880d681SAndroid Build Coastguard Worker           DefmPrefix->getAsUnquotedString() + "'");
2361*9880d681SAndroid Build Coastguard Worker     return nullptr;
2362*9880d681SAndroid Build Coastguard Worker   }
2363*9880d681SAndroid Build Coastguard Worker 
2364*9880d681SAndroid Build Coastguard Worker   // If the DefNameString didn't resolve, we probably have a reference to
2365*9880d681SAndroid Build Coastguard Worker   // NAME and need to replace it. We need to do at least this much greedily,
2366*9880d681SAndroid Build Coastguard Worker   // otherwise nested multiclasses will end up with incorrect NAME expansions.
2367*9880d681SAndroid Build Coastguard Worker   if (!DefNameString) {
2368*9880d681SAndroid Build Coastguard Worker     RecordVal *DefNameRV = CurRec->getValue("NAME");
2369*9880d681SAndroid Build Coastguard Worker     CurRec->resolveReferencesTo(DefNameRV);
2370*9880d681SAndroid Build Coastguard Worker   }
2371*9880d681SAndroid Build Coastguard Worker 
2372*9880d681SAndroid Build Coastguard Worker   if (!CurMultiClass) {
2373*9880d681SAndroid Build Coastguard Worker     // Now that we're at the top level, resolve all NAME references
2374*9880d681SAndroid Build Coastguard Worker     // in the resultant defs that weren't in the def names themselves.
2375*9880d681SAndroid Build Coastguard Worker     RecordVal *DefNameRV = CurRec->getValue("NAME");
2376*9880d681SAndroid Build Coastguard Worker     CurRec->resolveReferencesTo(DefNameRV);
2377*9880d681SAndroid Build Coastguard Worker 
2378*9880d681SAndroid Build Coastguard Worker     // Check if the name is a complex pattern.
2379*9880d681SAndroid Build Coastguard Worker     // If so, resolve it.
2380*9880d681SAndroid Build Coastguard Worker     DefName = CurRec->getNameInit();
2381*9880d681SAndroid Build Coastguard Worker     DefNameString = dyn_cast<StringInit>(DefName);
2382*9880d681SAndroid Build Coastguard Worker 
2383*9880d681SAndroid Build Coastguard Worker     // OK the pattern is more complex than simply using NAME.
2384*9880d681SAndroid Build Coastguard Worker     // Let's use the heavy weaponery.
2385*9880d681SAndroid Build Coastguard Worker     if (!DefNameString) {
2386*9880d681SAndroid Build Coastguard Worker       ResolveMulticlassDefArgs(MC, CurRec.get(), DefmPrefixRange.Start,
2387*9880d681SAndroid Build Coastguard Worker                                Lex.getLoc(), TArgs, TemplateVals,
2388*9880d681SAndroid Build Coastguard Worker                                false/*Delete args*/);
2389*9880d681SAndroid Build Coastguard Worker       DefName = CurRec->getNameInit();
2390*9880d681SAndroid Build Coastguard Worker       DefNameString = dyn_cast<StringInit>(DefName);
2391*9880d681SAndroid Build Coastguard Worker 
2392*9880d681SAndroid Build Coastguard Worker       if (!DefNameString)
2393*9880d681SAndroid Build Coastguard Worker         DefName = DefName->convertInitializerTo(StringRecTy::get());
2394*9880d681SAndroid Build Coastguard Worker 
2395*9880d681SAndroid Build Coastguard Worker       // We ran out of options here...
2396*9880d681SAndroid Build Coastguard Worker       DefNameString = dyn_cast<StringInit>(DefName);
2397*9880d681SAndroid Build Coastguard Worker       if (!DefNameString) {
2398*9880d681SAndroid Build Coastguard Worker         PrintFatalError(CurRec->getLoc()[CurRec->getLoc().size() - 1],
2399*9880d681SAndroid Build Coastguard Worker                         DefName->getAsUnquotedString() + " is not a string.");
2400*9880d681SAndroid Build Coastguard Worker         return nullptr;
2401*9880d681SAndroid Build Coastguard Worker       }
2402*9880d681SAndroid Build Coastguard Worker 
2403*9880d681SAndroid Build Coastguard Worker       CurRec->setName(DefName);
2404*9880d681SAndroid Build Coastguard Worker     }
2405*9880d681SAndroid Build Coastguard Worker 
2406*9880d681SAndroid Build Coastguard Worker     // Now that NAME references are resolved and we're at the top level of
2407*9880d681SAndroid Build Coastguard Worker     // any multiclass expansions, add the record to the RecordKeeper. If we are
2408*9880d681SAndroid Build Coastguard Worker     // currently in a multiclass, it means this defm appears inside a
2409*9880d681SAndroid Build Coastguard Worker     // multiclass and its name won't be fully resolvable until we see
2410*9880d681SAndroid Build Coastguard Worker     // the top-level defm. Therefore, we don't add this to the
2411*9880d681SAndroid Build Coastguard Worker     // RecordKeeper at this point. If we did we could get duplicate
2412*9880d681SAndroid Build Coastguard Worker     // defs as more than one probably refers to NAME or some other
2413*9880d681SAndroid Build Coastguard Worker     // common internal placeholder.
2414*9880d681SAndroid Build Coastguard Worker 
2415*9880d681SAndroid Build Coastguard Worker     // Ensure redefinition doesn't happen.
2416*9880d681SAndroid Build Coastguard Worker     if (Records.getDef(CurRec->getNameInitAsString())) {
2417*9880d681SAndroid Build Coastguard Worker       Error(DefmPrefixRange.Start, "def '" + CurRec->getNameInitAsString() +
2418*9880d681SAndroid Build Coastguard Worker             "' already defined, instantiating defm with subdef '" +
2419*9880d681SAndroid Build Coastguard Worker             DefProto->getNameInitAsString() + "'");
2420*9880d681SAndroid Build Coastguard Worker       return nullptr;
2421*9880d681SAndroid Build Coastguard Worker     }
2422*9880d681SAndroid Build Coastguard Worker 
2423*9880d681SAndroid Build Coastguard Worker     Record *CurRecSave = CurRec.get(); // Keep a copy before we release.
2424*9880d681SAndroid Build Coastguard Worker     Records.addDef(std::move(CurRec));
2425*9880d681SAndroid Build Coastguard Worker     return CurRecSave;
2426*9880d681SAndroid Build Coastguard Worker   }
2427*9880d681SAndroid Build Coastguard Worker 
2428*9880d681SAndroid Build Coastguard Worker   // FIXME This is bad but the ownership transfer to caller is pretty messy.
2429*9880d681SAndroid Build Coastguard Worker   // The unique_ptr in this function at least protects the exits above.
2430*9880d681SAndroid Build Coastguard Worker   return CurRec.release();
2431*9880d681SAndroid Build Coastguard Worker }
2432*9880d681SAndroid Build Coastguard Worker 
ResolveMulticlassDefArgs(MultiClass & MC,Record * CurRec,SMLoc DefmPrefixLoc,SMLoc SubClassLoc,ArrayRef<Init * > TArgs,std::vector<Init * > & TemplateVals,bool DeleteArgs)2433*9880d681SAndroid Build Coastguard Worker bool TGParser::ResolveMulticlassDefArgs(MultiClass &MC, Record *CurRec,
2434*9880d681SAndroid Build Coastguard Worker                                         SMLoc DefmPrefixLoc, SMLoc SubClassLoc,
2435*9880d681SAndroid Build Coastguard Worker                                         ArrayRef<Init *> TArgs,
2436*9880d681SAndroid Build Coastguard Worker                                         std::vector<Init *> &TemplateVals,
2437*9880d681SAndroid Build Coastguard Worker                                         bool DeleteArgs) {
2438*9880d681SAndroid Build Coastguard Worker   // Loop over all of the template arguments, setting them to the specified
2439*9880d681SAndroid Build Coastguard Worker   // value or leaving them as the default if necessary.
2440*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
2441*9880d681SAndroid Build Coastguard Worker     // Check if a value is specified for this temp-arg.
2442*9880d681SAndroid Build Coastguard Worker     if (i < TemplateVals.size()) {
2443*9880d681SAndroid Build Coastguard Worker       // Set it now.
2444*9880d681SAndroid Build Coastguard Worker       if (SetValue(CurRec, DefmPrefixLoc, TArgs[i], None, TemplateVals[i]))
2445*9880d681SAndroid Build Coastguard Worker         return true;
2446*9880d681SAndroid Build Coastguard Worker 
2447*9880d681SAndroid Build Coastguard Worker       // Resolve it next.
2448*9880d681SAndroid Build Coastguard Worker       CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i]));
2449*9880d681SAndroid Build Coastguard Worker 
2450*9880d681SAndroid Build Coastguard Worker       if (DeleteArgs)
2451*9880d681SAndroid Build Coastguard Worker         // Now remove it.
2452*9880d681SAndroid Build Coastguard Worker         CurRec->removeValue(TArgs[i]);
2453*9880d681SAndroid Build Coastguard Worker 
2454*9880d681SAndroid Build Coastguard Worker     } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
2455*9880d681SAndroid Build Coastguard Worker       return Error(SubClassLoc, "value not specified for template argument #" +
2456*9880d681SAndroid Build Coastguard Worker                    Twine(i) + " (" + TArgs[i]->getAsUnquotedString() +
2457*9880d681SAndroid Build Coastguard Worker                    ") of multiclassclass '" + MC.Rec.getNameInitAsString() +
2458*9880d681SAndroid Build Coastguard Worker                    "'");
2459*9880d681SAndroid Build Coastguard Worker     }
2460*9880d681SAndroid Build Coastguard Worker   }
2461*9880d681SAndroid Build Coastguard Worker   return false;
2462*9880d681SAndroid Build Coastguard Worker }
2463*9880d681SAndroid Build Coastguard Worker 
ResolveMulticlassDef(MultiClass & MC,Record * CurRec,Record * DefProto,SMLoc DefmPrefixLoc)2464*9880d681SAndroid Build Coastguard Worker bool TGParser::ResolveMulticlassDef(MultiClass &MC,
2465*9880d681SAndroid Build Coastguard Worker                                     Record *CurRec,
2466*9880d681SAndroid Build Coastguard Worker                                     Record *DefProto,
2467*9880d681SAndroid Build Coastguard Worker                                     SMLoc DefmPrefixLoc) {
2468*9880d681SAndroid Build Coastguard Worker   // If the mdef is inside a 'let' expression, add to each def.
2469*9880d681SAndroid Build Coastguard Worker   if (ApplyLetStack(CurRec))
2470*9880d681SAndroid Build Coastguard Worker     return Error(DefmPrefixLoc, "when instantiating this defm");
2471*9880d681SAndroid Build Coastguard Worker 
2472*9880d681SAndroid Build Coastguard Worker   // Don't create a top level definition for defm inside multiclasses,
2473*9880d681SAndroid Build Coastguard Worker   // instead, only update the prototypes and bind the template args
2474*9880d681SAndroid Build Coastguard Worker   // with the new created definition.
2475*9880d681SAndroid Build Coastguard Worker   if (!CurMultiClass)
2476*9880d681SAndroid Build Coastguard Worker     return false;
2477*9880d681SAndroid Build Coastguard Worker   for (const auto &Proto : CurMultiClass->DefPrototypes)
2478*9880d681SAndroid Build Coastguard Worker     if (Proto->getNameInit() == CurRec->getNameInit())
2479*9880d681SAndroid Build Coastguard Worker       return Error(DefmPrefixLoc, "defm '" + CurRec->getNameInitAsString() +
2480*9880d681SAndroid Build Coastguard Worker                    "' already defined in this multiclass!");
2481*9880d681SAndroid Build Coastguard Worker   CurMultiClass->DefPrototypes.push_back(std::unique_ptr<Record>(CurRec));
2482*9880d681SAndroid Build Coastguard Worker 
2483*9880d681SAndroid Build Coastguard Worker   // Copy the template arguments for the multiclass into the new def.
2484*9880d681SAndroid Build Coastguard Worker   for (Init * TA : CurMultiClass->Rec.getTemplateArgs()) {
2485*9880d681SAndroid Build Coastguard Worker     const RecordVal *RV = CurMultiClass->Rec.getValue(TA);
2486*9880d681SAndroid Build Coastguard Worker     assert(RV && "Template arg doesn't exist?");
2487*9880d681SAndroid Build Coastguard Worker     CurRec->addValue(*RV);
2488*9880d681SAndroid Build Coastguard Worker   }
2489*9880d681SAndroid Build Coastguard Worker 
2490*9880d681SAndroid Build Coastguard Worker   return false;
2491*9880d681SAndroid Build Coastguard Worker }
2492*9880d681SAndroid Build Coastguard Worker 
2493*9880d681SAndroid Build Coastguard Worker /// ParseDefm - Parse the instantiation of a multiclass.
2494*9880d681SAndroid Build Coastguard Worker ///
2495*9880d681SAndroid Build Coastguard Worker ///   DefMInst ::= DEFM ID ':' DefmSubClassRef ';'
2496*9880d681SAndroid Build Coastguard Worker ///
ParseDefm(MultiClass * CurMultiClass)2497*9880d681SAndroid Build Coastguard Worker bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
2498*9880d681SAndroid Build Coastguard Worker   assert(Lex.getCode() == tgtok::Defm && "Unexpected token!");
2499*9880d681SAndroid Build Coastguard Worker   SMLoc DefmLoc = Lex.getLoc();
2500*9880d681SAndroid Build Coastguard Worker   Init *DefmPrefix = nullptr;
2501*9880d681SAndroid Build Coastguard Worker 
2502*9880d681SAndroid Build Coastguard Worker   if (Lex.Lex() == tgtok::Id) {  // eat the defm.
2503*9880d681SAndroid Build Coastguard Worker     DefmPrefix = ParseObjectName(CurMultiClass);
2504*9880d681SAndroid Build Coastguard Worker   }
2505*9880d681SAndroid Build Coastguard Worker 
2506*9880d681SAndroid Build Coastguard Worker   SMLoc DefmPrefixEndLoc = Lex.getLoc();
2507*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::colon)
2508*9880d681SAndroid Build Coastguard Worker     return TokError("expected ':' after defm identifier");
2509*9880d681SAndroid Build Coastguard Worker 
2510*9880d681SAndroid Build Coastguard Worker   // Keep track of the new generated record definitions.
2511*9880d681SAndroid Build Coastguard Worker   std::vector<Record*> NewRecDefs;
2512*9880d681SAndroid Build Coastguard Worker 
2513*9880d681SAndroid Build Coastguard Worker   // This record also inherits from a regular class (non-multiclass)?
2514*9880d681SAndroid Build Coastguard Worker   bool InheritFromClass = false;
2515*9880d681SAndroid Build Coastguard Worker 
2516*9880d681SAndroid Build Coastguard Worker   // eat the colon.
2517*9880d681SAndroid Build Coastguard Worker   Lex.Lex();
2518*9880d681SAndroid Build Coastguard Worker 
2519*9880d681SAndroid Build Coastguard Worker   SMLoc SubClassLoc = Lex.getLoc();
2520*9880d681SAndroid Build Coastguard Worker   SubClassReference Ref = ParseSubClassReference(nullptr, true);
2521*9880d681SAndroid Build Coastguard Worker 
2522*9880d681SAndroid Build Coastguard Worker   while (1) {
2523*9880d681SAndroid Build Coastguard Worker     if (!Ref.Rec) return true;
2524*9880d681SAndroid Build Coastguard Worker 
2525*9880d681SAndroid Build Coastguard Worker     // To instantiate a multiclass, we need to first get the multiclass, then
2526*9880d681SAndroid Build Coastguard Worker     // instantiate each def contained in the multiclass with the SubClassRef
2527*9880d681SAndroid Build Coastguard Worker     // template parameters.
2528*9880d681SAndroid Build Coastguard Worker     MultiClass *MC = MultiClasses[Ref.Rec->getName()].get();
2529*9880d681SAndroid Build Coastguard Worker     assert(MC && "Didn't lookup multiclass correctly?");
2530*9880d681SAndroid Build Coastguard Worker     std::vector<Init*> &TemplateVals = Ref.TemplateArgs;
2531*9880d681SAndroid Build Coastguard Worker 
2532*9880d681SAndroid Build Coastguard Worker     // Verify that the correct number of template arguments were specified.
2533*9880d681SAndroid Build Coastguard Worker     ArrayRef<Init *> TArgs = MC->Rec.getTemplateArgs();
2534*9880d681SAndroid Build Coastguard Worker     if (TArgs.size() < TemplateVals.size())
2535*9880d681SAndroid Build Coastguard Worker       return Error(SubClassLoc,
2536*9880d681SAndroid Build Coastguard Worker                    "more template args specified than multiclass expects");
2537*9880d681SAndroid Build Coastguard Worker 
2538*9880d681SAndroid Build Coastguard Worker     // Loop over all the def's in the multiclass, instantiating each one.
2539*9880d681SAndroid Build Coastguard Worker     for (const std::unique_ptr<Record> &DefProto : MC->DefPrototypes) {
2540*9880d681SAndroid Build Coastguard Worker       // The record name construction goes as follow:
2541*9880d681SAndroid Build Coastguard Worker       //  - If the def name is a string, prepend the prefix.
2542*9880d681SAndroid Build Coastguard Worker       //  - If the def name is a more complex pattern, use that pattern.
2543*9880d681SAndroid Build Coastguard Worker       // As a result, the record is instantiated before resolving
2544*9880d681SAndroid Build Coastguard Worker       // arguments, as it would make its name a string.
2545*9880d681SAndroid Build Coastguard Worker       Record *CurRec = InstantiateMulticlassDef(*MC, DefProto.get(), DefmPrefix,
2546*9880d681SAndroid Build Coastguard Worker                                                 SMRange(DefmLoc,
2547*9880d681SAndroid Build Coastguard Worker                                                         DefmPrefixEndLoc),
2548*9880d681SAndroid Build Coastguard Worker                                                 TArgs, TemplateVals);
2549*9880d681SAndroid Build Coastguard Worker       if (!CurRec)
2550*9880d681SAndroid Build Coastguard Worker         return true;
2551*9880d681SAndroid Build Coastguard Worker 
2552*9880d681SAndroid Build Coastguard Worker       // Now that the record is instantiated, we can resolve arguments.
2553*9880d681SAndroid Build Coastguard Worker       if (ResolveMulticlassDefArgs(*MC, CurRec, DefmLoc, SubClassLoc,
2554*9880d681SAndroid Build Coastguard Worker                                    TArgs, TemplateVals, true/*Delete args*/))
2555*9880d681SAndroid Build Coastguard Worker         return Error(SubClassLoc, "could not instantiate def");
2556*9880d681SAndroid Build Coastguard Worker 
2557*9880d681SAndroid Build Coastguard Worker       if (ResolveMulticlassDef(*MC, CurRec, DefProto.get(), DefmLoc))
2558*9880d681SAndroid Build Coastguard Worker         return Error(SubClassLoc, "could not instantiate def");
2559*9880d681SAndroid Build Coastguard Worker 
2560*9880d681SAndroid Build Coastguard Worker       // Defs that can be used by other definitions should be fully resolved
2561*9880d681SAndroid Build Coastguard Worker       // before any use.
2562*9880d681SAndroid Build Coastguard Worker       if (DefProto->isResolveFirst() && !CurMultiClass) {
2563*9880d681SAndroid Build Coastguard Worker         CurRec->resolveReferences();
2564*9880d681SAndroid Build Coastguard Worker         CurRec->setResolveFirst(false);
2565*9880d681SAndroid Build Coastguard Worker       }
2566*9880d681SAndroid Build Coastguard Worker       NewRecDefs.push_back(CurRec);
2567*9880d681SAndroid Build Coastguard Worker     }
2568*9880d681SAndroid Build Coastguard Worker 
2569*9880d681SAndroid Build Coastguard Worker 
2570*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::comma) break;
2571*9880d681SAndroid Build Coastguard Worker     Lex.Lex(); // eat ','.
2572*9880d681SAndroid Build Coastguard Worker 
2573*9880d681SAndroid Build Coastguard Worker     if (Lex.getCode() != tgtok::Id)
2574*9880d681SAndroid Build Coastguard Worker       return TokError("expected identifier");
2575*9880d681SAndroid Build Coastguard Worker 
2576*9880d681SAndroid Build Coastguard Worker     SubClassLoc = Lex.getLoc();
2577*9880d681SAndroid Build Coastguard Worker 
2578*9880d681SAndroid Build Coastguard Worker     // A defm can inherit from regular classes (non-multiclass) as
2579*9880d681SAndroid Build Coastguard Worker     // long as they come in the end of the inheritance list.
2580*9880d681SAndroid Build Coastguard Worker     InheritFromClass = (Records.getClass(Lex.getCurStrVal()) != nullptr);
2581*9880d681SAndroid Build Coastguard Worker 
2582*9880d681SAndroid Build Coastguard Worker     if (InheritFromClass)
2583*9880d681SAndroid Build Coastguard Worker       break;
2584*9880d681SAndroid Build Coastguard Worker 
2585*9880d681SAndroid Build Coastguard Worker     Ref = ParseSubClassReference(nullptr, true);
2586*9880d681SAndroid Build Coastguard Worker   }
2587*9880d681SAndroid Build Coastguard Worker 
2588*9880d681SAndroid Build Coastguard Worker   if (InheritFromClass) {
2589*9880d681SAndroid Build Coastguard Worker     // Process all the classes to inherit as if they were part of a
2590*9880d681SAndroid Build Coastguard Worker     // regular 'def' and inherit all record values.
2591*9880d681SAndroid Build Coastguard Worker     SubClassReference SubClass = ParseSubClassReference(nullptr, false);
2592*9880d681SAndroid Build Coastguard Worker     while (1) {
2593*9880d681SAndroid Build Coastguard Worker       // Check for error.
2594*9880d681SAndroid Build Coastguard Worker       if (!SubClass.Rec) return true;
2595*9880d681SAndroid Build Coastguard Worker 
2596*9880d681SAndroid Build Coastguard Worker       // Get the expanded definition prototypes and teach them about
2597*9880d681SAndroid Build Coastguard Worker       // the record values the current class to inherit has
2598*9880d681SAndroid Build Coastguard Worker       for (Record *CurRec : NewRecDefs) {
2599*9880d681SAndroid Build Coastguard Worker         // Add it.
2600*9880d681SAndroid Build Coastguard Worker         if (AddSubClass(CurRec, SubClass))
2601*9880d681SAndroid Build Coastguard Worker           return true;
2602*9880d681SAndroid Build Coastguard Worker 
2603*9880d681SAndroid Build Coastguard Worker         if (ApplyLetStack(CurRec))
2604*9880d681SAndroid Build Coastguard Worker           return true;
2605*9880d681SAndroid Build Coastguard Worker       }
2606*9880d681SAndroid Build Coastguard Worker 
2607*9880d681SAndroid Build Coastguard Worker       if (Lex.getCode() != tgtok::comma) break;
2608*9880d681SAndroid Build Coastguard Worker       Lex.Lex(); // eat ','.
2609*9880d681SAndroid Build Coastguard Worker       SubClass = ParseSubClassReference(nullptr, false);
2610*9880d681SAndroid Build Coastguard Worker     }
2611*9880d681SAndroid Build Coastguard Worker   }
2612*9880d681SAndroid Build Coastguard Worker 
2613*9880d681SAndroid Build Coastguard Worker   if (!CurMultiClass)
2614*9880d681SAndroid Build Coastguard Worker     for (Record *CurRec : NewRecDefs)
2615*9880d681SAndroid Build Coastguard Worker       // See Record::setName().  This resolve step will see any new
2616*9880d681SAndroid Build Coastguard Worker       // name for the def that might have been created when resolving
2617*9880d681SAndroid Build Coastguard Worker       // inheritance, values and arguments above.
2618*9880d681SAndroid Build Coastguard Worker       CurRec->resolveReferences();
2619*9880d681SAndroid Build Coastguard Worker 
2620*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() != tgtok::semi)
2621*9880d681SAndroid Build Coastguard Worker     return TokError("expected ';' at end of defm");
2622*9880d681SAndroid Build Coastguard Worker   Lex.Lex();
2623*9880d681SAndroid Build Coastguard Worker 
2624*9880d681SAndroid Build Coastguard Worker   return false;
2625*9880d681SAndroid Build Coastguard Worker }
2626*9880d681SAndroid Build Coastguard Worker 
2627*9880d681SAndroid Build Coastguard Worker /// ParseObject
2628*9880d681SAndroid Build Coastguard Worker ///   Object ::= ClassInst
2629*9880d681SAndroid Build Coastguard Worker ///   Object ::= DefInst
2630*9880d681SAndroid Build Coastguard Worker ///   Object ::= MultiClassInst
2631*9880d681SAndroid Build Coastguard Worker ///   Object ::= DefMInst
2632*9880d681SAndroid Build Coastguard Worker ///   Object ::= LETCommand '{' ObjectList '}'
2633*9880d681SAndroid Build Coastguard Worker ///   Object ::= LETCommand Object
ParseObject(MultiClass * MC)2634*9880d681SAndroid Build Coastguard Worker bool TGParser::ParseObject(MultiClass *MC) {
2635*9880d681SAndroid Build Coastguard Worker   switch (Lex.getCode()) {
2636*9880d681SAndroid Build Coastguard Worker   default:
2637*9880d681SAndroid Build Coastguard Worker     return TokError("Expected class, def, defm, multiclass or let definition");
2638*9880d681SAndroid Build Coastguard Worker   case tgtok::Let:   return ParseTopLevelLet(MC);
2639*9880d681SAndroid Build Coastguard Worker   case tgtok::Def:   return ParseDef(MC);
2640*9880d681SAndroid Build Coastguard Worker   case tgtok::Foreach:   return ParseForeach(MC);
2641*9880d681SAndroid Build Coastguard Worker   case tgtok::Defm:  return ParseDefm(MC);
2642*9880d681SAndroid Build Coastguard Worker   case tgtok::Class: return ParseClass();
2643*9880d681SAndroid Build Coastguard Worker   case tgtok::MultiClass: return ParseMultiClass();
2644*9880d681SAndroid Build Coastguard Worker   }
2645*9880d681SAndroid Build Coastguard Worker }
2646*9880d681SAndroid Build Coastguard Worker 
2647*9880d681SAndroid Build Coastguard Worker /// ParseObjectList
2648*9880d681SAndroid Build Coastguard Worker ///   ObjectList :== Object*
ParseObjectList(MultiClass * MC)2649*9880d681SAndroid Build Coastguard Worker bool TGParser::ParseObjectList(MultiClass *MC) {
2650*9880d681SAndroid Build Coastguard Worker   while (isObjectStart(Lex.getCode())) {
2651*9880d681SAndroid Build Coastguard Worker     if (ParseObject(MC))
2652*9880d681SAndroid Build Coastguard Worker       return true;
2653*9880d681SAndroid Build Coastguard Worker   }
2654*9880d681SAndroid Build Coastguard Worker   return false;
2655*9880d681SAndroid Build Coastguard Worker }
2656*9880d681SAndroid Build Coastguard Worker 
ParseFile()2657*9880d681SAndroid Build Coastguard Worker bool TGParser::ParseFile() {
2658*9880d681SAndroid Build Coastguard Worker   Lex.Lex(); // Prime the lexer.
2659*9880d681SAndroid Build Coastguard Worker   if (ParseObjectList()) return true;
2660*9880d681SAndroid Build Coastguard Worker 
2661*9880d681SAndroid Build Coastguard Worker   // If we have unread input at the end of the file, report it.
2662*9880d681SAndroid Build Coastguard Worker   if (Lex.getCode() == tgtok::Eof)
2663*9880d681SAndroid Build Coastguard Worker     return false;
2664*9880d681SAndroid Build Coastguard Worker 
2665*9880d681SAndroid Build Coastguard Worker   return TokError("Unexpected input at top level");
2666*9880d681SAndroid Build Coastguard Worker }
2667*9880d681SAndroid Build Coastguard Worker 
2668