File: | lib/TableGen/TGParser.cpp |
Warning: | line 2042, column 51 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===- TGParser.cpp - Parser for TableGen Files ---------------------------===// | |||
2 | // | |||
3 | // The LLVM Compiler Infrastructure | |||
4 | // | |||
5 | // This file is distributed under the University of Illinois Open Source | |||
6 | // License. See LICENSE.TXT for details. | |||
7 | // | |||
8 | //===----------------------------------------------------------------------===// | |||
9 | // | |||
10 | // Implement the Parser for TableGen. | |||
11 | // | |||
12 | //===----------------------------------------------------------------------===// | |||
13 | ||||
14 | #include "TGParser.h" | |||
15 | #include "llvm/ADT/None.h" | |||
16 | #include "llvm/ADT/STLExtras.h" | |||
17 | #include "llvm/ADT/SmallVector.h" | |||
18 | #include "llvm/ADT/StringExtras.h" | |||
19 | #include "llvm/Config/llvm-config.h" | |||
20 | #include "llvm/Support/Casting.h" | |||
21 | #include "llvm/Support/Compiler.h" | |||
22 | #include "llvm/Support/ErrorHandling.h" | |||
23 | #include "llvm/Support/raw_ostream.h" | |||
24 | #include "llvm/TableGen/Record.h" | |||
25 | #include <algorithm> | |||
26 | #include <cassert> | |||
27 | #include <cstdint> | |||
28 | ||||
29 | using namespace llvm; | |||
30 | ||||
31 | //===----------------------------------------------------------------------===// | |||
32 | // Support Code for the Semantic Actions. | |||
33 | //===----------------------------------------------------------------------===// | |||
34 | ||||
35 | namespace llvm { | |||
36 | ||||
37 | struct SubClassReference { | |||
38 | SMRange RefRange; | |||
39 | Record *Rec; | |||
40 | SmallVector<Init*, 4> TemplateArgs; | |||
41 | ||||
42 | SubClassReference() : Rec(nullptr) {} | |||
43 | ||||
44 | bool isInvalid() const { return Rec == nullptr; } | |||
45 | }; | |||
46 | ||||
47 | struct SubMultiClassReference { | |||
48 | SMRange RefRange; | |||
49 | MultiClass *MC; | |||
50 | SmallVector<Init*, 4> TemplateArgs; | |||
51 | ||||
52 | SubMultiClassReference() : MC(nullptr) {} | |||
53 | ||||
54 | bool isInvalid() const { return MC == nullptr; } | |||
55 | void dump() const; | |||
56 | }; | |||
57 | ||||
58 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | |||
59 | LLVM_DUMP_METHOD__attribute__((noinline)) __attribute__((__used__)) void SubMultiClassReference::dump() const { | |||
60 | errs() << "Multiclass:\n"; | |||
61 | ||||
62 | MC->dump(); | |||
63 | ||||
64 | errs() << "Template args:\n"; | |||
65 | for (Init *TA : TemplateArgs) | |||
66 | TA->dump(); | |||
67 | } | |||
68 | #endif | |||
69 | ||||
70 | } // end namespace llvm | |||
71 | ||||
72 | static bool checkBitsConcrete(Record &R, const RecordVal &RV) { | |||
73 | BitsInit *BV = cast<BitsInit>(RV.getValue()); | |||
74 | for (unsigned i = 0, e = BV->getNumBits(); i != e; ++i) { | |||
75 | Init *Bit = BV->getBit(i); | |||
76 | bool IsReference = false; | |||
77 | if (auto VBI = dyn_cast<VarBitInit>(Bit)) { | |||
78 | if (auto VI = dyn_cast<VarInit>(VBI->getBitVar())) { | |||
79 | if (R.getValue(VI->getName())) | |||
80 | IsReference = true; | |||
81 | } | |||
82 | } else if (isa<VarInit>(Bit)) { | |||
83 | IsReference = true; | |||
84 | } | |||
85 | if (!(IsReference || Bit->isConcrete())) | |||
86 | return false; | |||
87 | } | |||
88 | return true; | |||
89 | } | |||
90 | ||||
91 | static void checkConcrete(Record &R) { | |||
92 | for (const RecordVal &RV : R.getValues()) { | |||
93 | // HACK: Disable this check for variables declared with 'field'. This is | |||
94 | // done merely because existing targets have legitimate cases of | |||
95 | // non-concrete variables in helper defs. Ideally, we'd introduce a | |||
96 | // 'maybe' or 'optional' modifier instead of this. | |||
97 | if (RV.getPrefix()) | |||
98 | continue; | |||
99 | ||||
100 | if (Init *V = RV.getValue()) { | |||
101 | bool Ok = isa<BitsInit>(V) ? checkBitsConcrete(R, RV) : V->isConcrete(); | |||
102 | if (!Ok) { | |||
103 | PrintError(R.getLoc(), | |||
104 | Twine("Initializer of '") + RV.getNameInitAsString() + | |||
105 | "' in '" + R.getNameInitAsString() + | |||
106 | "' could not be fully resolved: " + | |||
107 | RV.getValue()->getAsString()); | |||
108 | } | |||
109 | } | |||
110 | } | |||
111 | } | |||
112 | ||||
113 | /// Return an Init with a qualifier prefix referring | |||
114 | /// to CurRec's name. | |||
115 | static Init *QualifyName(Record &CurRec, MultiClass *CurMultiClass, | |||
116 | Init *Name, StringRef Scoper) { | |||
117 | Init *NewName = | |||
118 | BinOpInit::getStrConcat(CurRec.getNameInit(), StringInit::get(Scoper)); | |||
119 | NewName = BinOpInit::getStrConcat(NewName, Name); | |||
120 | if (CurMultiClass && Scoper != "::") { | |||
121 | Init *Prefix = BinOpInit::getStrConcat(CurMultiClass->Rec.getNameInit(), | |||
122 | StringInit::get("::")); | |||
123 | NewName = BinOpInit::getStrConcat(Prefix, NewName); | |||
124 | } | |||
125 | ||||
126 | if (BinOpInit *BinOp = dyn_cast<BinOpInit>(NewName)) | |||
127 | NewName = BinOp->Fold(&CurRec); | |||
128 | return NewName; | |||
129 | } | |||
130 | ||||
131 | /// Return the qualified version of the implicit 'NAME' template argument. | |||
132 | static Init *QualifiedNameOfImplicitName(Record &Rec, | |||
133 | MultiClass *MC = nullptr) { | |||
134 | return QualifyName(Rec, MC, StringInit::get("NAME"), MC ? "::" : ":"); | |||
135 | } | |||
136 | ||||
137 | static Init *QualifiedNameOfImplicitName(MultiClass *MC) { | |||
138 | return QualifiedNameOfImplicitName(MC->Rec, MC); | |||
139 | } | |||
140 | ||||
141 | bool TGParser::AddValue(Record *CurRec, SMLoc Loc, const RecordVal &RV) { | |||
142 | if (!CurRec) | |||
143 | CurRec = &CurMultiClass->Rec; | |||
144 | ||||
145 | if (RecordVal *ERV = CurRec->getValue(RV.getNameInit())) { | |||
146 | // The value already exists in the class, treat this as a set. | |||
147 | if (ERV->setValue(RV.getValue())) | |||
148 | return Error(Loc, "New definition of '" + RV.getName() + "' of type '" + | |||
149 | RV.getType()->getAsString() + "' is incompatible with " + | |||
150 | "previous definition of type '" + | |||
151 | ERV->getType()->getAsString() + "'"); | |||
152 | } else { | |||
153 | CurRec->addValue(RV); | |||
154 | } | |||
155 | return false; | |||
156 | } | |||
157 | ||||
158 | /// SetValue - | |||
159 | /// Return true on error, false on success. | |||
160 | bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName, | |||
161 | ArrayRef<unsigned> BitList, Init *V, | |||
162 | bool AllowSelfAssignment) { | |||
163 | if (!V) return false; | |||
164 | ||||
165 | if (!CurRec) CurRec = &CurMultiClass->Rec; | |||
166 | ||||
167 | RecordVal *RV = CurRec->getValue(ValName); | |||
168 | if (!RV) | |||
169 | return Error(Loc, "Value '" + ValName->getAsUnquotedString() + | |||
170 | "' unknown!"); | |||
171 | ||||
172 | // Do not allow assignments like 'X = X'. This will just cause infinite loops | |||
173 | // in the resolution machinery. | |||
174 | if (BitList.empty()) | |||
175 | if (VarInit *VI = dyn_cast<VarInit>(V)) | |||
176 | if (VI->getNameInit() == ValName && !AllowSelfAssignment) | |||
177 | return Error(Loc, "Recursion / self-assignment forbidden"); | |||
178 | ||||
179 | // If we are assigning to a subset of the bits in the value... then we must be | |||
180 | // assigning to a field of BitsRecTy, which must have a BitsInit | |||
181 | // initializer. | |||
182 | // | |||
183 | if (!BitList.empty()) { | |||
184 | BitsInit *CurVal = dyn_cast<BitsInit>(RV->getValue()); | |||
185 | if (!CurVal) | |||
186 | return Error(Loc, "Value '" + ValName->getAsUnquotedString() + | |||
187 | "' is not a bits type"); | |||
188 | ||||
189 | // Convert the incoming value to a bits type of the appropriate size... | |||
190 | Init *BI = V->getCastTo(BitsRecTy::get(BitList.size())); | |||
191 | if (!BI) | |||
192 | return Error(Loc, "Initializer is not compatible with bit range"); | |||
193 | ||||
194 | SmallVector<Init *, 16> NewBits(CurVal->getNumBits()); | |||
195 | ||||
196 | // Loop over bits, assigning values as appropriate. | |||
197 | for (unsigned i = 0, e = BitList.size(); i != e; ++i) { | |||
198 | unsigned Bit = BitList[i]; | |||
199 | if (NewBits[Bit]) | |||
200 | return Error(Loc, "Cannot set bit #" + Twine(Bit) + " of value '" + | |||
201 | ValName->getAsUnquotedString() + "' more than once"); | |||
202 | NewBits[Bit] = BI->getBit(i); | |||
203 | } | |||
204 | ||||
205 | for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i) | |||
206 | if (!NewBits[i]) | |||
207 | NewBits[i] = CurVal->getBit(i); | |||
208 | ||||
209 | V = BitsInit::get(NewBits); | |||
210 | } | |||
211 | ||||
212 | if (RV->setValue(V)) { | |||
213 | std::string InitType; | |||
214 | if (BitsInit *BI = dyn_cast<BitsInit>(V)) | |||
215 | InitType = (Twine("' of type bit initializer with length ") + | |||
216 | Twine(BI->getNumBits())).str(); | |||
217 | else if (TypedInit *TI = dyn_cast<TypedInit>(V)) | |||
218 | InitType = (Twine("' of type '") + TI->getType()->getAsString()).str(); | |||
219 | return Error(Loc, "Value '" + ValName->getAsUnquotedString() + | |||
220 | "' of type '" + RV->getType()->getAsString() + | |||
221 | "' is incompatible with initializer '" + | |||
222 | V->getAsString() + InitType + "'"); | |||
223 | } | |||
224 | return false; | |||
225 | } | |||
226 | ||||
227 | /// AddSubClass - Add SubClass as a subclass to CurRec, resolving its template | |||
228 | /// args as SubClass's template arguments. | |||
229 | bool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) { | |||
230 | Record *SC = SubClass.Rec; | |||
231 | // Add all of the values in the subclass into the current class. | |||
232 | for (const RecordVal &Val : SC->getValues()) | |||
233 | if (AddValue(CurRec, SubClass.RefRange.Start, Val)) | |||
234 | return true; | |||
235 | ||||
236 | ArrayRef<Init *> TArgs = SC->getTemplateArgs(); | |||
237 | ||||
238 | // Ensure that an appropriate number of template arguments are specified. | |||
239 | if (TArgs.size() < SubClass.TemplateArgs.size()) | |||
240 | return Error(SubClass.RefRange.Start, | |||
241 | "More template args specified than expected"); | |||
242 | ||||
243 | // Loop over all of the template arguments, setting them to the specified | |||
244 | // value or leaving them as the default if necessary. | |||
245 | MapResolver R(CurRec); | |||
246 | ||||
247 | for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { | |||
248 | if (i < SubClass.TemplateArgs.size()) { | |||
249 | // If a value is specified for this template arg, set it now. | |||
250 | if (SetValue(CurRec, SubClass.RefRange.Start, TArgs[i], | |||
251 | None, SubClass.TemplateArgs[i])) | |||
252 | return true; | |||
253 | } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) { | |||
254 | return Error(SubClass.RefRange.Start, | |||
255 | "Value not specified for template argument #" + | |||
256 | Twine(i) + " (" + TArgs[i]->getAsUnquotedString() + | |||
257 | ") of subclass '" + SC->getNameInitAsString() + "'!"); | |||
258 | } | |||
259 | ||||
260 | R.set(TArgs[i], CurRec->getValue(TArgs[i])->getValue()); | |||
261 | ||||
262 | CurRec->removeValue(TArgs[i]); | |||
263 | } | |||
264 | ||||
265 | Init *Name; | |||
266 | if (CurRec->isClass()) | |||
267 | Name = | |||
268 | VarInit::get(QualifiedNameOfImplicitName(*CurRec), StringRecTy::get()); | |||
269 | else | |||
270 | Name = CurRec->getNameInit(); | |||
271 | R.set(QualifiedNameOfImplicitName(*SC), Name); | |||
272 | ||||
273 | CurRec->resolveReferences(R); | |||
274 | ||||
275 | // Since everything went well, we can now set the "superclass" list for the | |||
276 | // current record. | |||
277 | ArrayRef<std::pair<Record *, SMRange>> SCs = SC->getSuperClasses(); | |||
278 | for (const auto &SCPair : SCs) { | |||
279 | if (CurRec->isSubClassOf(SCPair.first)) | |||
280 | return Error(SubClass.RefRange.Start, | |||
281 | "Already subclass of '" + SCPair.first->getName() + "'!\n"); | |||
282 | CurRec->addSuperClass(SCPair.first, SCPair.second); | |||
283 | } | |||
284 | ||||
285 | if (CurRec->isSubClassOf(SC)) | |||
286 | return Error(SubClass.RefRange.Start, | |||
287 | "Already subclass of '" + SC->getName() + "'!\n"); | |||
288 | CurRec->addSuperClass(SC, SubClass.RefRange); | |||
289 | return false; | |||
290 | } | |||
291 | ||||
292 | bool TGParser::AddSubClass(RecordsEntry &Entry, SubClassReference &SubClass) { | |||
293 | if (Entry.Rec) | |||
294 | return AddSubClass(Entry.Rec.get(), SubClass); | |||
295 | ||||
296 | for (auto &E : Entry.Loop->Entries) { | |||
297 | if (AddSubClass(E, SubClass)) | |||
298 | return true; | |||
299 | } | |||
300 | ||||
301 | return false; | |||
302 | } | |||
303 | ||||
304 | /// AddSubMultiClass - Add SubMultiClass as a subclass to | |||
305 | /// CurMC, resolving its template args as SubMultiClass's | |||
306 | /// template arguments. | |||
307 | bool TGParser::AddSubMultiClass(MultiClass *CurMC, | |||
308 | SubMultiClassReference &SubMultiClass) { | |||
309 | MultiClass *SMC = SubMultiClass.MC; | |||
310 | ||||
311 | ArrayRef<Init *> SMCTArgs = SMC->Rec.getTemplateArgs(); | |||
312 | if (SMCTArgs.size() < SubMultiClass.TemplateArgs.size()) | |||
313 | return Error(SubMultiClass.RefRange.Start, | |||
314 | "More template args specified than expected"); | |||
315 | ||||
316 | // Prepare the mapping of template argument name to value, filling in default | |||
317 | // values if necessary. | |||
318 | SubstStack TemplateArgs; | |||
319 | for (unsigned i = 0, e = SMCTArgs.size(); i != e; ++i) { | |||
320 | if (i < SubMultiClass.TemplateArgs.size()) { | |||
321 | TemplateArgs.emplace_back(SMCTArgs[i], SubMultiClass.TemplateArgs[i]); | |||
322 | } else { | |||
323 | Init *Default = SMC->Rec.getValue(SMCTArgs[i])->getValue(); | |||
324 | if (!Default->isComplete()) { | |||
325 | return Error(SubMultiClass.RefRange.Start, | |||
326 | "value not specified for template argument #" + Twine(i) + | |||
327 | " (" + SMCTArgs[i]->getAsUnquotedString() + | |||
328 | ") of multiclass '" + SMC->Rec.getNameInitAsString() + | |||
329 | "'"); | |||
330 | } | |||
331 | TemplateArgs.emplace_back(SMCTArgs[i], Default); | |||
332 | } | |||
333 | } | |||
334 | ||||
335 | TemplateArgs.emplace_back( | |||
336 | QualifiedNameOfImplicitName(SMC), | |||
337 | VarInit::get(QualifiedNameOfImplicitName(CurMC), StringRecTy::get())); | |||
338 | ||||
339 | // Add all of the defs in the subclass into the current multiclass. | |||
340 | return resolve(SMC->Entries, TemplateArgs, false, &CurMC->Entries); | |||
341 | } | |||
342 | ||||
343 | /// Add a record or foreach loop to the current context (global record keeper, | |||
344 | /// current inner-most foreach loop, or multiclass). | |||
345 | bool TGParser::addEntry(RecordsEntry E) { | |||
346 | assert(!E.Rec || !E.Loop)((!E.Rec || !E.Loop) ? static_cast<void> (0) : __assert_fail ("!E.Rec || !E.Loop", "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 346, __PRETTY_FUNCTION__)); | |||
347 | ||||
348 | if (!Loops.empty()) { | |||
349 | Loops.back()->Entries.push_back(std::move(E)); | |||
350 | return false; | |||
351 | } | |||
352 | ||||
353 | if (E.Loop) { | |||
354 | SubstStack Stack; | |||
355 | return resolve(*E.Loop, Stack, CurMultiClass == nullptr, | |||
356 | CurMultiClass ? &CurMultiClass->Entries : nullptr); | |||
357 | } | |||
358 | ||||
359 | if (CurMultiClass) { | |||
360 | CurMultiClass->Entries.push_back(std::move(E)); | |||
361 | return false; | |||
362 | } | |||
363 | ||||
364 | return addDefOne(std::move(E.Rec)); | |||
365 | } | |||
366 | ||||
367 | /// Resolve the entries in \p Loop, going over inner loops recursively | |||
368 | /// and making the given subsitutions of (name, value) pairs. | |||
369 | /// | |||
370 | /// The resulting records are stored in \p Dest if non-null. Otherwise, they | |||
371 | /// are added to the global record keeper. | |||
372 | bool TGParser::resolve(const ForeachLoop &Loop, SubstStack &Substs, | |||
373 | bool Final, std::vector<RecordsEntry> *Dest, | |||
374 | SMLoc *Loc) { | |||
375 | MapResolver R; | |||
376 | for (const auto &S : Substs) | |||
377 | R.set(S.first, S.second); | |||
378 | Init *List = Loop.ListValue->resolveReferences(R); | |||
379 | auto LI = dyn_cast<ListInit>(List); | |||
380 | if (!LI) { | |||
381 | if (!Final) { | |||
382 | Dest->emplace_back(make_unique<ForeachLoop>(Loop.Loc, Loop.IterVar, | |||
383 | List)); | |||
384 | return resolve(Loop.Entries, Substs, Final, &Dest->back().Loop->Entries, | |||
385 | Loc); | |||
386 | } | |||
387 | ||||
388 | PrintError(Loop.Loc, Twine("attempting to loop over '") + | |||
389 | List->getAsString() + "', expected a list"); | |||
390 | return true; | |||
391 | } | |||
392 | ||||
393 | bool Error = false; | |||
394 | for (auto Elt : *LI) { | |||
395 | Substs.emplace_back(Loop.IterVar->getNameInit(), Elt); | |||
396 | Error = resolve(Loop.Entries, Substs, Final, Dest); | |||
397 | Substs.pop_back(); | |||
398 | if (Error) | |||
399 | break; | |||
400 | } | |||
401 | return Error; | |||
402 | } | |||
403 | ||||
404 | /// Resolve the entries in \p Source, going over loops recursively and | |||
405 | /// making the given substitutions of (name, value) pairs. | |||
406 | /// | |||
407 | /// The resulting records are stored in \p Dest if non-null. Otherwise, they | |||
408 | /// are added to the global record keeper. | |||
409 | bool TGParser::resolve(const std::vector<RecordsEntry> &Source, | |||
410 | SubstStack &Substs, bool Final, | |||
411 | std::vector<RecordsEntry> *Dest, SMLoc *Loc) { | |||
412 | bool Error = false; | |||
413 | for (auto &E : Source) { | |||
414 | if (E.Loop) { | |||
415 | Error = resolve(*E.Loop, Substs, Final, Dest); | |||
416 | } else { | |||
417 | auto Rec = make_unique<Record>(*E.Rec); | |||
418 | if (Loc) | |||
419 | Rec->appendLoc(*Loc); | |||
420 | ||||
421 | MapResolver R(Rec.get()); | |||
422 | for (const auto &S : Substs) | |||
423 | R.set(S.first, S.second); | |||
424 | Rec->resolveReferences(R); | |||
425 | ||||
426 | if (Dest) | |||
427 | Dest->push_back(std::move(Rec)); | |||
428 | else | |||
429 | Error = addDefOne(std::move(Rec)); | |||
430 | } | |||
431 | if (Error) | |||
432 | break; | |||
433 | } | |||
434 | return Error; | |||
435 | } | |||
436 | ||||
437 | /// Resolve the record fully and add it to the record keeper. | |||
438 | bool TGParser::addDefOne(std::unique_ptr<Record> Rec) { | |||
439 | if (Record *Prev = Records.getDef(Rec->getNameInitAsString())) { | |||
440 | if (!Rec->isAnonymous()) { | |||
441 | PrintError(Rec->getLoc(), | |||
442 | "def already exists: " + Rec->getNameInitAsString()); | |||
443 | PrintNote(Prev->getLoc(), "location of previous definition"); | |||
444 | return true; | |||
445 | } | |||
446 | Rec->setName(Records.getNewAnonymousName()); | |||
447 | } | |||
448 | ||||
449 | Rec->resolveReferences(); | |||
450 | checkConcrete(*Rec); | |||
451 | ||||
452 | if (!isa<StringInit>(Rec->getNameInit())) { | |||
453 | PrintError(Rec->getLoc(), Twine("record name '") + | |||
454 | Rec->getNameInit()->getAsString() + | |||
455 | "' could not be fully resolved"); | |||
456 | return true; | |||
457 | } | |||
458 | ||||
459 | // If ObjectBody has template arguments, it's an error. | |||
460 | assert(Rec->getTemplateArgs().empty() && "How'd this get template args?")((Rec->getTemplateArgs().empty() && "How'd this get template args?" ) ? static_cast<void> (0) : __assert_fail ("Rec->getTemplateArgs().empty() && \"How'd this get template args?\"" , "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 460, __PRETTY_FUNCTION__)); | |||
461 | ||||
462 | for (DefsetRecord *Defset : Defsets) { | |||
463 | DefInit *I = Rec->getDefInit(); | |||
464 | if (!I->getType()->typeIsA(Defset->EltTy)) { | |||
465 | PrintError(Rec->getLoc(), Twine("adding record of incompatible type '") + | |||
466 | I->getType()->getAsString() + | |||
467 | "' to defset"); | |||
468 | PrintNote(Defset->Loc, "location of defset declaration"); | |||
469 | return true; | |||
470 | } | |||
471 | Defset->Elements.push_back(I); | |||
472 | } | |||
473 | ||||
474 | Records.addDef(std::move(Rec)); | |||
475 | return false; | |||
476 | } | |||
477 | ||||
478 | //===----------------------------------------------------------------------===// | |||
479 | // Parser Code | |||
480 | //===----------------------------------------------------------------------===// | |||
481 | ||||
482 | /// isObjectStart - Return true if this is a valid first token for an Object. | |||
483 | static bool isObjectStart(tgtok::TokKind K) { | |||
484 | return K == tgtok::Class || K == tgtok::Def || K == tgtok::Defm || | |||
485 | K == tgtok::Let || K == tgtok::MultiClass || K == tgtok::Foreach || | |||
486 | K == tgtok::Defset; | |||
487 | } | |||
488 | ||||
489 | /// ParseObjectName - If a valid object name is specified, return it. If no | |||
490 | /// name is specified, return the unset initializer. Return nullptr on parse | |||
491 | /// error. | |||
492 | /// ObjectName ::= Value [ '#' Value ]* | |||
493 | /// ObjectName ::= /*empty*/ | |||
494 | /// | |||
495 | Init *TGParser::ParseObjectName(MultiClass *CurMultiClass) { | |||
496 | switch (Lex.getCode()) { | |||
497 | case tgtok::colon: | |||
498 | case tgtok::semi: | |||
499 | case tgtok::l_brace: | |||
500 | // These are all of the tokens that can begin an object body. | |||
501 | // Some of these can also begin values but we disallow those cases | |||
502 | // because they are unlikely to be useful. | |||
503 | return UnsetInit::get(); | |||
504 | default: | |||
505 | break; | |||
506 | } | |||
507 | ||||
508 | Record *CurRec = nullptr; | |||
509 | if (CurMultiClass) | |||
510 | CurRec = &CurMultiClass->Rec; | |||
511 | ||||
512 | Init *Name = ParseValue(CurRec, StringRecTy::get(), ParseNameMode); | |||
513 | if (!Name) | |||
514 | return nullptr; | |||
515 | ||||
516 | if (CurMultiClass) { | |||
517 | Init *NameStr = QualifiedNameOfImplicitName(CurMultiClass); | |||
518 | HasReferenceResolver R(NameStr); | |||
519 | Name->resolveReferences(R); | |||
520 | if (!R.found()) | |||
521 | Name = BinOpInit::getStrConcat(VarInit::get(NameStr, StringRecTy::get()), | |||
522 | Name); | |||
523 | } | |||
524 | ||||
525 | return Name; | |||
526 | } | |||
527 | ||||
528 | /// ParseClassID - Parse and resolve a reference to a class name. This returns | |||
529 | /// null on error. | |||
530 | /// | |||
531 | /// ClassID ::= ID | |||
532 | /// | |||
533 | Record *TGParser::ParseClassID() { | |||
534 | if (Lex.getCode() != tgtok::Id) { | |||
535 | TokError("expected name for ClassID"); | |||
536 | return nullptr; | |||
537 | } | |||
538 | ||||
539 | Record *Result = Records.getClass(Lex.getCurStrVal()); | |||
540 | if (!Result) | |||
541 | TokError("Couldn't find class '" + Lex.getCurStrVal() + "'"); | |||
542 | ||||
543 | Lex.Lex(); | |||
544 | return Result; | |||
545 | } | |||
546 | ||||
547 | /// ParseMultiClassID - Parse and resolve a reference to a multiclass name. | |||
548 | /// This returns null on error. | |||
549 | /// | |||
550 | /// MultiClassID ::= ID | |||
551 | /// | |||
552 | MultiClass *TGParser::ParseMultiClassID() { | |||
553 | if (Lex.getCode() != tgtok::Id) { | |||
554 | TokError("expected name for MultiClassID"); | |||
555 | return nullptr; | |||
556 | } | |||
557 | ||||
558 | MultiClass *Result = MultiClasses[Lex.getCurStrVal()].get(); | |||
559 | if (!Result) | |||
560 | TokError("Couldn't find multiclass '" + Lex.getCurStrVal() + "'"); | |||
561 | ||||
562 | Lex.Lex(); | |||
563 | return Result; | |||
564 | } | |||
565 | ||||
566 | /// ParseSubClassReference - Parse a reference to a subclass or to a templated | |||
567 | /// subclass. This returns a SubClassRefTy with a null Record* on error. | |||
568 | /// | |||
569 | /// SubClassRef ::= ClassID | |||
570 | /// SubClassRef ::= ClassID '<' ValueList '>' | |||
571 | /// | |||
572 | SubClassReference TGParser:: | |||
573 | ParseSubClassReference(Record *CurRec, bool isDefm) { | |||
574 | SubClassReference Result; | |||
575 | Result.RefRange.Start = Lex.getLoc(); | |||
576 | ||||
577 | if (isDefm) { | |||
578 | if (MultiClass *MC = ParseMultiClassID()) | |||
579 | Result.Rec = &MC->Rec; | |||
580 | } else { | |||
581 | Result.Rec = ParseClassID(); | |||
582 | } | |||
583 | if (!Result.Rec) return Result; | |||
584 | ||||
585 | // If there is no template arg list, we're done. | |||
586 | if (Lex.getCode() != tgtok::less) { | |||
587 | Result.RefRange.End = Lex.getLoc(); | |||
588 | return Result; | |||
589 | } | |||
590 | Lex.Lex(); // Eat the '<' | |||
591 | ||||
592 | if (Lex.getCode() == tgtok::greater) { | |||
593 | TokError("subclass reference requires a non-empty list of template values"); | |||
594 | Result.Rec = nullptr; | |||
595 | return Result; | |||
596 | } | |||
597 | ||||
598 | ParseValueList(Result.TemplateArgs, CurRec, Result.Rec); | |||
599 | if (Result.TemplateArgs.empty()) { | |||
600 | Result.Rec = nullptr; // Error parsing value list. | |||
601 | return Result; | |||
602 | } | |||
603 | ||||
604 | if (Lex.getCode() != tgtok::greater) { | |||
605 | TokError("expected '>' in template value list"); | |||
606 | Result.Rec = nullptr; | |||
607 | return Result; | |||
608 | } | |||
609 | Lex.Lex(); | |||
610 | Result.RefRange.End = Lex.getLoc(); | |||
611 | ||||
612 | return Result; | |||
613 | } | |||
614 | ||||
615 | /// ParseSubMultiClassReference - Parse a reference to a subclass or to a | |||
616 | /// templated submulticlass. This returns a SubMultiClassRefTy with a null | |||
617 | /// Record* on error. | |||
618 | /// | |||
619 | /// SubMultiClassRef ::= MultiClassID | |||
620 | /// SubMultiClassRef ::= MultiClassID '<' ValueList '>' | |||
621 | /// | |||
622 | SubMultiClassReference TGParser:: | |||
623 | ParseSubMultiClassReference(MultiClass *CurMC) { | |||
624 | SubMultiClassReference Result; | |||
625 | Result.RefRange.Start = Lex.getLoc(); | |||
626 | ||||
627 | Result.MC = ParseMultiClassID(); | |||
628 | if (!Result.MC) return Result; | |||
629 | ||||
630 | // If there is no template arg list, we're done. | |||
631 | if (Lex.getCode() != tgtok::less) { | |||
632 | Result.RefRange.End = Lex.getLoc(); | |||
633 | return Result; | |||
634 | } | |||
635 | Lex.Lex(); // Eat the '<' | |||
636 | ||||
637 | if (Lex.getCode() == tgtok::greater) { | |||
638 | TokError("subclass reference requires a non-empty list of template values"); | |||
639 | Result.MC = nullptr; | |||
640 | return Result; | |||
641 | } | |||
642 | ||||
643 | ParseValueList(Result.TemplateArgs, &CurMC->Rec, &Result.MC->Rec); | |||
644 | if (Result.TemplateArgs.empty()) { | |||
645 | Result.MC = nullptr; // Error parsing value list. | |||
646 | return Result; | |||
647 | } | |||
648 | ||||
649 | if (Lex.getCode() != tgtok::greater) { | |||
650 | TokError("expected '>' in template value list"); | |||
651 | Result.MC = nullptr; | |||
652 | return Result; | |||
653 | } | |||
654 | Lex.Lex(); | |||
655 | Result.RefRange.End = Lex.getLoc(); | |||
656 | ||||
657 | return Result; | |||
658 | } | |||
659 | ||||
660 | /// ParseRangePiece - Parse a bit/value range. | |||
661 | /// RangePiece ::= INTVAL | |||
662 | /// RangePiece ::= INTVAL '-' INTVAL | |||
663 | /// RangePiece ::= INTVAL INTVAL | |||
664 | bool TGParser::ParseRangePiece(SmallVectorImpl<unsigned> &Ranges) { | |||
665 | if (Lex.getCode() != tgtok::IntVal) { | |||
666 | TokError("expected integer or bitrange"); | |||
667 | return true; | |||
668 | } | |||
669 | int64_t Start = Lex.getCurIntVal(); | |||
670 | int64_t End; | |||
671 | ||||
672 | if (Start < 0) | |||
673 | return TokError("invalid range, cannot be negative"); | |||
674 | ||||
675 | switch (Lex.Lex()) { // eat first character. | |||
676 | default: | |||
677 | Ranges.push_back(Start); | |||
678 | return false; | |||
679 | case tgtok::minus: | |||
680 | if (Lex.Lex() != tgtok::IntVal) { | |||
681 | TokError("expected integer value as end of range"); | |||
682 | return true; | |||
683 | } | |||
684 | End = Lex.getCurIntVal(); | |||
685 | break; | |||
686 | case tgtok::IntVal: | |||
687 | End = -Lex.getCurIntVal(); | |||
688 | break; | |||
689 | } | |||
690 | if (End < 0) | |||
691 | return TokError("invalid range, cannot be negative"); | |||
692 | Lex.Lex(); | |||
693 | ||||
694 | // Add to the range. | |||
695 | if (Start < End) | |||
696 | for (; Start <= End; ++Start) | |||
697 | Ranges.push_back(Start); | |||
698 | else | |||
699 | for (; Start >= End; --Start) | |||
700 | Ranges.push_back(Start); | |||
701 | return false; | |||
702 | } | |||
703 | ||||
704 | /// ParseRangeList - Parse a list of scalars and ranges into scalar values. | |||
705 | /// | |||
706 | /// RangeList ::= RangePiece (',' RangePiece)* | |||
707 | /// | |||
708 | void TGParser::ParseRangeList(SmallVectorImpl<unsigned> &Result) { | |||
709 | // Parse the first piece. | |||
710 | if (ParseRangePiece(Result)) { | |||
711 | Result.clear(); | |||
712 | return; | |||
713 | } | |||
714 | while (Lex.getCode() == tgtok::comma) { | |||
715 | Lex.Lex(); // Eat the comma. | |||
716 | ||||
717 | // Parse the next range piece. | |||
718 | if (ParseRangePiece(Result)) { | |||
719 | Result.clear(); | |||
720 | return; | |||
721 | } | |||
722 | } | |||
723 | } | |||
724 | ||||
725 | /// ParseOptionalRangeList - Parse either a range list in <>'s or nothing. | |||
726 | /// OptionalRangeList ::= '<' RangeList '>' | |||
727 | /// OptionalRangeList ::= /*empty*/ | |||
728 | bool TGParser::ParseOptionalRangeList(SmallVectorImpl<unsigned> &Ranges) { | |||
729 | if (Lex.getCode() != tgtok::less) | |||
730 | return false; | |||
731 | ||||
732 | SMLoc StartLoc = Lex.getLoc(); | |||
733 | Lex.Lex(); // eat the '<' | |||
734 | ||||
735 | // Parse the range list. | |||
736 | ParseRangeList(Ranges); | |||
737 | if (Ranges.empty()) return true; | |||
738 | ||||
739 | if (Lex.getCode() != tgtok::greater) { | |||
740 | TokError("expected '>' at end of range list"); | |||
741 | return Error(StartLoc, "to match this '<'"); | |||
742 | } | |||
743 | Lex.Lex(); // eat the '>'. | |||
744 | return false; | |||
745 | } | |||
746 | ||||
747 | /// ParseOptionalBitList - Parse either a bit list in {}'s or nothing. | |||
748 | /// OptionalBitList ::= '{' RangeList '}' | |||
749 | /// OptionalBitList ::= /*empty*/ | |||
750 | bool TGParser::ParseOptionalBitList(SmallVectorImpl<unsigned> &Ranges) { | |||
751 | if (Lex.getCode() != tgtok::l_brace) | |||
752 | return false; | |||
753 | ||||
754 | SMLoc StartLoc = Lex.getLoc(); | |||
755 | Lex.Lex(); // eat the '{' | |||
756 | ||||
757 | // Parse the range list. | |||
758 | ParseRangeList(Ranges); | |||
759 | if (Ranges.empty()) return true; | |||
760 | ||||
761 | if (Lex.getCode() != tgtok::r_brace) { | |||
762 | TokError("expected '}' at end of bit list"); | |||
763 | return Error(StartLoc, "to match this '{'"); | |||
764 | } | |||
765 | Lex.Lex(); // eat the '}'. | |||
766 | return false; | |||
767 | } | |||
768 | ||||
769 | /// ParseType - Parse and return a tblgen type. This returns null on error. | |||
770 | /// | |||
771 | /// Type ::= STRING // string type | |||
772 | /// Type ::= CODE // code type | |||
773 | /// Type ::= BIT // bit type | |||
774 | /// Type ::= BITS '<' INTVAL '>' // bits<x> type | |||
775 | /// Type ::= INT // int type | |||
776 | /// Type ::= LIST '<' Type '>' // list<x> type | |||
777 | /// Type ::= DAG // dag type | |||
778 | /// Type ::= ClassID // Record Type | |||
779 | /// | |||
780 | RecTy *TGParser::ParseType() { | |||
781 | switch (Lex.getCode()) { | |||
782 | default: TokError("Unknown token when expecting a type"); return nullptr; | |||
783 | case tgtok::String: Lex.Lex(); return StringRecTy::get(); | |||
784 | case tgtok::Code: Lex.Lex(); return CodeRecTy::get(); | |||
785 | case tgtok::Bit: Lex.Lex(); return BitRecTy::get(); | |||
786 | case tgtok::Int: Lex.Lex(); return IntRecTy::get(); | |||
787 | case tgtok::Dag: Lex.Lex(); return DagRecTy::get(); | |||
788 | case tgtok::Id: | |||
789 | if (Record *R = ParseClassID()) return RecordRecTy::get(R); | |||
790 | TokError("unknown class name"); | |||
791 | return nullptr; | |||
792 | case tgtok::Bits: { | |||
793 | if (Lex.Lex() != tgtok::less) { // Eat 'bits' | |||
794 | TokError("expected '<' after bits type"); | |||
795 | return nullptr; | |||
796 | } | |||
797 | if (Lex.Lex() != tgtok::IntVal) { // Eat '<' | |||
798 | TokError("expected integer in bits<n> type"); | |||
799 | return nullptr; | |||
800 | } | |||
801 | uint64_t Val = Lex.getCurIntVal(); | |||
802 | if (Lex.Lex() != tgtok::greater) { // Eat count. | |||
803 | TokError("expected '>' at end of bits<n> type"); | |||
804 | return nullptr; | |||
805 | } | |||
806 | Lex.Lex(); // Eat '>' | |||
807 | return BitsRecTy::get(Val); | |||
808 | } | |||
809 | case tgtok::List: { | |||
810 | if (Lex.Lex() != tgtok::less) { // Eat 'bits' | |||
811 | TokError("expected '<' after list type"); | |||
812 | return nullptr; | |||
813 | } | |||
814 | Lex.Lex(); // Eat '<' | |||
815 | RecTy *SubType = ParseType(); | |||
816 | if (!SubType) return nullptr; | |||
817 | ||||
818 | if (Lex.getCode() != tgtok::greater) { | |||
819 | TokError("expected '>' at end of list<ty> type"); | |||
820 | return nullptr; | |||
821 | } | |||
822 | Lex.Lex(); // Eat '>' | |||
823 | return ListRecTy::get(SubType); | |||
824 | } | |||
825 | } | |||
826 | } | |||
827 | ||||
828 | /// ParseIDValue - This is just like ParseIDValue above, but it assumes the ID | |||
829 | /// has already been read. | |||
830 | Init *TGParser::ParseIDValue(Record *CurRec, StringInit *Name, SMLoc NameLoc, | |||
831 | IDParseMode Mode) { | |||
832 | if (CurRec) { | |||
833 | if (const RecordVal *RV = CurRec->getValue(Name)) | |||
834 | return VarInit::get(Name, RV->getType()); | |||
835 | } | |||
836 | ||||
837 | if ((CurRec && CurRec->isClass()) || CurMultiClass) { | |||
838 | Init *TemplateArgName; | |||
839 | if (CurMultiClass) { | |||
840 | TemplateArgName = | |||
841 | QualifyName(CurMultiClass->Rec, CurMultiClass, Name, "::"); | |||
842 | } else | |||
843 | TemplateArgName = QualifyName(*CurRec, CurMultiClass, Name, ":"); | |||
844 | ||||
845 | Record *TemplateRec = CurMultiClass ? &CurMultiClass->Rec : CurRec; | |||
846 | if (TemplateRec->isTemplateArg(TemplateArgName)) { | |||
847 | const RecordVal *RV = TemplateRec->getValue(TemplateArgName); | |||
848 | assert(RV && "Template arg doesn't exist??")((RV && "Template arg doesn't exist??") ? static_cast <void> (0) : __assert_fail ("RV && \"Template arg doesn't exist??\"" , "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 848, __PRETTY_FUNCTION__)); | |||
849 | return VarInit::get(TemplateArgName, RV->getType()); | |||
850 | } else if (Name->getValue() == "NAME") { | |||
851 | return VarInit::get(TemplateArgName, StringRecTy::get()); | |||
852 | } | |||
853 | } | |||
854 | ||||
855 | // If this is in a foreach loop, make sure it's not a loop iterator | |||
856 | for (const auto &L : Loops) { | |||
857 | VarInit *IterVar = dyn_cast<VarInit>(L->IterVar); | |||
858 | if (IterVar && IterVar->getNameInit() == Name) | |||
859 | return IterVar; | |||
860 | } | |||
861 | ||||
862 | if (Mode == ParseNameMode) | |||
863 | return Name; | |||
864 | ||||
865 | if (Init *I = Records.getGlobal(Name->getValue())) | |||
866 | return I; | |||
867 | ||||
868 | // Allow self-references of concrete defs, but delay the lookup so that we | |||
869 | // get the correct type. | |||
870 | if (CurRec && !CurRec->isClass() && !CurMultiClass && | |||
871 | CurRec->getNameInit() == Name) | |||
872 | return UnOpInit::get(UnOpInit::CAST, Name, CurRec->getType()); | |||
873 | ||||
874 | Error(NameLoc, "Variable not defined: '" + Name->getValue() + "'"); | |||
875 | return nullptr; | |||
876 | } | |||
877 | ||||
878 | /// ParseOperation - Parse an operator. This returns null on error. | |||
879 | /// | |||
880 | /// Operation ::= XOperator ['<' Type '>'] '(' Args ')' | |||
881 | /// | |||
882 | Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) { | |||
883 | switch (Lex.getCode()) { | |||
884 | default: | |||
885 | TokError("unknown operation"); | |||
886 | return nullptr; | |||
887 | case tgtok::XHead: | |||
888 | case tgtok::XTail: | |||
889 | case tgtok::XSize: | |||
890 | case tgtok::XEmpty: | |||
891 | case tgtok::XCast: { // Value ::= !unop '(' Value ')' | |||
892 | UnOpInit::UnaryOp Code; | |||
893 | RecTy *Type = nullptr; | |||
894 | ||||
895 | switch (Lex.getCode()) { | |||
896 | default: llvm_unreachable("Unhandled code!")::llvm::llvm_unreachable_internal("Unhandled code!", "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 896); | |||
897 | case tgtok::XCast: | |||
898 | Lex.Lex(); // eat the operation | |||
899 | Code = UnOpInit::CAST; | |||
900 | ||||
901 | Type = ParseOperatorType(); | |||
902 | ||||
903 | if (!Type) { | |||
904 | TokError("did not get type for unary operator"); | |||
905 | return nullptr; | |||
906 | } | |||
907 | ||||
908 | break; | |||
909 | case tgtok::XHead: | |||
910 | Lex.Lex(); // eat the operation | |||
911 | Code = UnOpInit::HEAD; | |||
912 | break; | |||
913 | case tgtok::XTail: | |||
914 | Lex.Lex(); // eat the operation | |||
915 | Code = UnOpInit::TAIL; | |||
916 | break; | |||
917 | case tgtok::XSize: | |||
918 | Lex.Lex(); | |||
919 | Code = UnOpInit::SIZE; | |||
920 | Type = IntRecTy::get(); | |||
921 | break; | |||
922 | case tgtok::XEmpty: | |||
923 | Lex.Lex(); // eat the operation | |||
924 | Code = UnOpInit::EMPTY; | |||
925 | Type = IntRecTy::get(); | |||
926 | break; | |||
927 | } | |||
928 | if (Lex.getCode() != tgtok::l_paren) { | |||
929 | TokError("expected '(' after unary operator"); | |||
930 | return nullptr; | |||
931 | } | |||
932 | Lex.Lex(); // eat the '(' | |||
933 | ||||
934 | Init *LHS = ParseValue(CurRec); | |||
935 | if (!LHS) return nullptr; | |||
936 | ||||
937 | if (Code == UnOpInit::HEAD || | |||
938 | Code == UnOpInit::TAIL || | |||
939 | Code == UnOpInit::EMPTY) { | |||
940 | ListInit *LHSl = dyn_cast<ListInit>(LHS); | |||
941 | StringInit *LHSs = dyn_cast<StringInit>(LHS); | |||
942 | TypedInit *LHSt = dyn_cast<TypedInit>(LHS); | |||
943 | if (!LHSl && !LHSs && !LHSt) { | |||
944 | TokError("expected list or string type argument in unary operator"); | |||
945 | return nullptr; | |||
946 | } | |||
947 | if (LHSt) { | |||
948 | ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType()); | |||
949 | StringRecTy *SType = dyn_cast<StringRecTy>(LHSt->getType()); | |||
950 | if (!LType && !SType) { | |||
951 | TokError("expected list or string type argument in unary operator"); | |||
952 | return nullptr; | |||
953 | } | |||
954 | } | |||
955 | ||||
956 | if (Code == UnOpInit::HEAD || Code == UnOpInit::TAIL || | |||
957 | Code == UnOpInit::SIZE) { | |||
958 | if (!LHSl && !LHSt) { | |||
959 | TokError("expected list type argument in unary operator"); | |||
960 | return nullptr; | |||
961 | } | |||
962 | } | |||
963 | ||||
964 | if (Code == UnOpInit::HEAD || Code == UnOpInit::TAIL) { | |||
965 | if (LHSl && LHSl->empty()) { | |||
966 | TokError("empty list argument in unary operator"); | |||
967 | return nullptr; | |||
968 | } | |||
969 | if (LHSl) { | |||
970 | Init *Item = LHSl->getElement(0); | |||
971 | TypedInit *Itemt = dyn_cast<TypedInit>(Item); | |||
972 | if (!Itemt) { | |||
973 | TokError("untyped list element in unary operator"); | |||
974 | return nullptr; | |||
975 | } | |||
976 | Type = (Code == UnOpInit::HEAD) ? Itemt->getType() | |||
977 | : ListRecTy::get(Itemt->getType()); | |||
978 | } else { | |||
979 | assert(LHSt && "expected list type argument in unary operator")((LHSt && "expected list type argument in unary operator" ) ? static_cast<void> (0) : __assert_fail ("LHSt && \"expected list type argument in unary operator\"" , "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 979, __PRETTY_FUNCTION__)); | |||
980 | ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType()); | |||
981 | if (!LType) { | |||
982 | TokError("expected list type argument in unary operator"); | |||
983 | return nullptr; | |||
984 | } | |||
985 | Type = (Code == UnOpInit::HEAD) ? LType->getElementType() : LType; | |||
986 | } | |||
987 | } | |||
988 | } | |||
989 | ||||
990 | if (Lex.getCode() != tgtok::r_paren) { | |||
991 | TokError("expected ')' in unary operator"); | |||
992 | return nullptr; | |||
993 | } | |||
994 | Lex.Lex(); // eat the ')' | |||
995 | return (UnOpInit::get(Code, LHS, Type))->Fold(CurRec); | |||
996 | } | |||
997 | ||||
998 | case tgtok::XIsA: { | |||
999 | // Value ::= !isa '<' Type '>' '(' Value ')' | |||
1000 | Lex.Lex(); // eat the operation | |||
1001 | ||||
1002 | RecTy *Type = ParseOperatorType(); | |||
1003 | if (!Type) | |||
1004 | return nullptr; | |||
1005 | ||||
1006 | if (Lex.getCode() != tgtok::l_paren) { | |||
1007 | TokError("expected '(' after type of !isa"); | |||
1008 | return nullptr; | |||
1009 | } | |||
1010 | Lex.Lex(); // eat the '(' | |||
1011 | ||||
1012 | Init *LHS = ParseValue(CurRec); | |||
1013 | if (!LHS) | |||
1014 | return nullptr; | |||
1015 | ||||
1016 | if (Lex.getCode() != tgtok::r_paren) { | |||
1017 | TokError("expected ')' in !isa"); | |||
1018 | return nullptr; | |||
1019 | } | |||
1020 | Lex.Lex(); // eat the ')' | |||
1021 | ||||
1022 | return (IsAOpInit::get(Type, LHS))->Fold(); | |||
1023 | } | |||
1024 | ||||
1025 | case tgtok::XConcat: | |||
1026 | case tgtok::XADD: | |||
1027 | case tgtok::XAND: | |||
1028 | case tgtok::XOR: | |||
1029 | case tgtok::XSRA: | |||
1030 | case tgtok::XSRL: | |||
1031 | case tgtok::XSHL: | |||
1032 | case tgtok::XEq: | |||
1033 | case tgtok::XNe: | |||
1034 | case tgtok::XLe: | |||
1035 | case tgtok::XLt: | |||
1036 | case tgtok::XGe: | |||
1037 | case tgtok::XGt: | |||
1038 | case tgtok::XListConcat: | |||
1039 | case tgtok::XStrConcat: { // Value ::= !binop '(' Value ',' Value ')' | |||
1040 | tgtok::TokKind OpTok = Lex.getCode(); | |||
1041 | SMLoc OpLoc = Lex.getLoc(); | |||
1042 | Lex.Lex(); // eat the operation | |||
1043 | ||||
1044 | BinOpInit::BinaryOp Code; | |||
1045 | switch (OpTok) { | |||
1046 | default: llvm_unreachable("Unhandled code!")::llvm::llvm_unreachable_internal("Unhandled code!", "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 1046); | |||
1047 | case tgtok::XConcat: Code = BinOpInit::CONCAT; break; | |||
1048 | case tgtok::XADD: Code = BinOpInit::ADD; break; | |||
1049 | case tgtok::XAND: Code = BinOpInit::AND; break; | |||
1050 | case tgtok::XOR: Code = BinOpInit::OR; break; | |||
1051 | case tgtok::XSRA: Code = BinOpInit::SRA; break; | |||
1052 | case tgtok::XSRL: Code = BinOpInit::SRL; break; | |||
1053 | case tgtok::XSHL: Code = BinOpInit::SHL; break; | |||
1054 | case tgtok::XEq: Code = BinOpInit::EQ; break; | |||
1055 | case tgtok::XNe: Code = BinOpInit::NE; break; | |||
1056 | case tgtok::XLe: Code = BinOpInit::LE; break; | |||
1057 | case tgtok::XLt: Code = BinOpInit::LT; break; | |||
1058 | case tgtok::XGe: Code = BinOpInit::GE; break; | |||
1059 | case tgtok::XGt: Code = BinOpInit::GT; break; | |||
1060 | case tgtok::XListConcat: Code = BinOpInit::LISTCONCAT; break; | |||
1061 | case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; break; | |||
1062 | } | |||
1063 | ||||
1064 | RecTy *Type = nullptr; | |||
1065 | RecTy *ArgType = nullptr; | |||
1066 | switch (OpTok) { | |||
1067 | default: | |||
1068 | llvm_unreachable("Unhandled code!")::llvm::llvm_unreachable_internal("Unhandled code!", "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 1068); | |||
1069 | case tgtok::XConcat: | |||
1070 | Type = DagRecTy::get(); | |||
1071 | ArgType = DagRecTy::get(); | |||
1072 | break; | |||
1073 | case tgtok::XAND: | |||
1074 | case tgtok::XOR: | |||
1075 | case tgtok::XSRA: | |||
1076 | case tgtok::XSRL: | |||
1077 | case tgtok::XSHL: | |||
1078 | case tgtok::XADD: | |||
1079 | Type = IntRecTy::get(); | |||
1080 | ArgType = IntRecTy::get(); | |||
1081 | break; | |||
1082 | case tgtok::XEq: | |||
1083 | case tgtok::XNe: | |||
1084 | Type = BitRecTy::get(); | |||
1085 | // ArgType for Eq / Ne is not known at this point | |||
1086 | break; | |||
1087 | case tgtok::XLe: | |||
1088 | case tgtok::XLt: | |||
1089 | case tgtok::XGe: | |||
1090 | case tgtok::XGt: | |||
1091 | Type = BitRecTy::get(); | |||
1092 | ArgType = IntRecTy::get(); | |||
1093 | break; | |||
1094 | case tgtok::XListConcat: | |||
1095 | // We don't know the list type until we parse the first argument | |||
1096 | ArgType = ItemType; | |||
1097 | break; | |||
1098 | case tgtok::XStrConcat: | |||
1099 | Type = StringRecTy::get(); | |||
1100 | ArgType = StringRecTy::get(); | |||
1101 | break; | |||
1102 | } | |||
1103 | ||||
1104 | if (Type && ItemType && !Type->typeIsConvertibleTo(ItemType)) { | |||
1105 | Error(OpLoc, Twine("expected value of type '") + | |||
1106 | ItemType->getAsString() + "', got '" + | |||
1107 | Type->getAsString() + "'"); | |||
1108 | return nullptr; | |||
1109 | } | |||
1110 | ||||
1111 | if (Lex.getCode() != tgtok::l_paren) { | |||
1112 | TokError("expected '(' after binary operator"); | |||
1113 | return nullptr; | |||
1114 | } | |||
1115 | Lex.Lex(); // eat the '(' | |||
1116 | ||||
1117 | SmallVector<Init*, 2> InitList; | |||
1118 | ||||
1119 | for (;;) { | |||
1120 | SMLoc InitLoc = Lex.getLoc(); | |||
1121 | InitList.push_back(ParseValue(CurRec, ArgType)); | |||
1122 | if (!InitList.back()) return nullptr; | |||
1123 | ||||
1124 | // All BinOps require their arguments to be of compatible types. | |||
1125 | TypedInit *TI = dyn_cast<TypedInit>(InitList.back()); | |||
1126 | if (!ArgType) { | |||
1127 | ArgType = TI->getType(); | |||
1128 | ||||
1129 | switch (Code) { | |||
1130 | case BinOpInit::LISTCONCAT: | |||
1131 | if (!isa<ListRecTy>(ArgType)) { | |||
1132 | Error(InitLoc, Twine("expected a list, got value of type '") + | |||
1133 | ArgType->getAsString() + "'"); | |||
1134 | return nullptr; | |||
1135 | } | |||
1136 | break; | |||
1137 | case BinOpInit::EQ: | |||
1138 | case BinOpInit::NE: | |||
1139 | if (!ArgType->typeIsConvertibleTo(IntRecTy::get()) && | |||
1140 | !ArgType->typeIsConvertibleTo(StringRecTy::get())) { | |||
1141 | Error(InitLoc, Twine("expected int, bits, or string; got value of " | |||
1142 | "type '") + ArgType->getAsString() + "'"); | |||
1143 | return nullptr; | |||
1144 | } | |||
1145 | break; | |||
1146 | default: llvm_unreachable("other ops have fixed argument types")::llvm::llvm_unreachable_internal("other ops have fixed argument types" , "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 1146); | |||
1147 | } | |||
1148 | } else { | |||
1149 | RecTy *Resolved = resolveTypes(ArgType, TI->getType()); | |||
1150 | if (!Resolved) { | |||
1151 | Error(InitLoc, Twine("expected value of type '") + | |||
1152 | ArgType->getAsString() + "', got '" + | |||
1153 | TI->getType()->getAsString() + "'"); | |||
1154 | return nullptr; | |||
1155 | } | |||
1156 | if (Code != BinOpInit::ADD && Code != BinOpInit::AND && | |||
1157 | Code != BinOpInit::OR && Code != BinOpInit::SRA && | |||
1158 | Code != BinOpInit::SRL && Code != BinOpInit::SHL) | |||
1159 | ArgType = Resolved; | |||
1160 | } | |||
1161 | ||||
1162 | if (Lex.getCode() != tgtok::comma) | |||
1163 | break; | |||
1164 | Lex.Lex(); // eat the ',' | |||
1165 | } | |||
1166 | ||||
1167 | if (Lex.getCode() != tgtok::r_paren) { | |||
1168 | TokError("expected ')' in operator"); | |||
1169 | return nullptr; | |||
1170 | } | |||
1171 | Lex.Lex(); // eat the ')' | |||
1172 | ||||
1173 | if (Code == BinOpInit::LISTCONCAT) | |||
1174 | Type = ArgType; | |||
1175 | ||||
1176 | // We allow multiple operands to associative operators like !strconcat as | |||
1177 | // shorthand for nesting them. | |||
1178 | if (Code == BinOpInit::STRCONCAT || Code == BinOpInit::LISTCONCAT || | |||
1179 | Code == BinOpInit::CONCAT || Code == BinOpInit::ADD || | |||
1180 | Code == BinOpInit::AND || Code == BinOpInit::OR) { | |||
1181 | while (InitList.size() > 2) { | |||
1182 | Init *RHS = InitList.pop_back_val(); | |||
1183 | RHS = (BinOpInit::get(Code, InitList.back(), RHS, Type))->Fold(CurRec); | |||
1184 | InitList.back() = RHS; | |||
1185 | } | |||
1186 | } | |||
1187 | ||||
1188 | if (InitList.size() == 2) | |||
1189 | return (BinOpInit::get(Code, InitList[0], InitList[1], Type)) | |||
1190 | ->Fold(CurRec); | |||
1191 | ||||
1192 | Error(OpLoc, "expected two operands to operator"); | |||
1193 | return nullptr; | |||
1194 | } | |||
1195 | ||||
1196 | case tgtok::XForEach: { // Value ::= !foreach '(' Id ',' Value ',' Value ')' | |||
1197 | SMLoc OpLoc = Lex.getLoc(); | |||
1198 | Lex.Lex(); // eat the operation | |||
1199 | if (Lex.getCode() != tgtok::l_paren) { | |||
1200 | TokError("expected '(' after !foreach"); | |||
1201 | return nullptr; | |||
1202 | } | |||
1203 | ||||
1204 | if (Lex.Lex() != tgtok::Id) { // eat the '(' | |||
1205 | TokError("first argument of !foreach must be an identifier"); | |||
1206 | return nullptr; | |||
1207 | } | |||
1208 | ||||
1209 | Init *LHS = StringInit::get(Lex.getCurStrVal()); | |||
1210 | ||||
1211 | if (CurRec && CurRec->getValue(LHS)) { | |||
1212 | TokError((Twine("iteration variable '") + LHS->getAsString() + | |||
1213 | "' already defined") | |||
1214 | .str()); | |||
1215 | return nullptr; | |||
1216 | } | |||
1217 | ||||
1218 | if (Lex.Lex() != tgtok::comma) { // eat the id | |||
1219 | TokError("expected ',' in ternary operator"); | |||
1220 | return nullptr; | |||
1221 | } | |||
1222 | Lex.Lex(); // eat the ',' | |||
1223 | ||||
1224 | Init *MHS = ParseValue(CurRec); | |||
1225 | if (!MHS) | |||
1226 | return nullptr; | |||
1227 | ||||
1228 | if (Lex.getCode() != tgtok::comma) { | |||
1229 | TokError("expected ',' in ternary operator"); | |||
1230 | return nullptr; | |||
1231 | } | |||
1232 | Lex.Lex(); // eat the ',' | |||
1233 | ||||
1234 | TypedInit *MHSt = dyn_cast<TypedInit>(MHS); | |||
1235 | if (!MHSt) { | |||
1236 | TokError("could not get type of !foreach input"); | |||
1237 | return nullptr; | |||
1238 | } | |||
1239 | ||||
1240 | RecTy *InEltType = nullptr; | |||
1241 | RecTy *OutEltType = nullptr; | |||
1242 | bool IsDAG = false; | |||
1243 | ||||
1244 | if (ListRecTy *InListTy = dyn_cast<ListRecTy>(MHSt->getType())) { | |||
1245 | InEltType = InListTy->getElementType(); | |||
1246 | if (ItemType) { | |||
1247 | if (ListRecTy *OutListTy = dyn_cast<ListRecTy>(ItemType)) { | |||
1248 | OutEltType = OutListTy->getElementType(); | |||
1249 | } else { | |||
1250 | Error(OpLoc, | |||
1251 | "expected value of type '" + Twine(ItemType->getAsString()) + | |||
1252 | "', but got !foreach of list type"); | |||
1253 | return nullptr; | |||
1254 | } | |||
1255 | } | |||
1256 | } else if (DagRecTy *InDagTy = dyn_cast<DagRecTy>(MHSt->getType())) { | |||
1257 | InEltType = InDagTy; | |||
1258 | if (ItemType && !isa<DagRecTy>(ItemType)) { | |||
1259 | Error(OpLoc, | |||
1260 | "expected value of type '" + Twine(ItemType->getAsString()) + | |||
1261 | "', but got !foreach of dag type"); | |||
1262 | return nullptr; | |||
1263 | } | |||
1264 | IsDAG = true; | |||
1265 | } else { | |||
1266 | TokError("!foreach must have list or dag input"); | |||
1267 | return nullptr; | |||
1268 | } | |||
1269 | ||||
1270 | // We need to create a temporary record to provide a scope for the iteration | |||
1271 | // variable while parsing top-level foreach's. | |||
1272 | std::unique_ptr<Record> ParseRecTmp; | |||
1273 | Record *ParseRec = CurRec; | |||
1274 | if (!ParseRec) { | |||
1275 | ParseRecTmp = make_unique<Record>(".parse", ArrayRef<SMLoc>{}, Records); | |||
1276 | ParseRec = ParseRecTmp.get(); | |||
1277 | } | |||
1278 | ||||
1279 | ParseRec->addValue(RecordVal(LHS, InEltType, false)); | |||
1280 | Init *RHS = ParseValue(ParseRec, OutEltType); | |||
1281 | ParseRec->removeValue(LHS); | |||
1282 | if (!RHS) | |||
1283 | return nullptr; | |||
1284 | ||||
1285 | if (Lex.getCode() != tgtok::r_paren) { | |||
1286 | TokError("expected ')' in binary operator"); | |||
1287 | return nullptr; | |||
1288 | } | |||
1289 | Lex.Lex(); // eat the ')' | |||
1290 | ||||
1291 | RecTy *OutType; | |||
1292 | if (IsDAG) { | |||
1293 | OutType = InEltType; | |||
1294 | } else { | |||
1295 | TypedInit *RHSt = dyn_cast<TypedInit>(RHS); | |||
1296 | if (!RHSt) { | |||
1297 | TokError("could not get type of !foreach result"); | |||
1298 | return nullptr; | |||
1299 | } | |||
1300 | OutType = RHSt->getType()->getListTy(); | |||
1301 | } | |||
1302 | ||||
1303 | return (TernOpInit::get(TernOpInit::FOREACH, LHS, MHS, RHS, OutType)) | |||
1304 | ->Fold(CurRec); | |||
1305 | } | |||
1306 | ||||
1307 | case tgtok::XDag: | |||
1308 | case tgtok::XIf: | |||
1309 | case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')' | |||
1310 | TernOpInit::TernaryOp Code; | |||
1311 | RecTy *Type = nullptr; | |||
1312 | ||||
1313 | tgtok::TokKind LexCode = Lex.getCode(); | |||
1314 | Lex.Lex(); // eat the operation | |||
1315 | switch (LexCode) { | |||
1316 | default: llvm_unreachable("Unhandled code!")::llvm::llvm_unreachable_internal("Unhandled code!", "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 1316); | |||
1317 | case tgtok::XDag: | |||
1318 | Code = TernOpInit::DAG; | |||
1319 | Type = DagRecTy::get(); | |||
1320 | ItemType = nullptr; | |||
1321 | break; | |||
1322 | case tgtok::XIf: | |||
1323 | Code = TernOpInit::IF; | |||
1324 | break; | |||
1325 | case tgtok::XSubst: | |||
1326 | Code = TernOpInit::SUBST; | |||
1327 | break; | |||
1328 | } | |||
1329 | if (Lex.getCode() != tgtok::l_paren) { | |||
1330 | TokError("expected '(' after ternary operator"); | |||
1331 | return nullptr; | |||
1332 | } | |||
1333 | Lex.Lex(); // eat the '(' | |||
1334 | ||||
1335 | Init *LHS = ParseValue(CurRec); | |||
1336 | if (!LHS) return nullptr; | |||
1337 | ||||
1338 | if (Lex.getCode() != tgtok::comma) { | |||
1339 | TokError("expected ',' in ternary operator"); | |||
1340 | return nullptr; | |||
1341 | } | |||
1342 | Lex.Lex(); // eat the ',' | |||
1343 | ||||
1344 | SMLoc MHSLoc = Lex.getLoc(); | |||
1345 | Init *MHS = ParseValue(CurRec, ItemType); | |||
1346 | if (!MHS) | |||
1347 | return nullptr; | |||
1348 | ||||
1349 | if (Lex.getCode() != tgtok::comma) { | |||
1350 | TokError("expected ',' in ternary operator"); | |||
1351 | return nullptr; | |||
1352 | } | |||
1353 | Lex.Lex(); // eat the ',' | |||
1354 | ||||
1355 | SMLoc RHSLoc = Lex.getLoc(); | |||
1356 | Init *RHS = ParseValue(CurRec, ItemType); | |||
1357 | if (!RHS) | |||
1358 | return nullptr; | |||
1359 | ||||
1360 | if (Lex.getCode() != tgtok::r_paren) { | |||
1361 | TokError("expected ')' in binary operator"); | |||
1362 | return nullptr; | |||
1363 | } | |||
1364 | Lex.Lex(); // eat the ')' | |||
1365 | ||||
1366 | switch (LexCode) { | |||
1367 | default: llvm_unreachable("Unhandled code!")::llvm::llvm_unreachable_internal("Unhandled code!", "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 1367); | |||
1368 | case tgtok::XDag: { | |||
1369 | TypedInit *MHSt = dyn_cast<TypedInit>(MHS); | |||
1370 | if (!MHSt && !isa<UnsetInit>(MHS)) { | |||
1371 | Error(MHSLoc, "could not determine type of the child list in !dag"); | |||
1372 | return nullptr; | |||
1373 | } | |||
1374 | if (MHSt && !isa<ListRecTy>(MHSt->getType())) { | |||
1375 | Error(MHSLoc, Twine("expected list of children, got type '") + | |||
1376 | MHSt->getType()->getAsString() + "'"); | |||
1377 | return nullptr; | |||
1378 | } | |||
1379 | ||||
1380 | TypedInit *RHSt = dyn_cast<TypedInit>(RHS); | |||
1381 | if (!RHSt && !isa<UnsetInit>(RHS)) { | |||
1382 | Error(RHSLoc, "could not determine type of the name list in !dag"); | |||
1383 | return nullptr; | |||
1384 | } | |||
1385 | if (RHSt && StringRecTy::get()->getListTy() != RHSt->getType()) { | |||
1386 | Error(RHSLoc, Twine("expected list<string>, got type '") + | |||
1387 | RHSt->getType()->getAsString() + "'"); | |||
1388 | return nullptr; | |||
1389 | } | |||
1390 | ||||
1391 | if (!MHSt && !RHSt) { | |||
1392 | Error(MHSLoc, | |||
1393 | "cannot have both unset children and unset names in !dag"); | |||
1394 | return nullptr; | |||
1395 | } | |||
1396 | break; | |||
1397 | } | |||
1398 | case tgtok::XIf: { | |||
1399 | RecTy *MHSTy = nullptr; | |||
1400 | RecTy *RHSTy = nullptr; | |||
1401 | ||||
1402 | if (TypedInit *MHSt = dyn_cast<TypedInit>(MHS)) | |||
1403 | MHSTy = MHSt->getType(); | |||
1404 | if (BitsInit *MHSbits = dyn_cast<BitsInit>(MHS)) | |||
1405 | MHSTy = BitsRecTy::get(MHSbits->getNumBits()); | |||
1406 | if (isa<BitInit>(MHS)) | |||
1407 | MHSTy = BitRecTy::get(); | |||
1408 | ||||
1409 | if (TypedInit *RHSt = dyn_cast<TypedInit>(RHS)) | |||
1410 | RHSTy = RHSt->getType(); | |||
1411 | if (BitsInit *RHSbits = dyn_cast<BitsInit>(RHS)) | |||
1412 | RHSTy = BitsRecTy::get(RHSbits->getNumBits()); | |||
1413 | if (isa<BitInit>(RHS)) | |||
1414 | RHSTy = BitRecTy::get(); | |||
1415 | ||||
1416 | // For UnsetInit, it's typed from the other hand. | |||
1417 | if (isa<UnsetInit>(MHS)) | |||
1418 | MHSTy = RHSTy; | |||
1419 | if (isa<UnsetInit>(RHS)) | |||
1420 | RHSTy = MHSTy; | |||
1421 | ||||
1422 | if (!MHSTy || !RHSTy) { | |||
1423 | TokError("could not get type for !if"); | |||
1424 | return nullptr; | |||
1425 | } | |||
1426 | ||||
1427 | Type = resolveTypes(MHSTy, RHSTy); | |||
1428 | if (!Type) { | |||
1429 | TokError(Twine("inconsistent types '") + MHSTy->getAsString() + | |||
1430 | "' and '" + RHSTy->getAsString() + "' for !if"); | |||
1431 | return nullptr; | |||
1432 | } | |||
1433 | break; | |||
1434 | } | |||
1435 | case tgtok::XSubst: { | |||
1436 | TypedInit *RHSt = dyn_cast<TypedInit>(RHS); | |||
1437 | if (!RHSt) { | |||
1438 | TokError("could not get type for !subst"); | |||
1439 | return nullptr; | |||
1440 | } | |||
1441 | Type = RHSt->getType(); | |||
1442 | break; | |||
1443 | } | |||
1444 | } | |||
1445 | return (TernOpInit::get(Code, LHS, MHS, RHS, Type))->Fold(CurRec); | |||
1446 | } | |||
1447 | ||||
1448 | case tgtok::XFoldl: { | |||
1449 | // Value ::= !foldl '(' Id ',' Id ',' Value ',' Value ',' Value ')' | |||
1450 | Lex.Lex(); // eat the operation | |||
1451 | if (Lex.getCode() != tgtok::l_paren) { | |||
1452 | TokError("expected '(' after !foldl"); | |||
1453 | return nullptr; | |||
1454 | } | |||
1455 | Lex.Lex(); // eat the '(' | |||
1456 | ||||
1457 | Init *StartUntyped = ParseValue(CurRec); | |||
1458 | if (!StartUntyped) | |||
1459 | return nullptr; | |||
1460 | ||||
1461 | TypedInit *Start = dyn_cast<TypedInit>(StartUntyped); | |||
1462 | if (!Start) { | |||
1463 | TokError(Twine("could not get type of !foldl start: '") + | |||
1464 | StartUntyped->getAsString() + "'"); | |||
1465 | return nullptr; | |||
1466 | } | |||
1467 | ||||
1468 | if (Lex.getCode() != tgtok::comma) { | |||
1469 | TokError("expected ',' in !foldl"); | |||
1470 | return nullptr; | |||
1471 | } | |||
1472 | Lex.Lex(); // eat the ',' | |||
1473 | ||||
1474 | Init *ListUntyped = ParseValue(CurRec); | |||
1475 | if (!ListUntyped) | |||
1476 | return nullptr; | |||
1477 | ||||
1478 | TypedInit *List = dyn_cast<TypedInit>(ListUntyped); | |||
1479 | if (!List) { | |||
1480 | TokError(Twine("could not get type of !foldl list: '") + | |||
1481 | ListUntyped->getAsString() + "'"); | |||
1482 | return nullptr; | |||
1483 | } | |||
1484 | ||||
1485 | ListRecTy *ListType = dyn_cast<ListRecTy>(List->getType()); | |||
1486 | if (!ListType) { | |||
1487 | TokError(Twine("!foldl list must be a list, but is of type '") + | |||
1488 | List->getType()->getAsString()); | |||
1489 | return nullptr; | |||
1490 | } | |||
1491 | ||||
1492 | if (Lex.getCode() != tgtok::comma) { | |||
1493 | TokError("expected ',' in !foldl"); | |||
1494 | return nullptr; | |||
1495 | } | |||
1496 | ||||
1497 | if (Lex.Lex() != tgtok::Id) { // eat the ',' | |||
1498 | TokError("third argument of !foldl must be an identifier"); | |||
1499 | return nullptr; | |||
1500 | } | |||
1501 | ||||
1502 | Init *A = StringInit::get(Lex.getCurStrVal()); | |||
1503 | if (CurRec && CurRec->getValue(A)) { | |||
1504 | TokError((Twine("left !foldl variable '") + A->getAsString() + | |||
1505 | "' already defined") | |||
1506 | .str()); | |||
1507 | return nullptr; | |||
1508 | } | |||
1509 | ||||
1510 | if (Lex.Lex() != tgtok::comma) { // eat the id | |||
1511 | TokError("expected ',' in !foldl"); | |||
1512 | return nullptr; | |||
1513 | } | |||
1514 | ||||
1515 | if (Lex.Lex() != tgtok::Id) { // eat the ',' | |||
1516 | TokError("fourth argument of !foldl must be an identifier"); | |||
1517 | return nullptr; | |||
1518 | } | |||
1519 | ||||
1520 | Init *B = StringInit::get(Lex.getCurStrVal()); | |||
1521 | if (CurRec && CurRec->getValue(B)) { | |||
1522 | TokError((Twine("right !foldl variable '") + B->getAsString() + | |||
1523 | "' already defined") | |||
1524 | .str()); | |||
1525 | return nullptr; | |||
1526 | } | |||
1527 | ||||
1528 | if (Lex.Lex() != tgtok::comma) { // eat the id | |||
1529 | TokError("expected ',' in !foldl"); | |||
1530 | return nullptr; | |||
1531 | } | |||
1532 | Lex.Lex(); // eat the ',' | |||
1533 | ||||
1534 | // We need to create a temporary record to provide a scope for the iteration | |||
1535 | // variable while parsing top-level foreach's. | |||
1536 | std::unique_ptr<Record> ParseRecTmp; | |||
1537 | Record *ParseRec = CurRec; | |||
1538 | if (!ParseRec) { | |||
1539 | ParseRecTmp = make_unique<Record>(".parse", ArrayRef<SMLoc>{}, Records); | |||
1540 | ParseRec = ParseRecTmp.get(); | |||
1541 | } | |||
1542 | ||||
1543 | ParseRec->addValue(RecordVal(A, Start->getType(), false)); | |||
1544 | ParseRec->addValue(RecordVal(B, ListType->getElementType(), false)); | |||
1545 | Init *ExprUntyped = ParseValue(ParseRec); | |||
1546 | ParseRec->removeValue(A); | |||
1547 | ParseRec->removeValue(B); | |||
1548 | if (!ExprUntyped) | |||
1549 | return nullptr; | |||
1550 | ||||
1551 | TypedInit *Expr = dyn_cast<TypedInit>(ExprUntyped); | |||
1552 | if (!Expr) { | |||
1553 | TokError("could not get type of !foldl expression"); | |||
1554 | return nullptr; | |||
1555 | } | |||
1556 | ||||
1557 | if (Expr->getType() != Start->getType()) { | |||
1558 | TokError(Twine("!foldl expression must be of same type as start (") + | |||
1559 | Start->getType()->getAsString() + "), but is of type " + | |||
1560 | Expr->getType()->getAsString()); | |||
1561 | return nullptr; | |||
1562 | } | |||
1563 | ||||
1564 | if (Lex.getCode() != tgtok::r_paren) { | |||
1565 | TokError("expected ')' in fold operator"); | |||
1566 | return nullptr; | |||
1567 | } | |||
1568 | Lex.Lex(); // eat the ')' | |||
1569 | ||||
1570 | return FoldOpInit::get(Start, List, A, B, Expr, Start->getType()) | |||
1571 | ->Fold(CurRec); | |||
1572 | } | |||
1573 | } | |||
1574 | } | |||
1575 | ||||
1576 | /// ParseOperatorType - Parse a type for an operator. This returns | |||
1577 | /// null on error. | |||
1578 | /// | |||
1579 | /// OperatorType ::= '<' Type '>' | |||
1580 | /// | |||
1581 | RecTy *TGParser::ParseOperatorType() { | |||
1582 | RecTy *Type = nullptr; | |||
1583 | ||||
1584 | if (Lex.getCode() != tgtok::less) { | |||
1585 | TokError("expected type name for operator"); | |||
1586 | return nullptr; | |||
1587 | } | |||
1588 | Lex.Lex(); // eat the < | |||
1589 | ||||
1590 | Type = ParseType(); | |||
1591 | ||||
1592 | if (!Type) { | |||
1593 | TokError("expected type name for operator"); | |||
1594 | return nullptr; | |||
1595 | } | |||
1596 | ||||
1597 | if (Lex.getCode() != tgtok::greater) { | |||
1598 | TokError("expected type name for operator"); | |||
1599 | return nullptr; | |||
1600 | } | |||
1601 | Lex.Lex(); // eat the > | |||
1602 | ||||
1603 | return Type; | |||
1604 | } | |||
1605 | ||||
1606 | /// ParseSimpleValue - Parse a tblgen value. This returns null on error. | |||
1607 | /// | |||
1608 | /// SimpleValue ::= IDValue | |||
1609 | /// SimpleValue ::= INTVAL | |||
1610 | /// SimpleValue ::= STRVAL+ | |||
1611 | /// SimpleValue ::= CODEFRAGMENT | |||
1612 | /// SimpleValue ::= '?' | |||
1613 | /// SimpleValue ::= '{' ValueList '}' | |||
1614 | /// SimpleValue ::= ID '<' ValueListNE '>' | |||
1615 | /// SimpleValue ::= '[' ValueList ']' | |||
1616 | /// SimpleValue ::= '(' IDValue DagArgList ')' | |||
1617 | /// SimpleValue ::= CONCATTOK '(' Value ',' Value ')' | |||
1618 | /// SimpleValue ::= ADDTOK '(' Value ',' Value ')' | |||
1619 | /// SimpleValue ::= SHLTOK '(' Value ',' Value ')' | |||
1620 | /// SimpleValue ::= SRATOK '(' Value ',' Value ')' | |||
1621 | /// SimpleValue ::= SRLTOK '(' Value ',' Value ')' | |||
1622 | /// SimpleValue ::= LISTCONCATTOK '(' Value ',' Value ')' | |||
1623 | /// SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')' | |||
1624 | /// | |||
1625 | Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, | |||
1626 | IDParseMode Mode) { | |||
1627 | Init *R = nullptr; | |||
1628 | switch (Lex.getCode()) { | |||
1629 | default: TokError("Unknown token when parsing a value"); break; | |||
1630 | case tgtok::paste: | |||
1631 | // This is a leading paste operation. This is deprecated but | |||
1632 | // still exists in some .td files. Ignore it. | |||
1633 | Lex.Lex(); // Skip '#'. | |||
1634 | return ParseSimpleValue(CurRec, ItemType, Mode); | |||
1635 | case tgtok::IntVal: R = IntInit::get(Lex.getCurIntVal()); Lex.Lex(); break; | |||
1636 | case tgtok::BinaryIntVal: { | |||
1637 | auto BinaryVal = Lex.getCurBinaryIntVal(); | |||
1638 | SmallVector<Init*, 16> Bits(BinaryVal.second); | |||
1639 | for (unsigned i = 0, e = BinaryVal.second; i != e; ++i) | |||
1640 | Bits[i] = BitInit::get(BinaryVal.first & (1LL << i)); | |||
1641 | R = BitsInit::get(Bits); | |||
1642 | Lex.Lex(); | |||
1643 | break; | |||
1644 | } | |||
1645 | case tgtok::StrVal: { | |||
1646 | std::string Val = Lex.getCurStrVal(); | |||
1647 | Lex.Lex(); | |||
1648 | ||||
1649 | // Handle multiple consecutive concatenated strings. | |||
1650 | while (Lex.getCode() == tgtok::StrVal) { | |||
1651 | Val += Lex.getCurStrVal(); | |||
1652 | Lex.Lex(); | |||
1653 | } | |||
1654 | ||||
1655 | R = StringInit::get(Val); | |||
1656 | break; | |||
1657 | } | |||
1658 | case tgtok::CodeFragment: | |||
1659 | R = CodeInit::get(Lex.getCurStrVal()); | |||
1660 | Lex.Lex(); | |||
1661 | break; | |||
1662 | case tgtok::question: | |||
1663 | R = UnsetInit::get(); | |||
1664 | Lex.Lex(); | |||
1665 | break; | |||
1666 | case tgtok::Id: { | |||
1667 | SMLoc NameLoc = Lex.getLoc(); | |||
1668 | StringInit *Name = StringInit::get(Lex.getCurStrVal()); | |||
1669 | if (Lex.Lex() != tgtok::less) // consume the Id. | |||
1670 | return ParseIDValue(CurRec, Name, NameLoc, Mode); // Value ::= IDValue | |||
1671 | ||||
1672 | // Value ::= ID '<' ValueListNE '>' | |||
1673 | if (Lex.Lex() == tgtok::greater) { | |||
1674 | TokError("expected non-empty value list"); | |||
1675 | return nullptr; | |||
1676 | } | |||
1677 | ||||
1678 | // This is a CLASS<initvalslist> expression. This is supposed to synthesize | |||
1679 | // a new anonymous definition, deriving from CLASS<initvalslist> with no | |||
1680 | // body. | |||
1681 | Record *Class = Records.getClass(Name->getValue()); | |||
1682 | if (!Class) { | |||
1683 | Error(NameLoc, "Expected a class name, got '" + Name->getValue() + "'"); | |||
1684 | return nullptr; | |||
1685 | } | |||
1686 | ||||
1687 | SmallVector<Init *, 8> Args; | |||
1688 | ParseValueList(Args, CurRec, Class); | |||
1689 | if (Args.empty()) return nullptr; | |||
1690 | ||||
1691 | if (Lex.getCode() != tgtok::greater) { | |||
1692 | TokError("expected '>' at end of value list"); | |||
1693 | return nullptr; | |||
1694 | } | |||
1695 | Lex.Lex(); // eat the '>' | |||
1696 | ||||
1697 | // Typecheck the template arguments list | |||
1698 | ArrayRef<Init *> ExpectedArgs = Class->getTemplateArgs(); | |||
1699 | if (ExpectedArgs.size() < Args.size()) { | |||
1700 | Error(NameLoc, | |||
1701 | "More template args specified than expected"); | |||
1702 | return nullptr; | |||
1703 | } | |||
1704 | ||||
1705 | for (unsigned i = 0, e = ExpectedArgs.size(); i != e; ++i) { | |||
1706 | RecordVal *ExpectedArg = Class->getValue(ExpectedArgs[i]); | |||
1707 | if (i < Args.size()) { | |||
1708 | if (TypedInit *TI = dyn_cast<TypedInit>(Args[i])) { | |||
1709 | RecTy *ExpectedType = ExpectedArg->getType(); | |||
1710 | if (!TI->getType()->typeIsConvertibleTo(ExpectedType)) { | |||
1711 | Error(NameLoc, | |||
1712 | "Value specified for template argument #" + Twine(i) + " (" + | |||
1713 | ExpectedArg->getNameInitAsString() + ") is of type '" + | |||
1714 | TI->getType()->getAsString() + "', expected '" + | |||
1715 | ExpectedType->getAsString() + "': " + TI->getAsString()); | |||
1716 | return nullptr; | |||
1717 | } | |||
1718 | continue; | |||
1719 | } | |||
1720 | } else if (ExpectedArg->getValue()->isComplete()) | |||
1721 | continue; | |||
1722 | ||||
1723 | Error(NameLoc, | |||
1724 | "Value not specified for template argument #" + Twine(i) + " (" + | |||
1725 | ExpectedArgs[i]->getAsUnquotedString() + ")"); | |||
1726 | return nullptr; | |||
1727 | } | |||
1728 | ||||
1729 | return VarDefInit::get(Class, Args)->Fold(); | |||
1730 | } | |||
1731 | case tgtok::l_brace: { // Value ::= '{' ValueList '}' | |||
1732 | SMLoc BraceLoc = Lex.getLoc(); | |||
1733 | Lex.Lex(); // eat the '{' | |||
1734 | SmallVector<Init*, 16> Vals; | |||
1735 | ||||
1736 | if (Lex.getCode() != tgtok::r_brace) { | |||
1737 | ParseValueList(Vals, CurRec); | |||
1738 | if (Vals.empty()) return nullptr; | |||
1739 | } | |||
1740 | if (Lex.getCode() != tgtok::r_brace) { | |||
1741 | TokError("expected '}' at end of bit list value"); | |||
1742 | return nullptr; | |||
1743 | } | |||
1744 | Lex.Lex(); // eat the '}' | |||
1745 | ||||
1746 | SmallVector<Init *, 16> NewBits; | |||
1747 | ||||
1748 | // As we parse { a, b, ... }, 'a' is the highest bit, but we parse it | |||
1749 | // first. We'll first read everything in to a vector, then we can reverse | |||
1750 | // it to get the bits in the correct order for the BitsInit value. | |||
1751 | for (unsigned i = 0, e = Vals.size(); i != e; ++i) { | |||
1752 | // FIXME: The following two loops would not be duplicated | |||
1753 | // if the API was a little more orthogonal. | |||
1754 | ||||
1755 | // bits<n> values are allowed to initialize n bits. | |||
1756 | if (BitsInit *BI = dyn_cast<BitsInit>(Vals[i])) { | |||
1757 | for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) | |||
1758 | NewBits.push_back(BI->getBit((e - i) - 1)); | |||
1759 | continue; | |||
1760 | } | |||
1761 | // bits<n> can also come from variable initializers. | |||
1762 | if (VarInit *VI = dyn_cast<VarInit>(Vals[i])) { | |||
1763 | if (BitsRecTy *BitsRec = dyn_cast<BitsRecTy>(VI->getType())) { | |||
1764 | for (unsigned i = 0, e = BitsRec->getNumBits(); i != e; ++i) | |||
1765 | NewBits.push_back(VI->getBit((e - i) - 1)); | |||
1766 | continue; | |||
1767 | } | |||
1768 | // Fallthrough to try convert this to a bit. | |||
1769 | } | |||
1770 | // All other values must be convertible to just a single bit. | |||
1771 | Init *Bit = Vals[i]->getCastTo(BitRecTy::get()); | |||
1772 | if (!Bit) { | |||
1773 | Error(BraceLoc, "Element #" + Twine(i) + " (" + Vals[i]->getAsString() + | |||
1774 | ") is not convertable to a bit"); | |||
1775 | return nullptr; | |||
1776 | } | |||
1777 | NewBits.push_back(Bit); | |||
1778 | } | |||
1779 | std::reverse(NewBits.begin(), NewBits.end()); | |||
1780 | return BitsInit::get(NewBits); | |||
1781 | } | |||
1782 | case tgtok::l_square: { // Value ::= '[' ValueList ']' | |||
1783 | Lex.Lex(); // eat the '[' | |||
1784 | SmallVector<Init*, 16> Vals; | |||
1785 | ||||
1786 | RecTy *DeducedEltTy = nullptr; | |||
1787 | ListRecTy *GivenListTy = nullptr; | |||
1788 | ||||
1789 | if (ItemType) { | |||
1790 | ListRecTy *ListType = dyn_cast<ListRecTy>(ItemType); | |||
1791 | if (!ListType) { | |||
1792 | TokError(Twine("Type mismatch for list, expected list type, got ") + | |||
1793 | ItemType->getAsString()); | |||
1794 | return nullptr; | |||
1795 | } | |||
1796 | GivenListTy = ListType; | |||
1797 | } | |||
1798 | ||||
1799 | if (Lex.getCode() != tgtok::r_square) { | |||
1800 | ParseValueList(Vals, CurRec, nullptr, | |||
1801 | GivenListTy ? GivenListTy->getElementType() : nullptr); | |||
1802 | if (Vals.empty()) return nullptr; | |||
1803 | } | |||
1804 | if (Lex.getCode() != tgtok::r_square) { | |||
1805 | TokError("expected ']' at end of list value"); | |||
1806 | return nullptr; | |||
1807 | } | |||
1808 | Lex.Lex(); // eat the ']' | |||
1809 | ||||
1810 | RecTy *GivenEltTy = nullptr; | |||
1811 | if (Lex.getCode() == tgtok::less) { | |||
1812 | // Optional list element type | |||
1813 | Lex.Lex(); // eat the '<' | |||
1814 | ||||
1815 | GivenEltTy = ParseType(); | |||
1816 | if (!GivenEltTy) { | |||
1817 | // Couldn't parse element type | |||
1818 | return nullptr; | |||
1819 | } | |||
1820 | ||||
1821 | if (Lex.getCode() != tgtok::greater) { | |||
1822 | TokError("expected '>' at end of list element type"); | |||
1823 | return nullptr; | |||
1824 | } | |||
1825 | Lex.Lex(); // eat the '>' | |||
1826 | } | |||
1827 | ||||
1828 | // Check elements | |||
1829 | RecTy *EltTy = nullptr; | |||
1830 | for (Init *V : Vals) { | |||
1831 | TypedInit *TArg = dyn_cast<TypedInit>(V); | |||
1832 | if (TArg) { | |||
1833 | if (EltTy) { | |||
1834 | EltTy = resolveTypes(EltTy, TArg->getType()); | |||
1835 | if (!EltTy) { | |||
1836 | TokError("Incompatible types in list elements"); | |||
1837 | return nullptr; | |||
1838 | } | |||
1839 | } else { | |||
1840 | EltTy = TArg->getType(); | |||
1841 | } | |||
1842 | } | |||
1843 | } | |||
1844 | ||||
1845 | if (GivenEltTy) { | |||
1846 | if (EltTy) { | |||
1847 | // Verify consistency | |||
1848 | if (!EltTy->typeIsConvertibleTo(GivenEltTy)) { | |||
1849 | TokError("Incompatible types in list elements"); | |||
1850 | return nullptr; | |||
1851 | } | |||
1852 | } | |||
1853 | EltTy = GivenEltTy; | |||
1854 | } | |||
1855 | ||||
1856 | if (!EltTy) { | |||
1857 | if (!ItemType) { | |||
1858 | TokError("No type for list"); | |||
1859 | return nullptr; | |||
1860 | } | |||
1861 | DeducedEltTy = GivenListTy->getElementType(); | |||
1862 | } else { | |||
1863 | // Make sure the deduced type is compatible with the given type | |||
1864 | if (GivenListTy) { | |||
1865 | if (!EltTy->typeIsConvertibleTo(GivenListTy->getElementType())) { | |||
1866 | TokError(Twine("Element type mismatch for list: element type '") + | |||
1867 | EltTy->getAsString() + "' not convertible to '" + | |||
1868 | GivenListTy->getElementType()->getAsString()); | |||
1869 | return nullptr; | |||
1870 | } | |||
1871 | } | |||
1872 | DeducedEltTy = EltTy; | |||
1873 | } | |||
1874 | ||||
1875 | return ListInit::get(Vals, DeducedEltTy); | |||
1876 | } | |||
1877 | case tgtok::l_paren: { // Value ::= '(' IDValue DagArgList ')' | |||
1878 | Lex.Lex(); // eat the '(' | |||
1879 | if (Lex.getCode() != tgtok::Id && Lex.getCode() != tgtok::XCast) { | |||
1880 | TokError("expected identifier in dag init"); | |||
1881 | return nullptr; | |||
1882 | } | |||
1883 | ||||
1884 | Init *Operator = ParseValue(CurRec); | |||
1885 | if (!Operator) return nullptr; | |||
1886 | ||||
1887 | // If the operator name is present, parse it. | |||
1888 | StringInit *OperatorName = nullptr; | |||
1889 | if (Lex.getCode() == tgtok::colon) { | |||
1890 | if (Lex.Lex() != tgtok::VarName) { // eat the ':' | |||
1891 | TokError("expected variable name in dag operator"); | |||
1892 | return nullptr; | |||
1893 | } | |||
1894 | OperatorName = StringInit::get(Lex.getCurStrVal()); | |||
1895 | Lex.Lex(); // eat the VarName. | |||
1896 | } | |||
1897 | ||||
1898 | SmallVector<std::pair<llvm::Init*, StringInit*>, 8> DagArgs; | |||
1899 | if (Lex.getCode() != tgtok::r_paren) { | |||
1900 | ParseDagArgList(DagArgs, CurRec); | |||
1901 | if (DagArgs.empty()) return nullptr; | |||
1902 | } | |||
1903 | ||||
1904 | if (Lex.getCode() != tgtok::r_paren) { | |||
1905 | TokError("expected ')' in dag init"); | |||
1906 | return nullptr; | |||
1907 | } | |||
1908 | Lex.Lex(); // eat the ')' | |||
1909 | ||||
1910 | return DagInit::get(Operator, OperatorName, DagArgs); | |||
1911 | } | |||
1912 | ||||
1913 | case tgtok::XHead: | |||
1914 | case tgtok::XTail: | |||
1915 | case tgtok::XSize: | |||
1916 | case tgtok::XEmpty: | |||
1917 | case tgtok::XCast: // Value ::= !unop '(' Value ')' | |||
1918 | case tgtok::XIsA: | |||
1919 | case tgtok::XConcat: | |||
1920 | case tgtok::XDag: | |||
1921 | case tgtok::XADD: | |||
1922 | case tgtok::XAND: | |||
1923 | case tgtok::XOR: | |||
1924 | case tgtok::XSRA: | |||
1925 | case tgtok::XSRL: | |||
1926 | case tgtok::XSHL: | |||
1927 | case tgtok::XEq: | |||
1928 | case tgtok::XNe: | |||
1929 | case tgtok::XLe: | |||
1930 | case tgtok::XLt: | |||
1931 | case tgtok::XGe: | |||
1932 | case tgtok::XGt: | |||
1933 | case tgtok::XListConcat: | |||
1934 | case tgtok::XStrConcat: // Value ::= !binop '(' Value ',' Value ')' | |||
1935 | case tgtok::XIf: | |||
1936 | case tgtok::XFoldl: | |||
1937 | case tgtok::XForEach: | |||
1938 | case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')' | |||
1939 | return ParseOperation(CurRec, ItemType); | |||
1940 | } | |||
1941 | } | |||
1942 | ||||
1943 | return R; | |||
1944 | } | |||
1945 | ||||
1946 | /// ParseValue - Parse a tblgen value. This returns null on error. | |||
1947 | /// | |||
1948 | /// Value ::= SimpleValue ValueSuffix* | |||
1949 | /// ValueSuffix ::= '{' BitList '}' | |||
1950 | /// ValueSuffix ::= '[' BitList ']' | |||
1951 | /// ValueSuffix ::= '.' ID | |||
1952 | /// | |||
1953 | Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) { | |||
1954 | Init *Result = ParseSimpleValue(CurRec, ItemType, Mode); | |||
1955 | if (!Result) return nullptr; | |||
1956 | ||||
1957 | // Parse the suffixes now if present. | |||
1958 | while (true) { | |||
1959 | switch (Lex.getCode()) { | |||
1960 | default: return Result; | |||
1961 | case tgtok::l_brace: { | |||
1962 | if (Mode == ParseNameMode) | |||
1963 | // This is the beginning of the object body. | |||
1964 | return Result; | |||
1965 | ||||
1966 | SMLoc CurlyLoc = Lex.getLoc(); | |||
1967 | Lex.Lex(); // eat the '{' | |||
1968 | SmallVector<unsigned, 16> Ranges; | |||
1969 | ParseRangeList(Ranges); | |||
1970 | if (Ranges.empty()) return nullptr; | |||
1971 | ||||
1972 | // Reverse the bitlist. | |||
1973 | std::reverse(Ranges.begin(), Ranges.end()); | |||
1974 | Result = Result->convertInitializerBitRange(Ranges); | |||
1975 | if (!Result) { | |||
1976 | Error(CurlyLoc, "Invalid bit range for value"); | |||
1977 | return nullptr; | |||
1978 | } | |||
1979 | ||||
1980 | // Eat the '}'. | |||
1981 | if (Lex.getCode() != tgtok::r_brace) { | |||
1982 | TokError("expected '}' at end of bit range list"); | |||
1983 | return nullptr; | |||
1984 | } | |||
1985 | Lex.Lex(); | |||
1986 | break; | |||
1987 | } | |||
1988 | case tgtok::l_square: { | |||
1989 | SMLoc SquareLoc = Lex.getLoc(); | |||
1990 | Lex.Lex(); // eat the '[' | |||
1991 | SmallVector<unsigned, 16> Ranges; | |||
1992 | ParseRangeList(Ranges); | |||
1993 | if (Ranges.empty()) return nullptr; | |||
1994 | ||||
1995 | Result = Result->convertInitListSlice(Ranges); | |||
1996 | if (!Result) { | |||
1997 | Error(SquareLoc, "Invalid range for list slice"); | |||
1998 | return nullptr; | |||
1999 | } | |||
2000 | ||||
2001 | // Eat the ']'. | |||
2002 | if (Lex.getCode() != tgtok::r_square) { | |||
2003 | TokError("expected ']' at end of list slice"); | |||
2004 | return nullptr; | |||
2005 | } | |||
2006 | Lex.Lex(); | |||
2007 | break; | |||
2008 | } | |||
2009 | case tgtok::period: { | |||
2010 | if (Lex.Lex() != tgtok::Id) { // eat the . | |||
2011 | TokError("expected field identifier after '.'"); | |||
2012 | return nullptr; | |||
2013 | } | |||
2014 | StringInit *FieldName = StringInit::get(Lex.getCurStrVal()); | |||
2015 | if (!Result->getFieldType(FieldName)) { | |||
2016 | TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" + | |||
2017 | Result->getAsString() + "'"); | |||
2018 | return nullptr; | |||
2019 | } | |||
2020 | Result = FieldInit::get(Result, FieldName)->Fold(CurRec); | |||
2021 | Lex.Lex(); // eat field name | |||
2022 | break; | |||
2023 | } | |||
2024 | ||||
2025 | case tgtok::paste: | |||
2026 | SMLoc PasteLoc = Lex.getLoc(); | |||
2027 | ||||
2028 | // Create a !strconcat() operation, first casting each operand to | |||
2029 | // a string if necessary. | |||
2030 | ||||
2031 | TypedInit *LHS = dyn_cast<TypedInit>(Result); | |||
2032 | if (!LHS) { | |||
2033 | Error(PasteLoc, "LHS of paste is not typed!"); | |||
2034 | return nullptr; | |||
2035 | } | |||
2036 | ||||
2037 | if (LHS->getType() != StringRecTy::get()) { | |||
2038 | LHS = dyn_cast<TypedInit>( | |||
2039 | UnOpInit::get(UnOpInit::CAST, LHS, StringRecTy::get()) | |||
2040 | ->Fold(CurRec)); | |||
2041 | if (!LHS) { | |||
2042 | Error(PasteLoc, Twine("can't cast '") + LHS->getAsString() + | |||
| ||||
2043 | "' to string"); | |||
2044 | return nullptr; | |||
2045 | } | |||
2046 | } | |||
2047 | ||||
2048 | TypedInit *RHS = nullptr; | |||
2049 | ||||
2050 | Lex.Lex(); // Eat the '#'. | |||
2051 | switch (Lex.getCode()) { | |||
2052 | case tgtok::colon: | |||
2053 | case tgtok::semi: | |||
2054 | case tgtok::l_brace: | |||
2055 | // These are all of the tokens that can begin an object body. | |||
2056 | // Some of these can also begin values but we disallow those cases | |||
2057 | // because they are unlikely to be useful. | |||
2058 | ||||
2059 | // Trailing paste, concat with an empty string. | |||
2060 | RHS = StringInit::get(""); | |||
2061 | break; | |||
2062 | ||||
2063 | default: | |||
2064 | Init *RHSResult = ParseValue(CurRec, nullptr, ParseNameMode); | |||
2065 | RHS = dyn_cast<TypedInit>(RHSResult); | |||
2066 | if (!RHS) { | |||
2067 | Error(PasteLoc, "RHS of paste is not typed!"); | |||
2068 | return nullptr; | |||
2069 | } | |||
2070 | ||||
2071 | if (RHS->getType() != StringRecTy::get()) { | |||
2072 | RHS = dyn_cast<TypedInit>( | |||
2073 | UnOpInit::get(UnOpInit::CAST, RHS, StringRecTy::get()) | |||
2074 | ->Fold(CurRec)); | |||
2075 | if (!RHS) { | |||
2076 | Error(PasteLoc, Twine("can't cast '") + RHS->getAsString() + | |||
2077 | "' to string"); | |||
2078 | return nullptr; | |||
2079 | } | |||
2080 | } | |||
2081 | ||||
2082 | break; | |||
2083 | } | |||
2084 | ||||
2085 | Result = BinOpInit::getStrConcat(LHS, RHS); | |||
2086 | break; | |||
2087 | } | |||
2088 | } | |||
2089 | } | |||
2090 | ||||
2091 | /// ParseDagArgList - Parse the argument list for a dag literal expression. | |||
2092 | /// | |||
2093 | /// DagArg ::= Value (':' VARNAME)? | |||
2094 | /// DagArg ::= VARNAME | |||
2095 | /// DagArgList ::= DagArg | |||
2096 | /// DagArgList ::= DagArgList ',' DagArg | |||
2097 | void TGParser::ParseDagArgList( | |||
2098 | SmallVectorImpl<std::pair<llvm::Init*, StringInit*>> &Result, | |||
2099 | Record *CurRec) { | |||
2100 | ||||
2101 | while (true) { | |||
2102 | // DagArg ::= VARNAME | |||
2103 | if (Lex.getCode() == tgtok::VarName) { | |||
2104 | // A missing value is treated like '?'. | |||
2105 | StringInit *VarName = StringInit::get(Lex.getCurStrVal()); | |||
2106 | Result.emplace_back(UnsetInit::get(), VarName); | |||
2107 | Lex.Lex(); | |||
2108 | } else { | |||
2109 | // DagArg ::= Value (':' VARNAME)? | |||
2110 | Init *Val = ParseValue(CurRec); | |||
2111 | if (!Val) { | |||
2112 | Result.clear(); | |||
2113 | return; | |||
2114 | } | |||
2115 | ||||
2116 | // If the variable name is present, add it. | |||
2117 | StringInit *VarName = nullptr; | |||
2118 | if (Lex.getCode() == tgtok::colon) { | |||
2119 | if (Lex.Lex() != tgtok::VarName) { // eat the ':' | |||
2120 | TokError("expected variable name in dag literal"); | |||
2121 | Result.clear(); | |||
2122 | return; | |||
2123 | } | |||
2124 | VarName = StringInit::get(Lex.getCurStrVal()); | |||
2125 | Lex.Lex(); // eat the VarName. | |||
2126 | } | |||
2127 | ||||
2128 | Result.push_back(std::make_pair(Val, VarName)); | |||
2129 | } | |||
2130 | if (Lex.getCode() != tgtok::comma) break; | |||
2131 | Lex.Lex(); // eat the ',' | |||
2132 | } | |||
2133 | } | |||
2134 | ||||
2135 | /// ParseValueList - Parse a comma separated list of values, returning them as a | |||
2136 | /// vector. Note that this always expects to be able to parse at least one | |||
2137 | /// value. It returns an empty list if this is not possible. | |||
2138 | /// | |||
2139 | /// ValueList ::= Value (',' Value) | |||
2140 | /// | |||
2141 | void TGParser::ParseValueList(SmallVectorImpl<Init*> &Result, Record *CurRec, | |||
2142 | Record *ArgsRec, RecTy *EltTy) { | |||
2143 | RecTy *ItemType = EltTy; | |||
2144 | unsigned int ArgN = 0; | |||
2145 | if (ArgsRec && !EltTy) { | |||
2146 | ArrayRef<Init *> TArgs = ArgsRec->getTemplateArgs(); | |||
2147 | if (TArgs.empty()) { | |||
2148 | TokError("template argument provided to non-template class"); | |||
2149 | Result.clear(); | |||
2150 | return; | |||
2151 | } | |||
2152 | const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]); | |||
2153 | if (!RV) { | |||
2154 | errs() << "Cannot find template arg " << ArgN << " (" << TArgs[ArgN] | |||
2155 | << ")\n"; | |||
2156 | } | |||
2157 | assert(RV && "Template argument record not found??")((RV && "Template argument record not found??") ? static_cast <void> (0) : __assert_fail ("RV && \"Template argument record not found??\"" , "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 2157, __PRETTY_FUNCTION__)); | |||
2158 | ItemType = RV->getType(); | |||
2159 | ++ArgN; | |||
2160 | } | |||
2161 | Result.push_back(ParseValue(CurRec, ItemType)); | |||
2162 | if (!Result.back()) { | |||
2163 | Result.clear(); | |||
2164 | return; | |||
2165 | } | |||
2166 | ||||
2167 | while (Lex.getCode() == tgtok::comma) { | |||
2168 | Lex.Lex(); // Eat the comma | |||
2169 | ||||
2170 | if (ArgsRec && !EltTy) { | |||
2171 | ArrayRef<Init *> TArgs = ArgsRec->getTemplateArgs(); | |||
2172 | if (ArgN >= TArgs.size()) { | |||
2173 | TokError("too many template arguments"); | |||
2174 | Result.clear(); | |||
2175 | return; | |||
2176 | } | |||
2177 | const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]); | |||
2178 | assert(RV && "Template argument record not found??")((RV && "Template argument record not found??") ? static_cast <void> (0) : __assert_fail ("RV && \"Template argument record not found??\"" , "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 2178, __PRETTY_FUNCTION__)); | |||
2179 | ItemType = RV->getType(); | |||
2180 | ++ArgN; | |||
2181 | } | |||
2182 | Result.push_back(ParseValue(CurRec, ItemType)); | |||
2183 | if (!Result.back()) { | |||
2184 | Result.clear(); | |||
2185 | return; | |||
2186 | } | |||
2187 | } | |||
2188 | } | |||
2189 | ||||
2190 | /// ParseDeclaration - Read a declaration, returning the name of field ID, or an | |||
2191 | /// empty string on error. This can happen in a number of different context's, | |||
2192 | /// including within a def or in the template args for a def (which which case | |||
2193 | /// CurRec will be non-null) and within the template args for a multiclass (in | |||
2194 | /// which case CurRec will be null, but CurMultiClass will be set). This can | |||
2195 | /// also happen within a def that is within a multiclass, which will set both | |||
2196 | /// CurRec and CurMultiClass. | |||
2197 | /// | |||
2198 | /// Declaration ::= FIELD? Type ID ('=' Value)? | |||
2199 | /// | |||
2200 | Init *TGParser::ParseDeclaration(Record *CurRec, | |||
2201 | bool ParsingTemplateArgs) { | |||
2202 | // Read the field prefix if present. | |||
2203 | bool HasField = Lex.getCode() == tgtok::Field; | |||
2204 | if (HasField) Lex.Lex(); | |||
2205 | ||||
2206 | RecTy *Type = ParseType(); | |||
2207 | if (!Type) return nullptr; | |||
2208 | ||||
2209 | if (Lex.getCode() != tgtok::Id) { | |||
2210 | TokError("Expected identifier in declaration"); | |||
2211 | return nullptr; | |||
2212 | } | |||
2213 | ||||
2214 | std::string Str = Lex.getCurStrVal(); | |||
2215 | if (Str == "NAME") { | |||
2216 | TokError("'" + Str + "' is a reserved variable name"); | |||
2217 | return nullptr; | |||
2218 | } | |||
2219 | ||||
2220 | SMLoc IdLoc = Lex.getLoc(); | |||
2221 | Init *DeclName = StringInit::get(Str); | |||
2222 | Lex.Lex(); | |||
2223 | ||||
2224 | if (ParsingTemplateArgs) { | |||
2225 | if (CurRec) | |||
2226 | DeclName = QualifyName(*CurRec, CurMultiClass, DeclName, ":"); | |||
2227 | else | |||
2228 | assert(CurMultiClass)((CurMultiClass) ? static_cast<void> (0) : __assert_fail ("CurMultiClass", "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 2228, __PRETTY_FUNCTION__)); | |||
2229 | if (CurMultiClass) | |||
2230 | DeclName = QualifyName(CurMultiClass->Rec, CurMultiClass, DeclName, | |||
2231 | "::"); | |||
2232 | } | |||
2233 | ||||
2234 | // Add the value. | |||
2235 | if (AddValue(CurRec, IdLoc, RecordVal(DeclName, Type, HasField))) | |||
2236 | return nullptr; | |||
2237 | ||||
2238 | // If a value is present, parse it. | |||
2239 | if (Lex.getCode() == tgtok::equal) { | |||
2240 | Lex.Lex(); | |||
2241 | SMLoc ValLoc = Lex.getLoc(); | |||
2242 | Init *Val = ParseValue(CurRec, Type); | |||
2243 | if (!Val || | |||
2244 | SetValue(CurRec, ValLoc, DeclName, None, Val)) | |||
2245 | // Return the name, even if an error is thrown. This is so that we can | |||
2246 | // continue to make some progress, even without the value having been | |||
2247 | // initialized. | |||
2248 | return DeclName; | |||
2249 | } | |||
2250 | ||||
2251 | return DeclName; | |||
2252 | } | |||
2253 | ||||
2254 | /// ParseForeachDeclaration - Read a foreach declaration, returning | |||
2255 | /// the name of the declared object or a NULL Init on error. Return | |||
2256 | /// the name of the parsed initializer list through ForeachListName. | |||
2257 | /// | |||
2258 | /// ForeachDeclaration ::= ID '=' '{' RangeList '}' | |||
2259 | /// ForeachDeclaration ::= ID '=' RangePiece | |||
2260 | /// ForeachDeclaration ::= ID '=' Value | |||
2261 | /// | |||
2262 | VarInit *TGParser::ParseForeachDeclaration(Init *&ForeachListValue) { | |||
2263 | if (Lex.getCode() != tgtok::Id) { | |||
2264 | TokError("Expected identifier in foreach declaration"); | |||
2265 | return nullptr; | |||
2266 | } | |||
2267 | ||||
2268 | Init *DeclName = StringInit::get(Lex.getCurStrVal()); | |||
2269 | Lex.Lex(); | |||
2270 | ||||
2271 | // If a value is present, parse it. | |||
2272 | if (Lex.getCode() != tgtok::equal) { | |||
2273 | TokError("Expected '=' in foreach declaration"); | |||
2274 | return nullptr; | |||
2275 | } | |||
2276 | Lex.Lex(); // Eat the '=' | |||
2277 | ||||
2278 | RecTy *IterType = nullptr; | |||
2279 | SmallVector<unsigned, 16> Ranges; | |||
2280 | ||||
2281 | switch (Lex.getCode()) { | |||
2282 | case tgtok::IntVal: { // RangePiece. | |||
2283 | if (ParseRangePiece(Ranges)) | |||
2284 | return nullptr; | |||
2285 | break; | |||
2286 | } | |||
2287 | ||||
2288 | case tgtok::l_brace: { // '{' RangeList '}' | |||
2289 | Lex.Lex(); // eat the '{' | |||
2290 | ParseRangeList(Ranges); | |||
2291 | if (Lex.getCode() != tgtok::r_brace) { | |||
2292 | TokError("expected '}' at end of bit range list"); | |||
2293 | return nullptr; | |||
2294 | } | |||
2295 | Lex.Lex(); | |||
2296 | break; | |||
2297 | } | |||
2298 | ||||
2299 | default: { | |||
2300 | SMLoc ValueLoc = Lex.getLoc(); | |||
2301 | Init *I = ParseValue(nullptr); | |||
2302 | TypedInit *TI = dyn_cast<TypedInit>(I); | |||
2303 | if (!TI || !isa<ListRecTy>(TI->getType())) { | |||
2304 | std::string Type; | |||
2305 | if (TI) | |||
2306 | Type = (Twine("' of type '") + TI->getType()->getAsString()).str(); | |||
2307 | Error(ValueLoc, "expected a list, got '" + I->getAsString() + Type + "'"); | |||
2308 | if (CurMultiClass) | |||
2309 | PrintNote({}, "references to multiclass template arguments cannot be " | |||
2310 | "resolved at this time"); | |||
2311 | return nullptr; | |||
2312 | } | |||
2313 | ForeachListValue = I; | |||
2314 | IterType = cast<ListRecTy>(TI->getType())->getElementType(); | |||
2315 | break; | |||
2316 | } | |||
2317 | } | |||
2318 | ||||
2319 | if (!Ranges.empty()) { | |||
2320 | assert(!IterType && "Type already initialized?")((!IterType && "Type already initialized?") ? static_cast <void> (0) : __assert_fail ("!IterType && \"Type already initialized?\"" , "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 2320, __PRETTY_FUNCTION__)); | |||
2321 | IterType = IntRecTy::get(); | |||
2322 | std::vector<Init*> Values; | |||
2323 | for (unsigned R : Ranges) | |||
2324 | Values.push_back(IntInit::get(R)); | |||
2325 | ForeachListValue = ListInit::get(Values, IterType); | |||
2326 | } | |||
2327 | ||||
2328 | if (!IterType) | |||
2329 | return nullptr; | |||
2330 | ||||
2331 | return VarInit::get(DeclName, IterType); | |||
2332 | } | |||
2333 | ||||
2334 | /// ParseTemplateArgList - Read a template argument list, which is a non-empty | |||
2335 | /// sequence of template-declarations in <>'s. If CurRec is non-null, these are | |||
2336 | /// template args for a def, which may or may not be in a multiclass. If null, | |||
2337 | /// these are the template args for a multiclass. | |||
2338 | /// | |||
2339 | /// TemplateArgList ::= '<' Declaration (',' Declaration)* '>' | |||
2340 | /// | |||
2341 | bool TGParser::ParseTemplateArgList(Record *CurRec) { | |||
2342 | assert(Lex.getCode() == tgtok::less && "Not a template arg list!")((Lex.getCode() == tgtok::less && "Not a template arg list!" ) ? static_cast<void> (0) : __assert_fail ("Lex.getCode() == tgtok::less && \"Not a template arg list!\"" , "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 2342, __PRETTY_FUNCTION__)); | |||
2343 | Lex.Lex(); // eat the '<' | |||
2344 | ||||
2345 | Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->Rec; | |||
2346 | ||||
2347 | // Read the first declaration. | |||
2348 | Init *TemplArg = ParseDeclaration(CurRec, true/*templateargs*/); | |||
2349 | if (!TemplArg) | |||
2350 | return true; | |||
2351 | ||||
2352 | TheRecToAddTo->addTemplateArg(TemplArg); | |||
2353 | ||||
2354 | while (Lex.getCode() == tgtok::comma) { | |||
2355 | Lex.Lex(); // eat the ',' | |||
2356 | ||||
2357 | // Read the following declarations. | |||
2358 | SMLoc Loc = Lex.getLoc(); | |||
2359 | TemplArg = ParseDeclaration(CurRec, true/*templateargs*/); | |||
2360 | if (!TemplArg) | |||
2361 | return true; | |||
2362 | ||||
2363 | if (TheRecToAddTo->isTemplateArg(TemplArg)) | |||
2364 | return Error(Loc, "template argument with the same name has already been " | |||
2365 | "defined"); | |||
2366 | ||||
2367 | TheRecToAddTo->addTemplateArg(TemplArg); | |||
2368 | } | |||
2369 | ||||
2370 | if (Lex.getCode() != tgtok::greater) | |||
2371 | return TokError("expected '>' at end of template argument list"); | |||
2372 | Lex.Lex(); // eat the '>'. | |||
2373 | return false; | |||
2374 | } | |||
2375 | ||||
2376 | /// ParseBodyItem - Parse a single item at within the body of a def or class. | |||
2377 | /// | |||
2378 | /// BodyItem ::= Declaration ';' | |||
2379 | /// BodyItem ::= LET ID OptionalBitList '=' Value ';' | |||
2380 | bool TGParser::ParseBodyItem(Record *CurRec) { | |||
2381 | if (Lex.getCode() != tgtok::Let) { | |||
2382 | if (!ParseDeclaration(CurRec, false)) | |||
2383 | return true; | |||
2384 | ||||
2385 | if (Lex.getCode() != tgtok::semi) | |||
2386 | return TokError("expected ';' after declaration"); | |||
2387 | Lex.Lex(); | |||
2388 | return false; | |||
2389 | } | |||
2390 | ||||
2391 | // LET ID OptionalRangeList '=' Value ';' | |||
2392 | if (Lex.Lex() != tgtok::Id) | |||
2393 | return TokError("expected field identifier after let"); | |||
2394 | ||||
2395 | SMLoc IdLoc = Lex.getLoc(); | |||
2396 | StringInit *FieldName = StringInit::get(Lex.getCurStrVal()); | |||
2397 | Lex.Lex(); // eat the field name. | |||
2398 | ||||
2399 | SmallVector<unsigned, 16> BitList; | |||
2400 | if (ParseOptionalBitList(BitList)) | |||
2401 | return true; | |||
2402 | std::reverse(BitList.begin(), BitList.end()); | |||
2403 | ||||
2404 | if (Lex.getCode() != tgtok::equal) | |||
2405 | return TokError("expected '=' in let expression"); | |||
2406 | Lex.Lex(); // eat the '='. | |||
2407 | ||||
2408 | RecordVal *Field = CurRec->getValue(FieldName); | |||
2409 | if (!Field) | |||
2410 | return TokError("Value '" + FieldName->getValue() + "' unknown!"); | |||
2411 | ||||
2412 | RecTy *Type = Field->getType(); | |||
2413 | ||||
2414 | Init *Val = ParseValue(CurRec, Type); | |||
2415 | if (!Val) return true; | |||
2416 | ||||
2417 | if (Lex.getCode() != tgtok::semi) | |||
2418 | return TokError("expected ';' after let expression"); | |||
2419 | Lex.Lex(); | |||
2420 | ||||
2421 | return SetValue(CurRec, IdLoc, FieldName, BitList, Val); | |||
2422 | } | |||
2423 | ||||
2424 | /// ParseBody - Read the body of a class or def. Return true on error, false on | |||
2425 | /// success. | |||
2426 | /// | |||
2427 | /// Body ::= ';' | |||
2428 | /// Body ::= '{' BodyList '}' | |||
2429 | /// BodyList BodyItem* | |||
2430 | /// | |||
2431 | bool TGParser::ParseBody(Record *CurRec) { | |||
2432 | // If this is a null definition, just eat the semi and return. | |||
2433 | if (Lex.getCode() == tgtok::semi) { | |||
| ||||
2434 | Lex.Lex(); | |||
2435 | return false; | |||
2436 | } | |||
2437 | ||||
2438 | if (Lex.getCode() != tgtok::l_brace) | |||
2439 | return TokError("Expected ';' or '{' to start body"); | |||
2440 | // Eat the '{'. | |||
2441 | Lex.Lex(); | |||
2442 | ||||
2443 | while (Lex.getCode() != tgtok::r_brace) | |||
2444 | if (ParseBodyItem(CurRec)) | |||
2445 | return true; | |||
2446 | ||||
2447 | // Eat the '}'. | |||
2448 | Lex.Lex(); | |||
2449 | return false; | |||
2450 | } | |||
2451 | ||||
2452 | /// Apply the current let bindings to \a CurRec. | |||
2453 | /// \returns true on error, false otherwise. | |||
2454 | bool TGParser::ApplyLetStack(Record *CurRec) { | |||
2455 | for (SmallVectorImpl<LetRecord> &LetInfo : LetStack) | |||
2456 | for (LetRecord &LR : LetInfo) | |||
2457 | if (SetValue(CurRec, LR.Loc, LR.Name, LR.Bits, LR.Value)) | |||
2458 | return true; | |||
2459 | return false; | |||
2460 | } | |||
2461 | ||||
2462 | bool TGParser::ApplyLetStack(RecordsEntry &Entry) { | |||
2463 | if (Entry.Rec) | |||
2464 | return ApplyLetStack(Entry.Rec.get()); | |||
2465 | ||||
2466 | for (auto &E : Entry.Loop->Entries) { | |||
2467 | if (ApplyLetStack(E)) | |||
2468 | return true; | |||
2469 | } | |||
2470 | ||||
2471 | return false; | |||
2472 | } | |||
2473 | ||||
2474 | /// ParseObjectBody - Parse the body of a def or class. This consists of an | |||
2475 | /// optional ClassList followed by a Body. CurRec is the current def or class | |||
2476 | /// that is being parsed. | |||
2477 | /// | |||
2478 | /// ObjectBody ::= BaseClassList Body | |||
2479 | /// BaseClassList ::= /*empty*/ | |||
2480 | /// BaseClassList ::= ':' BaseClassListNE | |||
2481 | /// BaseClassListNE ::= SubClassRef (',' SubClassRef)* | |||
2482 | /// | |||
2483 | bool TGParser::ParseObjectBody(Record *CurRec) { | |||
2484 | // If there is a baseclass list, read it. | |||
2485 | if (Lex.getCode() == tgtok::colon) { | |||
2486 | Lex.Lex(); | |||
2487 | ||||
2488 | // Read all of the subclasses. | |||
2489 | SubClassReference SubClass = ParseSubClassReference(CurRec, false); | |||
2490 | while (true) { | |||
2491 | // Check for error. | |||
2492 | if (!SubClass.Rec) return true; | |||
2493 | ||||
2494 | // Add it. | |||
2495 | if (AddSubClass(CurRec, SubClass)) | |||
2496 | return true; | |||
2497 | ||||
2498 | if (Lex.getCode() != tgtok::comma) break; | |||
2499 | Lex.Lex(); // eat ','. | |||
2500 | SubClass = ParseSubClassReference(CurRec, false); | |||
2501 | } | |||
2502 | } | |||
2503 | ||||
2504 | if (ApplyLetStack(CurRec)) | |||
2505 | return true; | |||
2506 | ||||
2507 | return ParseBody(CurRec); | |||
2508 | } | |||
2509 | ||||
2510 | /// ParseDef - Parse and return a top level or multiclass def, return the record | |||
2511 | /// corresponding to it. This returns null on error. | |||
2512 | /// | |||
2513 | /// DefInst ::= DEF ObjectName ObjectBody | |||
2514 | /// | |||
2515 | bool TGParser::ParseDef(MultiClass *CurMultiClass) { | |||
2516 | SMLoc DefLoc = Lex.getLoc(); | |||
2517 | assert(Lex.getCode() == tgtok::Def && "Unknown tok")((Lex.getCode() == tgtok::Def && "Unknown tok") ? static_cast <void> (0) : __assert_fail ("Lex.getCode() == tgtok::Def && \"Unknown tok\"" , "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 2517, __PRETTY_FUNCTION__)); | |||
2518 | Lex.Lex(); // Eat the 'def' token. | |||
2519 | ||||
2520 | // Parse ObjectName and make a record for it. | |||
2521 | std::unique_ptr<Record> CurRec; | |||
2522 | Init *Name = ParseObjectName(CurMultiClass); | |||
2523 | if (!Name) | |||
2524 | return true; | |||
2525 | ||||
2526 | if (isa<UnsetInit>(Name)) | |||
2527 | CurRec = make_unique<Record>(Records.getNewAnonymousName(), DefLoc, Records, | |||
2528 | /*Anonymous=*/true); | |||
2529 | else | |||
2530 | CurRec = make_unique<Record>(Name, DefLoc, Records); | |||
2531 | ||||
2532 | if (ParseObjectBody(CurRec.get())) | |||
2533 | return true; | |||
2534 | ||||
2535 | return addEntry(std::move(CurRec)); | |||
2536 | } | |||
2537 | ||||
2538 | /// ParseDefset - Parse a defset statement. | |||
2539 | /// | |||
2540 | /// Defset ::= DEFSET Type Id '=' '{' ObjectList '}' | |||
2541 | /// | |||
2542 | bool TGParser::ParseDefset() { | |||
2543 | assert(Lex.getCode() == tgtok::Defset)((Lex.getCode() == tgtok::Defset) ? static_cast<void> ( 0) : __assert_fail ("Lex.getCode() == tgtok::Defset", "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 2543, __PRETTY_FUNCTION__)); | |||
2544 | Lex.Lex(); // Eat the 'defset' token | |||
2545 | ||||
2546 | DefsetRecord Defset; | |||
2547 | Defset.Loc = Lex.getLoc(); | |||
2548 | RecTy *Type = ParseType(); | |||
2549 | if (!Type) | |||
2550 | return true; | |||
2551 | if (!isa<ListRecTy>(Type)) | |||
2552 | return Error(Defset.Loc, "expected list type"); | |||
2553 | Defset.EltTy = cast<ListRecTy>(Type)->getElementType(); | |||
2554 | ||||
2555 | if (Lex.getCode() != tgtok::Id) | |||
2556 | return TokError("expected identifier"); | |||
2557 | StringInit *DeclName = StringInit::get(Lex.getCurStrVal()); | |||
2558 | if (Records.getGlobal(DeclName->getValue())) | |||
2559 | return TokError("def or global variable of this name already exists"); | |||
2560 | ||||
2561 | if (Lex.Lex() != tgtok::equal) // Eat the identifier | |||
2562 | return TokError("expected '='"); | |||
2563 | if (Lex.Lex() != tgtok::l_brace) // Eat the '=' | |||
2564 | return TokError("expected '{'"); | |||
2565 | SMLoc BraceLoc = Lex.getLoc(); | |||
2566 | Lex.Lex(); // Eat the '{' | |||
2567 | ||||
2568 | Defsets.push_back(&Defset); | |||
2569 | bool Err = ParseObjectList(nullptr); | |||
2570 | Defsets.pop_back(); | |||
2571 | if (Err) | |||
2572 | return true; | |||
2573 | ||||
2574 | if (Lex.getCode() != tgtok::r_brace) { | |||
2575 | TokError("expected '}' at end of defset"); | |||
2576 | return Error(BraceLoc, "to match this '{'"); | |||
2577 | } | |||
2578 | Lex.Lex(); // Eat the '}' | |||
2579 | ||||
2580 | Records.addExtraGlobal(DeclName->getValue(), | |||
2581 | ListInit::get(Defset.Elements, Defset.EltTy)); | |||
2582 | return false; | |||
2583 | } | |||
2584 | ||||
2585 | /// ParseForeach - Parse a for statement. Return the record corresponding | |||
2586 | /// to it. This returns true on error. | |||
2587 | /// | |||
2588 | /// Foreach ::= FOREACH Declaration IN '{ ObjectList '}' | |||
2589 | /// Foreach ::= FOREACH Declaration IN Object | |||
2590 | /// | |||
2591 | bool TGParser::ParseForeach(MultiClass *CurMultiClass) { | |||
2592 | SMLoc Loc = Lex.getLoc(); | |||
2593 | assert(Lex.getCode() == tgtok::Foreach && "Unknown tok")((Lex.getCode() == tgtok::Foreach && "Unknown tok") ? static_cast<void> (0) : __assert_fail ("Lex.getCode() == tgtok::Foreach && \"Unknown tok\"" , "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 2593, __PRETTY_FUNCTION__)); | |||
2594 | Lex.Lex(); // Eat the 'for' token. | |||
2595 | ||||
2596 | // Make a temporary object to record items associated with the for | |||
2597 | // loop. | |||
2598 | Init *ListValue = nullptr; | |||
2599 | VarInit *IterName = ParseForeachDeclaration(ListValue); | |||
2600 | if (!IterName) | |||
2601 | return TokError("expected declaration in for"); | |||
2602 | ||||
2603 | if (Lex.getCode() != tgtok::In) | |||
2604 | return TokError("Unknown tok"); | |||
2605 | Lex.Lex(); // Eat the in | |||
2606 | ||||
2607 | // Create a loop object and remember it. | |||
2608 | Loops.push_back(llvm::make_unique<ForeachLoop>(Loc, IterName, ListValue)); | |||
2609 | ||||
2610 | if (Lex.getCode() != tgtok::l_brace) { | |||
2611 | // FOREACH Declaration IN Object | |||
2612 | if (ParseObject(CurMultiClass)) | |||
2613 | return true; | |||
2614 | } else { | |||
2615 | SMLoc BraceLoc = Lex.getLoc(); | |||
2616 | // Otherwise, this is a group foreach. | |||
2617 | Lex.Lex(); // eat the '{'. | |||
2618 | ||||
2619 | // Parse the object list. | |||
2620 | if (ParseObjectList(CurMultiClass)) | |||
2621 | return true; | |||
2622 | ||||
2623 | if (Lex.getCode() != tgtok::r_brace) { | |||
2624 | TokError("expected '}' at end of foreach command"); | |||
2625 | return Error(BraceLoc, "to match this '{'"); | |||
2626 | } | |||
2627 | Lex.Lex(); // Eat the } | |||
2628 | } | |||
2629 | ||||
2630 | // Resolve the loop or store it for later resolution. | |||
2631 | std::unique_ptr<ForeachLoop> Loop = std::move(Loops.back()); | |||
2632 | Loops.pop_back(); | |||
2633 | ||||
2634 | return addEntry(std::move(Loop)); | |||
2635 | } | |||
2636 | ||||
2637 | /// ParseClass - Parse a tblgen class definition. | |||
2638 | /// | |||
2639 | /// ClassInst ::= CLASS ID TemplateArgList? ObjectBody | |||
2640 | /// | |||
2641 | bool TGParser::ParseClass() { | |||
2642 | assert(Lex.getCode() == tgtok::Class && "Unexpected token!")((Lex.getCode() == tgtok::Class && "Unexpected token!" ) ? static_cast<void> (0) : __assert_fail ("Lex.getCode() == tgtok::Class && \"Unexpected token!\"" , "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 2642, __PRETTY_FUNCTION__)); | |||
2643 | Lex.Lex(); | |||
2644 | ||||
2645 | if (Lex.getCode() != tgtok::Id) | |||
2646 | return TokError("expected class name after 'class' keyword"); | |||
2647 | ||||
2648 | Record *CurRec = Records.getClass(Lex.getCurStrVal()); | |||
2649 | if (CurRec) { | |||
2650 | // If the body was previously defined, this is an error. | |||
2651 | if (!CurRec->getValues().empty() || | |||
2652 | !CurRec->getSuperClasses().empty() || | |||
2653 | !CurRec->getTemplateArgs().empty()) | |||
2654 | return TokError("Class '" + CurRec->getNameInitAsString() + | |||
2655 | "' already defined"); | |||
2656 | } else { | |||
2657 | // If this is the first reference to this class, create and add it. | |||
2658 | auto NewRec = | |||
2659 | llvm::make_unique<Record>(Lex.getCurStrVal(), Lex.getLoc(), Records, | |||
2660 | /*Class=*/true); | |||
2661 | CurRec = NewRec.get(); | |||
2662 | Records.addClass(std::move(NewRec)); | |||
2663 | } | |||
2664 | Lex.Lex(); // eat the name. | |||
2665 | ||||
2666 | // If there are template args, parse them. | |||
2667 | if (Lex.getCode() == tgtok::less) | |||
2668 | if (ParseTemplateArgList(CurRec)) | |||
2669 | return true; | |||
2670 | ||||
2671 | return ParseObjectBody(CurRec); | |||
2672 | } | |||
2673 | ||||
2674 | /// ParseLetList - Parse a non-empty list of assignment expressions into a list | |||
2675 | /// of LetRecords. | |||
2676 | /// | |||
2677 | /// LetList ::= LetItem (',' LetItem)* | |||
2678 | /// LetItem ::= ID OptionalRangeList '=' Value | |||
2679 | /// | |||
2680 | void TGParser::ParseLetList(SmallVectorImpl<LetRecord> &Result) { | |||
2681 | while (true) { | |||
2682 | if (Lex.getCode() != tgtok::Id) { | |||
2683 | TokError("expected identifier in let definition"); | |||
2684 | Result.clear(); | |||
2685 | return; | |||
2686 | } | |||
2687 | ||||
2688 | StringInit *Name = StringInit::get(Lex.getCurStrVal()); | |||
2689 | SMLoc NameLoc = Lex.getLoc(); | |||
2690 | Lex.Lex(); // Eat the identifier. | |||
2691 | ||||
2692 | // Check for an optional RangeList. | |||
2693 | SmallVector<unsigned, 16> Bits; | |||
2694 | if (ParseOptionalRangeList(Bits)) { | |||
2695 | Result.clear(); | |||
2696 | return; | |||
2697 | } | |||
2698 | std::reverse(Bits.begin(), Bits.end()); | |||
2699 | ||||
2700 | if (Lex.getCode() != tgtok::equal) { | |||
2701 | TokError("expected '=' in let expression"); | |||
2702 | Result.clear(); | |||
2703 | return; | |||
2704 | } | |||
2705 | Lex.Lex(); // eat the '='. | |||
2706 | ||||
2707 | Init *Val = ParseValue(nullptr); | |||
2708 | if (!Val) { | |||
2709 | Result.clear(); | |||
2710 | return; | |||
2711 | } | |||
2712 | ||||
2713 | // Now that we have everything, add the record. | |||
2714 | Result.emplace_back(Name, Bits, Val, NameLoc); | |||
2715 | ||||
2716 | if (Lex.getCode() != tgtok::comma) | |||
2717 | return; | |||
2718 | Lex.Lex(); // eat the comma. | |||
2719 | } | |||
2720 | } | |||
2721 | ||||
2722 | /// ParseTopLevelLet - Parse a 'let' at top level. This can be a couple of | |||
2723 | /// different related productions. This works inside multiclasses too. | |||
2724 | /// | |||
2725 | /// Object ::= LET LetList IN '{' ObjectList '}' | |||
2726 | /// Object ::= LET LetList IN Object | |||
2727 | /// | |||
2728 | bool TGParser::ParseTopLevelLet(MultiClass *CurMultiClass) { | |||
2729 | assert(Lex.getCode() == tgtok::Let && "Unexpected token")((Lex.getCode() == tgtok::Let && "Unexpected token") ? static_cast<void> (0) : __assert_fail ("Lex.getCode() == tgtok::Let && \"Unexpected token\"" , "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 2729, __PRETTY_FUNCTION__)); | |||
2730 | Lex.Lex(); | |||
2731 | ||||
2732 | // Add this entry to the let stack. | |||
2733 | SmallVector<LetRecord, 8> LetInfo; | |||
2734 | ParseLetList(LetInfo); | |||
2735 | if (LetInfo.empty()) return true; | |||
2736 | LetStack.push_back(std::move(LetInfo)); | |||
2737 | ||||
2738 | if (Lex.getCode() != tgtok::In) | |||
2739 | return TokError("expected 'in' at end of top-level 'let'"); | |||
2740 | Lex.Lex(); | |||
2741 | ||||
2742 | // If this is a scalar let, just handle it now | |||
2743 | if (Lex.getCode() != tgtok::l_brace) { | |||
2744 | // LET LetList IN Object | |||
2745 | if (ParseObject(CurMultiClass)) | |||
2746 | return true; | |||
2747 | } else { // Object ::= LETCommand '{' ObjectList '}' | |||
2748 | SMLoc BraceLoc = Lex.getLoc(); | |||
2749 | // Otherwise, this is a group let. | |||
2750 | Lex.Lex(); // eat the '{'. | |||
2751 | ||||
2752 | // Parse the object list. | |||
2753 | if (ParseObjectList(CurMultiClass)) | |||
2754 | return true; | |||
2755 | ||||
2756 | if (Lex.getCode() != tgtok::r_brace) { | |||
2757 | TokError("expected '}' at end of top level let command"); | |||
2758 | return Error(BraceLoc, "to match this '{'"); | |||
2759 | } | |||
2760 | Lex.Lex(); | |||
2761 | } | |||
2762 | ||||
2763 | // Outside this let scope, this let block is not active. | |||
2764 | LetStack.pop_back(); | |||
2765 | return false; | |||
2766 | } | |||
2767 | ||||
2768 | /// ParseMultiClass - Parse a multiclass definition. | |||
2769 | /// | |||
2770 | /// MultiClassInst ::= MULTICLASS ID TemplateArgList? | |||
2771 | /// ':' BaseMultiClassList '{' MultiClassObject+ '}' | |||
2772 | /// MultiClassObject ::= DefInst | |||
2773 | /// MultiClassObject ::= MultiClassInst | |||
2774 | /// MultiClassObject ::= DefMInst | |||
2775 | /// MultiClassObject ::= LETCommand '{' ObjectList '}' | |||
2776 | /// MultiClassObject ::= LETCommand Object | |||
2777 | /// | |||
2778 | bool TGParser::ParseMultiClass() { | |||
2779 | assert(Lex.getCode() == tgtok::MultiClass && "Unexpected token")((Lex.getCode() == tgtok::MultiClass && "Unexpected token" ) ? static_cast<void> (0) : __assert_fail ("Lex.getCode() == tgtok::MultiClass && \"Unexpected token\"" , "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 2779, __PRETTY_FUNCTION__)); | |||
2780 | Lex.Lex(); // Eat the multiclass token. | |||
2781 | ||||
2782 | if (Lex.getCode() != tgtok::Id) | |||
2783 | return TokError("expected identifier after multiclass for name"); | |||
2784 | std::string Name = Lex.getCurStrVal(); | |||
2785 | ||||
2786 | auto Result = | |||
2787 | MultiClasses.insert(std::make_pair(Name, | |||
2788 | llvm::make_unique<MultiClass>(Name, Lex.getLoc(),Records))); | |||
2789 | ||||
2790 | if (!Result.second) | |||
2791 | return TokError("multiclass '" + Name + "' already defined"); | |||
2792 | ||||
2793 | CurMultiClass = Result.first->second.get(); | |||
2794 | Lex.Lex(); // Eat the identifier. | |||
2795 | ||||
2796 | // If there are template args, parse them. | |||
2797 | if (Lex.getCode() == tgtok::less) | |||
2798 | if (ParseTemplateArgList(nullptr)) | |||
2799 | return true; | |||
2800 | ||||
2801 | bool inherits = false; | |||
2802 | ||||
2803 | // If there are submulticlasses, parse them. | |||
2804 | if (Lex.getCode() == tgtok::colon) { | |||
2805 | inherits = true; | |||
2806 | ||||
2807 | Lex.Lex(); | |||
2808 | ||||
2809 | // Read all of the submulticlasses. | |||
2810 | SubMultiClassReference SubMultiClass = | |||
2811 | ParseSubMultiClassReference(CurMultiClass); | |||
2812 | while (true) { | |||
2813 | // Check for error. | |||
2814 | if (!SubMultiClass.MC) return true; | |||
2815 | ||||
2816 | // Add it. | |||
2817 | if (AddSubMultiClass(CurMultiClass, SubMultiClass)) | |||
2818 | return true; | |||
2819 | ||||
2820 | if (Lex.getCode() != tgtok::comma) break; | |||
2821 | Lex.Lex(); // eat ','. | |||
2822 | SubMultiClass = ParseSubMultiClassReference(CurMultiClass); | |||
2823 | } | |||
2824 | } | |||
2825 | ||||
2826 | if (Lex.getCode() != tgtok::l_brace) { | |||
2827 | if (!inherits) | |||
2828 | return TokError("expected '{' in multiclass definition"); | |||
2829 | if (Lex.getCode() != tgtok::semi) | |||
2830 | return TokError("expected ';' in multiclass definition"); | |||
2831 | Lex.Lex(); // eat the ';'. | |||
2832 | } else { | |||
2833 | if (Lex.Lex() == tgtok::r_brace) // eat the '{'. | |||
2834 | return TokError("multiclass must contain at least one def"); | |||
2835 | ||||
2836 | while (Lex.getCode() != tgtok::r_brace) { | |||
2837 | switch (Lex.getCode()) { | |||
2838 | default: | |||
2839 | return TokError("expected 'let', 'def', 'defm' or 'foreach' in " | |||
2840 | "multiclass body"); | |||
2841 | case tgtok::Let: | |||
2842 | case tgtok::Def: | |||
2843 | case tgtok::Defm: | |||
2844 | case tgtok::Foreach: | |||
2845 | if (ParseObject(CurMultiClass)) | |||
2846 | return true; | |||
2847 | break; | |||
2848 | } | |||
2849 | } | |||
2850 | Lex.Lex(); // eat the '}'. | |||
2851 | } | |||
2852 | ||||
2853 | CurMultiClass = nullptr; | |||
2854 | return false; | |||
2855 | } | |||
2856 | ||||
2857 | /// ParseDefm - Parse the instantiation of a multiclass. | |||
2858 | /// | |||
2859 | /// DefMInst ::= DEFM ID ':' DefmSubClassRef ';' | |||
2860 | /// | |||
2861 | bool TGParser::ParseDefm(MultiClass *CurMultiClass) { | |||
2862 | assert(Lex.getCode() == tgtok::Defm && "Unexpected token!")((Lex.getCode() == tgtok::Defm && "Unexpected token!" ) ? static_cast<void> (0) : __assert_fail ("Lex.getCode() == tgtok::Defm && \"Unexpected token!\"" , "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 2862, __PRETTY_FUNCTION__)); | |||
2863 | Lex.Lex(); // eat the defm | |||
2864 | ||||
2865 | Init *DefmName = ParseObjectName(CurMultiClass); | |||
2866 | if (!DefmName) | |||
2867 | return true; | |||
2868 | if (isa<UnsetInit>(DefmName)) { | |||
2869 | DefmName = Records.getNewAnonymousName(); | |||
2870 | if (CurMultiClass) | |||
2871 | DefmName = BinOpInit::getStrConcat( | |||
2872 | VarInit::get(QualifiedNameOfImplicitName(CurMultiClass), | |||
2873 | StringRecTy::get()), | |||
2874 | DefmName); | |||
2875 | } | |||
2876 | ||||
2877 | if (Lex.getCode() != tgtok::colon) | |||
2878 | return TokError("expected ':' after defm identifier"); | |||
2879 | ||||
2880 | // Keep track of the new generated record definitions. | |||
2881 | std::vector<RecordsEntry> NewEntries; | |||
2882 | ||||
2883 | // This record also inherits from a regular class (non-multiclass)? | |||
2884 | bool InheritFromClass = false; | |||
2885 | ||||
2886 | // eat the colon. | |||
2887 | Lex.Lex(); | |||
2888 | ||||
2889 | SMLoc SubClassLoc = Lex.getLoc(); | |||
2890 | SubClassReference Ref = ParseSubClassReference(nullptr, true); | |||
2891 | ||||
2892 | while (true) { | |||
2893 | if (!Ref.Rec) return true; | |||
2894 | ||||
2895 | // To instantiate a multiclass, we need to first get the multiclass, then | |||
2896 | // instantiate each def contained in the multiclass with the SubClassRef | |||
2897 | // template parameters. | |||
2898 | MultiClass *MC = MultiClasses[Ref.Rec->getName()].get(); | |||
2899 | assert(MC && "Didn't lookup multiclass correctly?")((MC && "Didn't lookup multiclass correctly?") ? static_cast <void> (0) : __assert_fail ("MC && \"Didn't lookup multiclass correctly?\"" , "/build/llvm-toolchain-snapshot-8~svn350071/lib/TableGen/TGParser.cpp" , 2899, __PRETTY_FUNCTION__)); | |||
2900 | ArrayRef<Init*> TemplateVals = Ref.TemplateArgs; | |||
2901 | ||||
2902 | // Verify that the correct number of template arguments were specified. | |||
2903 | ArrayRef<Init *> TArgs = MC->Rec.getTemplateArgs(); | |||
2904 | if (TArgs.size() < TemplateVals.size()) | |||
2905 | return Error(SubClassLoc, | |||
2906 | "more template args specified than multiclass expects"); | |||
2907 | ||||
2908 | SubstStack Substs; | |||
2909 | for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { | |||
2910 | if (i < TemplateVals.size()) { | |||
2911 | Substs.emplace_back(TArgs[i], TemplateVals[i]); | |||
2912 | } else { | |||
2913 | Init *Default = MC->Rec.getValue(TArgs[i])->getValue(); | |||
2914 | if (!Default->isComplete()) { | |||
2915 | return Error(SubClassLoc, | |||
2916 | "value not specified for template argument #" + | |||
2917 | Twine(i) + " (" + TArgs[i]->getAsUnquotedString() + | |||
2918 | ") of multiclass '" + MC->Rec.getNameInitAsString() + | |||
2919 | "'"); | |||
2920 | } | |||
2921 | Substs.emplace_back(TArgs[i], Default); | |||
2922 | } | |||
2923 | } | |||
2924 | ||||
2925 | Substs.emplace_back(QualifiedNameOfImplicitName(MC), DefmName); | |||
2926 | ||||
2927 | if (resolve(MC->Entries, Substs, CurMultiClass == nullptr, &NewEntries, | |||
2928 | &SubClassLoc)) | |||
2929 | return true; | |||
2930 | ||||
2931 | if (Lex.getCode() != tgtok::comma) break; | |||
2932 | Lex.Lex(); // eat ','. | |||
2933 | ||||
2934 | if (Lex.getCode() != tgtok::Id) | |||
2935 | return TokError("expected identifier"); | |||
2936 | ||||
2937 | SubClassLoc = Lex.getLoc(); | |||
2938 | ||||
2939 | // A defm can inherit from regular classes (non-multiclass) as | |||
2940 | // long as they come in the end of the inheritance list. | |||
2941 | InheritFromClass = (Records.getClass(Lex.getCurStrVal()) != nullptr); | |||
2942 | ||||
2943 | if (InheritFromClass) | |||
2944 | break; | |||
2945 | ||||
2946 | Ref = ParseSubClassReference(nullptr, true); | |||
2947 | } | |||
2948 | ||||
2949 | if (InheritFromClass) { | |||
2950 | // Process all the classes to inherit as if they were part of a | |||
2951 | // regular 'def' and inherit all record values. | |||
2952 | SubClassReference SubClass = ParseSubClassReference(nullptr, false); | |||
2953 | while (true) { | |||
2954 | // Check for error. | |||
2955 | if (!SubClass.Rec) return true; | |||
2956 | ||||
2957 | // Get the expanded definition prototypes and teach them about | |||
2958 | // the record values the current class to inherit has | |||
2959 | for (auto &E : NewEntries) { | |||
2960 | // Add it. | |||
2961 | if (AddSubClass(E, SubClass)) | |||
2962 | return true; | |||
2963 | } | |||
2964 | ||||
2965 | if (Lex.getCode() != tgtok::comma) break; | |||
2966 | Lex.Lex(); // eat ','. | |||
2967 | SubClass = ParseSubClassReference(nullptr, false); | |||
2968 | } | |||
2969 | } | |||
2970 | ||||
2971 | for (auto &E : NewEntries) { | |||
2972 | if (ApplyLetStack(E)) | |||
2973 | return true; | |||
2974 | ||||
2975 | addEntry(std::move(E)); | |||
2976 | } | |||
2977 | ||||
2978 | if (Lex.getCode() != tgtok::semi) | |||
2979 | return TokError("expected ';' at end of defm"); | |||
2980 | Lex.Lex(); | |||
2981 | ||||
2982 | return false; | |||
2983 | } | |||
2984 | ||||
2985 | /// ParseObject | |||
2986 | /// Object ::= ClassInst | |||
2987 | /// Object ::= DefInst | |||
2988 | /// Object ::= MultiClassInst | |||
2989 | /// Object ::= DefMInst | |||
2990 | /// Object ::= LETCommand '{' ObjectList '}' | |||
2991 | /// Object ::= LETCommand Object | |||
2992 | bool TGParser::ParseObject(MultiClass *MC) { | |||
2993 | switch (Lex.getCode()) { | |||
2994 | default: | |||
2995 | return TokError("Expected class, def, defm, defset, multiclass, let or " | |||
2996 | "foreach"); | |||
2997 | case tgtok::Let: return ParseTopLevelLet(MC); | |||
2998 | case tgtok::Def: return ParseDef(MC); | |||
2999 | case tgtok::Foreach: return ParseForeach(MC); | |||
3000 | case tgtok::Defm: return ParseDefm(MC); | |||
3001 | case tgtok::Defset: | |||
3002 | if (MC) | |||
3003 | return TokError("defset is not allowed inside multiclass"); | |||
3004 | return ParseDefset(); | |||
3005 | case tgtok::Class: | |||
3006 | if (MC) | |||
3007 | return TokError("class is not allowed inside multiclass"); | |||
3008 | if (!Loops.empty()) | |||
3009 | return TokError("class is not allowed inside foreach loop"); | |||
3010 | return ParseClass(); | |||
3011 | case tgtok::MultiClass: | |||
3012 | if (!Loops.empty()) | |||
3013 | return TokError("multiclass is not allowed inside foreach loop"); | |||
3014 | return ParseMultiClass(); | |||
3015 | } | |||
3016 | } | |||
3017 | ||||
3018 | /// ParseObjectList | |||
3019 | /// ObjectList :== Object* | |||
3020 | bool TGParser::ParseObjectList(MultiClass *MC) { | |||
3021 | while (isObjectStart(Lex.getCode())) { | |||
3022 | if (ParseObject(MC)) | |||
3023 | return true; | |||
3024 | } | |||
3025 | return false; | |||
3026 | } | |||
3027 | ||||
3028 | bool TGParser::ParseFile() { | |||
3029 | Lex.Lex(); // Prime the lexer. | |||
3030 | if (ParseObjectList()) return true; | |||
3031 | ||||
3032 | // If we have unread input at the end of the file, report it. | |||
3033 | if (Lex.getCode() == tgtok::Eof) | |||
3034 | return false; | |||
3035 | ||||
3036 | return TokError("Unexpected input at top level"); | |||
3037 | } | |||
3038 | ||||
3039 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | |||
3040 | LLVM_DUMP_METHOD__attribute__((noinline)) __attribute__((__used__)) void RecordsEntry::dump() const { | |||
3041 | if (Loop) | |||
3042 | Loop->dump(); | |||
3043 | if (Rec) | |||
3044 | Rec->dump(); | |||
3045 | } | |||
3046 | ||||
3047 | LLVM_DUMP_METHOD__attribute__((noinline)) __attribute__((__used__)) void ForeachLoop::dump() const { | |||
3048 | errs() << "foreach " << IterVar->getAsString() << " = " | |||
3049 | << ListValue->getAsString() << " in {\n"; | |||
3050 | ||||
3051 | for (const auto &E : Entries) | |||
3052 | E.dump(); | |||
3053 | ||||
3054 | errs() << "}\n"; | |||
3055 | } | |||
3056 | ||||
3057 | LLVM_DUMP_METHOD__attribute__((noinline)) __attribute__((__used__)) void MultiClass::dump() const { | |||
3058 | errs() << "Record:\n"; | |||
3059 | Rec.dump(); | |||
3060 | ||||
3061 | errs() << "Defs:\n"; | |||
3062 | for (const auto &E : Entries) | |||
3063 | E.dump(); | |||
3064 | } | |||
3065 | #endif |
1 | //===- llvm/Support/Casting.h - Allow flexible, checked, casts --*- C++ -*-===// |
2 | // |
3 | // The LLVM Compiler Infrastructure |
4 | // |
5 | // This file is distributed under the University of Illinois Open Source |
6 | // License. See LICENSE.TXT for details. |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | // |
10 | // This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(), |
11 | // and dyn_cast_or_null<X>() templates. |
12 | // |
13 | //===----------------------------------------------------------------------===// |
14 | |
15 | #ifndef LLVM_SUPPORT_CASTING_H |
16 | #define LLVM_SUPPORT_CASTING_H |
17 | |
18 | #include "llvm/Support/Compiler.h" |
19 | #include "llvm/Support/type_traits.h" |
20 | #include <cassert> |
21 | #include <memory> |
22 | #include <type_traits> |
23 | |
24 | namespace llvm { |
25 | |
26 | //===----------------------------------------------------------------------===// |
27 | // isa<x> Support Templates |
28 | //===----------------------------------------------------------------------===// |
29 | |
30 | // Define a template that can be specialized by smart pointers to reflect the |
31 | // fact that they are automatically dereferenced, and are not involved with the |
32 | // template selection process... the default implementation is a noop. |
33 | // |
34 | template<typename From> struct simplify_type { |
35 | using SimpleType = From; // The real type this represents... |
36 | |
37 | // An accessor to get the real value... |
38 | static SimpleType &getSimplifiedValue(From &Val) { return Val; } |
39 | }; |
40 | |
41 | template<typename From> struct simplify_type<const From> { |
42 | using NonConstSimpleType = typename simplify_type<From>::SimpleType; |
43 | using SimpleType = |
44 | typename add_const_past_pointer<NonConstSimpleType>::type; |
45 | using RetType = |
46 | typename add_lvalue_reference_if_not_pointer<SimpleType>::type; |
47 | |
48 | static RetType getSimplifiedValue(const From& Val) { |
49 | return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val)); |
50 | } |
51 | }; |
52 | |
53 | // The core of the implementation of isa<X> is here; To and From should be |
54 | // the names of classes. This template can be specialized to customize the |
55 | // implementation of isa<> without rewriting it from scratch. |
56 | template <typename To, typename From, typename Enabler = void> |
57 | struct isa_impl { |
58 | static inline bool doit(const From &Val) { |
59 | return To::classof(&Val); |
60 | } |
61 | }; |
62 | |
63 | /// Always allow upcasts, and perform no dynamic check for them. |
64 | template <typename To, typename From> |
65 | struct isa_impl< |
66 | To, From, typename std::enable_if<std::is_base_of<To, From>::value>::type> { |
67 | static inline bool doit(const From &) { return true; } |
68 | }; |
69 | |
70 | template <typename To, typename From> struct isa_impl_cl { |
71 | static inline bool doit(const From &Val) { |
72 | return isa_impl<To, From>::doit(Val); |
73 | } |
74 | }; |
75 | |
76 | template <typename To, typename From> struct isa_impl_cl<To, const From> { |
77 | static inline bool doit(const From &Val) { |
78 | return isa_impl<To, From>::doit(Val); |
79 | } |
80 | }; |
81 | |
82 | template <typename To, typename From> |
83 | struct isa_impl_cl<To, const std::unique_ptr<From>> { |
84 | static inline bool doit(const std::unique_ptr<From> &Val) { |
85 | assert(Val && "isa<> used on a null pointer")((Val && "isa<> used on a null pointer") ? static_cast <void> (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-8~svn350071/include/llvm/Support/Casting.h" , 85, __PRETTY_FUNCTION__)); |
86 | return isa_impl_cl<To, From>::doit(*Val); |
87 | } |
88 | }; |
89 | |
90 | template <typename To, typename From> struct isa_impl_cl<To, From*> { |
91 | static inline bool doit(const From *Val) { |
92 | assert(Val && "isa<> used on a null pointer")((Val && "isa<> used on a null pointer") ? static_cast <void> (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-8~svn350071/include/llvm/Support/Casting.h" , 92, __PRETTY_FUNCTION__)); |
93 | return isa_impl<To, From>::doit(*Val); |
94 | } |
95 | }; |
96 | |
97 | template <typename To, typename From> struct isa_impl_cl<To, From*const> { |
98 | static inline bool doit(const From *Val) { |
99 | assert(Val && "isa<> used on a null pointer")((Val && "isa<> used on a null pointer") ? static_cast <void> (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-8~svn350071/include/llvm/Support/Casting.h" , 99, __PRETTY_FUNCTION__)); |
100 | return isa_impl<To, From>::doit(*Val); |
101 | } |
102 | }; |
103 | |
104 | template <typename To, typename From> struct isa_impl_cl<To, const From*> { |
105 | static inline bool doit(const From *Val) { |
106 | assert(Val && "isa<> used on a null pointer")((Val && "isa<> used on a null pointer") ? static_cast <void> (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-8~svn350071/include/llvm/Support/Casting.h" , 106, __PRETTY_FUNCTION__)); |
107 | return isa_impl<To, From>::doit(*Val); |
108 | } |
109 | }; |
110 | |
111 | template <typename To, typename From> struct isa_impl_cl<To, const From*const> { |
112 | static inline bool doit(const From *Val) { |
113 | assert(Val && "isa<> used on a null pointer")((Val && "isa<> used on a null pointer") ? static_cast <void> (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-8~svn350071/include/llvm/Support/Casting.h" , 113, __PRETTY_FUNCTION__)); |
114 | return isa_impl<To, From>::doit(*Val); |
115 | } |
116 | }; |
117 | |
118 | template<typename To, typename From, typename SimpleFrom> |
119 | struct isa_impl_wrap { |
120 | // When From != SimplifiedType, we can simplify the type some more by using |
121 | // the simplify_type template. |
122 | static bool doit(const From &Val) { |
123 | return isa_impl_wrap<To, SimpleFrom, |
124 | typename simplify_type<SimpleFrom>::SimpleType>::doit( |
125 | simplify_type<const From>::getSimplifiedValue(Val)); |
126 | } |
127 | }; |
128 | |
129 | template<typename To, typename FromTy> |
130 | struct isa_impl_wrap<To, FromTy, FromTy> { |
131 | // When From == SimpleType, we are as simple as we are going to get. |
132 | static bool doit(const FromTy &Val) { |
133 | return isa_impl_cl<To,FromTy>::doit(Val); |
134 | } |
135 | }; |
136 | |
137 | // isa<X> - Return true if the parameter to the template is an instance of the |
138 | // template type argument. Used like this: |
139 | // |
140 | // if (isa<Type>(myVal)) { ... } |
141 | // |
142 | template <class X, class Y> LLVM_NODISCARD[[clang::warn_unused_result]] inline bool isa(const Y &Val) { |
143 | return isa_impl_wrap<X, const Y, |
144 | typename simplify_type<const Y>::SimpleType>::doit(Val); |
145 | } |
146 | |
147 | //===----------------------------------------------------------------------===// |
148 | // cast<x> Support Templates |
149 | //===----------------------------------------------------------------------===// |
150 | |
151 | template<class To, class From> struct cast_retty; |
152 | |
153 | // Calculate what type the 'cast' function should return, based on a requested |
154 | // type of To and a source type of From. |
155 | template<class To, class From> struct cast_retty_impl { |
156 | using ret_type = To &; // Normal case, return Ty& |
157 | }; |
158 | template<class To, class From> struct cast_retty_impl<To, const From> { |
159 | using ret_type = const To &; // Normal case, return Ty& |
160 | }; |
161 | |
162 | template<class To, class From> struct cast_retty_impl<To, From*> { |
163 | using ret_type = To *; // Pointer arg case, return Ty* |
164 | }; |
165 | |
166 | template<class To, class From> struct cast_retty_impl<To, const From*> { |
167 | using ret_type = const To *; // Constant pointer arg case, return const Ty* |
168 | }; |
169 | |
170 | template<class To, class From> struct cast_retty_impl<To, const From*const> { |
171 | using ret_type = const To *; // Constant pointer arg case, return const Ty* |
172 | }; |
173 | |
174 | template <class To, class From> |
175 | struct cast_retty_impl<To, std::unique_ptr<From>> { |
176 | private: |
177 | using PointerType = typename cast_retty_impl<To, From *>::ret_type; |
178 | using ResultType = typename std::remove_pointer<PointerType>::type; |
179 | |
180 | public: |
181 | using ret_type = std::unique_ptr<ResultType>; |
182 | }; |
183 | |
184 | template<class To, class From, class SimpleFrom> |
185 | struct cast_retty_wrap { |
186 | // When the simplified type and the from type are not the same, use the type |
187 | // simplifier to reduce the type, then reuse cast_retty_impl to get the |
188 | // resultant type. |
189 | using ret_type = typename cast_retty<To, SimpleFrom>::ret_type; |
190 | }; |
191 | |
192 | template<class To, class FromTy> |
193 | struct cast_retty_wrap<To, FromTy, FromTy> { |
194 | // When the simplified type is equal to the from type, use it directly. |
195 | using ret_type = typename cast_retty_impl<To,FromTy>::ret_type; |
196 | }; |
197 | |
198 | template<class To, class From> |
199 | struct cast_retty { |
200 | using ret_type = typename cast_retty_wrap< |
201 | To, From, typename simplify_type<From>::SimpleType>::ret_type; |
202 | }; |
203 | |
204 | // Ensure the non-simple values are converted using the simplify_type template |
205 | // that may be specialized by smart pointers... |
206 | // |
207 | template<class To, class From, class SimpleFrom> struct cast_convert_val { |
208 | // This is not a simple type, use the template to simplify it... |
209 | static typename cast_retty<To, From>::ret_type doit(From &Val) { |
210 | return cast_convert_val<To, SimpleFrom, |
211 | typename simplify_type<SimpleFrom>::SimpleType>::doit( |
212 | simplify_type<From>::getSimplifiedValue(Val)); |
213 | } |
214 | }; |
215 | |
216 | template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> { |
217 | // This _is_ a simple type, just cast it. |
218 | static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) { |
219 | typename cast_retty<To, FromTy>::ret_type Res2 |
220 | = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val); |
221 | return Res2; |
222 | } |
223 | }; |
224 | |
225 | template <class X> struct is_simple_type { |
226 | static const bool value = |
227 | std::is_same<X, typename simplify_type<X>::SimpleType>::value; |
228 | }; |
229 | |
230 | // cast<X> - Return the argument parameter cast to the specified type. This |
231 | // casting operator asserts that the type is correct, so it does not return null |
232 | // on failure. It does not allow a null argument (use cast_or_null for that). |
233 | // It is typically used like this: |
234 | // |
235 | // cast<Instruction>(myVal)->getParent() |
236 | // |
237 | template <class X, class Y> |
238 | inline typename std::enable_if<!is_simple_type<Y>::value, |
239 | typename cast_retty<X, const Y>::ret_type>::type |
240 | cast(const Y &Val) { |
241 | assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")((isa<X>(Val) && "cast<Ty>() argument of incompatible type!" ) ? static_cast<void> (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-8~svn350071/include/llvm/Support/Casting.h" , 241, __PRETTY_FUNCTION__)); |
242 | return cast_convert_val< |
243 | X, const Y, typename simplify_type<const Y>::SimpleType>::doit(Val); |
244 | } |
245 | |
246 | template <class X, class Y> |
247 | inline typename cast_retty<X, Y>::ret_type cast(Y &Val) { |
248 | assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")((isa<X>(Val) && "cast<Ty>() argument of incompatible type!" ) ? static_cast<void> (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-8~svn350071/include/llvm/Support/Casting.h" , 248, __PRETTY_FUNCTION__)); |
249 | return cast_convert_val<X, Y, |
250 | typename simplify_type<Y>::SimpleType>::doit(Val); |
251 | } |
252 | |
253 | template <class X, class Y> |
254 | inline typename cast_retty<X, Y *>::ret_type cast(Y *Val) { |
255 | assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")((isa<X>(Val) && "cast<Ty>() argument of incompatible type!" ) ? static_cast<void> (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-8~svn350071/include/llvm/Support/Casting.h" , 255, __PRETTY_FUNCTION__)); |
256 | return cast_convert_val<X, Y*, |
257 | typename simplify_type<Y*>::SimpleType>::doit(Val); |
258 | } |
259 | |
260 | template <class X, class Y> |
261 | inline typename cast_retty<X, std::unique_ptr<Y>>::ret_type |
262 | cast(std::unique_ptr<Y> &&Val) { |
263 | assert(isa<X>(Val.get()) && "cast<Ty>() argument of incompatible type!")((isa<X>(Val.get()) && "cast<Ty>() argument of incompatible type!" ) ? static_cast<void> (0) : __assert_fail ("isa<X>(Val.get()) && \"cast<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-8~svn350071/include/llvm/Support/Casting.h" , 263, __PRETTY_FUNCTION__)); |
264 | using ret_type = typename cast_retty<X, std::unique_ptr<Y>>::ret_type; |
265 | return ret_type( |
266 | cast_convert_val<X, Y *, typename simplify_type<Y *>::SimpleType>::doit( |
267 | Val.release())); |
268 | } |
269 | |
270 | // cast_or_null<X> - Functionally identical to cast, except that a null value is |
271 | // accepted. |
272 | // |
273 | template <class X, class Y> |
274 | LLVM_NODISCARD[[clang::warn_unused_result]] inline |
275 | typename std::enable_if<!is_simple_type<Y>::value, |
276 | typename cast_retty<X, const Y>::ret_type>::type |
277 | cast_or_null(const Y &Val) { |
278 | if (!Val) |
279 | return nullptr; |
280 | assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")((isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!" ) ? static_cast<void> (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-8~svn350071/include/llvm/Support/Casting.h" , 280, __PRETTY_FUNCTION__)); |
281 | return cast<X>(Val); |
282 | } |
283 | |
284 | template <class X, class Y> |
285 | LLVM_NODISCARD[[clang::warn_unused_result]] inline |
286 | typename std::enable_if<!is_simple_type<Y>::value, |
287 | typename cast_retty<X, Y>::ret_type>::type |
288 | cast_or_null(Y &Val) { |
289 | if (!Val) |
290 | return nullptr; |
291 | assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")((isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!" ) ? static_cast<void> (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-8~svn350071/include/llvm/Support/Casting.h" , 291, __PRETTY_FUNCTION__)); |
292 | return cast<X>(Val); |
293 | } |
294 | |
295 | template <class X, class Y> |
296 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type |
297 | cast_or_null(Y *Val) { |
298 | if (!Val) return nullptr; |
299 | assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")((isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!" ) ? static_cast<void> (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-8~svn350071/include/llvm/Support/Casting.h" , 299, __PRETTY_FUNCTION__)); |
300 | return cast<X>(Val); |
301 | } |
302 | |
303 | template <class X, class Y> |
304 | inline typename cast_retty<X, std::unique_ptr<Y>>::ret_type |
305 | cast_or_null(std::unique_ptr<Y> &&Val) { |
306 | if (!Val) |
307 | return nullptr; |
308 | return cast<X>(std::move(Val)); |
309 | } |
310 | |
311 | // dyn_cast<X> - Return the argument parameter cast to the specified type. This |
312 | // casting operator returns null if the argument is of the wrong type, so it can |
313 | // be used to test for a type as well as cast if successful. This should be |
314 | // used in the context of an if statement like this: |
315 | // |
316 | // if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... } |
317 | // |
318 | |
319 | template <class X, class Y> |
320 | LLVM_NODISCARD[[clang::warn_unused_result]] inline |
321 | typename std::enable_if<!is_simple_type<Y>::value, |
322 | typename cast_retty<X, const Y>::ret_type>::type |
323 | dyn_cast(const Y &Val) { |
324 | return isa<X>(Val) ? cast<X>(Val) : nullptr; |
325 | } |
326 | |
327 | template <class X, class Y> |
328 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y>::ret_type dyn_cast(Y &Val) { |
329 | return isa<X>(Val) ? cast<X>(Val) : nullptr; |
330 | } |
331 | |
332 | template <class X, class Y> |
333 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type dyn_cast(Y *Val) { |
334 | return isa<X>(Val) ? cast<X>(Val) : nullptr; |
335 | } |
336 | |
337 | // dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null |
338 | // value is accepted. |
339 | // |
340 | template <class X, class Y> |
341 | LLVM_NODISCARD[[clang::warn_unused_result]] inline |
342 | typename std::enable_if<!is_simple_type<Y>::value, |
343 | typename cast_retty<X, const Y>::ret_type>::type |
344 | dyn_cast_or_null(const Y &Val) { |
345 | return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; |
346 | } |
347 | |
348 | template <class X, class Y> |
349 | LLVM_NODISCARD[[clang::warn_unused_result]] inline |
350 | typename std::enable_if<!is_simple_type<Y>::value, |
351 | typename cast_retty<X, Y>::ret_type>::type |
352 | dyn_cast_or_null(Y &Val) { |
353 | return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; |
354 | } |
355 | |
356 | template <class X, class Y> |
357 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type |
358 | dyn_cast_or_null(Y *Val) { |
359 | return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; |
360 | } |
361 | |
362 | // unique_dyn_cast<X> - Given a unique_ptr<Y>, try to return a unique_ptr<X>, |
363 | // taking ownership of the input pointer iff isa<X>(Val) is true. If the |
364 | // cast is successful, From refers to nullptr on exit and the casted value |
365 | // is returned. If the cast is unsuccessful, the function returns nullptr |
366 | // and From is unchanged. |
367 | template <class X, class Y> |
368 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast(std::unique_ptr<Y> &Val) |
369 | -> decltype(cast<X>(Val)) { |
370 | if (!isa<X>(Val)) |
371 | return nullptr; |
372 | return cast<X>(std::move(Val)); |
373 | } |
374 | |
375 | template <class X, class Y> |
376 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast(std::unique_ptr<Y> &&Val) |
377 | -> decltype(cast<X>(Val)) { |
378 | return unique_dyn_cast<X, Y>(Val); |
379 | } |
380 | |
381 | // dyn_cast_or_null<X> - Functionally identical to unique_dyn_cast, except that |
382 | // a null value is accepted. |
383 | template <class X, class Y> |
384 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &Val) |
385 | -> decltype(cast<X>(Val)) { |
386 | if (!Val) |
387 | return nullptr; |
388 | return unique_dyn_cast<X, Y>(Val); |
389 | } |
390 | |
391 | template <class X, class Y> |
392 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &&Val) |
393 | -> decltype(cast<X>(Val)) { |
394 | return unique_dyn_cast_or_null<X, Y>(Val); |
395 | } |
396 | |
397 | } // end namespace llvm |
398 | |
399 | #endif // LLVM_SUPPORT_CASTING_H |