1226584Sdim//===- Record.cpp - Record implementation ---------------------------------===//
2226584Sdim//
3226584Sdim//                     The LLVM Compiler Infrastructure
4226584Sdim//
5226584Sdim// This file is distributed under the University of Illinois Open Source
6226584Sdim// License. See LICENSE.TXT for details.
7226584Sdim//
8226584Sdim//===----------------------------------------------------------------------===//
9226584Sdim//
10226584Sdim// Implement the tablegen record classes.
11226584Sdim//
12226584Sdim//===----------------------------------------------------------------------===//
13226584Sdim
14226584Sdim#include "llvm/TableGen/Record.h"
15226584Sdim#include "llvm/ADT/DenseMap.h"
16226584Sdim#include "llvm/ADT/FoldingSet.h"
17234353Sdim#include "llvm/ADT/Hashing.h"
18249423Sdim#include "llvm/ADT/STLExtras.h"
19226584Sdim#include "llvm/ADT/SmallVector.h"
20226584Sdim#include "llvm/ADT/StringExtras.h"
21226584Sdim#include "llvm/ADT/StringMap.h"
22249423Sdim#include "llvm/Support/DataTypes.h"
23249423Sdim#include "llvm/Support/ErrorHandling.h"
24249423Sdim#include "llvm/Support/Format.h"
25249423Sdim#include "llvm/TableGen/Error.h"
26226584Sdim
27226584Sdimusing namespace llvm;
28226584Sdim
29226584Sdim//===----------------------------------------------------------------------===//
30226584Sdim//    std::string wrapper for DenseMap purposes
31226584Sdim//===----------------------------------------------------------------------===//
32226584Sdim
33234353Sdimnamespace llvm {
34234353Sdim
35226584Sdim/// TableGenStringKey - This is a wrapper for std::string suitable for
36226584Sdim/// using as a key to a DenseMap.  Because there isn't a particularly
37226584Sdim/// good way to indicate tombstone or empty keys for strings, we want
38226584Sdim/// to wrap std::string to indicate that this is a "special" string
39226584Sdim/// not expected to take on certain values (those of the tombstone and
40226584Sdim/// empty keys).  This makes things a little safer as it clarifies
41226584Sdim/// that DenseMap is really not appropriate for general strings.
42226584Sdim
43226584Sdimclass TableGenStringKey {
44226584Sdimpublic:
45226584Sdim  TableGenStringKey(const std::string &str) : data(str) {}
46226584Sdim  TableGenStringKey(const char *str) : data(str) {}
47226584Sdim
48226584Sdim  const std::string &str() const { return data; }
49234353Sdim
50234353Sdim  friend hash_code hash_value(const TableGenStringKey &Value) {
51234353Sdim    using llvm::hash_value;
52234353Sdim    return hash_value(Value.str());
53234353Sdim  }
54226584Sdimprivate:
55226584Sdim  std::string data;
56226584Sdim};
57226584Sdim
58226584Sdim/// Specialize DenseMapInfo for TableGenStringKey.
59226584Sdimtemplate<> struct DenseMapInfo<TableGenStringKey> {
60226584Sdim  static inline TableGenStringKey getEmptyKey() {
61226584Sdim    TableGenStringKey Empty("<<<EMPTY KEY>>>");
62226584Sdim    return Empty;
63226584Sdim  }
64226584Sdim  static inline TableGenStringKey getTombstoneKey() {
65226584Sdim    TableGenStringKey Tombstone("<<<TOMBSTONE KEY>>>");
66226584Sdim    return Tombstone;
67226584Sdim  }
68226584Sdim  static unsigned getHashValue(const TableGenStringKey& Val) {
69234353Sdim    using llvm::hash_value;
70234353Sdim    return hash_value(Val);
71226584Sdim  }
72226584Sdim  static bool isEqual(const TableGenStringKey& LHS,
73226584Sdim                      const TableGenStringKey& RHS) {
74226584Sdim    return LHS.str() == RHS.str();
75226584Sdim  }
76226584Sdim};
77226584Sdim
78234353Sdim} // namespace llvm
79226584Sdim
80226584Sdim//===----------------------------------------------------------------------===//
81226584Sdim//    Type implementations
82226584Sdim//===----------------------------------------------------------------------===//
83226584Sdim
84226584SdimBitRecTy BitRecTy::Shared;
85226584SdimIntRecTy IntRecTy::Shared;
86226584SdimStringRecTy StringRecTy::Shared;
87226584SdimDagRecTy DagRecTy::Shared;
88226584Sdim
89234353Sdimvoid RecTy::anchor() { }
90226584Sdimvoid RecTy::dump() const { print(errs()); }
91226584Sdim
92226584SdimListRecTy *RecTy::getListTy() {
93226584Sdim  if (!ListTy)
94226584Sdim    ListTy = new ListRecTy(this);
95226584Sdim  return ListTy;
96226584Sdim}
97226584Sdim
98249423Sdimbool RecTy::baseClassOf(const RecTy *RHS) const{
99249423Sdim  assert (RHS && "NULL pointer");
100249423Sdim  return Kind == RHS->getRecTyKind();
101249423Sdim}
102249423Sdim
103226584SdimInit *BitRecTy::convertValue(BitsInit *BI) {
104226584Sdim  if (BI->getNumBits() != 1) return 0; // Only accept if just one bit!
105226584Sdim  return BI->getBit(0);
106226584Sdim}
107226584Sdim
108226584SdimInit *BitRecTy::convertValue(IntInit *II) {
109226584Sdim  int64_t Val = II->getValue();
110226584Sdim  if (Val != 0 && Val != 1) return 0;  // Only accept 0 or 1 for a bit!
111226584Sdim
112226584Sdim  return BitInit::get(Val != 0);
113226584Sdim}
114226584Sdim
115226584SdimInit *BitRecTy::convertValue(TypedInit *VI) {
116243830Sdim  RecTy *Ty = VI->getType();
117243830Sdim  if (isa<BitRecTy>(Ty) || isa<BitsRecTy>(Ty) || isa<IntRecTy>(Ty))
118226584Sdim    return VI;  // Accept variable if it is already of bit type!
119226584Sdim  return 0;
120226584Sdim}
121226584Sdim
122249423Sdimbool BitRecTy::baseClassOf(const RecTy *RHS) const{
123249423Sdim  if(RecTy::baseClassOf(RHS) || getRecTyKind() == IntRecTyKind)
124249423Sdim    return true;
125249423Sdim  if(const BitsRecTy *BitsTy = dyn_cast<BitsRecTy>(RHS))
126249423Sdim    return BitsTy->getNumBits() == 1;
127249423Sdim  return false;
128249423Sdim}
129249423Sdim
130226584SdimBitsRecTy *BitsRecTy::get(unsigned Sz) {
131226584Sdim  static std::vector<BitsRecTy*> Shared;
132226584Sdim  if (Sz >= Shared.size())
133226584Sdim    Shared.resize(Sz + 1);
134226584Sdim  BitsRecTy *&Ty = Shared[Sz];
135226584Sdim  if (!Ty)
136226584Sdim    Ty = new BitsRecTy(Sz);
137226584Sdim  return Ty;
138226584Sdim}
139226584Sdim
140226584Sdimstd::string BitsRecTy::getAsString() const {
141226584Sdim  return "bits<" + utostr(Size) + ">";
142226584Sdim}
143226584Sdim
144226584SdimInit *BitsRecTy::convertValue(UnsetInit *UI) {
145226584Sdim  SmallVector<Init *, 16> NewBits(Size);
146226584Sdim
147226584Sdim  for (unsigned i = 0; i != Size; ++i)
148226584Sdim    NewBits[i] = UnsetInit::get();
149226584Sdim
150226584Sdim  return BitsInit::get(NewBits);
151226584Sdim}
152226584Sdim
153226584SdimInit *BitsRecTy::convertValue(BitInit *UI) {
154226584Sdim  if (Size != 1) return 0;  // Can only convert single bit.
155226584Sdim          return BitsInit::get(UI);
156226584Sdim}
157226584Sdim
158226584Sdim/// canFitInBitfield - Return true if the number of bits is large enough to hold
159226584Sdim/// the integer value.
160226584Sdimstatic bool canFitInBitfield(int64_t Value, unsigned NumBits) {
161226584Sdim  // For example, with NumBits == 4, we permit Values from [-7 .. 15].
162226584Sdim  return (NumBits >= sizeof(Value) * 8) ||
163226584Sdim         (Value >> NumBits == 0) || (Value >> (NumBits-1) == -1);
164226584Sdim}
165226584Sdim
166226584Sdim/// convertValue from Int initializer to bits type: Split the integer up into the
167226584Sdim/// appropriate bits.
168226584Sdim///
169226584SdimInit *BitsRecTy::convertValue(IntInit *II) {
170226584Sdim  int64_t Value = II->getValue();
171226584Sdim  // Make sure this bitfield is large enough to hold the integer value.
172226584Sdim  if (!canFitInBitfield(Value, Size))
173226584Sdim    return 0;
174226584Sdim
175226584Sdim  SmallVector<Init *, 16> NewBits(Size);
176226584Sdim
177226584Sdim  for (unsigned i = 0; i != Size; ++i)
178226584Sdim    NewBits[i] = BitInit::get(Value & (1LL << i));
179226584Sdim
180226584Sdim  return BitsInit::get(NewBits);
181226584Sdim}
182226584Sdim
183226584SdimInit *BitsRecTy::convertValue(BitsInit *BI) {
184226584Sdim  // If the number of bits is right, return it.  Otherwise we need to expand or
185226584Sdim  // truncate.
186226584Sdim  if (BI->getNumBits() == Size) return BI;
187226584Sdim  return 0;
188226584Sdim}
189226584Sdim
190226584SdimInit *BitsRecTy::convertValue(TypedInit *VI) {
191243830Sdim  if (Size == 1 && isa<BitRecTy>(VI->getType()))
192226584Sdim    return BitsInit::get(VI);
193226584Sdim
194243830Sdim  if (VI->getType()->typeIsConvertibleTo(this)) {
195243830Sdim    SmallVector<Init *, 16> NewBits(Size);
196226584Sdim
197243830Sdim    for (unsigned i = 0; i != Size; ++i)
198243830Sdim      NewBits[i] = VarBitInit::get(VI, i);
199243830Sdim    return BitsInit::get(NewBits);
200226584Sdim  }
201226584Sdim
202226584Sdim  return 0;
203226584Sdim}
204226584Sdim
205249423Sdimbool BitsRecTy::baseClassOf(const RecTy *RHS) const{
206249423Sdim  if (RecTy::baseClassOf(RHS)) //argument and the receiver are the same type
207249423Sdim    return cast<BitsRecTy>(RHS)->Size == Size;
208249423Sdim  RecTyKind kind = RHS->getRecTyKind();
209249423Sdim  return (kind == BitRecTyKind && Size == 1) || (kind == IntRecTyKind);
210249423Sdim}
211249423Sdim
212226584SdimInit *IntRecTy::convertValue(BitInit *BI) {
213226584Sdim  return IntInit::get(BI->getValue());
214226584Sdim}
215226584Sdim
216226584SdimInit *IntRecTy::convertValue(BitsInit *BI) {
217226584Sdim  int64_t Result = 0;
218226584Sdim  for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
219243830Sdim    if (BitInit *Bit = dyn_cast<BitInit>(BI->getBit(i))) {
220226584Sdim      Result |= Bit->getValue() << i;
221226584Sdim    } else {
222226584Sdim      return 0;
223226584Sdim    }
224226584Sdim  return IntInit::get(Result);
225226584Sdim}
226226584Sdim
227226584SdimInit *IntRecTy::convertValue(TypedInit *TI) {
228226584Sdim  if (TI->getType()->typeIsConvertibleTo(this))
229226584Sdim    return TI;  // Accept variable if already of the right type!
230226584Sdim  return 0;
231226584Sdim}
232226584Sdim
233249423Sdimbool IntRecTy::baseClassOf(const RecTy *RHS) const{
234249423Sdim  RecTyKind kind = RHS->getRecTyKind();
235249423Sdim  return kind==BitRecTyKind || kind==BitsRecTyKind || kind==IntRecTyKind;
236249423Sdim}
237249423Sdim
238226584SdimInit *StringRecTy::convertValue(UnOpInit *BO) {
239226584Sdim  if (BO->getOpcode() == UnOpInit::CAST) {
240226584Sdim    Init *L = BO->getOperand()->convertInitializerTo(this);
241226584Sdim    if (L == 0) return 0;
242226584Sdim    if (L != BO->getOperand())
243226584Sdim      return UnOpInit::get(UnOpInit::CAST, L, new StringRecTy);
244226584Sdim    return BO;
245226584Sdim  }
246226584Sdim
247226584Sdim  return convertValue((TypedInit*)BO);
248226584Sdim}
249226584Sdim
250226584SdimInit *StringRecTy::convertValue(BinOpInit *BO) {
251226584Sdim  if (BO->getOpcode() == BinOpInit::STRCONCAT) {
252226584Sdim    Init *L = BO->getLHS()->convertInitializerTo(this);
253226584Sdim    Init *R = BO->getRHS()->convertInitializerTo(this);
254226584Sdim    if (L == 0 || R == 0) return 0;
255226584Sdim    if (L != BO->getLHS() || R != BO->getRHS())
256226584Sdim      return BinOpInit::get(BinOpInit::STRCONCAT, L, R, new StringRecTy);
257226584Sdim    return BO;
258226584Sdim  }
259226584Sdim
260226584Sdim  return convertValue((TypedInit*)BO);
261226584Sdim}
262226584Sdim
263226584Sdim
264226584SdimInit *StringRecTy::convertValue(TypedInit *TI) {
265243830Sdim  if (isa<StringRecTy>(TI->getType()))
266226584Sdim    return TI;  // Accept variable if already of the right type!
267226584Sdim  return 0;
268226584Sdim}
269226584Sdim
270226584Sdimstd::string ListRecTy::getAsString() const {
271226584Sdim  return "list<" + Ty->getAsString() + ">";
272226584Sdim}
273226584Sdim
274226584SdimInit *ListRecTy::convertValue(ListInit *LI) {
275226584Sdim  std::vector<Init*> Elements;
276226584Sdim
277226584Sdim  // Verify that all of the elements of the list are subclasses of the
278226584Sdim  // appropriate class!
279226584Sdim  for (unsigned i = 0, e = LI->getSize(); i != e; ++i)
280226584Sdim    if (Init *CI = LI->getElement(i)->convertInitializerTo(Ty))
281226584Sdim      Elements.push_back(CI);
282226584Sdim    else
283226584Sdim      return 0;
284226584Sdim
285243830Sdim  if (!isa<ListRecTy>(LI->getType()))
286226584Sdim    return 0;
287226584Sdim
288226584Sdim  return ListInit::get(Elements, this);
289226584Sdim}
290226584Sdim
291226584SdimInit *ListRecTy::convertValue(TypedInit *TI) {
292226584Sdim  // Ensure that TI is compatible with our class.
293243830Sdim  if (ListRecTy *LRT = dyn_cast<ListRecTy>(TI->getType()))
294226584Sdim    if (LRT->getElementType()->typeIsConvertibleTo(getElementType()))
295226584Sdim      return TI;
296226584Sdim  return 0;
297226584Sdim}
298226584Sdim
299249423Sdimbool ListRecTy::baseClassOf(const RecTy *RHS) const{
300249423Sdim  if(const ListRecTy* ListTy = dyn_cast<ListRecTy>(RHS))
301249423Sdim    return ListTy->getElementType()->typeIsConvertibleTo(Ty);
302249423Sdim  return false;
303249423Sdim}
304249423Sdim
305226584SdimInit *DagRecTy::convertValue(TypedInit *TI) {
306226584Sdim  if (TI->getType()->typeIsConvertibleTo(this))
307226584Sdim    return TI;
308226584Sdim  return 0;
309226584Sdim}
310226584Sdim
311226584SdimInit *DagRecTy::convertValue(UnOpInit *BO) {
312226584Sdim  if (BO->getOpcode() == UnOpInit::CAST) {
313226584Sdim    Init *L = BO->getOperand()->convertInitializerTo(this);
314226584Sdim    if (L == 0) return 0;
315226584Sdim    if (L != BO->getOperand())
316226584Sdim      return UnOpInit::get(UnOpInit::CAST, L, new DagRecTy);
317226584Sdim    return BO;
318226584Sdim  }
319226584Sdim  return 0;
320226584Sdim}
321226584Sdim
322226584SdimInit *DagRecTy::convertValue(BinOpInit *BO) {
323226584Sdim  if (BO->getOpcode() == BinOpInit::CONCAT) {
324226584Sdim    Init *L = BO->getLHS()->convertInitializerTo(this);
325226584Sdim    Init *R = BO->getRHS()->convertInitializerTo(this);
326226584Sdim    if (L == 0 || R == 0) return 0;
327226584Sdim    if (L != BO->getLHS() || R != BO->getRHS())
328226584Sdim      return BinOpInit::get(BinOpInit::CONCAT, L, R, new DagRecTy);
329226584Sdim    return BO;
330226584Sdim  }
331226584Sdim  return 0;
332226584Sdim}
333226584Sdim
334226584SdimRecordRecTy *RecordRecTy::get(Record *R) {
335243830Sdim  return dyn_cast<RecordRecTy>(R->getDefInit()->getType());
336226584Sdim}
337226584Sdim
338226584Sdimstd::string RecordRecTy::getAsString() const {
339226584Sdim  return Rec->getName();
340226584Sdim}
341226584Sdim
342226584SdimInit *RecordRecTy::convertValue(DefInit *DI) {
343226584Sdim  // Ensure that DI is a subclass of Rec.
344226584Sdim  if (!DI->getDef()->isSubClassOf(Rec))
345226584Sdim    return 0;
346226584Sdim  return DI;
347226584Sdim}
348226584Sdim
349226584SdimInit *RecordRecTy::convertValue(TypedInit *TI) {
350226584Sdim  // Ensure that TI is compatible with Rec.
351243830Sdim  if (RecordRecTy *RRT = dyn_cast<RecordRecTy>(TI->getType()))
352226584Sdim    if (RRT->getRecord()->isSubClassOf(getRecord()) ||
353226584Sdim        RRT->getRecord() == getRecord())
354226584Sdim      return TI;
355226584Sdim  return 0;
356226584Sdim}
357226584Sdim
358249423Sdimbool RecordRecTy::baseClassOf(const RecTy *RHS) const{
359249423Sdim  const RecordRecTy *RTy = dyn_cast<RecordRecTy>(RHS);
360249423Sdim  if (!RTy)
361249423Sdim    return false;
362249423Sdim
363249423Sdim  if (Rec == RTy->getRecord() || RTy->getRecord()->isSubClassOf(Rec))
364226584Sdim    return true;
365226584Sdim
366226584Sdim  const std::vector<Record*> &SC = Rec->getSuperClasses();
367226584Sdim  for (unsigned i = 0, e = SC.size(); i != e; ++i)
368249423Sdim    if (RTy->getRecord()->isSubClassOf(SC[i]))
369226584Sdim      return true;
370226584Sdim
371226584Sdim  return false;
372226584Sdim}
373226584Sdim
374226584Sdim/// resolveTypes - Find a common type that T1 and T2 convert to.
375226584Sdim/// Return 0 if no such type exists.
376226584Sdim///
377226584SdimRecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) {
378243830Sdim  if (T1->typeIsConvertibleTo(T2))
379243830Sdim    return T2;
380243830Sdim  if (T2->typeIsConvertibleTo(T1))
381243830Sdim    return T1;
382243830Sdim
383243830Sdim  // If one is a Record type, check superclasses
384243830Sdim  if (RecordRecTy *RecTy1 = dyn_cast<RecordRecTy>(T1)) {
385243830Sdim    // See if T2 inherits from a type T1 also inherits from
386243830Sdim    const std::vector<Record *> &T1SuperClasses =
387243830Sdim      RecTy1->getRecord()->getSuperClasses();
388243830Sdim    for(std::vector<Record *>::const_iterator i = T1SuperClasses.begin(),
389243830Sdim          iend = T1SuperClasses.end();
390243830Sdim        i != iend;
391243830Sdim        ++i) {
392243830Sdim      RecordRecTy *SuperRecTy1 = RecordRecTy::get(*i);
393243830Sdim      RecTy *NewType1 = resolveTypes(SuperRecTy1, T2);
394243830Sdim      if (NewType1 != 0) {
395243830Sdim        if (NewType1 != SuperRecTy1) {
396243830Sdim          delete SuperRecTy1;
397226584Sdim        }
398243830Sdim        return NewType1;
399226584Sdim      }
400243830Sdim    }
401243830Sdim  }
402243830Sdim  if (RecordRecTy *RecTy2 = dyn_cast<RecordRecTy>(T2)) {
403243830Sdim    // See if T1 inherits from a type T2 also inherits from
404243830Sdim    const std::vector<Record *> &T2SuperClasses =
405243830Sdim      RecTy2->getRecord()->getSuperClasses();
406243830Sdim    for (std::vector<Record *>::const_iterator i = T2SuperClasses.begin(),
407243830Sdim          iend = T2SuperClasses.end();
408243830Sdim        i != iend;
409243830Sdim        ++i) {
410243830Sdim      RecordRecTy *SuperRecTy2 = RecordRecTy::get(*i);
411243830Sdim      RecTy *NewType2 = resolveTypes(T1, SuperRecTy2);
412243830Sdim      if (NewType2 != 0) {
413243830Sdim        if (NewType2 != SuperRecTy2) {
414243830Sdim          delete SuperRecTy2;
415226584Sdim        }
416243830Sdim        return NewType2;
417226584Sdim      }
418226584Sdim    }
419226584Sdim  }
420243830Sdim  return 0;
421226584Sdim}
422226584Sdim
423226584Sdim
424226584Sdim//===----------------------------------------------------------------------===//
425226584Sdim//    Initializer implementations
426226584Sdim//===----------------------------------------------------------------------===//
427226584Sdim
428234353Sdimvoid Init::anchor() { }
429226584Sdimvoid Init::dump() const { return print(errs()); }
430226584Sdim
431234353Sdimvoid UnsetInit::anchor() { }
432234353Sdim
433226584SdimUnsetInit *UnsetInit::get() {
434226584Sdim  static UnsetInit TheInit;
435226584Sdim  return &TheInit;
436226584Sdim}
437226584Sdim
438234353Sdimvoid BitInit::anchor() { }
439234353Sdim
440226584SdimBitInit *BitInit::get(bool V) {
441226584Sdim  static BitInit True(true);
442226584Sdim  static BitInit False(false);
443226584Sdim
444226584Sdim  return V ? &True : &False;
445226584Sdim}
446226584Sdim
447226584Sdimstatic void
448226584SdimProfileBitsInit(FoldingSetNodeID &ID, ArrayRef<Init *> Range) {
449226584Sdim  ID.AddInteger(Range.size());
450226584Sdim
451226584Sdim  for (ArrayRef<Init *>::iterator i = Range.begin(),
452226584Sdim         iend = Range.end();
453226584Sdim       i != iend;
454226584Sdim       ++i)
455226584Sdim    ID.AddPointer(*i);
456226584Sdim}
457226584Sdim
458226584SdimBitsInit *BitsInit::get(ArrayRef<Init *> Range) {
459226584Sdim  typedef FoldingSet<BitsInit> Pool;
460226584Sdim  static Pool ThePool;
461226584Sdim
462226584Sdim  FoldingSetNodeID ID;
463226584Sdim  ProfileBitsInit(ID, Range);
464226584Sdim
465226584Sdim  void *IP = 0;
466226584Sdim  if (BitsInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
467226584Sdim    return I;
468226584Sdim
469226584Sdim  BitsInit *I = new BitsInit(Range);
470226584Sdim  ThePool.InsertNode(I, IP);
471226584Sdim
472226584Sdim  return I;
473226584Sdim}
474226584Sdim
475226584Sdimvoid BitsInit::Profile(FoldingSetNodeID &ID) const {
476226584Sdim  ProfileBitsInit(ID, Bits);
477226584Sdim}
478226584Sdim
479226584SdimInit *
480226584SdimBitsInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const {
481226584Sdim  SmallVector<Init *, 16> NewBits(Bits.size());
482226584Sdim
483226584Sdim  for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
484226584Sdim    if (Bits[i] >= getNumBits())
485226584Sdim      return 0;
486226584Sdim    NewBits[i] = getBit(Bits[i]);
487226584Sdim  }
488226584Sdim  return BitsInit::get(NewBits);
489226584Sdim}
490226584Sdim
491226584Sdimstd::string BitsInit::getAsString() const {
492226584Sdim  std::string Result = "{ ";
493226584Sdim  for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
494226584Sdim    if (i) Result += ", ";
495226584Sdim    if (Init *Bit = getBit(e-i-1))
496226584Sdim      Result += Bit->getAsString();
497226584Sdim    else
498226584Sdim      Result += "*";
499226584Sdim  }
500226584Sdim  return Result + " }";
501226584Sdim}
502226584Sdim
503243830Sdim// Fix bit initializer to preserve the behavior that bit reference from a unset
504243830Sdim// bits initializer will resolve into VarBitInit to keep the field name and bit
505243830Sdim// number used in targets with fixed insn length.
506243830Sdimstatic Init *fixBitInit(const RecordVal *RV, Init *Before, Init *After) {
507243830Sdim  if (RV || After != UnsetInit::get())
508243830Sdim    return After;
509243830Sdim  return Before;
510243830Sdim}
511243830Sdim
512226584Sdim// resolveReferences - If there are any field references that refer to fields
513226584Sdim// that have been filled in, we can propagate the values now.
514226584Sdim//
515226584SdimInit *BitsInit::resolveReferences(Record &R, const RecordVal *RV) const {
516226584Sdim  bool Changed = false;
517226584Sdim  SmallVector<Init *, 16> NewBits(getNumBits());
518226584Sdim
519243830Sdim  Init *CachedInit = 0;
520243830Sdim  Init *CachedBitVar = 0;
521243830Sdim  bool CachedBitVarChanged = false;
522243830Sdim
523243830Sdim  for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
524243830Sdim    Init *CurBit = Bits[i];
525243830Sdim    Init *CurBitVar = CurBit->getBitVar();
526243830Sdim
527243830Sdim    NewBits[i] = CurBit;
528243830Sdim
529243830Sdim    if (CurBitVar == CachedBitVar) {
530243830Sdim      if (CachedBitVarChanged) {
531243830Sdim        Init *Bit = CachedInit->getBit(CurBit->getBitNum());
532243830Sdim        NewBits[i] = fixBitInit(RV, CurBit, Bit);
533243830Sdim      }
534243830Sdim      continue;
535243830Sdim    }
536243830Sdim    CachedBitVar = CurBitVar;
537243830Sdim    CachedBitVarChanged = false;
538243830Sdim
539226584Sdim    Init *B;
540243830Sdim    do {
541243830Sdim      B = CurBitVar;
542243830Sdim      CurBitVar = CurBitVar->resolveReferences(R, RV);
543243830Sdim      CachedBitVarChanged |= B != CurBitVar;
544243830Sdim      Changed |= B != CurBitVar;
545243830Sdim    } while (B != CurBitVar);
546243830Sdim    CachedInit = CurBitVar;
547226584Sdim
548243830Sdim    if (CachedBitVarChanged) {
549243830Sdim      Init *Bit = CurBitVar->getBit(CurBit->getBitNum());
550243830Sdim      NewBits[i] = fixBitInit(RV, CurBit, Bit);
551243830Sdim    }
552226584Sdim  }
553226584Sdim
554226584Sdim  if (Changed)
555226584Sdim    return BitsInit::get(NewBits);
556226584Sdim
557226584Sdim  return const_cast<BitsInit *>(this);
558226584Sdim}
559226584Sdim
560226584SdimIntInit *IntInit::get(int64_t V) {
561226584Sdim  typedef DenseMap<int64_t, IntInit *> Pool;
562226584Sdim  static Pool ThePool;
563226584Sdim
564226584Sdim  IntInit *&I = ThePool[V];
565226584Sdim  if (!I) I = new IntInit(V);
566226584Sdim  return I;
567226584Sdim}
568226584Sdim
569226584Sdimstd::string IntInit::getAsString() const {
570226584Sdim  return itostr(Value);
571226584Sdim}
572226584Sdim
573226584SdimInit *
574226584SdimIntInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const {
575226584Sdim  SmallVector<Init *, 16> NewBits(Bits.size());
576226584Sdim
577226584Sdim  for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
578226584Sdim    if (Bits[i] >= 64)
579226584Sdim      return 0;
580226584Sdim
581226584Sdim    NewBits[i] = BitInit::get(Value & (INT64_C(1) << Bits[i]));
582226584Sdim  }
583226584Sdim  return BitsInit::get(NewBits);
584226584Sdim}
585226584Sdim
586234353Sdimvoid StringInit::anchor() { }
587234353Sdim
588234353SdimStringInit *StringInit::get(StringRef V) {
589226584Sdim  typedef StringMap<StringInit *> Pool;
590226584Sdim  static Pool ThePool;
591226584Sdim
592226584Sdim  StringInit *&I = ThePool[V];
593226584Sdim  if (!I) I = new StringInit(V);
594226584Sdim  return I;
595226584Sdim}
596226584Sdim
597226584Sdimstatic void ProfileListInit(FoldingSetNodeID &ID,
598226584Sdim                            ArrayRef<Init *> Range,
599226584Sdim                            RecTy *EltTy) {
600226584Sdim  ID.AddInteger(Range.size());
601226584Sdim  ID.AddPointer(EltTy);
602226584Sdim
603226584Sdim  for (ArrayRef<Init *>::iterator i = Range.begin(),
604226584Sdim         iend = Range.end();
605226584Sdim       i != iend;
606226584Sdim       ++i)
607226584Sdim    ID.AddPointer(*i);
608226584Sdim}
609226584Sdim
610226584SdimListInit *ListInit::get(ArrayRef<Init *> Range, RecTy *EltTy) {
611226584Sdim  typedef FoldingSet<ListInit> Pool;
612226584Sdim  static Pool ThePool;
613226584Sdim
614226584Sdim  // Just use the FoldingSetNodeID to compute a hash.  Use a DenseMap
615226584Sdim  // for actual storage.
616226584Sdim  FoldingSetNodeID ID;
617226584Sdim  ProfileListInit(ID, Range, EltTy);
618226584Sdim
619226584Sdim  void *IP = 0;
620226584Sdim  if (ListInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
621226584Sdim    return I;
622226584Sdim
623226584Sdim  ListInit *I = new ListInit(Range, EltTy);
624226584Sdim  ThePool.InsertNode(I, IP);
625226584Sdim  return I;
626226584Sdim}
627226584Sdim
628226584Sdimvoid ListInit::Profile(FoldingSetNodeID &ID) const {
629243830Sdim  ListRecTy *ListType = dyn_cast<ListRecTy>(getType());
630226584Sdim  assert(ListType && "Bad type for ListInit!");
631226584Sdim  RecTy *EltTy = ListType->getElementType();
632226584Sdim
633226584Sdim  ProfileListInit(ID, Values, EltTy);
634226584Sdim}
635226584Sdim
636226584SdimInit *
637226584SdimListInit::convertInitListSlice(const std::vector<unsigned> &Elements) const {
638226584Sdim  std::vector<Init*> Vals;
639226584Sdim  for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
640226584Sdim    if (Elements[i] >= getSize())
641226584Sdim      return 0;
642226584Sdim    Vals.push_back(getElement(Elements[i]));
643226584Sdim  }
644226584Sdim  return ListInit::get(Vals, getType());
645226584Sdim}
646226584Sdim
647226584SdimRecord *ListInit::getElementAsRecord(unsigned i) const {
648226584Sdim  assert(i < Values.size() && "List element index out of range!");
649243830Sdim  DefInit *DI = dyn_cast<DefInit>(Values[i]);
650243830Sdim  if (DI == 0)
651243830Sdim    PrintFatalError("Expected record in list!");
652226584Sdim  return DI->getDef();
653226584Sdim}
654226584Sdim
655226584SdimInit *ListInit::resolveReferences(Record &R, const RecordVal *RV) const {
656226584Sdim  std::vector<Init*> Resolved;
657226584Sdim  Resolved.reserve(getSize());
658226584Sdim  bool Changed = false;
659226584Sdim
660226584Sdim  for (unsigned i = 0, e = getSize(); i != e; ++i) {
661226584Sdim    Init *E;
662226584Sdim    Init *CurElt = getElement(i);
663226584Sdim
664226584Sdim    do {
665226584Sdim      E = CurElt;
666226584Sdim      CurElt = CurElt->resolveReferences(R, RV);
667226584Sdim      Changed |= E != CurElt;
668226584Sdim    } while (E != CurElt);
669226584Sdim    Resolved.push_back(E);
670226584Sdim  }
671226584Sdim
672226584Sdim  if (Changed)
673226584Sdim    return ListInit::get(Resolved, getType());
674226584Sdim  return const_cast<ListInit *>(this);
675226584Sdim}
676226584Sdim
677226584SdimInit *ListInit::resolveListElementReference(Record &R, const RecordVal *IRV,
678226584Sdim                                            unsigned Elt) const {
679226584Sdim  if (Elt >= getSize())
680226584Sdim    return 0;  // Out of range reference.
681226584Sdim  Init *E = getElement(Elt);
682226584Sdim  // If the element is set to some value, or if we are resolving a reference
683226584Sdim  // to a specific variable and that variable is explicitly unset, then
684226584Sdim  // replace the VarListElementInit with it.
685243830Sdim  if (IRV || !isa<UnsetInit>(E))
686226584Sdim    return E;
687226584Sdim  return 0;
688226584Sdim}
689226584Sdim
690226584Sdimstd::string ListInit::getAsString() const {
691226584Sdim  std::string Result = "[";
692226584Sdim  for (unsigned i = 0, e = Values.size(); i != e; ++i) {
693226584Sdim    if (i) Result += ", ";
694226584Sdim    Result += Values[i]->getAsString();
695226584Sdim  }
696226584Sdim  return Result + "]";
697226584Sdim}
698226584Sdim
699226584SdimInit *OpInit::resolveListElementReference(Record &R, const RecordVal *IRV,
700226584Sdim                                          unsigned Elt) const {
701226584Sdim  Init *Resolved = resolveReferences(R, IRV);
702243830Sdim  OpInit *OResolved = dyn_cast<OpInit>(Resolved);
703226584Sdim  if (OResolved) {
704226584Sdim    Resolved = OResolved->Fold(&R, 0);
705226584Sdim  }
706226584Sdim
707226584Sdim  if (Resolved != this) {
708243830Sdim    TypedInit *Typed = dyn_cast<TypedInit>(Resolved);
709226584Sdim    assert(Typed && "Expected typed init for list reference");
710226584Sdim    if (Typed) {
711226584Sdim      Init *New = Typed->resolveListElementReference(R, IRV, Elt);
712226584Sdim      if (New)
713226584Sdim        return New;
714226584Sdim      return VarListElementInit::get(Typed, Elt);
715226584Sdim    }
716226584Sdim  }
717226584Sdim
718226584Sdim  return 0;
719226584Sdim}
720226584Sdim
721243830SdimInit *OpInit::getBit(unsigned Bit) const {
722243830Sdim  if (getType() == BitRecTy::get())
723243830Sdim    return const_cast<OpInit*>(this);
724243830Sdim  return VarBitInit::get(const_cast<OpInit*>(this), Bit);
725243830Sdim}
726243830Sdim
727226584SdimUnOpInit *UnOpInit::get(UnaryOp opc, Init *lhs, RecTy *Type) {
728226584Sdim  typedef std::pair<std::pair<unsigned, Init *>, RecTy *> Key;
729226584Sdim
730226584Sdim  typedef DenseMap<Key, UnOpInit *> Pool;
731226584Sdim  static Pool ThePool;
732226584Sdim
733226584Sdim  Key TheKey(std::make_pair(std::make_pair(opc, lhs), Type));
734226584Sdim
735226584Sdim  UnOpInit *&I = ThePool[TheKey];
736226584Sdim  if (!I) I = new UnOpInit(opc, lhs, Type);
737226584Sdim  return I;
738226584Sdim}
739226584Sdim
740226584SdimInit *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
741226584Sdim  switch (getOpcode()) {
742226584Sdim  case CAST: {
743226584Sdim    if (getType()->getAsString() == "string") {
744243830Sdim      if (StringInit *LHSs = dyn_cast<StringInit>(LHS))
745226584Sdim        return LHSs;
746226584Sdim
747243830Sdim      if (DefInit *LHSd = dyn_cast<DefInit>(LHS))
748226584Sdim        return StringInit::get(LHSd->getDef()->getName());
749234353Sdim
750243830Sdim      if (IntInit *LHSi = dyn_cast<IntInit>(LHS))
751234353Sdim        return StringInit::get(LHSi->getAsString());
752226584Sdim    } else {
753243830Sdim      if (StringInit *LHSs = dyn_cast<StringInit>(LHS)) {
754226584Sdim        std::string Name = LHSs->getValue();
755226584Sdim
756226584Sdim        // From TGParser::ParseIDValue
757226584Sdim        if (CurRec) {
758226584Sdim          if (const RecordVal *RV = CurRec->getValue(Name)) {
759226584Sdim            if (RV->getType() != getType())
760243830Sdim              PrintFatalError("type mismatch in cast");
761226584Sdim            return VarInit::get(Name, RV->getType());
762226584Sdim          }
763226584Sdim
764234353Sdim          Init *TemplateArgName = QualifyName(*CurRec, CurMultiClass, Name,
765234353Sdim                                              ":");
766234353Sdim
767226584Sdim          if (CurRec->isTemplateArg(TemplateArgName)) {
768226584Sdim            const RecordVal *RV = CurRec->getValue(TemplateArgName);
769226584Sdim            assert(RV && "Template arg doesn't exist??");
770226584Sdim
771226584Sdim            if (RV->getType() != getType())
772243830Sdim              PrintFatalError("type mismatch in cast");
773226584Sdim
774226584Sdim            return VarInit::get(TemplateArgName, RV->getType());
775226584Sdim          }
776226584Sdim        }
777226584Sdim
778226584Sdim        if (CurMultiClass) {
779234353Sdim          Init *MCName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name, "::");
780234353Sdim
781226584Sdim          if (CurMultiClass->Rec.isTemplateArg(MCName)) {
782226584Sdim            const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
783226584Sdim            assert(RV && "Template arg doesn't exist??");
784226584Sdim
785226584Sdim            if (RV->getType() != getType())
786243830Sdim              PrintFatalError("type mismatch in cast");
787226584Sdim
788226584Sdim            return VarInit::get(MCName, RV->getType());
789226584Sdim          }
790226584Sdim        }
791226584Sdim
792226584Sdim        if (Record *D = (CurRec->getRecords()).getDef(Name))
793226584Sdim          return DefInit::get(D);
794226584Sdim
795243830Sdim        PrintFatalError(CurRec->getLoc(),
796243830Sdim                        "Undefined reference:'" + Name + "'\n");
797226584Sdim      }
798226584Sdim    }
799226584Sdim    break;
800226584Sdim  }
801226584Sdim  case HEAD: {
802243830Sdim    if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
803226584Sdim      if (LHSl->getSize() == 0) {
804226584Sdim        assert(0 && "Empty list in car");
805226584Sdim        return 0;
806226584Sdim      }
807226584Sdim      return LHSl->getElement(0);
808226584Sdim    }
809226584Sdim    break;
810226584Sdim  }
811226584Sdim  case TAIL: {
812243830Sdim    if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
813226584Sdim      if (LHSl->getSize() == 0) {
814226584Sdim        assert(0 && "Empty list in cdr");
815226584Sdim        return 0;
816226584Sdim      }
817226584Sdim      // Note the +1.  We can't just pass the result of getValues()
818226584Sdim      // directly.
819226584Sdim      ArrayRef<Init *>::iterator begin = LHSl->getValues().begin()+1;
820226584Sdim      ArrayRef<Init *>::iterator end   = LHSl->getValues().end();
821226584Sdim      ListInit *Result =
822226584Sdim        ListInit::get(ArrayRef<Init *>(begin, end - begin),
823226584Sdim                      LHSl->getType());
824226584Sdim      return Result;
825226584Sdim    }
826226584Sdim    break;
827226584Sdim  }
828226584Sdim  case EMPTY: {
829243830Sdim    if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
830226584Sdim      if (LHSl->getSize() == 0) {
831226584Sdim        return IntInit::get(1);
832226584Sdim      } else {
833226584Sdim        return IntInit::get(0);
834226584Sdim      }
835226584Sdim    }
836243830Sdim    if (StringInit *LHSs = dyn_cast<StringInit>(LHS)) {
837226584Sdim      if (LHSs->getValue().empty()) {
838226584Sdim        return IntInit::get(1);
839226584Sdim      } else {
840226584Sdim        return IntInit::get(0);
841226584Sdim      }
842226584Sdim    }
843226584Sdim
844226584Sdim    break;
845226584Sdim  }
846226584Sdim  }
847226584Sdim  return const_cast<UnOpInit *>(this);
848226584Sdim}
849226584Sdim
850226584SdimInit *UnOpInit::resolveReferences(Record &R, const RecordVal *RV) const {
851226584Sdim  Init *lhs = LHS->resolveReferences(R, RV);
852226584Sdim
853226584Sdim  if (LHS != lhs)
854226584Sdim    return (UnOpInit::get(getOpcode(), lhs, getType()))->Fold(&R, 0);
855226584Sdim  return Fold(&R, 0);
856226584Sdim}
857226584Sdim
858226584Sdimstd::string UnOpInit::getAsString() const {
859226584Sdim  std::string Result;
860226584Sdim  switch (Opc) {
861226584Sdim  case CAST: Result = "!cast<" + getType()->getAsString() + ">"; break;
862226584Sdim  case HEAD: Result = "!head"; break;
863226584Sdim  case TAIL: Result = "!tail"; break;
864226584Sdim  case EMPTY: Result = "!empty"; break;
865226584Sdim  }
866226584Sdim  return Result + "(" + LHS->getAsString() + ")";
867226584Sdim}
868226584Sdim
869226584SdimBinOpInit *BinOpInit::get(BinaryOp opc, Init *lhs,
870226584Sdim                          Init *rhs, RecTy *Type) {
871226584Sdim  typedef std::pair<
872226584Sdim    std::pair<std::pair<unsigned, Init *>, Init *>,
873226584Sdim    RecTy *
874226584Sdim    > Key;
875226584Sdim
876226584Sdim  typedef DenseMap<Key, BinOpInit *> Pool;
877226584Sdim  static Pool ThePool;
878226584Sdim
879226584Sdim  Key TheKey(std::make_pair(std::make_pair(std::make_pair(opc, lhs), rhs),
880226584Sdim                            Type));
881226584Sdim
882226584Sdim  BinOpInit *&I = ThePool[TheKey];
883226584Sdim  if (!I) I = new BinOpInit(opc, lhs, rhs, Type);
884226584Sdim  return I;
885226584Sdim}
886226584Sdim
887226584SdimInit *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
888226584Sdim  switch (getOpcode()) {
889226584Sdim  case CONCAT: {
890243830Sdim    DagInit *LHSs = dyn_cast<DagInit>(LHS);
891243830Sdim    DagInit *RHSs = dyn_cast<DagInit>(RHS);
892226584Sdim    if (LHSs && RHSs) {
893243830Sdim      DefInit *LOp = dyn_cast<DefInit>(LHSs->getOperator());
894243830Sdim      DefInit *ROp = dyn_cast<DefInit>(RHSs->getOperator());
895226584Sdim      if (LOp == 0 || ROp == 0 || LOp->getDef() != ROp->getDef())
896243830Sdim        PrintFatalError("Concated Dag operators do not match!");
897226584Sdim      std::vector<Init*> Args;
898226584Sdim      std::vector<std::string> ArgNames;
899226584Sdim      for (unsigned i = 0, e = LHSs->getNumArgs(); i != e; ++i) {
900226584Sdim        Args.push_back(LHSs->getArg(i));
901226584Sdim        ArgNames.push_back(LHSs->getArgName(i));
902226584Sdim      }
903226584Sdim      for (unsigned i = 0, e = RHSs->getNumArgs(); i != e; ++i) {
904226584Sdim        Args.push_back(RHSs->getArg(i));
905226584Sdim        ArgNames.push_back(RHSs->getArgName(i));
906226584Sdim      }
907226584Sdim      return DagInit::get(LHSs->getOperator(), "", Args, ArgNames);
908226584Sdim    }
909226584Sdim    break;
910226584Sdim  }
911226584Sdim  case STRCONCAT: {
912243830Sdim    StringInit *LHSs = dyn_cast<StringInit>(LHS);
913243830Sdim    StringInit *RHSs = dyn_cast<StringInit>(RHS);
914226584Sdim    if (LHSs && RHSs)
915226584Sdim      return StringInit::get(LHSs->getValue() + RHSs->getValue());
916226584Sdim    break;
917226584Sdim  }
918226584Sdim  case EQ: {
919226584Sdim    // try to fold eq comparison for 'bit' and 'int', otherwise fallback
920226584Sdim    // to string objects.
921243830Sdim    IntInit *L =
922243830Sdim      dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(IntRecTy::get()));
923243830Sdim    IntInit *R =
924243830Sdim      dyn_cast_or_null<IntInit>(RHS->convertInitializerTo(IntRecTy::get()));
925226584Sdim
926226584Sdim    if (L && R)
927226584Sdim      return IntInit::get(L->getValue() == R->getValue());
928226584Sdim
929243830Sdim    StringInit *LHSs = dyn_cast<StringInit>(LHS);
930243830Sdim    StringInit *RHSs = dyn_cast<StringInit>(RHS);
931226584Sdim
932226584Sdim    // Make sure we've resolved
933226584Sdim    if (LHSs && RHSs)
934226584Sdim      return IntInit::get(LHSs->getValue() == RHSs->getValue());
935226584Sdim
936226584Sdim    break;
937226584Sdim  }
938249423Sdim  case ADD:
939226584Sdim  case SHL:
940226584Sdim  case SRA:
941226584Sdim  case SRL: {
942243830Sdim    IntInit *LHSi = dyn_cast<IntInit>(LHS);
943243830Sdim    IntInit *RHSi = dyn_cast<IntInit>(RHS);
944226584Sdim    if (LHSi && RHSi) {
945226584Sdim      int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue();
946226584Sdim      int64_t Result;
947226584Sdim      switch (getOpcode()) {
948234353Sdim      default: llvm_unreachable("Bad opcode!");
949249423Sdim      case ADD: Result = LHSv +  RHSv; break;
950226584Sdim      case SHL: Result = LHSv << RHSv; break;
951226584Sdim      case SRA: Result = LHSv >> RHSv; break;
952226584Sdim      case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break;
953226584Sdim      }
954226584Sdim      return IntInit::get(Result);
955226584Sdim    }
956226584Sdim    break;
957226584Sdim  }
958226584Sdim  }
959226584Sdim  return const_cast<BinOpInit *>(this);
960226584Sdim}
961226584Sdim
962226584SdimInit *BinOpInit::resolveReferences(Record &R, const RecordVal *RV) const {
963226584Sdim  Init *lhs = LHS->resolveReferences(R, RV);
964226584Sdim  Init *rhs = RHS->resolveReferences(R, RV);
965226584Sdim
966226584Sdim  if (LHS != lhs || RHS != rhs)
967226584Sdim    return (BinOpInit::get(getOpcode(), lhs, rhs, getType()))->Fold(&R, 0);
968226584Sdim  return Fold(&R, 0);
969226584Sdim}
970226584Sdim
971226584Sdimstd::string BinOpInit::getAsString() const {
972226584Sdim  std::string Result;
973226584Sdim  switch (Opc) {
974226584Sdim  case CONCAT: Result = "!con"; break;
975249423Sdim  case ADD: Result = "!add"; break;
976226584Sdim  case SHL: Result = "!shl"; break;
977226584Sdim  case SRA: Result = "!sra"; break;
978226584Sdim  case SRL: Result = "!srl"; break;
979226584Sdim  case EQ: Result = "!eq"; break;
980226584Sdim  case STRCONCAT: Result = "!strconcat"; break;
981226584Sdim  }
982226584Sdim  return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
983226584Sdim}
984226584Sdim
985226584SdimTernOpInit *TernOpInit::get(TernaryOp opc, Init *lhs,
986226584Sdim                                  Init *mhs, Init *rhs,
987226584Sdim                                  RecTy *Type) {
988226584Sdim  typedef std::pair<
989226584Sdim    std::pair<
990226584Sdim      std::pair<std::pair<unsigned, RecTy *>, Init *>,
991226584Sdim      Init *
992226584Sdim      >,
993226584Sdim    Init *
994226584Sdim    > Key;
995226584Sdim
996226584Sdim  typedef DenseMap<Key, TernOpInit *> Pool;
997226584Sdim  static Pool ThePool;
998226584Sdim
999226584Sdim  Key TheKey(std::make_pair(std::make_pair(std::make_pair(std::make_pair(opc,
1000226584Sdim                                                                         Type),
1001226584Sdim                                                          lhs),
1002226584Sdim                                           mhs),
1003226584Sdim                            rhs));
1004226584Sdim
1005226584Sdim  TernOpInit *&I = ThePool[TheKey];
1006226584Sdim  if (!I) I = new TernOpInit(opc, lhs, mhs, rhs, Type);
1007226584Sdim  return I;
1008226584Sdim}
1009226584Sdim
1010226584Sdimstatic Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
1011226584Sdim                           Record *CurRec, MultiClass *CurMultiClass);
1012226584Sdim
1013226584Sdimstatic Init *EvaluateOperation(OpInit *RHSo, Init *LHS, Init *Arg,
1014226584Sdim                               RecTy *Type, Record *CurRec,
1015226584Sdim                               MultiClass *CurMultiClass) {
1016226584Sdim  std::vector<Init *> NewOperands;
1017226584Sdim
1018243830Sdim  TypedInit *TArg = dyn_cast<TypedInit>(Arg);
1019226584Sdim
1020226584Sdim  // If this is a dag, recurse
1021226584Sdim  if (TArg && TArg->getType()->getAsString() == "dag") {
1022226584Sdim    Init *Result = ForeachHelper(LHS, Arg, RHSo, Type,
1023226584Sdim                                 CurRec, CurMultiClass);
1024226584Sdim    if (Result != 0) {
1025226584Sdim      return Result;
1026226584Sdim    } else {
1027226584Sdim      return 0;
1028226584Sdim    }
1029226584Sdim  }
1030226584Sdim
1031226584Sdim  for (int i = 0; i < RHSo->getNumOperands(); ++i) {
1032243830Sdim    OpInit *RHSoo = dyn_cast<OpInit>(RHSo->getOperand(i));
1033226584Sdim
1034226584Sdim    if (RHSoo) {
1035226584Sdim      Init *Result = EvaluateOperation(RHSoo, LHS, Arg,
1036226584Sdim                                       Type, CurRec, CurMultiClass);
1037226584Sdim      if (Result != 0) {
1038226584Sdim        NewOperands.push_back(Result);
1039226584Sdim      } else {
1040226584Sdim        NewOperands.push_back(Arg);
1041226584Sdim      }
1042226584Sdim    } else if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
1043226584Sdim      NewOperands.push_back(Arg);
1044226584Sdim    } else {
1045226584Sdim      NewOperands.push_back(RHSo->getOperand(i));
1046226584Sdim    }
1047226584Sdim  }
1048226584Sdim
1049226584Sdim  // Now run the operator and use its result as the new leaf
1050226584Sdim  const OpInit *NewOp = RHSo->clone(NewOperands);
1051226584Sdim  Init *NewVal = NewOp->Fold(CurRec, CurMultiClass);
1052226584Sdim  if (NewVal != NewOp)
1053226584Sdim    return NewVal;
1054226584Sdim
1055226584Sdim  return 0;
1056226584Sdim}
1057226584Sdim
1058226584Sdimstatic Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
1059226584Sdim                           Record *CurRec, MultiClass *CurMultiClass) {
1060243830Sdim  DagInit *MHSd = dyn_cast<DagInit>(MHS);
1061243830Sdim  ListInit *MHSl = dyn_cast<ListInit>(MHS);
1062226584Sdim
1063243830Sdim  OpInit *RHSo = dyn_cast<OpInit>(RHS);
1064226584Sdim
1065226584Sdim  if (!RHSo) {
1066243830Sdim    PrintFatalError(CurRec->getLoc(), "!foreach requires an operator\n");
1067226584Sdim  }
1068226584Sdim
1069243830Sdim  TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
1070226584Sdim
1071243830Sdim  if (!LHSt)
1072243830Sdim    PrintFatalError(CurRec->getLoc(), "!foreach requires typed variable\n");
1073226584Sdim
1074243830Sdim  if ((MHSd && isa<DagRecTy>(Type)) || (MHSl && isa<ListRecTy>(Type))) {
1075226584Sdim    if (MHSd) {
1076226584Sdim      Init *Val = MHSd->getOperator();
1077226584Sdim      Init *Result = EvaluateOperation(RHSo, LHS, Val,
1078226584Sdim                                       Type, CurRec, CurMultiClass);
1079226584Sdim      if (Result != 0) {
1080226584Sdim        Val = Result;
1081226584Sdim      }
1082226584Sdim
1083226584Sdim      std::vector<std::pair<Init *, std::string> > args;
1084226584Sdim      for (unsigned int i = 0; i < MHSd->getNumArgs(); ++i) {
1085226584Sdim        Init *Arg;
1086226584Sdim        std::string ArgName;
1087226584Sdim        Arg = MHSd->getArg(i);
1088226584Sdim        ArgName = MHSd->getArgName(i);
1089226584Sdim
1090226584Sdim        // Process args
1091226584Sdim        Init *Result = EvaluateOperation(RHSo, LHS, Arg, Type,
1092226584Sdim                                         CurRec, CurMultiClass);
1093226584Sdim        if (Result != 0) {
1094226584Sdim          Arg = Result;
1095226584Sdim        }
1096226584Sdim
1097226584Sdim        // TODO: Process arg names
1098226584Sdim        args.push_back(std::make_pair(Arg, ArgName));
1099226584Sdim      }
1100226584Sdim
1101226584Sdim      return DagInit::get(Val, "", args);
1102226584Sdim    }
1103226584Sdim    if (MHSl) {
1104226584Sdim      std::vector<Init *> NewOperands;
1105226584Sdim      std::vector<Init *> NewList(MHSl->begin(), MHSl->end());
1106226584Sdim
1107226584Sdim      for (std::vector<Init *>::iterator li = NewList.begin(),
1108226584Sdim             liend = NewList.end();
1109226584Sdim           li != liend;
1110226584Sdim           ++li) {
1111226584Sdim        Init *Item = *li;
1112226584Sdim        NewOperands.clear();
1113226584Sdim        for(int i = 0; i < RHSo->getNumOperands(); ++i) {
1114226584Sdim          // First, replace the foreach variable with the list item
1115226584Sdim          if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
1116226584Sdim            NewOperands.push_back(Item);
1117226584Sdim          } else {
1118226584Sdim            NewOperands.push_back(RHSo->getOperand(i));
1119226584Sdim          }
1120226584Sdim        }
1121226584Sdim
1122226584Sdim        // Now run the operator and use its result as the new list item
1123226584Sdim        const OpInit *NewOp = RHSo->clone(NewOperands);
1124226584Sdim        Init *NewItem = NewOp->Fold(CurRec, CurMultiClass);
1125226584Sdim        if (NewItem != NewOp)
1126226584Sdim          *li = NewItem;
1127226584Sdim      }
1128226584Sdim      return ListInit::get(NewList, MHSl->getType());
1129226584Sdim    }
1130226584Sdim  }
1131226584Sdim  return 0;
1132226584Sdim}
1133226584Sdim
1134226584SdimInit *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
1135226584Sdim  switch (getOpcode()) {
1136226584Sdim  case SUBST: {
1137243830Sdim    DefInit *LHSd = dyn_cast<DefInit>(LHS);
1138243830Sdim    VarInit *LHSv = dyn_cast<VarInit>(LHS);
1139243830Sdim    StringInit *LHSs = dyn_cast<StringInit>(LHS);
1140226584Sdim
1141243830Sdim    DefInit *MHSd = dyn_cast<DefInit>(MHS);
1142243830Sdim    VarInit *MHSv = dyn_cast<VarInit>(MHS);
1143243830Sdim    StringInit *MHSs = dyn_cast<StringInit>(MHS);
1144226584Sdim
1145243830Sdim    DefInit *RHSd = dyn_cast<DefInit>(RHS);
1146243830Sdim    VarInit *RHSv = dyn_cast<VarInit>(RHS);
1147243830Sdim    StringInit *RHSs = dyn_cast<StringInit>(RHS);
1148226584Sdim
1149226584Sdim    if ((LHSd && MHSd && RHSd)
1150226584Sdim        || (LHSv && MHSv && RHSv)
1151226584Sdim        || (LHSs && MHSs && RHSs)) {
1152226584Sdim      if (RHSd) {
1153226584Sdim        Record *Val = RHSd->getDef();
1154226584Sdim        if (LHSd->getAsString() == RHSd->getAsString()) {
1155226584Sdim          Val = MHSd->getDef();
1156226584Sdim        }
1157226584Sdim        return DefInit::get(Val);
1158226584Sdim      }
1159226584Sdim      if (RHSv) {
1160226584Sdim        std::string Val = RHSv->getName();
1161226584Sdim        if (LHSv->getAsString() == RHSv->getAsString()) {
1162226584Sdim          Val = MHSv->getName();
1163226584Sdim        }
1164226584Sdim        return VarInit::get(Val, getType());
1165226584Sdim      }
1166226584Sdim      if (RHSs) {
1167226584Sdim        std::string Val = RHSs->getValue();
1168226584Sdim
1169226584Sdim        std::string::size_type found;
1170226584Sdim        std::string::size_type idx = 0;
1171226584Sdim        do {
1172226584Sdim          found = Val.find(LHSs->getValue(), idx);
1173226584Sdim          if (found != std::string::npos) {
1174226584Sdim            Val.replace(found, LHSs->getValue().size(), MHSs->getValue());
1175226584Sdim          }
1176226584Sdim          idx = found +  MHSs->getValue().size();
1177226584Sdim        } while (found != std::string::npos);
1178226584Sdim
1179226584Sdim        return StringInit::get(Val);
1180226584Sdim      }
1181226584Sdim    }
1182226584Sdim    break;
1183226584Sdim  }
1184226584Sdim
1185226584Sdim  case FOREACH: {
1186226584Sdim    Init *Result = ForeachHelper(LHS, MHS, RHS, getType(),
1187226584Sdim                                 CurRec, CurMultiClass);
1188226584Sdim    if (Result != 0) {
1189226584Sdim      return Result;
1190226584Sdim    }
1191226584Sdim    break;
1192226584Sdim  }
1193226584Sdim
1194226584Sdim  case IF: {
1195243830Sdim    IntInit *LHSi = dyn_cast<IntInit>(LHS);
1196226584Sdim    if (Init *I = LHS->convertInitializerTo(IntRecTy::get()))
1197243830Sdim      LHSi = dyn_cast<IntInit>(I);
1198226584Sdim    if (LHSi) {
1199226584Sdim      if (LHSi->getValue()) {
1200226584Sdim        return MHS;
1201226584Sdim      } else {
1202226584Sdim        return RHS;
1203226584Sdim      }
1204226584Sdim    }
1205226584Sdim    break;
1206226584Sdim  }
1207226584Sdim  }
1208226584Sdim
1209226584Sdim  return const_cast<TernOpInit *>(this);
1210226584Sdim}
1211226584Sdim
1212226584SdimInit *TernOpInit::resolveReferences(Record &R,
1213226584Sdim                                    const RecordVal *RV) const {
1214226584Sdim  Init *lhs = LHS->resolveReferences(R, RV);
1215226584Sdim
1216226584Sdim  if (Opc == IF && lhs != LHS) {
1217243830Sdim    IntInit *Value = dyn_cast<IntInit>(lhs);
1218226584Sdim    if (Init *I = lhs->convertInitializerTo(IntRecTy::get()))
1219243830Sdim      Value = dyn_cast<IntInit>(I);
1220226584Sdim    if (Value != 0) {
1221226584Sdim      // Short-circuit
1222226584Sdim      if (Value->getValue()) {
1223226584Sdim        Init *mhs = MHS->resolveReferences(R, RV);
1224226584Sdim        return (TernOpInit::get(getOpcode(), lhs, mhs,
1225226584Sdim                                RHS, getType()))->Fold(&R, 0);
1226226584Sdim      } else {
1227226584Sdim        Init *rhs = RHS->resolveReferences(R, RV);
1228226584Sdim        return (TernOpInit::get(getOpcode(), lhs, MHS,
1229226584Sdim                                rhs, getType()))->Fold(&R, 0);
1230226584Sdim      }
1231226584Sdim    }
1232226584Sdim  }
1233226584Sdim
1234226584Sdim  Init *mhs = MHS->resolveReferences(R, RV);
1235226584Sdim  Init *rhs = RHS->resolveReferences(R, RV);
1236226584Sdim
1237226584Sdim  if (LHS != lhs || MHS != mhs || RHS != rhs)
1238226584Sdim    return (TernOpInit::get(getOpcode(), lhs, mhs, rhs,
1239226584Sdim                            getType()))->Fold(&R, 0);
1240226584Sdim  return Fold(&R, 0);
1241226584Sdim}
1242226584Sdim
1243226584Sdimstd::string TernOpInit::getAsString() const {
1244226584Sdim  std::string Result;
1245226584Sdim  switch (Opc) {
1246226584Sdim  case SUBST: Result = "!subst"; break;
1247226584Sdim  case FOREACH: Result = "!foreach"; break;
1248226584Sdim  case IF: Result = "!if"; break;
1249226584Sdim }
1250226584Sdim  return Result + "(" + LHS->getAsString() + ", " + MHS->getAsString() + ", "
1251226584Sdim    + RHS->getAsString() + ")";
1252226584Sdim}
1253226584Sdim
1254226584SdimRecTy *TypedInit::getFieldType(const std::string &FieldName) const {
1255243830Sdim  if (RecordRecTy *RecordType = dyn_cast<RecordRecTy>(getType()))
1256243830Sdim    if (RecordVal *Field = RecordType->getRecord()->getValue(FieldName))
1257226584Sdim      return Field->getType();
1258226584Sdim  return 0;
1259226584Sdim}
1260226584Sdim
1261226584SdimInit *
1262226584SdimTypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const {
1263243830Sdim  BitsRecTy *T = dyn_cast<BitsRecTy>(getType());
1264226584Sdim  if (T == 0) return 0;  // Cannot subscript a non-bits variable.
1265226584Sdim  unsigned NumBits = T->getNumBits();
1266226584Sdim
1267226584Sdim  SmallVector<Init *, 16> NewBits(Bits.size());
1268226584Sdim  for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
1269226584Sdim    if (Bits[i] >= NumBits)
1270226584Sdim      return 0;
1271226584Sdim
1272226584Sdim    NewBits[i] = VarBitInit::get(const_cast<TypedInit *>(this), Bits[i]);
1273226584Sdim  }
1274226584Sdim  return BitsInit::get(NewBits);
1275226584Sdim}
1276226584Sdim
1277226584SdimInit *
1278226584SdimTypedInit::convertInitListSlice(const std::vector<unsigned> &Elements) const {
1279243830Sdim  ListRecTy *T = dyn_cast<ListRecTy>(getType());
1280226584Sdim  if (T == 0) return 0;  // Cannot subscript a non-list variable.
1281226584Sdim
1282226584Sdim  if (Elements.size() == 1)
1283226584Sdim    return VarListElementInit::get(const_cast<TypedInit *>(this), Elements[0]);
1284226584Sdim
1285226584Sdim  std::vector<Init*> ListInits;
1286226584Sdim  ListInits.reserve(Elements.size());
1287226584Sdim  for (unsigned i = 0, e = Elements.size(); i != e; ++i)
1288226584Sdim    ListInits.push_back(VarListElementInit::get(const_cast<TypedInit *>(this),
1289226584Sdim                                                Elements[i]));
1290226584Sdim  return ListInit::get(ListInits, T);
1291226584Sdim}
1292226584Sdim
1293226584Sdim
1294226584SdimVarInit *VarInit::get(const std::string &VN, RecTy *T) {
1295234353Sdim  Init *Value = StringInit::get(VN);
1296234353Sdim  return VarInit::get(Value, T);
1297234353Sdim}
1298234353Sdim
1299234353SdimVarInit *VarInit::get(Init *VN, RecTy *T) {
1300234353Sdim  typedef std::pair<RecTy *, Init *> Key;
1301226584Sdim  typedef DenseMap<Key, VarInit *> Pool;
1302226584Sdim  static Pool ThePool;
1303226584Sdim
1304226584Sdim  Key TheKey(std::make_pair(T, VN));
1305226584Sdim
1306226584Sdim  VarInit *&I = ThePool[TheKey];
1307226584Sdim  if (!I) I = new VarInit(VN, T);
1308226584Sdim  return I;
1309226584Sdim}
1310226584Sdim
1311234353Sdimconst std::string &VarInit::getName() const {
1312243830Sdim  StringInit *NameString = dyn_cast<StringInit>(getNameInit());
1313234353Sdim  assert(NameString && "VarInit name is not a string!");
1314234353Sdim  return NameString->getValue();
1315234353Sdim}
1316234353Sdim
1317243830SdimInit *VarInit::getBit(unsigned Bit) const {
1318243830Sdim  if (getType() == BitRecTy::get())
1319243830Sdim    return const_cast<VarInit*>(this);
1320243830Sdim  return VarBitInit::get(const_cast<VarInit*>(this), Bit);
1321226584Sdim}
1322226584Sdim
1323226584SdimInit *VarInit::resolveListElementReference(Record &R,
1324226584Sdim                                           const RecordVal *IRV,
1325226584Sdim                                           unsigned Elt) const {
1326234353Sdim  if (R.isTemplateArg(getNameInit())) return 0;
1327234353Sdim  if (IRV && IRV->getNameInit() != getNameInit()) return 0;
1328226584Sdim
1329234353Sdim  RecordVal *RV = R.getValue(getNameInit());
1330226584Sdim  assert(RV && "Reference to a non-existent variable?");
1331243830Sdim  ListInit *LI = dyn_cast<ListInit>(RV->getValue());
1332226584Sdim  if (!LI) {
1333243830Sdim    TypedInit *VI = dyn_cast<TypedInit>(RV->getValue());
1334226584Sdim    assert(VI && "Invalid list element!");
1335226584Sdim    return VarListElementInit::get(VI, Elt);
1336226584Sdim  }
1337226584Sdim
1338226584Sdim  if (Elt >= LI->getSize())
1339226584Sdim    return 0;  // Out of range reference.
1340226584Sdim  Init *E = LI->getElement(Elt);
1341226584Sdim  // If the element is set to some value, or if we are resolving a reference
1342226584Sdim  // to a specific variable and that variable is explicitly unset, then
1343226584Sdim  // replace the VarListElementInit with it.
1344243830Sdim  if (IRV || !isa<UnsetInit>(E))
1345226584Sdim    return E;
1346226584Sdim  return 0;
1347226584Sdim}
1348226584Sdim
1349226584Sdim
1350226584SdimRecTy *VarInit::getFieldType(const std::string &FieldName) const {
1351243830Sdim  if (RecordRecTy *RTy = dyn_cast<RecordRecTy>(getType()))
1352226584Sdim    if (const RecordVal *RV = RTy->getRecord()->getValue(FieldName))
1353226584Sdim      return RV->getType();
1354226584Sdim  return 0;
1355226584Sdim}
1356226584Sdim
1357226584SdimInit *VarInit::getFieldInit(Record &R, const RecordVal *RV,
1358226584Sdim                            const std::string &FieldName) const {
1359243830Sdim  if (isa<RecordRecTy>(getType()))
1360226584Sdim    if (const RecordVal *Val = R.getValue(VarName)) {
1361243830Sdim      if (RV != Val && (RV || isa<UnsetInit>(Val->getValue())))
1362226584Sdim        return 0;
1363226584Sdim      Init *TheInit = Val->getValue();
1364226584Sdim      assert(TheInit != this && "Infinite loop detected!");
1365226584Sdim      if (Init *I = TheInit->getFieldInit(R, RV, FieldName))
1366226584Sdim        return I;
1367226584Sdim      else
1368226584Sdim        return 0;
1369226584Sdim    }
1370226584Sdim  return 0;
1371226584Sdim}
1372226584Sdim
1373226584Sdim/// resolveReferences - This method is used by classes that refer to other
1374226584Sdim/// variables which may not be defined at the time the expression is formed.
1375226584Sdim/// If a value is set for the variable later, this method will be called on
1376226584Sdim/// users of the value to allow the value to propagate out.
1377226584Sdim///
1378226584SdimInit *VarInit::resolveReferences(Record &R, const RecordVal *RV) const {
1379226584Sdim  if (RecordVal *Val = R.getValue(VarName))
1380243830Sdim    if (RV == Val || (RV == 0 && !isa<UnsetInit>(Val->getValue())))
1381226584Sdim      return Val->getValue();
1382226584Sdim  return const_cast<VarInit *>(this);
1383226584Sdim}
1384226584Sdim
1385226584SdimVarBitInit *VarBitInit::get(TypedInit *T, unsigned B) {
1386226584Sdim  typedef std::pair<TypedInit *, unsigned> Key;
1387226584Sdim  typedef DenseMap<Key, VarBitInit *> Pool;
1388226584Sdim
1389226584Sdim  static Pool ThePool;
1390226584Sdim
1391226584Sdim  Key TheKey(std::make_pair(T, B));
1392226584Sdim
1393226584Sdim  VarBitInit *&I = ThePool[TheKey];
1394226584Sdim  if (!I) I = new VarBitInit(T, B);
1395226584Sdim  return I;
1396226584Sdim}
1397226584Sdim
1398226584Sdimstd::string VarBitInit::getAsString() const {
1399226584Sdim   return TI->getAsString() + "{" + utostr(Bit) + "}";
1400226584Sdim}
1401226584Sdim
1402226584SdimInit *VarBitInit::resolveReferences(Record &R, const RecordVal *RV) const {
1403243830Sdim  Init *I = TI->resolveReferences(R, RV);
1404243830Sdim  if (TI != I)
1405243830Sdim    return I->getBit(getBitNum());
1406243830Sdim
1407243830Sdim  return const_cast<VarBitInit*>(this);
1408226584Sdim}
1409226584Sdim
1410226584SdimVarListElementInit *VarListElementInit::get(TypedInit *T,
1411226584Sdim                                            unsigned E) {
1412226584Sdim  typedef std::pair<TypedInit *, unsigned> Key;
1413226584Sdim  typedef DenseMap<Key, VarListElementInit *> Pool;
1414226584Sdim
1415226584Sdim  static Pool ThePool;
1416226584Sdim
1417226584Sdim  Key TheKey(std::make_pair(T, E));
1418226584Sdim
1419226584Sdim  VarListElementInit *&I = ThePool[TheKey];
1420226584Sdim  if (!I) I = new VarListElementInit(T, E);
1421226584Sdim  return I;
1422226584Sdim}
1423226584Sdim
1424226584Sdimstd::string VarListElementInit::getAsString() const {
1425226584Sdim  return TI->getAsString() + "[" + utostr(Element) + "]";
1426226584Sdim}
1427226584Sdim
1428226584SdimInit *
1429226584SdimVarListElementInit::resolveReferences(Record &R, const RecordVal *RV) const {
1430226584Sdim  if (Init *I = getVariable()->resolveListElementReference(R, RV,
1431226584Sdim                                                           getElementNum()))
1432226584Sdim    return I;
1433226584Sdim  return const_cast<VarListElementInit *>(this);
1434226584Sdim}
1435226584Sdim
1436243830SdimInit *VarListElementInit::getBit(unsigned Bit) const {
1437243830Sdim  if (getType() == BitRecTy::get())
1438243830Sdim    return const_cast<VarListElementInit*>(this);
1439243830Sdim  return VarBitInit::get(const_cast<VarListElementInit*>(this), Bit);
1440226584Sdim}
1441226584Sdim
1442226584SdimInit *VarListElementInit:: resolveListElementReference(Record &R,
1443226584Sdim                                                       const RecordVal *RV,
1444226584Sdim                                                       unsigned Elt) const {
1445226584Sdim  Init *Result = TI->resolveListElementReference(R, RV, Element);
1446226584Sdim
1447226584Sdim  if (Result) {
1448243830Sdim    if (TypedInit *TInit = dyn_cast<TypedInit>(Result)) {
1449226584Sdim      Init *Result2 = TInit->resolveListElementReference(R, RV, Elt);
1450226584Sdim      if (Result2) return Result2;
1451226584Sdim      return new VarListElementInit(TInit, Elt);
1452226584Sdim    }
1453226584Sdim    return Result;
1454226584Sdim  }
1455226584Sdim
1456226584Sdim  return 0;
1457226584Sdim}
1458226584Sdim
1459226584SdimDefInit *DefInit::get(Record *R) {
1460226584Sdim  return R->getDefInit();
1461226584Sdim}
1462226584Sdim
1463226584SdimRecTy *DefInit::getFieldType(const std::string &FieldName) const {
1464226584Sdim  if (const RecordVal *RV = Def->getValue(FieldName))
1465226584Sdim    return RV->getType();
1466226584Sdim  return 0;
1467226584Sdim}
1468226584Sdim
1469226584SdimInit *DefInit::getFieldInit(Record &R, const RecordVal *RV,
1470226584Sdim                            const std::string &FieldName) const {
1471226584Sdim  return Def->getValue(FieldName)->getValue();
1472226584Sdim}
1473226584Sdim
1474226584Sdim
1475226584Sdimstd::string DefInit::getAsString() const {
1476226584Sdim  return Def->getName();
1477226584Sdim}
1478226584Sdim
1479226584SdimFieldInit *FieldInit::get(Init *R, const std::string &FN) {
1480226584Sdim  typedef std::pair<Init *, TableGenStringKey> Key;
1481226584Sdim  typedef DenseMap<Key, FieldInit *> Pool;
1482226584Sdim  static Pool ThePool;
1483226584Sdim
1484226584Sdim  Key TheKey(std::make_pair(R, FN));
1485226584Sdim
1486226584Sdim  FieldInit *&I = ThePool[TheKey];
1487226584Sdim  if (!I) I = new FieldInit(R, FN);
1488226584Sdim  return I;
1489226584Sdim}
1490226584Sdim
1491243830SdimInit *FieldInit::getBit(unsigned Bit) const {
1492243830Sdim  if (getType() == BitRecTy::get())
1493243830Sdim    return const_cast<FieldInit*>(this);
1494243830Sdim  return VarBitInit::get(const_cast<FieldInit*>(this), Bit);
1495226584Sdim}
1496226584Sdim
1497226584SdimInit *FieldInit::resolveListElementReference(Record &R, const RecordVal *RV,
1498226584Sdim                                             unsigned Elt) const {
1499226584Sdim  if (Init *ListVal = Rec->getFieldInit(R, RV, FieldName))
1500243830Sdim    if (ListInit *LI = dyn_cast<ListInit>(ListVal)) {
1501226584Sdim      if (Elt >= LI->getSize()) return 0;
1502226584Sdim      Init *E = LI->getElement(Elt);
1503226584Sdim
1504226584Sdim      // If the element is set to some value, or if we are resolving a
1505226584Sdim      // reference to a specific variable and that variable is explicitly
1506226584Sdim      // unset, then replace the VarListElementInit with it.
1507243830Sdim      if (RV || !isa<UnsetInit>(E))
1508226584Sdim        return E;
1509226584Sdim    }
1510226584Sdim  return 0;
1511226584Sdim}
1512226584Sdim
1513226584SdimInit *FieldInit::resolveReferences(Record &R, const RecordVal *RV) const {
1514226584Sdim  Init *NewRec = RV ? Rec->resolveReferences(R, RV) : Rec;
1515226584Sdim
1516226584Sdim  Init *BitsVal = NewRec->getFieldInit(R, RV, FieldName);
1517226584Sdim  if (BitsVal) {
1518226584Sdim    Init *BVR = BitsVal->resolveReferences(R, RV);
1519226584Sdim    return BVR->isComplete() ? BVR : const_cast<FieldInit *>(this);
1520226584Sdim  }
1521226584Sdim
1522226584Sdim  if (NewRec != Rec) {
1523226584Sdim    return FieldInit::get(NewRec, FieldName);
1524226584Sdim  }
1525226584Sdim  return const_cast<FieldInit *>(this);
1526226584Sdim}
1527226584Sdim
1528249423Sdimstatic void ProfileDagInit(FoldingSetNodeID &ID, Init *V, const std::string &VN,
1529249423Sdim                           ArrayRef<Init *> ArgRange,
1530249423Sdim                           ArrayRef<std::string> NameRange) {
1531226584Sdim  ID.AddPointer(V);
1532226584Sdim  ID.AddString(VN);
1533226584Sdim
1534226584Sdim  ArrayRef<Init *>::iterator Arg  = ArgRange.begin();
1535226584Sdim  ArrayRef<std::string>::iterator  Name = NameRange.begin();
1536226584Sdim  while (Arg != ArgRange.end()) {
1537226584Sdim    assert(Name != NameRange.end() && "Arg name underflow!");
1538226584Sdim    ID.AddPointer(*Arg++);
1539226584Sdim    ID.AddString(*Name++);
1540226584Sdim  }
1541226584Sdim  assert(Name == NameRange.end() && "Arg name overflow!");
1542226584Sdim}
1543226584Sdim
1544226584SdimDagInit *
1545226584SdimDagInit::get(Init *V, const std::string &VN,
1546226584Sdim             ArrayRef<Init *> ArgRange,
1547226584Sdim             ArrayRef<std::string> NameRange) {
1548226584Sdim  typedef FoldingSet<DagInit> Pool;
1549226584Sdim  static Pool ThePool;
1550226584Sdim
1551226584Sdim  FoldingSetNodeID ID;
1552226584Sdim  ProfileDagInit(ID, V, VN, ArgRange, NameRange);
1553226584Sdim
1554226584Sdim  void *IP = 0;
1555226584Sdim  if (DagInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
1556226584Sdim    return I;
1557226584Sdim
1558226584Sdim  DagInit *I = new DagInit(V, VN, ArgRange, NameRange);
1559226584Sdim  ThePool.InsertNode(I, IP);
1560226584Sdim
1561226584Sdim  return I;
1562226584Sdim}
1563226584Sdim
1564226584SdimDagInit *
1565226584SdimDagInit::get(Init *V, const std::string &VN,
1566226584Sdim             const std::vector<std::pair<Init*, std::string> > &args) {
1567226584Sdim  typedef std::pair<Init*, std::string> PairType;
1568226584Sdim
1569226584Sdim  std::vector<Init *> Args;
1570226584Sdim  std::vector<std::string> Names;
1571226584Sdim
1572226584Sdim  for (std::vector<PairType>::const_iterator i = args.begin(),
1573226584Sdim         iend = args.end();
1574226584Sdim       i != iend;
1575226584Sdim       ++i) {
1576226584Sdim    Args.push_back(i->first);
1577226584Sdim    Names.push_back(i->second);
1578226584Sdim  }
1579226584Sdim
1580226584Sdim  return DagInit::get(V, VN, Args, Names);
1581226584Sdim}
1582226584Sdim
1583226584Sdimvoid DagInit::Profile(FoldingSetNodeID &ID) const {
1584226584Sdim  ProfileDagInit(ID, Val, ValName, Args, ArgNames);
1585226584Sdim}
1586226584Sdim
1587226584SdimInit *DagInit::resolveReferences(Record &R, const RecordVal *RV) const {
1588226584Sdim  std::vector<Init*> NewArgs;
1589226584Sdim  for (unsigned i = 0, e = Args.size(); i != e; ++i)
1590226584Sdim    NewArgs.push_back(Args[i]->resolveReferences(R, RV));
1591226584Sdim
1592226584Sdim  Init *Op = Val->resolveReferences(R, RV);
1593226584Sdim
1594226584Sdim  if (Args != NewArgs || Op != Val)
1595226584Sdim    return DagInit::get(Op, ValName, NewArgs, ArgNames);
1596226584Sdim
1597226584Sdim  return const_cast<DagInit *>(this);
1598226584Sdim}
1599226584Sdim
1600226584Sdim
1601226584Sdimstd::string DagInit::getAsString() const {
1602226584Sdim  std::string Result = "(" + Val->getAsString();
1603226584Sdim  if (!ValName.empty())
1604226584Sdim    Result += ":" + ValName;
1605226584Sdim  if (Args.size()) {
1606226584Sdim    Result += " " + Args[0]->getAsString();
1607226584Sdim    if (!ArgNames[0].empty()) Result += ":$" + ArgNames[0];
1608226584Sdim    for (unsigned i = 1, e = Args.size(); i != e; ++i) {
1609226584Sdim      Result += ", " + Args[i]->getAsString();
1610226584Sdim      if (!ArgNames[i].empty()) Result += ":$" + ArgNames[i];
1611226584Sdim    }
1612226584Sdim  }
1613226584Sdim  return Result + ")";
1614226584Sdim}
1615226584Sdim
1616226584Sdim
1617226584Sdim//===----------------------------------------------------------------------===//
1618226584Sdim//    Other implementations
1619226584Sdim//===----------------------------------------------------------------------===//
1620226584Sdim
1621226584SdimRecordVal::RecordVal(Init *N, RecTy *T, unsigned P)
1622226584Sdim  : Name(N), Ty(T), Prefix(P) {
1623226584Sdim  Value = Ty->convertValue(UnsetInit::get());
1624226584Sdim  assert(Value && "Cannot create unset value for current type!");
1625226584Sdim}
1626226584Sdim
1627226584SdimRecordVal::RecordVal(const std::string &N, RecTy *T, unsigned P)
1628226584Sdim  : Name(StringInit::get(N)), Ty(T), Prefix(P) {
1629226584Sdim  Value = Ty->convertValue(UnsetInit::get());
1630226584Sdim  assert(Value && "Cannot create unset value for current type!");
1631226584Sdim}
1632226584Sdim
1633226584Sdimconst std::string &RecordVal::getName() const {
1634243830Sdim  StringInit *NameString = dyn_cast<StringInit>(Name);
1635226584Sdim  assert(NameString && "RecordVal name is not a string!");
1636226584Sdim  return NameString->getValue();
1637226584Sdim}
1638226584Sdim
1639226584Sdimvoid RecordVal::dump() const { errs() << *this; }
1640226584Sdim
1641226584Sdimvoid RecordVal::print(raw_ostream &OS, bool PrintSem) const {
1642226584Sdim  if (getPrefix()) OS << "field ";
1643234353Sdim  OS << *getType() << " " << getNameInitAsString();
1644226584Sdim
1645226584Sdim  if (getValue())
1646226584Sdim    OS << " = " << *getValue();
1647226584Sdim
1648226584Sdim  if (PrintSem) OS << ";\n";
1649226584Sdim}
1650226584Sdim
1651226584Sdimunsigned Record::LastID = 0;
1652226584Sdim
1653234353Sdimvoid Record::init() {
1654234353Sdim  checkName();
1655234353Sdim
1656234353Sdim  // Every record potentially has a def at the top.  This value is
1657234353Sdim  // replaced with the top-level def name at instantiation time.
1658234353Sdim  RecordVal DN("NAME", StringRecTy::get(), 0);
1659234353Sdim  addValue(DN);
1660234353Sdim}
1661234353Sdim
1662226584Sdimvoid Record::checkName() {
1663226584Sdim  // Ensure the record name has string type.
1664243830Sdim  const TypedInit *TypedName = dyn_cast<const TypedInit>(Name);
1665226584Sdim  assert(TypedName && "Record name is not typed!");
1666226584Sdim  RecTy *Type = TypedName->getType();
1667243830Sdim  if (!isa<StringRecTy>(Type))
1668243830Sdim    PrintFatalError(getLoc(), "Record name is not a string!");
1669226584Sdim}
1670226584Sdim
1671226584SdimDefInit *Record::getDefInit() {
1672226584Sdim  if (!TheInit)
1673226584Sdim    TheInit = new DefInit(this, new RecordRecTy(this));
1674226584Sdim  return TheInit;
1675226584Sdim}
1676226584Sdim
1677226584Sdimconst std::string &Record::getName() const {
1678243830Sdim  const StringInit *NameString = dyn_cast<StringInit>(Name);
1679226584Sdim  assert(NameString && "Record name is not a string!");
1680226584Sdim  return NameString->getValue();
1681226584Sdim}
1682226584Sdim
1683226584Sdimvoid Record::setName(Init *NewName) {
1684226584Sdim  if (TrackedRecords.getDef(Name->getAsUnquotedString()) == this) {
1685226584Sdim    TrackedRecords.removeDef(Name->getAsUnquotedString());
1686226584Sdim    TrackedRecords.addDef(this);
1687234353Sdim  } else if (TrackedRecords.getClass(Name->getAsUnquotedString()) == this) {
1688226584Sdim    TrackedRecords.removeClass(Name->getAsUnquotedString());
1689226584Sdim    TrackedRecords.addClass(this);
1690234353Sdim  }  // Otherwise this isn't yet registered.
1691234353Sdim  Name = NewName;
1692226584Sdim  checkName();
1693226584Sdim  // DO NOT resolve record values to the name at this point because
1694226584Sdim  // there might be default values for arguments of this def.  Those
1695226584Sdim  // arguments might not have been resolved yet so we don't want to
1696226584Sdim  // prematurely assume values for those arguments were not passed to
1697226584Sdim  // this def.
1698226584Sdim  //
1699226584Sdim  // Nonetheless, it may be that some of this Record's values
1700226584Sdim  // reference the record name.  Indeed, the reason for having the
1701226584Sdim  // record name be an Init is to provide this flexibility.  The extra
1702226584Sdim  // resolve steps after completely instantiating defs takes care of
1703226584Sdim  // this.  See TGParser::ParseDef and TGParser::ParseDefm.
1704226584Sdim}
1705226584Sdim
1706226584Sdimvoid Record::setName(const std::string &Name) {
1707226584Sdim  setName(StringInit::get(Name));
1708226584Sdim}
1709226584Sdim
1710226584Sdim/// resolveReferencesTo - If anything in this record refers to RV, replace the
1711226584Sdim/// reference to RV with the RHS of RV.  If RV is null, we resolve all possible
1712226584Sdim/// references.
1713226584Sdimvoid Record::resolveReferencesTo(const RecordVal *RV) {
1714226584Sdim  for (unsigned i = 0, e = Values.size(); i != e; ++i) {
1715234353Sdim    if (RV == &Values[i]) // Skip resolve the same field as the given one
1716234353Sdim      continue;
1717226584Sdim    if (Init *V = Values[i].getValue())
1718243830Sdim      if (Values[i].setValue(V->resolveReferences(*this, RV)))
1719243830Sdim        PrintFatalError(getLoc(), "Invalid value is found when setting '"
1720243830Sdim                      + Values[i].getNameInitAsString()
1721243830Sdim                      + "' after resolving references"
1722243830Sdim                      + (RV ? " against '" + RV->getNameInitAsString()
1723243830Sdim                              + "' of ("
1724243830Sdim                              + RV->getValue()->getAsUnquotedString() + ")"
1725243830Sdim                            : "")
1726243830Sdim                      + "\n");
1727226584Sdim  }
1728234353Sdim  Init *OldName = getNameInit();
1729234353Sdim  Init *NewName = Name->resolveReferences(*this, RV);
1730234353Sdim  if (NewName != OldName) {
1731234353Sdim    // Re-register with RecordKeeper.
1732234353Sdim    setName(NewName);
1733234353Sdim  }
1734226584Sdim}
1735226584Sdim
1736226584Sdimvoid Record::dump() const { errs() << *this; }
1737226584Sdim
1738226584Sdimraw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) {
1739234353Sdim  OS << R.getNameInitAsString();
1740226584Sdim
1741234353Sdim  const std::vector<Init *> &TArgs = R.getTemplateArgs();
1742226584Sdim  if (!TArgs.empty()) {
1743226584Sdim    OS << "<";
1744226584Sdim    for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
1745226584Sdim      if (i) OS << ", ";
1746226584Sdim      const RecordVal *RV = R.getValue(TArgs[i]);
1747226584Sdim      assert(RV && "Template argument record not found??");
1748226584Sdim      RV->print(OS, false);
1749226584Sdim    }
1750226584Sdim    OS << ">";
1751226584Sdim  }
1752226584Sdim
1753226584Sdim  OS << " {";
1754226584Sdim  const std::vector<Record*> &SC = R.getSuperClasses();
1755226584Sdim  if (!SC.empty()) {
1756226584Sdim    OS << "\t//";
1757226584Sdim    for (unsigned i = 0, e = SC.size(); i != e; ++i)
1758234353Sdim      OS << " " << SC[i]->getNameInitAsString();
1759226584Sdim  }
1760226584Sdim  OS << "\n";
1761226584Sdim
1762226584Sdim  const std::vector<RecordVal> &Vals = R.getValues();
1763226584Sdim  for (unsigned i = 0, e = Vals.size(); i != e; ++i)
1764226584Sdim    if (Vals[i].getPrefix() && !R.isTemplateArg(Vals[i].getName()))
1765226584Sdim      OS << Vals[i];
1766226584Sdim  for (unsigned i = 0, e = Vals.size(); i != e; ++i)
1767226584Sdim    if (!Vals[i].getPrefix() && !R.isTemplateArg(Vals[i].getName()))
1768226584Sdim      OS << Vals[i];
1769226584Sdim
1770226584Sdim  return OS << "}\n";
1771226584Sdim}
1772226584Sdim
1773226584Sdim/// getValueInit - Return the initializer for a value with the specified name,
1774243830Sdim/// or abort if the field does not exist.
1775226584Sdim///
1776226584SdimInit *Record::getValueInit(StringRef FieldName) const {
1777226584Sdim  const RecordVal *R = getValue(FieldName);
1778226584Sdim  if (R == 0 || R->getValue() == 0)
1779243830Sdim    PrintFatalError(getLoc(), "Record `" + getName() +
1780243830Sdim      "' does not have a field named `" + FieldName.str() + "'!\n");
1781226584Sdim  return R->getValue();
1782226584Sdim}
1783226584Sdim
1784226584Sdim
1785226584Sdim/// getValueAsString - This method looks up the specified field and returns its
1786243830Sdim/// value as a string, aborts if the field does not exist or if
1787226584Sdim/// the value is not a string.
1788226584Sdim///
1789226584Sdimstd::string Record::getValueAsString(StringRef FieldName) const {
1790226584Sdim  const RecordVal *R = getValue(FieldName);
1791226584Sdim  if (R == 0 || R->getValue() == 0)
1792243830Sdim    PrintFatalError(getLoc(), "Record `" + getName() +
1793243830Sdim      "' does not have a field named `" + FieldName.str() + "'!\n");
1794226584Sdim
1795243830Sdim  if (StringInit *SI = dyn_cast<StringInit>(R->getValue()))
1796226584Sdim    return SI->getValue();
1797243830Sdim  PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
1798243830Sdim    FieldName.str() + "' does not have a string initializer!");
1799226584Sdim}
1800226584Sdim
1801226584Sdim/// getValueAsBitsInit - This method looks up the specified field and returns
1802243830Sdim/// its value as a BitsInit, aborts if the field does not exist or if
1803243830Sdim/// the value is not the right type.
1804226584Sdim///
1805226584SdimBitsInit *Record::getValueAsBitsInit(StringRef FieldName) const {
1806226584Sdim  const RecordVal *R = getValue(FieldName);
1807226584Sdim  if (R == 0 || R->getValue() == 0)
1808243830Sdim    PrintFatalError(getLoc(), "Record `" + getName() +
1809243830Sdim      "' does not have a field named `" + FieldName.str() + "'!\n");
1810226584Sdim
1811243830Sdim  if (BitsInit *BI = dyn_cast<BitsInit>(R->getValue()))
1812226584Sdim    return BI;
1813243830Sdim  PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
1814243830Sdim    FieldName.str() + "' does not have a BitsInit initializer!");
1815226584Sdim}
1816226584Sdim
1817226584Sdim/// getValueAsListInit - This method looks up the specified field and returns
1818243830Sdim/// its value as a ListInit, aborting if the field does not exist or if
1819243830Sdim/// the value is not the right type.
1820226584Sdim///
1821226584SdimListInit *Record::getValueAsListInit(StringRef FieldName) const {
1822226584Sdim  const RecordVal *R = getValue(FieldName);
1823226584Sdim  if (R == 0 || R->getValue() == 0)
1824243830Sdim    PrintFatalError(getLoc(), "Record `" + getName() +
1825243830Sdim      "' does not have a field named `" + FieldName.str() + "'!\n");
1826226584Sdim
1827243830Sdim  if (ListInit *LI = dyn_cast<ListInit>(R->getValue()))
1828226584Sdim    return LI;
1829243830Sdim  PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
1830243830Sdim    FieldName.str() + "' does not have a list initializer!");
1831226584Sdim}
1832226584Sdim
1833226584Sdim/// getValueAsListOfDefs - This method looks up the specified field and returns
1834243830Sdim/// its value as a vector of records, aborting if the field does not exist
1835243830Sdim/// or if the value is not the right type.
1836226584Sdim///
1837226584Sdimstd::vector<Record*>
1838226584SdimRecord::getValueAsListOfDefs(StringRef FieldName) const {
1839226584Sdim  ListInit *List = getValueAsListInit(FieldName);
1840226584Sdim  std::vector<Record*> Defs;
1841226584Sdim  for (unsigned i = 0; i < List->getSize(); i++) {
1842243830Sdim    if (DefInit *DI = dyn_cast<DefInit>(List->getElement(i))) {
1843226584Sdim      Defs.push_back(DI->getDef());
1844226584Sdim    } else {
1845243830Sdim      PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
1846243830Sdim        FieldName.str() + "' list is not entirely DefInit!");
1847226584Sdim    }
1848226584Sdim  }
1849226584Sdim  return Defs;
1850226584Sdim}
1851226584Sdim
1852226584Sdim/// getValueAsInt - This method looks up the specified field and returns its
1853243830Sdim/// value as an int64_t, aborting if the field does not exist or if the value
1854243830Sdim/// is not the right type.
1855226584Sdim///
1856226584Sdimint64_t Record::getValueAsInt(StringRef FieldName) const {
1857226584Sdim  const RecordVal *R = getValue(FieldName);
1858226584Sdim  if (R == 0 || R->getValue() == 0)
1859243830Sdim    PrintFatalError(getLoc(), "Record `" + getName() +
1860243830Sdim      "' does not have a field named `" + FieldName.str() + "'!\n");
1861226584Sdim
1862243830Sdim  if (IntInit *II = dyn_cast<IntInit>(R->getValue()))
1863226584Sdim    return II->getValue();
1864243830Sdim  PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
1865243830Sdim    FieldName.str() + "' does not have an int initializer!");
1866226584Sdim}
1867226584Sdim
1868226584Sdim/// getValueAsListOfInts - This method looks up the specified field and returns
1869243830Sdim/// its value as a vector of integers, aborting if the field does not exist or
1870243830Sdim/// if the value is not the right type.
1871226584Sdim///
1872226584Sdimstd::vector<int64_t>
1873226584SdimRecord::getValueAsListOfInts(StringRef FieldName) const {
1874226584Sdim  ListInit *List = getValueAsListInit(FieldName);
1875226584Sdim  std::vector<int64_t> Ints;
1876226584Sdim  for (unsigned i = 0; i < List->getSize(); i++) {
1877243830Sdim    if (IntInit *II = dyn_cast<IntInit>(List->getElement(i))) {
1878226584Sdim      Ints.push_back(II->getValue());
1879226584Sdim    } else {
1880243830Sdim      PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
1881243830Sdim        FieldName.str() + "' does not have a list of ints initializer!");
1882226584Sdim    }
1883226584Sdim  }
1884226584Sdim  return Ints;
1885226584Sdim}
1886226584Sdim
1887226584Sdim/// getValueAsListOfStrings - This method looks up the specified field and
1888243830Sdim/// returns its value as a vector of strings, aborting if the field does not
1889243830Sdim/// exist or if the value is not the right type.
1890226584Sdim///
1891226584Sdimstd::vector<std::string>
1892226584SdimRecord::getValueAsListOfStrings(StringRef FieldName) const {
1893226584Sdim  ListInit *List = getValueAsListInit(FieldName);
1894226584Sdim  std::vector<std::string> Strings;
1895226584Sdim  for (unsigned i = 0; i < List->getSize(); i++) {
1896243830Sdim    if (StringInit *II = dyn_cast<StringInit>(List->getElement(i))) {
1897226584Sdim      Strings.push_back(II->getValue());
1898226584Sdim    } else {
1899243830Sdim      PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
1900243830Sdim        FieldName.str() + "' does not have a list of strings initializer!");
1901226584Sdim    }
1902226584Sdim  }
1903226584Sdim  return Strings;
1904226584Sdim}
1905226584Sdim
1906226584Sdim/// getValueAsDef - This method looks up the specified field and returns its
1907243830Sdim/// value as a Record, aborting if the field does not exist or if the value
1908243830Sdim/// is not the right type.
1909226584Sdim///
1910226584SdimRecord *Record::getValueAsDef(StringRef FieldName) const {
1911226584Sdim  const RecordVal *R = getValue(FieldName);
1912226584Sdim  if (R == 0 || R->getValue() == 0)
1913243830Sdim    PrintFatalError(getLoc(), "Record `" + getName() +
1914243830Sdim      "' does not have a field named `" + FieldName.str() + "'!\n");
1915226584Sdim
1916243830Sdim  if (DefInit *DI = dyn_cast<DefInit>(R->getValue()))
1917226584Sdim    return DI->getDef();
1918243830Sdim  PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
1919243830Sdim    FieldName.str() + "' does not have a def initializer!");
1920226584Sdim}
1921226584Sdim
1922226584Sdim/// getValueAsBit - This method looks up the specified field and returns its
1923243830Sdim/// value as a bit, aborting if the field does not exist or if the value is
1924243830Sdim/// not the right type.
1925226584Sdim///
1926226584Sdimbool Record::getValueAsBit(StringRef FieldName) const {
1927226584Sdim  const RecordVal *R = getValue(FieldName);
1928226584Sdim  if (R == 0 || R->getValue() == 0)
1929243830Sdim    PrintFatalError(getLoc(), "Record `" + getName() +
1930243830Sdim      "' does not have a field named `" + FieldName.str() + "'!\n");
1931226584Sdim
1932243830Sdim  if (BitInit *BI = dyn_cast<BitInit>(R->getValue()))
1933226584Sdim    return BI->getValue();
1934243830Sdim  PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
1935243830Sdim    FieldName.str() + "' does not have a bit initializer!");
1936226584Sdim}
1937226584Sdim
1938243830Sdimbool Record::getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const {
1939243830Sdim  const RecordVal *R = getValue(FieldName);
1940243830Sdim  if (R == 0 || R->getValue() == 0)
1941243830Sdim    PrintFatalError(getLoc(), "Record `" + getName() +
1942243830Sdim      "' does not have a field named `" + FieldName.str() + "'!\n");
1943243830Sdim
1944243830Sdim  if (R->getValue() == UnsetInit::get()) {
1945243830Sdim    Unset = true;
1946243830Sdim    return false;
1947243830Sdim  }
1948243830Sdim  Unset = false;
1949243830Sdim  if (BitInit *BI = dyn_cast<BitInit>(R->getValue()))
1950243830Sdim    return BI->getValue();
1951243830Sdim  PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
1952243830Sdim    FieldName.str() + "' does not have a bit initializer!");
1953243830Sdim}
1954243830Sdim
1955226584Sdim/// getValueAsDag - This method looks up the specified field and returns its
1956243830Sdim/// value as an Dag, aborting if the field does not exist or if the value is
1957243830Sdim/// not the right type.
1958226584Sdim///
1959226584SdimDagInit *Record::getValueAsDag(StringRef FieldName) const {
1960226584Sdim  const RecordVal *R = getValue(FieldName);
1961226584Sdim  if (R == 0 || R->getValue() == 0)
1962243830Sdim    PrintFatalError(getLoc(), "Record `" + getName() +
1963243830Sdim      "' does not have a field named `" + FieldName.str() + "'!\n");
1964226584Sdim
1965243830Sdim  if (DagInit *DI = dyn_cast<DagInit>(R->getValue()))
1966226584Sdim    return DI;
1967243830Sdim  PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
1968243830Sdim    FieldName.str() + "' does not have a dag initializer!");
1969226584Sdim}
1970226584Sdim
1971226584Sdim
1972226584Sdimvoid MultiClass::dump() const {
1973226584Sdim  errs() << "Record:\n";
1974226584Sdim  Rec.dump();
1975226584Sdim
1976226584Sdim  errs() << "Defs:\n";
1977226584Sdim  for (RecordVector::const_iterator r = DefPrototypes.begin(),
1978226584Sdim         rend = DefPrototypes.end();
1979226584Sdim       r != rend;
1980226584Sdim       ++r) {
1981226584Sdim    (*r)->dump();
1982226584Sdim  }
1983226584Sdim}
1984226584Sdim
1985226584Sdim
1986226584Sdimvoid RecordKeeper::dump() const { errs() << *this; }
1987226584Sdim
1988226584Sdimraw_ostream &llvm::operator<<(raw_ostream &OS, const RecordKeeper &RK) {
1989226584Sdim  OS << "------------- Classes -----------------\n";
1990226584Sdim  const std::map<std::string, Record*> &Classes = RK.getClasses();
1991226584Sdim  for (std::map<std::string, Record*>::const_iterator I = Classes.begin(),
1992226584Sdim         E = Classes.end(); I != E; ++I)
1993226584Sdim    OS << "class " << *I->second;
1994226584Sdim
1995226584Sdim  OS << "------------- Defs -----------------\n";
1996226584Sdim  const std::map<std::string, Record*> &Defs = RK.getDefs();
1997226584Sdim  for (std::map<std::string, Record*>::const_iterator I = Defs.begin(),
1998226584Sdim         E = Defs.end(); I != E; ++I)
1999226584Sdim    OS << "def " << *I->second;
2000226584Sdim  return OS;
2001226584Sdim}
2002226584Sdim
2003226584Sdim
2004226584Sdim/// getAllDerivedDefinitions - This method returns all concrete definitions
2005226584Sdim/// that derive from the specified class name.  If a class with the specified
2006226584Sdim/// name does not exist, an error is printed and true is returned.
2007226584Sdimstd::vector<Record*>
2008226584SdimRecordKeeper::getAllDerivedDefinitions(const std::string &ClassName) const {
2009226584Sdim  Record *Class = getClass(ClassName);
2010226584Sdim  if (!Class)
2011243830Sdim    PrintFatalError("ERROR: Couldn't find the `" + ClassName + "' class!\n");
2012226584Sdim
2013226584Sdim  std::vector<Record*> Defs;
2014226584Sdim  for (std::map<std::string, Record*>::const_iterator I = getDefs().begin(),
2015226584Sdim         E = getDefs().end(); I != E; ++I)
2016226584Sdim    if (I->second->isSubClassOf(Class))
2017226584Sdim      Defs.push_back(I->second);
2018226584Sdim
2019226584Sdim  return Defs;
2020226584Sdim}
2021226584Sdim
2022234353Sdim/// QualifyName - Return an Init with a qualifier prefix referring
2023234353Sdim/// to CurRec's name.
2024234353SdimInit *llvm::QualifyName(Record &CurRec, MultiClass *CurMultiClass,
2025234353Sdim                        Init *Name, const std::string &Scoper) {
2026243830Sdim  RecTy *Type = dyn_cast<TypedInit>(Name)->getType();
2027234353Sdim
2028234353Sdim  BinOpInit *NewName =
2029234353Sdim    BinOpInit::get(BinOpInit::STRCONCAT,
2030234353Sdim                      BinOpInit::get(BinOpInit::STRCONCAT,
2031234353Sdim                                        CurRec.getNameInit(),
2032234353Sdim                                        StringInit::get(Scoper),
2033234353Sdim                                        Type)->Fold(&CurRec, CurMultiClass),
2034234353Sdim                      Name,
2035234353Sdim                      Type);
2036234353Sdim
2037234353Sdim  if (CurMultiClass && Scoper != "::") {
2038234353Sdim    NewName =
2039234353Sdim      BinOpInit::get(BinOpInit::STRCONCAT,
2040234353Sdim                        BinOpInit::get(BinOpInit::STRCONCAT,
2041234353Sdim                                          CurMultiClass->Rec.getNameInit(),
2042234353Sdim                                          StringInit::get("::"),
2043234353Sdim                                          Type)->Fold(&CurRec, CurMultiClass),
2044234353Sdim                        NewName->Fold(&CurRec, CurMultiClass),
2045234353Sdim                        Type);
2046234353Sdim  }
2047234353Sdim
2048234353Sdim  return NewName->Fold(&CurRec, CurMultiClass);
2049234353Sdim}
2050234353Sdim
2051234353Sdim/// QualifyName - Return an Init with a qualifier prefix referring
2052234353Sdim/// to CurRec's name.
2053234353SdimInit *llvm::QualifyName(Record &CurRec, MultiClass *CurMultiClass,
2054234353Sdim                        const std::string &Name,
2055234353Sdim                        const std::string &Scoper) {
2056234353Sdim  return QualifyName(CurRec, CurMultiClass, StringInit::get(Name), Scoper);
2057234353Sdim}
2058