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