199461Sobrien//===- llvm/TableGen/Record.h - Classes for Table Records -------*- C++ -*-===//
2218822Sdim//
3218822Sdim//                     The LLVM Compiler Infrastructure
499461Sobrien//
599461Sobrien// This file is distributed under the University of Illinois Open Source
699461Sobrien// License. See LICENSE.TXT for details.
799461Sobrien//
899461Sobrien//===----------------------------------------------------------------------===//
999461Sobrien//
1099461Sobrien// This file defines the main TableGen data structures, including the TableGen
1199461Sobrien// types, values, and high-level data structures.
1299461Sobrien//
1399461Sobrien//===----------------------------------------------------------------------===//
1499461Sobrien
1599461Sobrien#ifndef LLVM_TABLEGEN_RECORD_H
1699461Sobrien#define LLVM_TABLEGEN_RECORD_H
1799461Sobrien
1899461Sobrien#include "llvm/ADT/ArrayRef.h"
1999461Sobrien#include "llvm/ADT/FoldingSet.h"
20218822Sdim#include "llvm/Support/Allocator.h"
21218822Sdim#include "llvm/Support/Casting.h"
2299461Sobrien#include "llvm/Support/DataTypes.h"
23218822Sdim#include "llvm/Support/ErrorHandling.h"
2499461Sobrien#include "llvm/Support/SourceMgr.h"
2599461Sobrien#include "llvm/Support/raw_ostream.h"
2699461Sobrien#include <map>
2799461Sobrien
2899461Sobriennamespace llvm {
2999461Sobrienclass raw_ostream;
3099461Sobrien
3199461Sobrien// RecTy subclasses.
3299461Sobrienclass BitRecTy;
33130561Sobrienclass BitsRecTy;
3499461Sobrienclass IntRecTy;
3599461Sobrienclass StringRecTy;
3699461Sobrienclass ListRecTy;
3799461Sobrienclass DagRecTy;
3899461Sobrienclass RecordRecTy;
39130561Sobrien
4099461Sobrien// Init subclasses.
41130561Sobrienclass Init;
4299461Sobrienclass UnsetInit;
4399461Sobrienclass BitInit;
44218822Sdimclass BitsInit;
45107492Sobrienclass IntInit;
46130561Sobrienclass StringInit;
4799461Sobrienclass ListInit;
4899461Sobrienclass UnOpInit;
49130561Sobrienclass BinOpInit;
50130561Sobrienclass TernOpInit;
51130561Sobrienclass DefInit;
52130561Sobrienclass DagInit;
5399461Sobrienclass TypedInit;
54130561Sobrienclass VarInit;
5599461Sobrienclass FieldInit;
56130561Sobrienclass VarBitInit;
5799461Sobrienclass VarListElementInit;
58130561Sobrien
5999461Sobrien// Other classes.
60130561Sobrienclass Record;
6199461Sobrienclass RecordVal;
6299461Sobrienstruct MultiClass;
63130561Sobrienclass RecordKeeper;
6499461Sobrien
6599461Sobrien//===----------------------------------------------------------------------===//
6699461Sobrien//  Type Classes
6799461Sobrien//===----------------------------------------------------------------------===//
68130561Sobrien
6999461Sobrienclass RecTy {
70130561Sobrienpublic:
71130561Sobrien  /// \brief Subclass discriminator (for dyn_cast<> et al.)
72130561Sobrien  enum RecTyKind {
73130561Sobrien    BitRecTyKind,
74130561Sobrien    BitsRecTyKind,
75130561Sobrien    IntRecTyKind,
76130561Sobrien    StringRecTyKind,
77130561Sobrien    ListRecTyKind,
78130561Sobrien    DagRecTyKind,
79130561Sobrien    RecordRecTyKind
80130561Sobrien  };
81130561Sobrien
82130561Sobrienprivate:
83130561Sobrien  RecTyKind Kind;
84130561Sobrien  ListRecTy *ListTy;
85130561Sobrien  virtual void anchor();
8699461Sobrien
8799461Sobrienpublic:
8899461Sobrien  RecTyKind getRecTyKind() const { return Kind; }
8999461Sobrien
9099461Sobrien  RecTy(RecTyKind K) : Kind(K), ListTy(0) {}
9199461Sobrien  virtual ~RecTy() {}
9299461Sobrien
9399461Sobrien  virtual std::string getAsString() const = 0;
9499461Sobrien  void print(raw_ostream &OS) const { OS << getAsString(); }
9599461Sobrien  void dump() const;
9699461Sobrien
97130561Sobrien  /// typeIsConvertibleTo - Return true if all values of 'this' type can be
9899461Sobrien  /// converted to the specified type.
9999461Sobrien  virtual bool typeIsConvertibleTo(const RecTy *RHS) const = 0;
10099461Sobrien
10199461Sobrien  /// getListTy - Returns the type representing list<this>.
102130561Sobrien  ListRecTy *getListTy();
10399461Sobrien
10499461Sobrienpublic:   // These methods should only be called from subclasses of Init
105130561Sobrien  virtual Init *convertValue( UnsetInit *UI) { return 0; }
10699461Sobrien  virtual Init *convertValue(   BitInit *BI) { return 0; }
107130561Sobrien  virtual Init *convertValue(  BitsInit *BI) { return 0; }
108130561Sobrien  virtual Init *convertValue(   IntInit *II) { return 0; }
109130561Sobrien  virtual Init *convertValue(StringInit *SI) { return 0; }
110130561Sobrien  virtual Init *convertValue(  ListInit *LI) { return 0; }
111130561Sobrien  virtual Init *convertValue( UnOpInit *UI) {
112130561Sobrien    return convertValue((TypedInit*)UI);
113130561Sobrien  }
114130561Sobrien  virtual Init *convertValue( BinOpInit *UI) {
115130561Sobrien    return convertValue((TypedInit*)UI);
116130561Sobrien  }
117130561Sobrien  virtual Init *convertValue( TernOpInit *UI) {
118130561Sobrien    return convertValue((TypedInit*)UI);
119130561Sobrien  }
120130561Sobrien  virtual Init *convertValue(VarBitInit *VB) { return 0; }
121130561Sobrien  virtual Init *convertValue(   DefInit *DI) { return 0; }
122130561Sobrien  virtual Init *convertValue(   DagInit *DI) { return 0; }
123130561Sobrien  virtual Init *convertValue( TypedInit *TI) { return 0; }
124130561Sobrien  virtual Init *convertValue(   VarInit *VI) {
125130561Sobrien    return convertValue((TypedInit*)VI);
126130561Sobrien  }
127130561Sobrien  virtual Init *convertValue( FieldInit *FI) {
128130561Sobrien    return convertValue((TypedInit*)FI);
129130561Sobrien  }
130130561Sobrien
131130561Sobrienpublic:
132130561Sobrien  virtual bool baseClassOf(const RecTy*) const;
133130561Sobrien};
134130561Sobrien
135130561Sobrieninline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) {
136130561Sobrien  Ty.print(OS);
137130561Sobrien  return OS;
138130561Sobrien}
139130561Sobrien
140130561Sobrien
141130561Sobrien/// BitRecTy - 'bit' - Represent a single bit
142130561Sobrien///
143130561Sobrienclass BitRecTy : public RecTy {
144130561Sobrien  static BitRecTy Shared;
145130561Sobrien  BitRecTy() : RecTy(BitRecTyKind) {}
146130561Sobrienpublic:
147130561Sobrien  static bool classof(const RecTy *RT) {
148130561Sobrien    return RT->getRecTyKind() == BitRecTyKind;
149130561Sobrien  }
150130561Sobrien
151130561Sobrien  static BitRecTy *get() { return &Shared; }
152130561Sobrien
153130561Sobrien  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
154130561Sobrien  virtual Init *convertValue(   BitInit *BI) { return (Init*)BI; }
155130561Sobrien  virtual Init *convertValue(  BitsInit *BI);
156130561Sobrien  virtual Init *convertValue(   IntInit *II);
157130561Sobrien  virtual Init *convertValue(StringInit *SI) { return 0; }
158130561Sobrien  virtual Init *convertValue(  ListInit *LI) { return 0; }
159130561Sobrien  virtual Init *convertValue(VarBitInit *VB) { return (Init*)VB; }
160130561Sobrien  virtual Init *convertValue(   DefInit *DI) { return 0; }
161130561Sobrien  virtual Init *convertValue(   DagInit *DI) { return 0; }
162130561Sobrien  virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
163130561Sobrien  virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
164130561Sobrien  virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
165130561Sobrien  virtual Init *convertValue( TypedInit *TI);
166130561Sobrien  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
167130561Sobrien  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
168130561Sobrien
169130561Sobrien  virtual std::string getAsString() const { return "bit"; }
170130561Sobrien
171130561Sobrien  virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
172130561Sobrien    return RHS->baseClassOf(this);
173130561Sobrien  }
174130561Sobrien  virtual bool baseClassOf(const RecTy*) const;
175130561Sobrien};
176130561Sobrien
177130561Sobrien
178130561Sobrien/// BitsRecTy - 'bits<n>' - Represent a fixed number of bits
179130561Sobrien///
180130561Sobrienclass BitsRecTy : public RecTy {
181130561Sobrien  unsigned Size;
182130561Sobrien  explicit BitsRecTy(unsigned Sz) : RecTy(BitsRecTyKind), Size(Sz) {}
183130561Sobrienpublic:
184130561Sobrien  static bool classof(const RecTy *RT) {
185130561Sobrien    return RT->getRecTyKind() == BitsRecTyKind;
186130561Sobrien  }
187130561Sobrien
188130561Sobrien  static BitsRecTy *get(unsigned Sz);
189130561Sobrien
190130561Sobrien  unsigned getNumBits() const { return Size; }
191130561Sobrien
192130561Sobrien  virtual Init *convertValue( UnsetInit *UI);
193130561Sobrien  virtual Init *convertValue(   BitInit *UI);
194130561Sobrien  virtual Init *convertValue(  BitsInit *BI);
195130561Sobrien  virtual Init *convertValue(   IntInit *II);
196130561Sobrien  virtual Init *convertValue(StringInit *SI) { return 0; }
197130561Sobrien  virtual Init *convertValue(  ListInit *LI) { return 0; }
198130561Sobrien  virtual Init *convertValue(VarBitInit *VB) { return 0; }
199130561Sobrien  virtual Init *convertValue(   DefInit *DI) { return 0; }
200130561Sobrien  virtual Init *convertValue(   DagInit *DI) { return 0; }
201130561Sobrien  virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
202130561Sobrien  virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
203130561Sobrien  virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
204130561Sobrien  virtual Init *convertValue( TypedInit *TI);
205130561Sobrien  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
206130561Sobrien  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
207130561Sobrien
208130561Sobrien  virtual std::string getAsString() const;
209130561Sobrien
210130561Sobrien  virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
211130561Sobrien    return RHS->baseClassOf(this);
212130561Sobrien  }
213130561Sobrien  virtual bool baseClassOf(const RecTy*) const;
21499461Sobrien};
21599461Sobrien
21699461Sobrien
21799461Sobrien/// IntRecTy - 'int' - Represent an integer value of no particular size
218130561Sobrien///
21999461Sobrienclass IntRecTy : public RecTy {
220130561Sobrien  static IntRecTy Shared;
22199461Sobrien  IntRecTy() : RecTy(IntRecTyKind) {}
22299461Sobrienpublic:
22399461Sobrien  static bool classof(const RecTy *RT) {
22499461Sobrien    return RT->getRecTyKind() == IntRecTyKind;
22599461Sobrien  }
22699461Sobrien
22799461Sobrien  static IntRecTy *get() { return &Shared; }
22899461Sobrien
22999461Sobrien  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
23099461Sobrien  virtual Init *convertValue(   BitInit *BI);
23199461Sobrien  virtual Init *convertValue(  BitsInit *BI);
23299461Sobrien  virtual Init *convertValue(   IntInit *II) { return (Init*)II; }
23399461Sobrien  virtual Init *convertValue(StringInit *SI) { return 0; }
23499461Sobrien  virtual Init *convertValue(  ListInit *LI) { return 0; }
23599461Sobrien  virtual Init *convertValue(VarBitInit *VB) { return 0; }
23699461Sobrien  virtual Init *convertValue(   DefInit *DI) { return 0; }
23799461Sobrien  virtual Init *convertValue(   DagInit *DI) { return 0; }
23899461Sobrien  virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
23999461Sobrien  virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
24099461Sobrien  virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
24199461Sobrien  virtual Init *convertValue( TypedInit *TI);
24299461Sobrien  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
24399461Sobrien  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
24499461Sobrien
24599461Sobrien  virtual std::string getAsString() const { return "int"; }
24699461Sobrien
24799461Sobrien  virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
24899461Sobrien    return RHS->baseClassOf(this);
24999461Sobrien  }
25099461Sobrien
25199461Sobrien  virtual bool baseClassOf(const RecTy*) const;
25299461Sobrien};
25399461Sobrien
25499461Sobrien/// StringRecTy - 'string' - Represent an string value
25599461Sobrien///
25699461Sobrienclass StringRecTy : public RecTy {
25799461Sobrien  static StringRecTy Shared;
258130561Sobrien  StringRecTy() : RecTy(StringRecTyKind) {}
25999461Sobrienpublic:
26099461Sobrien  static bool classof(const RecTy *RT) {
26199461Sobrien    return RT->getRecTyKind() == StringRecTyKind;
26299461Sobrien  }
26399461Sobrien
26499461Sobrien  static StringRecTy *get() { return &Shared; }
26599461Sobrien
26699461Sobrien  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
26799461Sobrien  virtual Init *convertValue(   BitInit *BI) { return 0; }
26899461Sobrien  virtual Init *convertValue(  BitsInit *BI) { return 0; }
26999461Sobrien  virtual Init *convertValue(   IntInit *II) { return 0; }
27099461Sobrien  virtual Init *convertValue(StringInit *SI) { return (Init*)SI; }
27199461Sobrien  virtual Init *convertValue(  ListInit *LI) { return 0; }
27299461Sobrien  virtual Init *convertValue( UnOpInit *BO);
27399461Sobrien  virtual Init *convertValue( BinOpInit *BO);
27499461Sobrien  virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
27599461Sobrien
27699461Sobrien  virtual Init *convertValue(VarBitInit *VB) { return 0; }
277130561Sobrien  virtual Init *convertValue(   DefInit *DI) { return 0; }
278130561Sobrien  virtual Init *convertValue(   DagInit *DI) { return 0; }
279130561Sobrien  virtual Init *convertValue( TypedInit *TI);
280130561Sobrien  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
281130561Sobrien  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
282130561Sobrien
283130561Sobrien  virtual std::string getAsString() const { return "string"; }
284130561Sobrien
285130561Sobrien  virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
286130561Sobrien    return RHS->baseClassOf(this);
287130561Sobrien  }
288130561Sobrien};
289130561Sobrien
290130561Sobrien/// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must be of
291130561Sobrien/// the specified type.
292130561Sobrien///
293130561Sobrienclass ListRecTy : public RecTy {
294130561Sobrien  RecTy *Ty;
295130561Sobrien  explicit ListRecTy(RecTy *T) : RecTy(ListRecTyKind), Ty(T) {}
296130561Sobrien  friend ListRecTy *RecTy::getListTy();
297130561Sobrienpublic:
298130561Sobrien  static bool classof(const RecTy *RT) {
299130561Sobrien    return RT->getRecTyKind() == ListRecTyKind;
300130561Sobrien  }
301130561Sobrien
302130561Sobrien  static ListRecTy *get(RecTy *T) { return T->getListTy(); }
303130561Sobrien  RecTy *getElementType() const { return Ty; }
304130561Sobrien
305130561Sobrien  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
306130561Sobrien  virtual Init *convertValue(   BitInit *BI) { return 0; }
307130561Sobrien  virtual Init *convertValue(  BitsInit *BI) { return 0; }
308130561Sobrien  virtual Init *convertValue(   IntInit *II) { return 0; }
309130561Sobrien  virtual Init *convertValue(StringInit *SI) { return 0; }
310130561Sobrien  virtual Init *convertValue(  ListInit *LI);
311130561Sobrien  virtual Init *convertValue(VarBitInit *VB) { return 0; }
312130561Sobrien  virtual Init *convertValue(   DefInit *DI) { return 0; }
313130561Sobrien  virtual Init *convertValue(   DagInit *DI) { return 0; }
314130561Sobrien  virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
315130561Sobrien  virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
316130561Sobrien  virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
317130561Sobrien  virtual Init *convertValue( TypedInit *TI);
318130561Sobrien  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
319130561Sobrien  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
320130561Sobrien
321130561Sobrien  virtual std::string getAsString() const;
322130561Sobrien
323130561Sobrien  virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
324130561Sobrien    return RHS->baseClassOf(this);
325130561Sobrien  }
326130561Sobrien
32799461Sobrien  virtual bool baseClassOf(const RecTy*) const;
32899461Sobrien};
32999461Sobrien
33099461Sobrien/// DagRecTy - 'dag' - Represent a dag fragment
33199461Sobrien///
33299461Sobrienclass DagRecTy : public RecTy {
33399461Sobrien  static DagRecTy Shared;
33499461Sobrien  DagRecTy() : RecTy(DagRecTyKind) {}
33599461Sobrienpublic:
33699461Sobrien  static bool classof(const RecTy *RT) {
337218822Sdim    return RT->getRecTyKind() == DagRecTyKind;
338218822Sdim  }
339218822Sdim
340218822Sdim  static DagRecTy *get() { return &Shared; }
341218822Sdim
342218822Sdim  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
343218822Sdim  virtual Init *convertValue(   BitInit *BI) { return 0; }
344218822Sdim  virtual Init *convertValue(  BitsInit *BI) { return 0; }
345218822Sdim  virtual Init *convertValue(   IntInit *II) { return 0; }
346218822Sdim  virtual Init *convertValue(StringInit *SI) { return 0; }
347218822Sdim  virtual Init *convertValue(  ListInit *LI) { return 0; }
348218822Sdim  virtual Init *convertValue(VarBitInit *VB) { return 0; }
349218822Sdim  virtual Init *convertValue(   DefInit *DI) { return 0; }
350218822Sdim  virtual Init *convertValue( UnOpInit *BO);
351218822Sdim  virtual Init *convertValue( BinOpInit *BO);
352218822Sdim  virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
353218822Sdim  virtual Init *convertValue(   DagInit *CI) { return (Init*)CI; }
354218822Sdim  virtual Init *convertValue( TypedInit *TI);
355218822Sdim  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
35699461Sobrien  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
35799461Sobrien
35899461Sobrien  virtual std::string getAsString() const { return "dag"; }
35999461Sobrien
36099461Sobrien  virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
36199461Sobrien    return RHS->baseClassOf(this);
36299461Sobrien  }
36399461Sobrien};
36499461Sobrien
365218822Sdim
366218822Sdim/// RecordRecTy - '[classname]' - Represent an instance of a class, such as:
36799461Sobrien/// (R32 X = EAX).
36899461Sobrien///
36999461Sobrienclass RecordRecTy : public RecTy {
37099461Sobrien  Record *Rec;
37199461Sobrien  explicit RecordRecTy(Record *R) : RecTy(RecordRecTyKind), Rec(R) {}
37299461Sobrien  friend class Record;
37399461Sobrienpublic:
37499461Sobrien  static bool classof(const RecTy *RT) {
37599461Sobrien    return RT->getRecTyKind() == RecordRecTyKind;
37699461Sobrien  }
377218822Sdim
378218822Sdim  static RecordRecTy *get(Record *R);
379218822Sdim
380218822Sdim  Record *getRecord() const { return Rec; }
381218822Sdim
382218822Sdim  virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
383218822Sdim  virtual Init *convertValue(   BitInit *BI) { return 0; }
38499461Sobrien  virtual Init *convertValue(  BitsInit *BI) { return 0; }
38599461Sobrien  virtual Init *convertValue(   IntInit *II) { return 0; }
38699461Sobrien  virtual Init *convertValue(StringInit *SI) { return 0; }
387130561Sobrien  virtual Init *convertValue(  ListInit *LI) { return 0; }
388130561Sobrien  virtual Init *convertValue(VarBitInit *VB) { return 0; }
389130561Sobrien  virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
390130561Sobrien  virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
391130561Sobrien  virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
392130561Sobrien  virtual Init *convertValue(   DefInit *DI);
393130561Sobrien  virtual Init *convertValue(   DagInit *DI) { return 0; }
394130561Sobrien  virtual Init *convertValue( TypedInit *VI);
395130561Sobrien  virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
396130561Sobrien  virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
397130561Sobrien
398130561Sobrien  virtual std::string getAsString() const;
399130561Sobrien
400130561Sobrien  virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
401130561Sobrien    return RHS->baseClassOf(this);
402130561Sobrien  }
403130561Sobrien  virtual bool baseClassOf(const RecTy*) const;
404130561Sobrien};
405130561Sobrien
406130561Sobrien/// resolveTypes - Find a common type that T1 and T2 convert to.
407130561Sobrien/// Return 0 if no such type exists.
408130561Sobrien///
409130561SobrienRecTy *resolveTypes(RecTy *T1, RecTy *T2);
410130561Sobrien
411130561Sobrien//===----------------------------------------------------------------------===//
412130561Sobrien//  Initializer Classes
413130561Sobrien//===----------------------------------------------------------------------===//
414130561Sobrien
415130561Sobrienclass Init {
416130561Sobrienprotected:
417130561Sobrien  /// \brief Discriminator enum (for isa<>, dyn_cast<>, et al.)
418130561Sobrien  ///
419130561Sobrien  /// This enum is laid out by a preorder traversal of the inheritance
420130561Sobrien  /// hierarchy, and does not contain an entry for abstract classes, as per
421130561Sobrien  /// the recommendation in docs/HowToSetUpLLVMStyleRTTI.rst.
422130561Sobrien  ///
423130561Sobrien  /// We also explicitly include "first" and "last" values for each
424130561Sobrien  /// interior node of the inheritance tree, to make it easier to read the
425130561Sobrien  /// corresponding classof().
426130561Sobrien  ///
427130561Sobrien  /// We could pack these a bit tighter by not having the IK_FirstXXXInit
428130561Sobrien  /// and IK_LastXXXInit be their own values, but that would degrade
429130561Sobrien  /// readability for really no benefit.
430130561Sobrien  enum InitKind {
431130561Sobrien    IK_BitInit,
432218822Sdim    IK_BitsInit,
433130561Sobrien    IK_FirstTypedInit,
434130561Sobrien    IK_DagInit,
435130561Sobrien    IK_DefInit,
436130561Sobrien    IK_FieldInit,
437130561Sobrien    IK_IntInit,
438130561Sobrien    IK_ListInit,
439130561Sobrien    IK_FirstOpInit,
440130561Sobrien    IK_BinOpInit,
441130561Sobrien    IK_TernOpInit,
442130561Sobrien    IK_UnOpInit,
443130561Sobrien    IK_LastOpInit,
444130561Sobrien    IK_StringInit,
445130561Sobrien    IK_VarInit,
446130561Sobrien    IK_VarListElementInit,
447130561Sobrien    IK_LastTypedInit,
448130561Sobrien    IK_UnsetInit,
449130561Sobrien    IK_VarBitInit
450130561Sobrien  };
451130561Sobrien
452130561Sobrienprivate:
453130561Sobrien  const InitKind Kind;
454130561Sobrien  Init(const Init &) LLVM_DELETED_FUNCTION;
455130561Sobrien  Init &operator=(const Init &) LLVM_DELETED_FUNCTION;
456130561Sobrien  virtual void anchor();
457130561Sobrien
45899461Sobrienpublic:
45999461Sobrien  InitKind getKind() const { return Kind; }
46099461Sobrien
46199461Sobrienprotected:
46299461Sobrien  explicit Init(InitKind K) : Kind(K) {}
463130561Sobrien
46499461Sobrienpublic:
46599461Sobrien  virtual ~Init() {}
46699461Sobrien
46799461Sobrien  /// isComplete - This virtual method should be overridden by values that may
46899461Sobrien  /// not be completely specified yet.
46999461Sobrien  virtual bool isComplete() const { return true; }
47099461Sobrien
47199461Sobrien  /// print - Print out this value.
47299461Sobrien  void print(raw_ostream &OS) const { OS << getAsString(); }
47399461Sobrien
47499461Sobrien  /// getAsString - Convert this value to a string form.
475130561Sobrien  virtual std::string getAsString() const = 0;
476130561Sobrien  /// getAsUnquotedString - Convert this value to a string form,
477130561Sobrien  /// without adding quote markers.  This primaruly affects
478130561Sobrien  /// StringInits where we will not surround the string value with
479130561Sobrien  /// quotes.
480130561Sobrien  virtual std::string getAsUnquotedString() const { return getAsString(); }
48199461Sobrien
48299461Sobrien  /// dump - Debugging method that may be called through a debugger, just
48399461Sobrien  /// invokes print on stderr.
48499461Sobrien  void dump() const;
48599461Sobrien
48699461Sobrien  /// convertInitializerTo - This virtual function is a simple call-back
48799461Sobrien  /// function that should be overridden to call the appropriate
48899461Sobrien  /// RecTy::convertValue method.
48999461Sobrien  ///
49099461Sobrien  virtual Init *convertInitializerTo(RecTy *Ty) const = 0;
49199461Sobrien
49299461Sobrien  /// convertInitializerBitRange - This method is used to implement the bitrange
49399461Sobrien  /// selection operator.  Given an initializer, it selects the specified bits
49499461Sobrien  /// out, returning them as a new init of bits type.  If it is not legal to use
49599461Sobrien  /// the bit subscript operator on this initializer, return null.
49699461Sobrien  ///
49799461Sobrien  virtual Init *
49899461Sobrien  convertInitializerBitRange(const std::vector<unsigned> &Bits) const {
49999461Sobrien    return 0;
50099461Sobrien  }
50199461Sobrien
50299461Sobrien  /// convertInitListSlice - This method is used to implement the list slice
50399461Sobrien  /// selection operator.  Given an initializer, it selects the specified list
50499461Sobrien  /// elements, returning them as a new init of list type.  If it is not legal
505130561Sobrien  /// to take a slice of this, return null.
50699461Sobrien  ///
50799461Sobrien  virtual Init *
50899461Sobrien  convertInitListSlice(const std::vector<unsigned> &Elements) const {
50999461Sobrien    return 0;
51099461Sobrien  }
51199461Sobrien
51299461Sobrien  /// getFieldType - This method is used to implement the FieldInit class.
51399461Sobrien  /// Implementors of this method should return the type of the named field if
51499461Sobrien  /// they are of record type.
51599461Sobrien  ///
51699461Sobrien  virtual RecTy *getFieldType(const std::string &FieldName) const { return 0; }
51799461Sobrien
51899461Sobrien  /// getFieldInit - This method complements getFieldType to return the
51999461Sobrien  /// initializer for the specified field.  If getFieldType returns non-null
52099461Sobrien  /// this method should return non-null, otherwise it returns null.
52199461Sobrien  ///
52299461Sobrien  virtual Init *getFieldInit(Record &R, const RecordVal *RV,
52399461Sobrien                             const std::string &FieldName) const {
52499461Sobrien    return 0;
52599461Sobrien  }
52699461Sobrien
52799461Sobrien  /// resolveReferences - This method is used by classes that refer to other
52899461Sobrien  /// variables which may not be defined at the time the expression is formed.
52999461Sobrien  /// If a value is set for the variable later, this method will be called on
53099461Sobrien  /// users of the value to allow the value to propagate out.
53199461Sobrien  ///
53299461Sobrien  virtual Init *resolveReferences(Record &R, const RecordVal *RV) const {
53399461Sobrien    return const_cast<Init *>(this);
53499461Sobrien  }
53599461Sobrien
53699461Sobrien  /// getBit - This method is used to return the initializer for the specified
53799461Sobrien  /// bit.
53899461Sobrien  virtual Init *getBit(unsigned Bit) const = 0;
53999461Sobrien
54099461Sobrien  /// getBitVar - This method is used to retrieve the initializer for bit
54199461Sobrien  /// reference. For non-VarBitInit, it simply returns itself.
54299461Sobrien  virtual Init *getBitVar() const { return const_cast<Init*>(this); }
54399461Sobrien
54499461Sobrien  /// getBitNum - This method is used to retrieve the bit number of a bit
54599461Sobrien  /// reference. For non-VarBitInit, it simply returns 0.
54699461Sobrien  virtual unsigned getBitNum() const { return 0; }
54799461Sobrien};
54899461Sobrien
54999461Sobrieninline raw_ostream &operator<<(raw_ostream &OS, const Init &I) {
55099461Sobrien  I.print(OS); return OS;
55199461Sobrien}
55299461Sobrien
55399461Sobrien/// TypedInit - This is the common super-class of types that have a specific,
55499461Sobrien/// explicit, type.
55599461Sobrien///
55699461Sobrienclass TypedInit : public Init {
55799461Sobrien  RecTy *Ty;
55899461Sobrien
55999461Sobrien  TypedInit(const TypedInit &Other) LLVM_DELETED_FUNCTION;
56099461Sobrien  TypedInit &operator=(const TypedInit &Other) LLVM_DELETED_FUNCTION;
56199461Sobrien
56299461Sobrienprotected:
56399461Sobrien  explicit TypedInit(InitKind K, RecTy *T) : Init(K), Ty(T) {}
56499461Sobrien
56599461Sobrienpublic:
56699461Sobrien  static bool classof(const Init *I) {
56799461Sobrien    return I->getKind() >= IK_FirstTypedInit &&
56899461Sobrien           I->getKind() <= IK_LastTypedInit;
56999461Sobrien  }
57099461Sobrien  RecTy *getType() const { return Ty; }
57199461Sobrien
57299461Sobrien  virtual Init *
57399461Sobrien  convertInitializerBitRange(const std::vector<unsigned> &Bits) const;
57499461Sobrien  virtual Init *
57599461Sobrien  convertInitListSlice(const std::vector<unsigned> &Elements) const;
57699461Sobrien
57799461Sobrien  /// getFieldType - This method is used to implement the FieldInit class.
57899461Sobrien  /// Implementors of this method should return the type of the named field if
57999461Sobrien  /// they are of record type.
58099461Sobrien  ///
58199461Sobrien  virtual RecTy *getFieldType(const std::string &FieldName) const;
58299461Sobrien
58399461Sobrien  /// resolveListElementReference - This method is used to implement
58499461Sobrien  /// VarListElementInit::resolveReferences.  If the list element is resolvable
58599461Sobrien  /// now, we return the resolved value, otherwise we return null.
58699461Sobrien  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
58799461Sobrien                                            unsigned Elt) const = 0;
58899461Sobrien};
58999461Sobrien
59099461Sobrien
59199461Sobrien/// UnsetInit - ? - Represents an uninitialized value
59299461Sobrien///
59399461Sobrienclass UnsetInit : public Init {
59499461Sobrien  UnsetInit() : Init(IK_UnsetInit) {}
59599461Sobrien  UnsetInit(const UnsetInit &) LLVM_DELETED_FUNCTION;
59699461Sobrien  UnsetInit &operator=(const UnsetInit &Other) LLVM_DELETED_FUNCTION;
59799461Sobrien  virtual void anchor();
59899461Sobrien
59999461Sobrienpublic:
60099461Sobrien  static bool classof(const Init *I) {
60199461Sobrien    return I->getKind() == IK_UnsetInit;
60299461Sobrien  }
60399461Sobrien  static UnsetInit *get();
60499461Sobrien
60599461Sobrien  virtual Init *convertInitializerTo(RecTy *Ty) const {
60699461Sobrien    return Ty->convertValue(const_cast<UnsetInit *>(this));
60799461Sobrien  }
60899461Sobrien
60999461Sobrien  virtual Init *getBit(unsigned Bit) const {
61099461Sobrien    return const_cast<UnsetInit*>(this);
61199461Sobrien  }
61299461Sobrien
61399461Sobrien  virtual bool isComplete() const { return false; }
61499461Sobrien  virtual std::string getAsString() const { return "?"; }
61599461Sobrien};
61699461Sobrien
61799461Sobrien
61899461Sobrien/// BitInit - true/false - Represent a concrete initializer for a bit.
61999461Sobrien///
62099461Sobrienclass BitInit : public Init {
62199461Sobrien  bool Value;
62299461Sobrien
62399461Sobrien  explicit BitInit(bool V) : Init(IK_BitInit), Value(V) {}
62499461Sobrien  BitInit(const BitInit &Other) LLVM_DELETED_FUNCTION;
62599461Sobrien  BitInit &operator=(BitInit &Other) LLVM_DELETED_FUNCTION;
62699461Sobrien  virtual void anchor();
62799461Sobrien
62899461Sobrienpublic:
62999461Sobrien  static bool classof(const Init *I) {
63099461Sobrien    return I->getKind() == IK_BitInit;
63199461Sobrien  }
63299461Sobrien  static BitInit *get(bool V);
63399461Sobrien
63499461Sobrien  bool getValue() const { return Value; }
63599461Sobrien
63699461Sobrien  virtual Init *convertInitializerTo(RecTy *Ty) const {
63799461Sobrien    return Ty->convertValue(const_cast<BitInit *>(this));
63899461Sobrien  }
63999461Sobrien
64099461Sobrien  virtual Init *getBit(unsigned Bit) const {
64199461Sobrien    assert(Bit < 1 && "Bit index out of range!");
64299461Sobrien    return const_cast<BitInit*>(this);
64399461Sobrien  }
64499461Sobrien
64599461Sobrien  virtual std::string getAsString() const { return Value ? "1" : "0"; }
64699461Sobrien};
64799461Sobrien
64899461Sobrien/// BitsInit - { a, b, c } - Represents an initializer for a BitsRecTy value.
64999461Sobrien/// It contains a vector of bits, whose size is determined by the type.
65099461Sobrien///
65199461Sobrienclass BitsInit : public Init, public FoldingSetNode {
65299461Sobrien  std::vector<Init*> Bits;
65399461Sobrien
65499461Sobrien  BitsInit(ArrayRef<Init *> Range)
65599461Sobrien    : Init(IK_BitsInit), Bits(Range.begin(), Range.end()) {}
65699461Sobrien
65799461Sobrien  BitsInit(const BitsInit &Other) LLVM_DELETED_FUNCTION;
65899461Sobrien  BitsInit &operator=(const BitsInit &Other) LLVM_DELETED_FUNCTION;
65999461Sobrien
66099461Sobrienpublic:
66199461Sobrien  static bool classof(const Init *I) {
662130561Sobrien    return I->getKind() == IK_BitsInit;
663130561Sobrien  }
664130561Sobrien  static BitsInit *get(ArrayRef<Init *> Range);
665130561Sobrien
666130561Sobrien  void Profile(FoldingSetNodeID &ID) const;
667130561Sobrien
668130561Sobrien  unsigned getNumBits() const { return Bits.size(); }
669130561Sobrien
670130561Sobrien  virtual Init *convertInitializerTo(RecTy *Ty) const {
671130561Sobrien    return Ty->convertValue(const_cast<BitsInit *>(this));
67299461Sobrien  }
67399461Sobrien  virtual Init *
674130561Sobrien  convertInitializerBitRange(const std::vector<unsigned> &Bits) const;
675130561Sobrien
676130561Sobrien  virtual bool isComplete() const {
677130561Sobrien    for (unsigned i = 0; i != getNumBits(); ++i)
678130561Sobrien      if (!getBit(i)->isComplete()) return false;
679130561Sobrien    return true;
680130561Sobrien  }
681130561Sobrien  bool allInComplete() const {
682130561Sobrien    for (unsigned i = 0; i != getNumBits(); ++i)
683130561Sobrien      if (getBit(i)->isComplete()) return false;
684130561Sobrien    return true;
685130561Sobrien  }
686130561Sobrien  virtual std::string getAsString() const;
687130561Sobrien
688130561Sobrien  virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
689130561Sobrien
690130561Sobrien  virtual Init *getBit(unsigned Bit) const {
691130561Sobrien    assert(Bit < Bits.size() && "Bit index out of range!");
692218822Sdim    return Bits[Bit];
693130561Sobrien  }
694130561Sobrien};
695218822Sdim
696218822Sdim
697218822Sdim/// IntInit - 7 - Represent an initialization by a literal integer value.
698218822Sdim///
699218822Sdimclass IntInit : public TypedInit {
700218822Sdim  int64_t Value;
701218822Sdim
702130561Sobrien  explicit IntInit(int64_t V)
703130561Sobrien    : TypedInit(IK_IntInit, IntRecTy::get()), Value(V) {}
704130561Sobrien
705130561Sobrien  IntInit(const IntInit &Other) LLVM_DELETED_FUNCTION;
706130561Sobrien  IntInit &operator=(const IntInit &Other) LLVM_DELETED_FUNCTION;
707130561Sobrien
708130561Sobrienpublic:
709130561Sobrien  static bool classof(const Init *I) {
710130561Sobrien    return I->getKind() == IK_IntInit;
711130561Sobrien  }
71299461Sobrien  static IntInit *get(int64_t V);
71399461Sobrien
71499461Sobrien  int64_t getValue() const { return Value; }
71599461Sobrien
71699461Sobrien  virtual Init *convertInitializerTo(RecTy *Ty) const {
71799461Sobrien    return Ty->convertValue(const_cast<IntInit *>(this));
71899461Sobrien  }
71999461Sobrien  virtual Init *
72099461Sobrien  convertInitializerBitRange(const std::vector<unsigned> &Bits) const;
72199461Sobrien
72299461Sobrien  virtual std::string getAsString() const;
72399461Sobrien
72499461Sobrien  /// resolveListElementReference - This method is used to implement
72599461Sobrien  /// VarListElementInit::resolveReferences.  If the list element is resolvable
72699461Sobrien  /// now, we return the resolved value, otherwise we return null.
727130561Sobrien  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
728130561Sobrien                                            unsigned Elt) const {
729130561Sobrien    llvm_unreachable("Illegal element reference off int");
730130561Sobrien  }
731130561Sobrien
73299461Sobrien  virtual Init *getBit(unsigned Bit) const {
73399461Sobrien    return BitInit::get((Value & (1ULL << Bit)) != 0);
73499461Sobrien  }
73599461Sobrien};
73699461Sobrien
73799461Sobrien
73899461Sobrien/// StringInit - "foo" - Represent an initialization by a string value.
73999461Sobrien///
74099461Sobrienclass StringInit : public TypedInit {
74199461Sobrien  std::string Value;
74299461Sobrien
74399461Sobrien  explicit StringInit(const std::string &V)
74499461Sobrien    : TypedInit(IK_StringInit, StringRecTy::get()), Value(V) {}
74599461Sobrien
74699461Sobrien  StringInit(const StringInit &Other) LLVM_DELETED_FUNCTION;
74799461Sobrien  StringInit &operator=(const StringInit &Other) LLVM_DELETED_FUNCTION;
74899461Sobrien  virtual void anchor();
74999461Sobrien
75099461Sobrienpublic:
75199461Sobrien  static bool classof(const Init *I) {
75299461Sobrien    return I->getKind() == IK_StringInit;
75399461Sobrien  }
75499461Sobrien  static StringInit *get(StringRef);
75599461Sobrien
75699461Sobrien  const std::string &getValue() const { return Value; }
75799461Sobrien
75899461Sobrien  virtual Init *convertInitializerTo(RecTy *Ty) const {
75999461Sobrien    return Ty->convertValue(const_cast<StringInit *>(this));
76099461Sobrien  }
76199461Sobrien
76299461Sobrien  virtual std::string getAsString() const { return "\"" + Value + "\""; }
76399461Sobrien  virtual std::string getAsUnquotedString() const { return Value; }
76499461Sobrien
76599461Sobrien  /// resolveListElementReference - This method is used to implement
76699461Sobrien  /// VarListElementInit::resolveReferences.  If the list element is resolvable
767130561Sobrien  /// now, we return the resolved value, otherwise we return null.
768130561Sobrien  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
76999461Sobrien                                            unsigned Elt) const {
77099461Sobrien    llvm_unreachable("Illegal element reference off string");
77199461Sobrien  }
77299461Sobrien
77399461Sobrien  virtual Init *getBit(unsigned Bit) const {
77499461Sobrien    llvm_unreachable("Illegal bit reference off string");
77599461Sobrien  }
77699461Sobrien};
77799461Sobrien
77899461Sobrien/// ListInit - [AL, AH, CL] - Represent a list of defs
77999461Sobrien///
78099461Sobrienclass ListInit : public TypedInit, public FoldingSetNode {
78199461Sobrien  std::vector<Init*> Values;
78299461Sobrienpublic:
783107492Sobrien  typedef std::vector<Init*>::const_iterator const_iterator;
78499461Sobrien
78599461Sobrienprivate:
78699461Sobrien  explicit ListInit(ArrayRef<Init *> Range, RecTy *EltTy)
787218822Sdim    : TypedInit(IK_ListInit, ListRecTy::get(EltTy)),
788218822Sdim      Values(Range.begin(), Range.end()) {}
78999461Sobrien
790107492Sobrien  ListInit(const ListInit &Other) LLVM_DELETED_FUNCTION;
79199461Sobrien  ListInit &operator=(const ListInit &Other) LLVM_DELETED_FUNCTION;
79299461Sobrien
79399461Sobrienpublic:
79499461Sobrien  static bool classof(const Init *I) {
79599461Sobrien    return I->getKind() == IK_ListInit;
79699461Sobrien  }
79799461Sobrien  static ListInit *get(ArrayRef<Init *> Range, RecTy *EltTy);
79899461Sobrien
79999461Sobrien  void Profile(FoldingSetNodeID &ID) const;
80099461Sobrien
801130561Sobrien  unsigned getSize() const { return Values.size(); }
80299461Sobrien  Init *getElement(unsigned i) const {
80399461Sobrien    assert(i < Values.size() && "List element index out of range!");
80499461Sobrien    return Values[i];
80599461Sobrien  }
80699461Sobrien
80799461Sobrien  Record *getElementAsRecord(unsigned i) const;
80899461Sobrien
80999461Sobrien  virtual Init *
810130561Sobrien    convertInitListSlice(const std::vector<unsigned> &Elements) const;
81199461Sobrien
81299461Sobrien  virtual Init *convertInitializerTo(RecTy *Ty) const {
81399461Sobrien    return Ty->convertValue(const_cast<ListInit *>(this));
81499461Sobrien  }
81599461Sobrien
81699461Sobrien  /// resolveReferences - This method is used by classes that refer to other
81799461Sobrien  /// variables which may not be defined at the time they expression is formed.
818130561Sobrien  /// If a value is set for the variable later, this method will be called on
81999461Sobrien  /// users of the value to allow the value to propagate out.
82099461Sobrien  ///
82199461Sobrien  virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
82299461Sobrien
82399461Sobrien  virtual std::string getAsString() const;
82499461Sobrien
82599461Sobrien  ArrayRef<Init*> getValues() const { return Values; }
826218822Sdim
827218822Sdim  inline const_iterator begin() const { return Values.begin(); }
828218822Sdim  inline const_iterator end  () const { return Values.end();   }
829218822Sdim
830218822Sdim  inline size_t         size () const { return Values.size();  }
831218822Sdim  inline bool           empty() const { return Values.empty(); }
83299461Sobrien
83399461Sobrien  /// resolveListElementReference - This method is used to implement
834130561Sobrien  /// VarListElementInit::resolveReferences.  If the list element is resolvable
835130561Sobrien  /// now, we return the resolved value, otherwise we return null.
83699461Sobrien  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
83799461Sobrien                                            unsigned Elt) const;
83899461Sobrien
83999461Sobrien  virtual Init *getBit(unsigned Bit) const {
84099461Sobrien    llvm_unreachable("Illegal bit reference off list");
84199461Sobrien  }
842130561Sobrien};
84399461Sobrien
84499461Sobrien
84599461Sobrien/// OpInit - Base class for operators
84699461Sobrien///
84799461Sobrienclass OpInit : public TypedInit {
84899461Sobrien  OpInit(const OpInit &Other) LLVM_DELETED_FUNCTION;
84999461Sobrien  OpInit &operator=(OpInit &Other) LLVM_DELETED_FUNCTION;
85099461Sobrien
851130561Sobrienprotected:
85299461Sobrien  explicit OpInit(InitKind K, RecTy *Type) : TypedInit(K, Type) {}
85399461Sobrien
854130561Sobrienpublic:
85599461Sobrien  static bool classof(const Init *I) {
85699461Sobrien    return I->getKind() >= IK_FirstOpInit &&
85799461Sobrien           I->getKind() <= IK_LastOpInit;
85899461Sobrien  }
85999461Sobrien  // Clone - Clone this operator, replacing arguments with the new list
86099461Sobrien  virtual OpInit *clone(std::vector<Init *> &Operands) const = 0;
86199461Sobrien
86299461Sobrien  virtual int getNumOperands() const = 0;
86399461Sobrien  virtual Init *getOperand(int i) const = 0;
86499461Sobrien
86599461Sobrien  // Fold - If possible, fold this to a simpler init.  Return this if not
866130561Sobrien  // possible to fold.
86799461Sobrien  virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const = 0;
86899461Sobrien
86999461Sobrien  virtual Init *convertInitializerTo(RecTy *Ty) const {
87099461Sobrien    return Ty->convertValue(const_cast<OpInit *>(this));
87199461Sobrien  }
872218822Sdim
873218822Sdim  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
87499461Sobrien                                            unsigned Elt) const;
87599461Sobrien
87699461Sobrien  virtual Init *getBit(unsigned Bit) const;
87799461Sobrien};
87899461Sobrien
87999461Sobrien
88099461Sobrien/// UnOpInit - !op (X) - Transform an init.
88199461Sobrien///
88299461Sobrienclass UnOpInit : public OpInit {
88399461Sobrienpublic:
88499461Sobrien  enum UnaryOp { CAST, HEAD, TAIL, EMPTY };
88599461Sobrienprivate:
88699461Sobrien  UnaryOp Opc;
88799461Sobrien  Init *LHS;
888218822Sdim
88999461Sobrien  UnOpInit(UnaryOp opc, Init *lhs, RecTy *Type)
89099461Sobrien    : OpInit(IK_UnOpInit, Type), Opc(opc), LHS(lhs) {}
89199461Sobrien
89299461Sobrien  UnOpInit(const UnOpInit &Other) LLVM_DELETED_FUNCTION;
89399461Sobrien  UnOpInit &operator=(const UnOpInit &Other) LLVM_DELETED_FUNCTION;
89499461Sobrien
89599461Sobrienpublic:
89699461Sobrien  static bool classof(const Init *I) {
89799461Sobrien    return I->getKind() == IK_UnOpInit;
89899461Sobrien  }
89999461Sobrien  static UnOpInit *get(UnaryOp opc, Init *lhs, RecTy *Type);
90099461Sobrien
90199461Sobrien  // Clone - Clone this operator, replacing arguments with the new list
90299461Sobrien  virtual OpInit *clone(std::vector<Init *> &Operands) const {
90399461Sobrien    assert(Operands.size() == 1 &&
90499461Sobrien           "Wrong number of operands for unary operation");
90599461Sobrien    return UnOpInit::get(getOpcode(), *Operands.begin(), getType());
90699461Sobrien  }
90799461Sobrien
90899461Sobrien  virtual int getNumOperands() const { return 1; }
90999461Sobrien  virtual Init *getOperand(int i) const {
91099461Sobrien    assert(i == 0 && "Invalid operand id for unary operator");
91199461Sobrien    return getOperand();
912130561Sobrien  }
913130561Sobrien
914130561Sobrien  UnaryOp getOpcode() const { return Opc; }
915130561Sobrien  Init *getOperand() const { return LHS; }
916130561Sobrien
917130561Sobrien  // Fold - If possible, fold this to a simpler init.  Return this if not
918130561Sobrien  // possible to fold.
919130561Sobrien  virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const;
920130561Sobrien
921218822Sdim  virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
922218822Sdim
923218822Sdim  virtual std::string getAsString() const;
924218822Sdim};
925218822Sdim
926218822Sdim/// BinOpInit - !op (X, Y) - Combine two inits.
927218822Sdim///
928218822Sdimclass BinOpInit : public OpInit {
929218822Sdimpublic:
930218822Sdim  enum BinaryOp { ADD, SHL, SRA, SRL, STRCONCAT, CONCAT, EQ };
931130561Sobrienprivate:
932218822Sdim  BinaryOp Opc;
93399461Sobrien  Init *LHS, *RHS;
93499461Sobrien
935130561Sobrien  BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) :
936130561Sobrien      OpInit(IK_BinOpInit, Type), Opc(opc), LHS(lhs), RHS(rhs) {}
937130561Sobrien
938130561Sobrien  BinOpInit(const BinOpInit &Other) LLVM_DELETED_FUNCTION;
939130561Sobrien  BinOpInit &operator=(const BinOpInit &Other) LLVM_DELETED_FUNCTION;
940130561Sobrien
941130561Sobrienpublic:
942130561Sobrien  static bool classof(const Init *I) {
943130561Sobrien    return I->getKind() == IK_BinOpInit;
944130561Sobrien  }
945130561Sobrien  static BinOpInit *get(BinaryOp opc, Init *lhs, Init *rhs,
946130561Sobrien                        RecTy *Type);
947130561Sobrien
948130561Sobrien  // Clone - Clone this operator, replacing arguments with the new list
949130561Sobrien  virtual OpInit *clone(std::vector<Init *> &Operands) const {
950130561Sobrien    assert(Operands.size() == 2 &&
951130561Sobrien           "Wrong number of operands for binary operation");
952130561Sobrien    return BinOpInit::get(getOpcode(), Operands[0], Operands[1], getType());
953130561Sobrien  }
954130561Sobrien
955130561Sobrien  virtual int getNumOperands() const { return 2; }
956130561Sobrien  virtual Init *getOperand(int i) const {
957130561Sobrien    assert((i == 0 || i == 1) && "Invalid operand id for binary operator");
958130561Sobrien    if (i == 0) {
959130561Sobrien      return getLHS();
960130561Sobrien    } else {
961130561Sobrien      return getRHS();
96299461Sobrien    }
96399461Sobrien  }
96499461Sobrien
96599461Sobrien  BinaryOp getOpcode() const { return Opc; }
966130561Sobrien  Init *getLHS() const { return LHS; }
96799461Sobrien  Init *getRHS() const { return RHS; }
96899461Sobrien
96999461Sobrien  // Fold - If possible, fold this to a simpler init.  Return this if not
97099461Sobrien  // possible to fold.
97199461Sobrien  virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const;
97299461Sobrien
97399461Sobrien  virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
97499461Sobrien
97599461Sobrien  virtual std::string getAsString() const;
97699461Sobrien};
97799461Sobrien
97899461Sobrien/// TernOpInit - !op (X, Y, Z) - Combine two inits.
979130561Sobrien///
980130561Sobrienclass TernOpInit : public OpInit {
98199461Sobrienpublic:
982130561Sobrien  enum TernaryOp { SUBST, FOREACH, IF };
983130561Sobrienprivate:
98499461Sobrien  TernaryOp Opc;
98599461Sobrien  Init *LHS, *MHS, *RHS;
98699461Sobrien
98799461Sobrien  TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs,
988130561Sobrien             RecTy *Type) :
98999461Sobrien      OpInit(IK_TernOpInit, Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {}
99099461Sobrien
99199461Sobrien  TernOpInit(const TernOpInit &Other) LLVM_DELETED_FUNCTION;
99299461Sobrien  TernOpInit &operator=(const TernOpInit &Other) LLVM_DELETED_FUNCTION;
99399461Sobrien
99499461Sobrienpublic:
995130561Sobrien  static bool classof(const Init *I) {
99699461Sobrien    return I->getKind() == IK_TernOpInit;
99799461Sobrien  }
99899461Sobrien  static TernOpInit *get(TernaryOp opc, Init *lhs,
99999461Sobrien                         Init *mhs, Init *rhs,
100099461Sobrien                         RecTy *Type);
100199461Sobrien
100299461Sobrien  // Clone - Clone this operator, replacing arguments with the new list
1003218822Sdim  virtual OpInit *clone(std::vector<Init *> &Operands) const {
1004218822Sdim    assert(Operands.size() == 3 &&
1005130561Sobrien           "Wrong number of operands for ternary operation");
100699461Sobrien    return TernOpInit::get(getOpcode(), Operands[0], Operands[1], Operands[2],
100799461Sobrien                           getType());
100899461Sobrien  }
100999461Sobrien
101099461Sobrien  virtual int getNumOperands() const { return 3; }
1011218822Sdim  virtual Init *getOperand(int i) const {
1012218822Sdim    assert((i == 0 || i == 1 || i == 2) &&
1013218822Sdim           "Invalid operand id for ternary operator");
1014218822Sdim    if (i == 0) {
1015218822Sdim      return getLHS();
1016218822Sdim    } else if (i == 1) {
101799461Sobrien      return getMHS();
1018130561Sobrien    } else {
1019130561Sobrien      return getRHS();
1020130561Sobrien    }
1021130561Sobrien  }
1022130561Sobrien
1023130561Sobrien  TernaryOp getOpcode() const { return Opc; }
102499461Sobrien  Init *getLHS() const { return LHS; }
102599461Sobrien  Init *getMHS() const { return MHS; }
1026130561Sobrien  Init *getRHS() const { return RHS; }
1027130561Sobrien
102899461Sobrien  // Fold - If possible, fold this to a simpler init.  Return this if not
102999461Sobrien  // possible to fold.
1030130561Sobrien  virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const;
1031130561Sobrien
1032130561Sobrien  virtual bool isComplete() const { return false; }
1033130561Sobrien
1034130561Sobrien  virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
1035130561Sobrien
1036130561Sobrien  virtual std::string getAsString() const;
1037130561Sobrien};
1038130561Sobrien
1039130561Sobrien
1040130561Sobrien/// VarInit - 'Opcode' - Represent a reference to an entire variable object.
1041130561Sobrien///
1042130561Sobrienclass VarInit : public TypedInit {
1043130561Sobrien  Init *VarName;
104499461Sobrien
1045130561Sobrien  explicit VarInit(const std::string &VN, RecTy *T)
104699461Sobrien      : TypedInit(IK_VarInit, T), VarName(StringInit::get(VN)) {}
1047130561Sobrien  explicit VarInit(Init *VN, RecTy *T)
1048130561Sobrien      : TypedInit(IK_VarInit, T), VarName(VN) {}
1049130561Sobrien
1050130561Sobrien  VarInit(const VarInit &Other) LLVM_DELETED_FUNCTION;
105199461Sobrien  VarInit &operator=(const VarInit &Other) LLVM_DELETED_FUNCTION;
1052130561Sobrien
1053130561Sobrienpublic:
1054130561Sobrien  static bool classof(const Init *I) {
1055130561Sobrien    return I->getKind() == IK_VarInit;
105699461Sobrien  }
1057130561Sobrien  static VarInit *get(const std::string &VN, RecTy *T);
1058130561Sobrien  static VarInit *get(Init *VN, RecTy *T);
1059130561Sobrien
106099461Sobrien  virtual Init *convertInitializerTo(RecTy *Ty) const {
106199461Sobrien    return Ty->convertValue(const_cast<VarInit *>(this));
106299461Sobrien  }
106399461Sobrien
106499461Sobrien  const std::string &getName() const;
106599461Sobrien  Init *getNameInit() const { return VarName; }
106699461Sobrien  std::string getNameInitAsString() const {
1067130561Sobrien    return getNameInit()->getAsUnquotedString();
106899461Sobrien  }
1069130561Sobrien
1070130561Sobrien  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
1071130561Sobrien                                            unsigned Elt) const;
1072130561Sobrien
1073130561Sobrien  virtual RecTy *getFieldType(const std::string &FieldName) const;
1074130561Sobrien  virtual Init *getFieldInit(Record &R, const RecordVal *RV,
1075130561Sobrien                             const std::string &FieldName) const;
1076130561Sobrien
1077130561Sobrien  /// resolveReferences - This method is used by classes that refer to other
107899461Sobrien  /// variables which may not be defined at the time they expression is formed.
107999461Sobrien  /// If a value is set for the variable later, this method will be called on
1080130561Sobrien  /// users of the value to allow the value to propagate out.
1081130561Sobrien  ///
108299461Sobrien  virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
1083130561Sobrien
1084130561Sobrien  virtual Init *getBit(unsigned Bit) const;
108599461Sobrien
1086130561Sobrien  virtual std::string getAsString() const { return getName(); }
1087130561Sobrien};
1088130561Sobrien
1089130561Sobrien
1090130561Sobrien/// VarBitInit - Opcode{0} - Represent access to one bit of a variable or field.
109199461Sobrien///
109299461Sobrienclass VarBitInit : public Init {
1093130561Sobrien  TypedInit *TI;
1094130561Sobrien  unsigned Bit;
1095130561Sobrien
1096218822Sdim  VarBitInit(TypedInit *T, unsigned B) : Init(IK_VarBitInit), TI(T), Bit(B) {
1097130561Sobrien    assert(T->getType() &&
1098130561Sobrien           (isa<IntRecTy>(T->getType()) ||
1099130561Sobrien            (isa<BitsRecTy>(T->getType()) &&
110099461Sobrien             cast<BitsRecTy>(T->getType())->getNumBits() > B)) &&
1101130561Sobrien           "Illegal VarBitInit expression!");
1102130561Sobrien  }
1103130561Sobrien
1104130561Sobrien  VarBitInit(const VarBitInit &Other) LLVM_DELETED_FUNCTION;
1105130561Sobrien  VarBitInit &operator=(const VarBitInit &Other) LLVM_DELETED_FUNCTION;
1106130561Sobrien
1107130561Sobrienpublic:
1108130561Sobrien  static bool classof(const Init *I) {
1109130561Sobrien    return I->getKind() == IK_VarBitInit;
1110130561Sobrien  }
1111130561Sobrien  static VarBitInit *get(TypedInit *T, unsigned B);
1112130561Sobrien
1113130561Sobrien  virtual Init *convertInitializerTo(RecTy *Ty) const {
1114130561Sobrien    return Ty->convertValue(const_cast<VarBitInit *>(this));
1115130561Sobrien  }
1116130561Sobrien
1117218822Sdim  virtual Init *getBitVar() const { return TI; }
1118130561Sobrien  virtual unsigned getBitNum() const { return Bit; }
1119130561Sobrien
1120130561Sobrien  virtual std::string getAsString() const;
1121130561Sobrien  virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
112299461Sobrien
112399461Sobrien  virtual Init *getBit(unsigned B) const {
1124130561Sobrien    assert(B < 1 && "Bit index out of range!");
1125130561Sobrien    return const_cast<VarBitInit*>(this);
1126130561Sobrien  }
1127130561Sobrien};
1128130561Sobrien
1129130561Sobrien/// VarListElementInit - List[4] - Represent access to one element of a var or
1130130561Sobrien/// field.
1131130561Sobrienclass VarListElementInit : public TypedInit {
1132130561Sobrien  TypedInit *TI;
1133130561Sobrien  unsigned Element;
1134130561Sobrien
1135130561Sobrien  VarListElementInit(TypedInit *T, unsigned E)
1136130561Sobrien      : TypedInit(IK_VarListElementInit,
1137130561Sobrien                  cast<ListRecTy>(T->getType())->getElementType()),
1138130561Sobrien        TI(T), Element(E) {
1139130561Sobrien    assert(T->getType() && isa<ListRecTy>(T->getType()) &&
1140130561Sobrien           "Illegal VarBitInit expression!");
1141130561Sobrien  }
1142130561Sobrien
1143130561Sobrien  VarListElementInit(const VarListElementInit &Other) LLVM_DELETED_FUNCTION;
1144130561Sobrien  void operator=(const VarListElementInit &Other) LLVM_DELETED_FUNCTION;
1145130561Sobrien
1146130561Sobrienpublic:
1147130561Sobrien  static bool classof(const Init *I) {
1148130561Sobrien    return I->getKind() == IK_VarListElementInit;
1149130561Sobrien  }
1150130561Sobrien  static VarListElementInit *get(TypedInit *T, unsigned E);
1151130561Sobrien
1152130561Sobrien  virtual Init *convertInitializerTo(RecTy *Ty) const {
1153130561Sobrien    return Ty->convertValue(const_cast<VarListElementInit *>(this));
1154130561Sobrien  }
1155130561Sobrien
1156130561Sobrien  TypedInit *getVariable() const { return TI; }
1157130561Sobrien  unsigned getElementNum() const { return Element; }
1158130561Sobrien
1159130561Sobrien  /// resolveListElementReference - This method is used to implement
1160130561Sobrien  /// VarListElementInit::resolveReferences.  If the list element is resolvable
1161130561Sobrien  /// now, we return the resolved value, otherwise we return null.
1162130561Sobrien  virtual Init *resolveListElementReference(Record &R,
1163130561Sobrien                                            const RecordVal *RV,
1164130561Sobrien                                            unsigned Elt) const;
1165130561Sobrien
1166130561Sobrien  virtual std::string getAsString() const;
1167130561Sobrien  virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
1168130561Sobrien
1169130561Sobrien  virtual Init *getBit(unsigned Bit) const;
1170130561Sobrien};
1171130561Sobrien
1172130561Sobrien/// DefInit - AL - Represent a reference to a 'def' in the description
1173130561Sobrien///
1174130561Sobrienclass DefInit : public TypedInit {
1175130561Sobrien  Record *Def;
1176130561Sobrien
1177130561Sobrien  DefInit(Record *D, RecordRecTy *T) : TypedInit(IK_DefInit, T), Def(D) {}
1178130561Sobrien  friend class Record;
1179130561Sobrien
1180130561Sobrien  DefInit(const DefInit &Other) LLVM_DELETED_FUNCTION;
1181130561Sobrien  DefInit &operator=(const DefInit &Other) LLVM_DELETED_FUNCTION;
1182130561Sobrien
1183130561Sobrienpublic:
1184130561Sobrien  static bool classof(const Init *I) {
1185218822Sdim    return I->getKind() == IK_DefInit;
1186218822Sdim  }
1187130561Sobrien  static DefInit *get(Record*);
1188130561Sobrien
1189130561Sobrien  virtual Init *convertInitializerTo(RecTy *Ty) const {
1190130561Sobrien    return Ty->convertValue(const_cast<DefInit *>(this));
1191130561Sobrien  }
1192130561Sobrien
1193130561Sobrien  Record *getDef() const { return Def; }
1194130561Sobrien
1195130561Sobrien  //virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
1196130561Sobrien
1197130561Sobrien  virtual RecTy *getFieldType(const std::string &FieldName) const;
1198130561Sobrien  virtual Init *getFieldInit(Record &R, const RecordVal *RV,
1199130561Sobrien                             const std::string &FieldName) const;
1200130561Sobrien
1201130561Sobrien  virtual std::string getAsString() const;
1202130561Sobrien
1203130561Sobrien  virtual Init *getBit(unsigned Bit) const {
1204130561Sobrien    llvm_unreachable("Illegal bit reference off def");
1205130561Sobrien  }
1206130561Sobrien
1207130561Sobrien  /// resolveListElementReference - This method is used to implement
1208130561Sobrien  /// VarListElementInit::resolveReferences.  If the list element is resolvable
1209130561Sobrien  /// now, we return the resolved value, otherwise we return null.
1210130561Sobrien  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
1211130561Sobrien                                            unsigned Elt) const {
1212130561Sobrien    llvm_unreachable("Illegal element reference off def");
121399461Sobrien  }
1214130561Sobrien};
1215130561Sobrien
121699461Sobrien
121799461Sobrien/// FieldInit - X.Y - Represent a reference to a subfield of a variable
121899461Sobrien///
121999461Sobrienclass FieldInit : public TypedInit {
122099461Sobrien  Init *Rec;                // Record we are referring to
122199461Sobrien  std::string FieldName;    // Field we are accessing
122299461Sobrien
122399461Sobrien  FieldInit(Init *R, const std::string &FN)
122499461Sobrien      : TypedInit(IK_FieldInit, R->getFieldType(FN)), Rec(R), FieldName(FN) {
122599461Sobrien    assert(getType() && "FieldInit with non-record type!");
1226218822Sdim  }
122799461Sobrien
122899461Sobrien  FieldInit(const FieldInit &Other) LLVM_DELETED_FUNCTION;
122999461Sobrien  FieldInit &operator=(const FieldInit &Other) LLVM_DELETED_FUNCTION;
123099461Sobrien
123199461Sobrienpublic:
123299461Sobrien  static bool classof(const Init *I) {
123399461Sobrien    return I->getKind() == IK_FieldInit;
123499461Sobrien  }
123599461Sobrien  static FieldInit *get(Init *R, const std::string &FN);
123699461Sobrien  static FieldInit *get(Init *R, const Init *FN);
123799461Sobrien
123899461Sobrien  virtual Init *convertInitializerTo(RecTy *Ty) const {
123999461Sobrien    return Ty->convertValue(const_cast<FieldInit *>(this));
124099461Sobrien  }
124199461Sobrien
124299461Sobrien  virtual Init *getBit(unsigned Bit) const;
124399461Sobrien
124499461Sobrien  virtual Init *resolveListElementReference(Record &R,
124599461Sobrien                                            const RecordVal *RV,
124699461Sobrien                                            unsigned Elt) const;
124799461Sobrien
124899461Sobrien  virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
124999461Sobrien
125099461Sobrien  virtual std::string getAsString() const {
125199461Sobrien    return Rec->getAsString() + "." + FieldName;
125299461Sobrien  }
125399461Sobrien};
125499461Sobrien
125599461Sobrien/// DagInit - (v a, b) - Represent a DAG tree value.  DAG inits are required
125699461Sobrien/// to have at least one value then a (possibly empty) list of arguments.  Each
125799461Sobrien/// argument can have a name associated with it.
125899461Sobrien///
125999461Sobrienclass DagInit : public TypedInit, public FoldingSetNode {
126099461Sobrien  Init *Val;
126199461Sobrien  std::string ValName;
126299461Sobrien  std::vector<Init*> Args;
1263218822Sdim  std::vector<std::string> ArgNames;
1264130561Sobrien
1265130561Sobrien  DagInit(Init *V, const std::string &VN,
126699461Sobrien          ArrayRef<Init *> ArgRange,
126799461Sobrien          ArrayRef<std::string> NameRange)
126899461Sobrien      : TypedInit(IK_DagInit, DagRecTy::get()), Val(V), ValName(VN),
1269218822Sdim          Args(ArgRange.begin(), ArgRange.end()),
127099461Sobrien          ArgNames(NameRange.begin(), NameRange.end()) {}
127199461Sobrien
127299461Sobrien  DagInit(const DagInit &Other) LLVM_DELETED_FUNCTION;
127399461Sobrien  DagInit &operator=(const DagInit &Other) LLVM_DELETED_FUNCTION;
127499461Sobrien
127599461Sobrienpublic:
127699461Sobrien  static bool classof(const Init *I) {
127799461Sobrien    return I->getKind() == IK_DagInit;
127899461Sobrien  }
127999461Sobrien  static DagInit *get(Init *V, const std::string &VN,
128099461Sobrien                      ArrayRef<Init *> ArgRange,
128199461Sobrien                      ArrayRef<std::string> NameRange);
128299461Sobrien  static DagInit *get(Init *V, const std::string &VN,
128399461Sobrien                      const std::vector<
128499461Sobrien                        std::pair<Init*, std::string> > &args);
128599461Sobrien
128699461Sobrien  void Profile(FoldingSetNodeID &ID) const;
1287130561Sobrien
128899461Sobrien  virtual Init *convertInitializerTo(RecTy *Ty) const {
1289218822Sdim    return Ty->convertValue(const_cast<DagInit *>(this));
129099461Sobrien  }
129199461Sobrien
129299461Sobrien  Init *getOperator() const { return Val; }
129399461Sobrien
1294218822Sdim  const std::string &getName() const { return ValName; }
1295218822Sdim
129699461Sobrien  unsigned getNumArgs() const { return Args.size(); }
129799461Sobrien  Init *getArg(unsigned Num) const {
129899461Sobrien    assert(Num < Args.size() && "Arg number out of range!");
129999461Sobrien    return Args[Num];
130099461Sobrien  }
130199461Sobrien  const std::string &getArgName(unsigned Num) const {
130299461Sobrien    assert(Num < ArgNames.size() && "Arg number out of range!");
130399461Sobrien    return ArgNames[Num];
130499461Sobrien  }
130599461Sobrien
130699461Sobrien  virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
130799461Sobrien
130899461Sobrien  virtual std::string getAsString() const;
130999461Sobrien
131099461Sobrien  typedef std::vector<Init*>::const_iterator       const_arg_iterator;
1311218822Sdim  typedef std::vector<std::string>::const_iterator const_name_iterator;
1312218822Sdim
1313218822Sdim  inline const_arg_iterator  arg_begin() const { return Args.begin(); }
131499461Sobrien  inline const_arg_iterator  arg_end  () const { return Args.end();   }
131599461Sobrien
1316130561Sobrien  inline size_t              arg_size () const { return Args.size();  }
131799461Sobrien  inline bool                arg_empty() const { return Args.empty(); }
131899461Sobrien
131999461Sobrien  inline const_name_iterator name_begin() const { return ArgNames.begin(); }
132099461Sobrien  inline const_name_iterator name_end  () const { return ArgNames.end();   }
132199461Sobrien
132299461Sobrien  inline size_t              name_size () const { return ArgNames.size();  }
132399461Sobrien  inline bool                name_empty() const { return ArgNames.empty(); }
132499461Sobrien
132599461Sobrien  virtual Init *getBit(unsigned Bit) const {
132699461Sobrien    llvm_unreachable("Illegal bit reference off dag");
132799461Sobrien  }
132899461Sobrien
132999461Sobrien  virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
133099461Sobrien                                            unsigned Elt) const {
133199461Sobrien    llvm_unreachable("Illegal element reference off dag");
1332130561Sobrien  }
1333218822Sdim};
133499461Sobrien
133599461Sobrien//===----------------------------------------------------------------------===//
133699461Sobrien//  High-Level Classes
133799461Sobrien//===----------------------------------------------------------------------===//
1338130561Sobrien
133999461Sobrienclass RecordVal {
1340218822Sdim  Init *Name;
1341218822Sdim  RecTy *Ty;
134299461Sobrien  unsigned Prefix;
134399461Sobrien  Init *Value;
134499461Sobrienpublic:
134599461Sobrien  RecordVal(Init *N, RecTy *T, unsigned P);
134699461Sobrien  RecordVal(const std::string &N, RecTy *T, unsigned P);
134799461Sobrien
1348130561Sobrien  const std::string &getName() const;
134999461Sobrien  const Init *getNameInit() const { return Name; }
135099461Sobrien  std::string getNameInitAsString() const {
135199461Sobrien    return getNameInit()->getAsUnquotedString();
1352130561Sobrien  }
135399461Sobrien
135499461Sobrien  unsigned getPrefix() const { return Prefix; }
135599461Sobrien  RecTy *getType() const { return Ty; }
135699461Sobrien  Init *getValue() const { return Value; }
135799461Sobrien
135899461Sobrien  bool setValue(Init *V) {
135999461Sobrien    if (V) {
136099461Sobrien      Value = V->convertInitializerTo(Ty);
136199461Sobrien      return Value == 0;
136299461Sobrien    }
136399461Sobrien    Value = 0;
136499461Sobrien    return false;
136599461Sobrien  }
136699461Sobrien
136799461Sobrien  void dump() const;
136899461Sobrien  void print(raw_ostream &OS, bool PrintSem = true) const;
136999461Sobrien};
137099461Sobrien
1371130561Sobrieninline raw_ostream &operator<<(raw_ostream &OS, const RecordVal &RV) {
1372130561Sobrien  RV.print(OS << "  ");
1373130561Sobrien  return OS;
1374130561Sobrien}
137599461Sobrien
137699461Sobrienclass Record {
137799461Sobrien  static unsigned LastID;
1378130561Sobrien
1379130561Sobrien  // Unique record ID.
1380130561Sobrien  unsigned ID;
1381130561Sobrien  Init *Name;
138299461Sobrien  // Location where record was instantiated, followed by the location of
138399461Sobrien  // multiclass prototypes used.
138499461Sobrien  SmallVector<SMLoc, 4> Locs;
138599461Sobrien  std::vector<Init *> TemplateArgs;
138699461Sobrien  std::vector<RecordVal> Values;
138799461Sobrien  std::vector<Record *> SuperClasses;
1388130561Sobrien  std::vector<SMRange> SuperClassRanges;
138999461Sobrien
139099461Sobrien  // Tracks Record instances. Not owned by Record.
139199461Sobrien  RecordKeeper &TrackedRecords;
139299461Sobrien
139399461Sobrien  DefInit *TheInit;
139499461Sobrien  bool IsAnonymous;
1395218822Sdim
1396218822Sdim  void init();
1397218822Sdim  void checkName();
1398218822Sdim
1399218822Sdimpublic:
140099461Sobrien
140199461Sobrien  // Constructs a record.
1402218822Sdim  explicit Record(const std::string &N, ArrayRef<SMLoc> locs,
1403218822Sdim                  RecordKeeper &records, bool Anonymous = false) :
1404218822Sdim    ID(LastID++), Name(StringInit::get(N)), Locs(locs.begin(), locs.end()),
1405218822Sdim    TrackedRecords(records), TheInit(0), IsAnonymous(Anonymous) {
1406218822Sdim    init();
1407218822Sdim  }
1408218822Sdim  explicit Record(Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records,
140999461Sobrien                  bool Anonymous = false) :
141099461Sobrien    ID(LastID++), Name(N), Locs(locs.begin(), locs.end()),
141199461Sobrien    TrackedRecords(records), TheInit(0), IsAnonymous(Anonymous) {
141299461Sobrien    init();
141399461Sobrien  }
1414130561Sobrien
1415218822Sdim  // When copy-constructing a Record, we must still guarantee a globally unique
1416218822Sdim  // ID number.  All other fields can be copied normally.
1417218822Sdim  Record(const Record &O) :
1418218822Sdim    ID(LastID++), Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs),
141999461Sobrien    Values(O.Values), SuperClasses(O.SuperClasses),
142099461Sobrien    SuperClassRanges(O.SuperClassRanges), TrackedRecords(O.TrackedRecords),
142199461Sobrien    TheInit(O.TheInit), IsAnonymous(O.IsAnonymous) { }
142299461Sobrien
142399461Sobrien  ~Record() {}
142499461Sobrien
142599461Sobrien
142699461Sobrien  static unsigned getNewUID() { return LastID++; }
142799461Sobrien
142899461Sobrien
142999461Sobrien  unsigned getID() const { return ID; }
143099461Sobrien
143199461Sobrien  const std::string &getName() const;
143299461Sobrien  Init *getNameInit() const {
1433130561Sobrien    return Name;
1434130561Sobrien  }
1435130561Sobrien  const std::string getNameInitAsString() const {
1436130561Sobrien    return getNameInit()->getAsUnquotedString();
143799461Sobrien  }
1438130561Sobrien
1439130561Sobrien  void setName(Init *Name);               // Also updates RecordKeeper.
1440130561Sobrien  void setName(const std::string &Name);  // Also updates RecordKeeper.
1441130561Sobrien
1442130561Sobrien  ArrayRef<SMLoc> getLoc() const { return Locs; }
1443130561Sobrien
144499461Sobrien  /// get the corresponding DefInit.
1445130561Sobrien  DefInit *getDefInit();
1446218822Sdim
1447218822Sdim  const std::vector<Init *> &getTemplateArgs() const {
1448218822Sdim    return TemplateArgs;
1449130561Sobrien  }
145099461Sobrien  const std::vector<RecordVal> &getValues() const { return Values; }
1451130561Sobrien  const std::vector<Record*>   &getSuperClasses() const { return SuperClasses; }
1452130561Sobrien  ArrayRef<SMRange> getSuperClassRanges() const { return SuperClassRanges; }
1453130561Sobrien
1454130561Sobrien  bool isTemplateArg(Init *Name) const {
1455130561Sobrien    for (unsigned i = 0, e = TemplateArgs.size(); i != e; ++i)
1456130561Sobrien      if (TemplateArgs[i] == Name) return true;
1457130561Sobrien    return false;
1458130561Sobrien  }
145999461Sobrien  bool isTemplateArg(StringRef Name) const {
1460130561Sobrien    return isTemplateArg(StringInit::get(Name.str()));
1461130561Sobrien  }
1462130561Sobrien
1463130561Sobrien  const RecordVal *getValue(const Init *Name) const {
1464130561Sobrien    for (unsigned i = 0, e = Values.size(); i != e; ++i)
1465130561Sobrien      if (Values[i].getNameInit() == Name) return &Values[i];
1466130561Sobrien    return 0;
1467130561Sobrien  }
146899461Sobrien  const RecordVal *getValue(StringRef Name) const {
1469130561Sobrien    return getValue(StringInit::get(Name));
1470130561Sobrien  }
1471130561Sobrien  RecordVal *getValue(const Init *Name) {
1472130561Sobrien    for (unsigned i = 0, e = Values.size(); i != e; ++i)
1473130561Sobrien      if (Values[i].getNameInit() == Name) return &Values[i];
1474130561Sobrien    return 0;
1475130561Sobrien  }
1476130561Sobrien  RecordVal *getValue(StringRef Name) {
1477130561Sobrien    return getValue(StringInit::get(Name));
1478130561Sobrien  }
1479130561Sobrien
1480130561Sobrien  void addTemplateArg(Init *Name) {
1481130561Sobrien    assert(!isTemplateArg(Name) && "Template arg already defined!");
1482130561Sobrien    TemplateArgs.push_back(Name);
1483130561Sobrien  }
1484130561Sobrien  void addTemplateArg(StringRef Name) {
1485130561Sobrien    addTemplateArg(StringInit::get(Name.str()));
1486130561Sobrien  }
1487130561Sobrien
1488130561Sobrien  void addValue(const RecordVal &RV) {
1489130561Sobrien    assert(getValue(RV.getNameInit()) == 0 && "Value already added!");
1490130561Sobrien    Values.push_back(RV);
1491130561Sobrien    if (Values.size() > 1)
1492130561Sobrien      // Keep NAME at the end of the list.  It makes record dumps a
1493130561Sobrien      // bit prettier and allows TableGen tests to be written more
1494130561Sobrien      // naturally.  Tests can use CHECK-NEXT to look for Record
1495130561Sobrien      // fields they expect to see after a def.  They can't do that if
1496130561Sobrien      // NAME is the first Record field.
1497130561Sobrien      std::swap(Values[Values.size() - 2], Values[Values.size() - 1]);
1498130561Sobrien  }
1499130561Sobrien
1500130561Sobrien  void removeValue(Init *Name) {
1501130561Sobrien    for (unsigned i = 0, e = Values.size(); i != e; ++i)
1502130561Sobrien      if (Values[i].getNameInit() == Name) {
1503130561Sobrien        Values.erase(Values.begin()+i);
1504130561Sobrien        return;
1505130561Sobrien      }
1506130561Sobrien    llvm_unreachable("Cannot remove an entry that does not exist!");
1507130561Sobrien  }
1508130561Sobrien
1509130561Sobrien  void removeValue(StringRef Name) {
1510130561Sobrien    removeValue(StringInit::get(Name.str()));
1511130561Sobrien  }
1512130561Sobrien
1513130561Sobrien  bool isSubClassOf(const Record *R) const {
1514130561Sobrien    for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
1515130561Sobrien      if (SuperClasses[i] == R)
1516130561Sobrien        return true;
1517130561Sobrien    return false;
1518130561Sobrien  }
1519130561Sobrien
1520130561Sobrien  bool isSubClassOf(StringRef Name) const {
1521130561Sobrien    for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
1522130561Sobrien      if (SuperClasses[i]->getNameInitAsString() == Name)
1523130561Sobrien        return true;
1524130561Sobrien    return false;
1525130561Sobrien  }
1526130561Sobrien
1527130561Sobrien  void addSuperClass(Record *R, SMRange Range) {
1528130561Sobrien    assert(!isSubClassOf(R) && "Already subclassing record!");
152999461Sobrien    SuperClasses.push_back(R);
1530130561Sobrien    SuperClassRanges.push_back(Range);
1531130561Sobrien  }
153299461Sobrien
1533130561Sobrien  /// resolveReferences - If there are any field references that refer to fields
1534130561Sobrien  /// that have been filled in, we can propagate the values now.
1535130561Sobrien  ///
1536130561Sobrien  void resolveReferences() { resolveReferencesTo(0); }
1537130561Sobrien
1538130561Sobrien  /// resolveReferencesTo - If anything in this record refers to RV, replace the
1539130561Sobrien  /// reference to RV with the RHS of RV.  If RV is null, we resolve all
154099461Sobrien  /// possible references.
1541130561Sobrien  void resolveReferencesTo(const RecordVal *RV);
1542130561Sobrien
1543130561Sobrien  RecordKeeper &getRecords() const {
1544130561Sobrien    return TrackedRecords;
154599461Sobrien  }
1546130561Sobrien
1547130561Sobrien  bool isAnonymous() const {
154899461Sobrien    return IsAnonymous;
1549130561Sobrien  }
1550130561Sobrien
1551130561Sobrien  void dump() const;
1552130561Sobrien
1553130561Sobrien  //===--------------------------------------------------------------------===//
1554130561Sobrien  // High-level methods useful to tablegen back-ends
1555130561Sobrien  //
1556130561Sobrien
1557130561Sobrien  /// getValueInit - Return the initializer for a value with the specified name,
1558130561Sobrien  /// or throw an exception if the field does not exist.
1559130561Sobrien  ///
1560130561Sobrien  Init *getValueInit(StringRef FieldName) const;
1561130561Sobrien
1562130561Sobrien  /// Return true if the named field is unset.
1563130561Sobrien  bool isValueUnset(StringRef FieldName) const {
1564130561Sobrien    return getValueInit(FieldName) == UnsetInit::get();
1565130561Sobrien  }
1566130561Sobrien
1567130561Sobrien  /// getValueAsString - This method looks up the specified field and returns
1568130561Sobrien  /// its value as a string, throwing an exception if the field does not exist
1569130561Sobrien  /// or if the value is not a string.
157099461Sobrien  ///
157199461Sobrien  std::string getValueAsString(StringRef FieldName) const;
157299461Sobrien
157399461Sobrien  /// getValueAsBitsInit - This method looks up the specified field and returns
157499461Sobrien  /// its value as a BitsInit, throwing an exception if the field does not exist
157599461Sobrien  /// or if the value is not the right type.
157699461Sobrien  ///
157799461Sobrien  BitsInit *getValueAsBitsInit(StringRef FieldName) const;
1578130561Sobrien
157999461Sobrien  /// getValueAsListInit - This method looks up the specified field and returns
158099461Sobrien  /// its value as a ListInit, throwing an exception if the field does not exist
158199461Sobrien  /// or if the value is not the right type.
158299461Sobrien  ///
158399461Sobrien  ListInit *getValueAsListInit(StringRef FieldName) const;
158499461Sobrien
158599461Sobrien  /// getValueAsListOfDefs - This method looks up the specified field and
158699461Sobrien  /// returns its value as a vector of records, throwing an exception if the
158799461Sobrien  /// field does not exist or if the value is not the right type.
1588107492Sobrien  ///
158999461Sobrien  std::vector<Record*> getValueAsListOfDefs(StringRef FieldName) const;
1590218822Sdim
159199461Sobrien  /// getValueAsListOfInts - This method looks up the specified field and
159299461Sobrien  /// returns its value as a vector of integers, throwing an exception if the
159399461Sobrien  /// field does not exist or if the value is not the right type.
1594218822Sdim  ///
1595218822Sdim  std::vector<int64_t> getValueAsListOfInts(StringRef FieldName) const;
159699461Sobrien
159799461Sobrien  /// getValueAsListOfStrings - This method looks up the specified field and
159899461Sobrien  /// returns its value as a vector of strings, throwing an exception if the
159999461Sobrien  /// field does not exist or if the value is not the right type.
1600130561Sobrien  ///
1601130561Sobrien  std::vector<std::string> getValueAsListOfStrings(StringRef FieldName) const;
160299461Sobrien
160399461Sobrien  /// getValueAsDef - This method looks up the specified field and returns its
160499461Sobrien  /// value as a Record, throwing an exception if the field does not exist or if
1605218822Sdim  /// the value is not the right type.
1606130561Sobrien  ///
160799461Sobrien  Record *getValueAsDef(StringRef FieldName) const;
160899461Sobrien
1609130561Sobrien  /// getValueAsBit - This method looks up the specified field and returns its
161099461Sobrien  /// value as a bit, throwing an exception if the field does not exist or if
161199461Sobrien  /// the value is not the right type.
161299461Sobrien  ///
161399461Sobrien  bool getValueAsBit(StringRef FieldName) const;
161499461Sobrien
161599461Sobrien  /// getValueAsBitOrUnset - This method looks up the specified field and
161699461Sobrien  /// returns its value as a bit. If the field is unset, sets Unset to true and
161799461Sobrien  /// retunrs false.
161899461Sobrien  ///
161999461Sobrien  bool getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const;
162099461Sobrien
162199461Sobrien  /// getValueAsInt - This method looks up the specified field and returns its
1622218822Sdim  /// value as an int64_t, throwing an exception if the field does not exist or
162399461Sobrien  /// if the value is not the right type.
1624218822Sdim  ///
1625218822Sdim  int64_t getValueAsInt(StringRef FieldName) const;
1626218822Sdim
1627218822Sdim  /// getValueAsDag - This method looks up the specified field and returns its
1628130561Sobrien  /// value as an Dag, throwing an exception if the field does not exist or if
1629218822Sdim  /// the value is not the right type.
1630130561Sobrien  ///
163199461Sobrien  DagInit *getValueAsDag(StringRef FieldName) const;
163299461Sobrien};
163399461Sobrien
163499461Sobrienraw_ostream &operator<<(raw_ostream &OS, const Record &R);
163599461Sobrien
163699461Sobrienstruct MultiClass {
163799461Sobrien  Record Rec;  // Placeholder for template args and Name.
163899461Sobrien  typedef std::vector<Record*> RecordVector;
163999461Sobrien  RecordVector DefPrototypes;
164099461Sobrien
1641130561Sobrien  void dump() const;
164299461Sobrien
164399461Sobrien  MultiClass(const std::string &Name, SMLoc Loc, RecordKeeper &Records) :
164499461Sobrien    Rec(Name, Loc, Records) {}
1645218822Sdim};
1646130561Sobrien
164799461Sobrienclass RecordKeeper {
164899461Sobrien  std::map<std::string, Record*> Classes, Defs;
164999461Sobrien
165099461Sobrienpublic:
1651218822Sdim  ~RecordKeeper() {
1652130561Sobrien    for (std::map<std::string, Record*>::iterator I = Classes.begin(),
165399461Sobrien           E = Classes.end(); I != E; ++I)
165499461Sobrien      delete I->second;
1655130561Sobrien    for (std::map<std::string, Record*>::iterator I = Defs.begin(),
165699461Sobrien           E = Defs.end(); I != E; ++I)
1657130561Sobrien      delete I->second;
1658130561Sobrien  }
165999461Sobrien
1660130561Sobrien  const std::map<std::string, Record*> &getClasses() const { return Classes; }
1661130561Sobrien  const std::map<std::string, Record*> &getDefs() const { return Defs; }
1662130561Sobrien
1663130561Sobrien  Record *getClass(const std::string &Name) const {
1664130561Sobrien    std::map<std::string, Record*>::const_iterator I = Classes.find(Name);
1665130561Sobrien    return I == Classes.end() ? 0 : I->second;
1666130561Sobrien  }
1667130561Sobrien  Record *getDef(const std::string &Name) const {
1668130561Sobrien    std::map<std::string, Record*>::const_iterator I = Defs.find(Name);
1669130561Sobrien    return I == Defs.end() ? 0 : I->second;
1670130561Sobrien  }
1671130561Sobrien  void addClass(Record *R) {
1672218822Sdim    bool Ins = Classes.insert(std::make_pair(R->getName(), R)).second;
1673130561Sobrien    (void)Ins;
1674130561Sobrien    assert(Ins && "Class already exists");
167599461Sobrien  }
167699461Sobrien  void addDef(Record *R) {
1677218822Sdim    bool Ins = Defs.insert(std::make_pair(R->getName(), R)).second;
1678218822Sdim    (void)Ins;
1679218822Sdim    assert(Ins && "Record already exists");
1680218822Sdim  }
1681218822Sdim
1682218822Sdim  /// removeClass - Remove, but do not delete, the specified record.
1683218822Sdim  ///
168499461Sobrien  void removeClass(const std::string &Name) {
168599461Sobrien    assert(Classes.count(Name) && "Class does not exist!");
168699461Sobrien    Classes.erase(Name);
168799461Sobrien  }
168899461Sobrien  /// removeDef - Remove, but do not delete, the specified record.
168999461Sobrien  ///
169099461Sobrien  void removeDef(const std::string &Name) {
169199461Sobrien    assert(Defs.count(Name) && "Def does not exist!");
169299461Sobrien    Defs.erase(Name);
169399461Sobrien  }
169499461Sobrien
169599461Sobrien  //===--------------------------------------------------------------------===//
169699461Sobrien  // High-level helper methods, useful for tablegen backends...
169799461Sobrien
169899461Sobrien  /// getAllDerivedDefinitions - This method returns all concrete definitions
169999461Sobrien  /// that derive from the specified class name.  If a class with the specified
170099461Sobrien  /// name does not exist, an exception is thrown.
1701218822Sdim  std::vector<Record*>
1702218822Sdim  getAllDerivedDefinitions(const std::string &ClassName) const;
170399461Sobrien
170499461Sobrien  void dump() const;
170599461Sobrien};
170699461Sobrien
1707218822Sdim/// LessRecord - Sorting predicate to sort record pointers by name.
170899461Sobrien///
170999461Sobrienstruct LessRecord {
171099461Sobrien  bool operator()(const Record *Rec1, const Record *Rec2) const {
171199461Sobrien    return StringRef(Rec1->getName()).compare_numeric(Rec2->getName()) < 0;
171299461Sobrien  }
1713130561Sobrien};
171499461Sobrien
171599461Sobrien/// LessRecordByID - Sorting predicate to sort record pointers by their
171699461Sobrien/// unique ID. If you just need a deterministic order, use this, since it
171799461Sobrien/// just compares two `unsigned`; the other sorting predicates require
171899461Sobrien/// string manipulation.
171999461Sobrienstruct LessRecordByID {
172099461Sobrien  bool operator()(const Record *LHS, const Record *RHS) const {
172199461Sobrien    return LHS->getID() < RHS->getID();
172299461Sobrien  }
172399461Sobrien};
1724130561Sobrien
172599461Sobrien/// LessRecordFieldName - Sorting predicate to sort record pointers by their
172699461Sobrien/// name field.
1727130561Sobrien///
1728130561Sobrienstruct LessRecordFieldName {
1729130561Sobrien  bool operator()(const Record *Rec1, const Record *Rec2) const {
173099461Sobrien    return Rec1->getValueAsString("Name") < Rec2->getValueAsString("Name");
173199461Sobrien  }
173299461Sobrien};
173399461Sobrien
173499461Sobrienstruct LessRecordRegister {
173599461Sobrien  static size_t min(size_t a, size_t b) { return a < b ? a : b; }
1736130561Sobrien  static bool ascii_isdigit(char x) { return x >= '0' && x <= '9'; }
1737130561Sobrien
1738130561Sobrien  struct RecordParts {
173999461Sobrien    SmallVector<std::pair< bool, StringRef>, 4> Parts;
174099461Sobrien
174199461Sobrien    RecordParts(StringRef Rec) {
174299461Sobrien      if (Rec.empty())
1743218822Sdim        return;
174499461Sobrien
1745130561Sobrien      size_t Len = 0;
1746130561Sobrien      const char *Start = Rec.data();
174799461Sobrien      const char *Curr = Start;
174899461Sobrien      bool isDigitPart = ascii_isdigit(Curr[0]);
1749130561Sobrien      for (size_t I = 0, E = Rec.size(); I != E; ++I, ++Len) {
1750130561Sobrien        bool isDigit = ascii_isdigit(Curr[I]);
175199461Sobrien        if (isDigit != isDigitPart) {
175299461Sobrien          Parts.push_back(std::make_pair(isDigitPart, StringRef(Start, Len)));
175399461Sobrien          Len = 0;
175499461Sobrien          Start = &Curr[I];
175599461Sobrien          isDigitPart = ascii_isdigit(Curr[I]);
1756218822Sdim        }
1757218822Sdim      }
175899461Sobrien      // Push the last part.
1759218822Sdim      Parts.push_back(std::make_pair(isDigitPart, StringRef(Start, Len)));
176099461Sobrien    }
176199461Sobrien
176299461Sobrien    size_t size() { return Parts.size(); }
176399461Sobrien
176499461Sobrien    std::pair<bool, StringRef> getPart(size_t i) {
176599461Sobrien      assert (i < Parts.size() && "Invalid idx!");
176699461Sobrien      return Parts[i];
1767218822Sdim    }
176899461Sobrien  };
176999461Sobrien
177099461Sobrien  bool operator()(const Record *Rec1, const Record *Rec2) const {
177199461Sobrien    RecordParts LHSParts(StringRef(Rec1->getName()));
177299461Sobrien    RecordParts RHSParts(StringRef(Rec2->getName()));
177399461Sobrien
1774218822Sdim    size_t LHSNumParts = LHSParts.size();
177599461Sobrien    size_t RHSNumParts = RHSParts.size();
177699461Sobrien    assert (LHSNumParts && RHSNumParts && "Expected at least one part!");
177799461Sobrien
1778218822Sdim    if (LHSNumParts != RHSNumParts)
177999461Sobrien      return LHSNumParts < RHSNumParts;
178099461Sobrien
1781218822Sdim    // We expect the registers to be of the form [_a-zA-z]+([0-9]*[_a-zA-Z]*)*.
178299461Sobrien    for (size_t I = 0, E = LHSNumParts; I < E; I+=2) {
178399461Sobrien      std::pair<bool, StringRef> LHSPart = LHSParts.getPart(I);
178499461Sobrien      std::pair<bool, StringRef> RHSPart = RHSParts.getPart(I);
178599461Sobrien      // Expect even part to always be alpha.
1786218822Sdim      assert (LHSPart.first == false && RHSPart.first == false &&
1787130561Sobrien              "Expected both parts to be alpha.");
178899461Sobrien      if (int Res = LHSPart.second.compare(RHSPart.second))
178999461Sobrien        return Res < 0;
179099461Sobrien    }
179199461Sobrien    for (size_t I = 1, E = LHSNumParts; I < E; I+=2) {
179299461Sobrien      std::pair<bool, StringRef> LHSPart = LHSParts.getPart(I);
1793218822Sdim      std::pair<bool, StringRef> RHSPart = RHSParts.getPart(I);
1794130561Sobrien      // Expect odd part to always be numeric.
179599461Sobrien      assert (LHSPart.first == true && RHSPart.first == true &&
179699461Sobrien              "Expected both parts to be numeric.");
1797130561Sobrien      if (LHSPart.second.size() != RHSPart.second.size())
1798130561Sobrien        return LHSPart.second.size() < RHSPart.second.size();
1799130561Sobrien
1800130561Sobrien      unsigned LHSVal, RHSVal;
1801130561Sobrien
1802130561Sobrien      bool LHSFailed = LHSPart.second.getAsInteger(10, LHSVal); (void)LHSFailed;
1803130561Sobrien      assert(!LHSFailed && "Unable to convert LHS to integer.");
1804130561Sobrien      bool RHSFailed = RHSPart.second.getAsInteger(10, RHSVal); (void)RHSFailed;
180599461Sobrien      assert(!RHSFailed && "Unable to convert RHS to integer.");
1806130561Sobrien
1807130561Sobrien      if (LHSVal != RHSVal)
1808130561Sobrien        return LHSVal < RHSVal;
1809130561Sobrien    }
1810130561Sobrien    return LHSNumParts < RHSNumParts;
1811218822Sdim  }
1812218822Sdim};
1813130561Sobrien
1814130561Sobrienraw_ostream &operator<<(raw_ostream &OS, const RecordKeeper &RK);
1815130561Sobrien
1816130561Sobrien/// QualifyName - Return an Init with a qualifier prefix referring
1817130561Sobrien/// to CurRec's name.
1818130561SobrienInit *QualifyName(Record &CurRec, MultiClass *CurMultiClass,
181999461Sobrien                  Init *Name, const std::string &Scoper);
1820130561Sobrien
1821130561Sobrien/// QualifyName - Return an Init with a qualifier prefix referring
182299461Sobrien/// to CurRec's name.
182399461SobrienInit *QualifyName(Record &CurRec, MultiClass *CurMultiClass,
182499461Sobrien                  const std::string &Name, const std::string &Scoper);
182599461Sobrien
1826218822Sdim} // End llvm namespace
182799461Sobrien
1828130561Sobrien#endif
1829130561Sobrien