Record.h revision 239462
1226584Sdim//===- llvm/TableGen/Record.h - Classes for Table Records -------*- C++ -*-===// 2226584Sdim// 3226584Sdim// The LLVM Compiler Infrastructure 4226584Sdim// 5226584Sdim// This file is distributed under the University of Illinois Open Source 6226584Sdim// License. See LICENSE.TXT for details. 7226584Sdim// 8226584Sdim//===----------------------------------------------------------------------===// 9226584Sdim// 10226584Sdim// This file defines the main TableGen data structures, including the TableGen 11226584Sdim// types, values, and high-level data structures. 12226584Sdim// 13226584Sdim//===----------------------------------------------------------------------===// 14226584Sdim 15226584Sdim#ifndef LLVM_TABLEGEN_RECORD_H 16226584Sdim#define LLVM_TABLEGEN_RECORD_H 17226584Sdim 18226584Sdim#include "llvm/ADT/ArrayRef.h" 19226584Sdim#include "llvm/ADT/FoldingSet.h" 20226584Sdim#include "llvm/Support/Allocator.h" 21226584Sdim#include "llvm/Support/SourceMgr.h" 22226584Sdim#include "llvm/Support/DataTypes.h" 23234353Sdim#include "llvm/Support/ErrorHandling.h" 24226584Sdim#include "llvm/Support/raw_ostream.h" 25226584Sdim#include <map> 26226584Sdim 27226584Sdimnamespace llvm { 28226584Sdimclass raw_ostream; 29226584Sdim 30226584Sdim// RecTy subclasses. 31226584Sdimclass BitRecTy; 32226584Sdimclass BitsRecTy; 33226584Sdimclass IntRecTy; 34226584Sdimclass StringRecTy; 35226584Sdimclass ListRecTy; 36226584Sdimclass DagRecTy; 37226584Sdimclass RecordRecTy; 38226584Sdim 39226584Sdim// Init subclasses. 40226584Sdimclass Init; 41226584Sdimclass UnsetInit; 42226584Sdimclass BitInit; 43226584Sdimclass BitsInit; 44226584Sdimclass IntInit; 45226584Sdimclass StringInit; 46226584Sdimclass ListInit; 47226584Sdimclass UnOpInit; 48226584Sdimclass BinOpInit; 49226584Sdimclass TernOpInit; 50226584Sdimclass DefInit; 51226584Sdimclass DagInit; 52226584Sdimclass TypedInit; 53226584Sdimclass VarInit; 54226584Sdimclass FieldInit; 55226584Sdimclass VarBitInit; 56226584Sdimclass VarListElementInit; 57226584Sdim 58226584Sdim// Other classes. 59226584Sdimclass Record; 60226584Sdimclass RecordVal; 61226584Sdimstruct MultiClass; 62226584Sdimclass RecordKeeper; 63226584Sdim 64226584Sdim//===----------------------------------------------------------------------===// 65226584Sdim// Type Classes 66226584Sdim//===----------------------------------------------------------------------===// 67226584Sdim 68226584Sdimclass RecTy { 69226584Sdim ListRecTy *ListTy; 70234353Sdim virtual void anchor(); 71226584Sdimpublic: 72226584Sdim RecTy() : ListTy(0) {} 73226584Sdim virtual ~RecTy() {} 74226584Sdim 75226584Sdim virtual std::string getAsString() const = 0; 76226584Sdim void print(raw_ostream &OS) const { OS << getAsString(); } 77226584Sdim void dump() const; 78226584Sdim 79226584Sdim /// typeIsConvertibleTo - Return true if all values of 'this' type can be 80226584Sdim /// converted to the specified type. 81226584Sdim virtual bool typeIsConvertibleTo(const RecTy *RHS) const = 0; 82226584Sdim 83226584Sdim /// getListTy - Returns the type representing list<this>. 84226584Sdim ListRecTy *getListTy(); 85226584Sdim 86226584Sdimpublic: // These methods should only be called from subclasses of Init 87226584Sdim virtual Init *convertValue( UnsetInit *UI) { return 0; } 88226584Sdim virtual Init *convertValue( BitInit *BI) { return 0; } 89226584Sdim virtual Init *convertValue( BitsInit *BI) { return 0; } 90226584Sdim virtual Init *convertValue( IntInit *II) { return 0; } 91226584Sdim virtual Init *convertValue(StringInit *SI) { return 0; } 92226584Sdim virtual Init *convertValue( ListInit *LI) { return 0; } 93226584Sdim virtual Init *convertValue( UnOpInit *UI) { 94226584Sdim return convertValue((TypedInit*)UI); 95226584Sdim } 96226584Sdim virtual Init *convertValue( BinOpInit *UI) { 97226584Sdim return convertValue((TypedInit*)UI); 98226584Sdim } 99226584Sdim virtual Init *convertValue( TernOpInit *UI) { 100226584Sdim return convertValue((TypedInit*)UI); 101226584Sdim } 102226584Sdim virtual Init *convertValue(VarBitInit *VB) { return 0; } 103226584Sdim virtual Init *convertValue( DefInit *DI) { return 0; } 104226584Sdim virtual Init *convertValue( DagInit *DI) { return 0; } 105226584Sdim virtual Init *convertValue( TypedInit *TI) { return 0; } 106226584Sdim virtual Init *convertValue( VarInit *VI) { 107226584Sdim return convertValue((TypedInit*)VI); 108226584Sdim } 109226584Sdim virtual Init *convertValue( FieldInit *FI) { 110226584Sdim return convertValue((TypedInit*)FI); 111226584Sdim } 112226584Sdim 113226584Sdimpublic: // These methods should only be called by subclasses of RecTy. 114226584Sdim // baseClassOf - These virtual methods should be overloaded to return true iff 115226584Sdim // all values of type 'RHS' can be converted to the 'this' type. 116226584Sdim virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } 117226584Sdim virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; } 118226584Sdim virtual bool baseClassOf(const IntRecTy *RHS) const { return false; } 119226584Sdim virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } 120226584Sdim virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } 121226584Sdim virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } 122226584Sdim virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } 123226584Sdim}; 124226584Sdim 125226584Sdiminline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) { 126226584Sdim Ty.print(OS); 127226584Sdim return OS; 128226584Sdim} 129226584Sdim 130226584Sdim 131226584Sdim/// BitRecTy - 'bit' - Represent a single bit 132226584Sdim/// 133226584Sdimclass BitRecTy : public RecTy { 134226584Sdim static BitRecTy Shared; 135226584Sdim BitRecTy() {} 136226584Sdimpublic: 137226584Sdim static BitRecTy *get() { return &Shared; } 138226584Sdim 139226584Sdim virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } 140226584Sdim virtual Init *convertValue( BitInit *BI) { return (Init*)BI; } 141226584Sdim virtual Init *convertValue( BitsInit *BI); 142226584Sdim virtual Init *convertValue( IntInit *II); 143226584Sdim virtual Init *convertValue(StringInit *SI) { return 0; } 144226584Sdim virtual Init *convertValue( ListInit *LI) { return 0; } 145226584Sdim virtual Init *convertValue(VarBitInit *VB) { return (Init*)VB; } 146226584Sdim virtual Init *convertValue( DefInit *DI) { return 0; } 147226584Sdim virtual Init *convertValue( DagInit *DI) { return 0; } 148226584Sdim virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);} 149226584Sdim virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);} 150226584Sdim virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);} 151226584Sdim virtual Init *convertValue( TypedInit *TI); 152226584Sdim virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} 153226584Sdim virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} 154226584Sdim 155226584Sdim std::string getAsString() const { return "bit"; } 156226584Sdim 157226584Sdim bool typeIsConvertibleTo(const RecTy *RHS) const { 158226584Sdim return RHS->baseClassOf(this); 159226584Sdim } 160226584Sdim virtual bool baseClassOf(const BitRecTy *RHS) const { return true; } 161226584Sdim virtual bool baseClassOf(const BitsRecTy *RHS) const; 162226584Sdim virtual bool baseClassOf(const IntRecTy *RHS) const { return true; } 163226584Sdim virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } 164226584Sdim virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } 165226584Sdim virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } 166226584Sdim virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } 167226584Sdim 168226584Sdim}; 169226584Sdim 170226584Sdim 171226584Sdim// BitsRecTy - 'bits<n>' - Represent a fixed number of bits 172226584Sdim/// BitsRecTy - 'bits<n>' - Represent a fixed number of bits 173226584Sdim/// 174226584Sdimclass BitsRecTy : public RecTy { 175226584Sdim unsigned Size; 176226584Sdim explicit BitsRecTy(unsigned Sz) : Size(Sz) {} 177226584Sdimpublic: 178226584Sdim static BitsRecTy *get(unsigned Sz); 179226584Sdim 180226584Sdim unsigned getNumBits() const { return Size; } 181226584Sdim 182226584Sdim virtual Init *convertValue( UnsetInit *UI); 183226584Sdim virtual Init *convertValue( BitInit *UI); 184226584Sdim virtual Init *convertValue( BitsInit *BI); 185226584Sdim virtual Init *convertValue( IntInit *II); 186226584Sdim virtual Init *convertValue(StringInit *SI) { return 0; } 187226584Sdim virtual Init *convertValue( ListInit *LI) { return 0; } 188226584Sdim virtual Init *convertValue(VarBitInit *VB) { return 0; } 189226584Sdim virtual Init *convertValue( DefInit *DI) { return 0; } 190226584Sdim virtual Init *convertValue( DagInit *DI) { return 0; } 191226584Sdim virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);} 192226584Sdim virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);} 193226584Sdim virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);} 194226584Sdim virtual Init *convertValue( TypedInit *TI); 195226584Sdim virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} 196226584Sdim virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} 197226584Sdim 198226584Sdim std::string getAsString() const; 199226584Sdim 200226584Sdim bool typeIsConvertibleTo(const RecTy *RHS) const { 201226584Sdim return RHS->baseClassOf(this); 202226584Sdim } 203226584Sdim virtual bool baseClassOf(const BitRecTy *RHS) const { return Size == 1; } 204226584Sdim virtual bool baseClassOf(const BitsRecTy *RHS) const { 205226584Sdim return RHS->Size == Size; 206226584Sdim } 207226584Sdim virtual bool baseClassOf(const IntRecTy *RHS) const { return true; } 208226584Sdim virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } 209226584Sdim virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } 210226584Sdim virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } 211226584Sdim virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } 212226584Sdim 213226584Sdim}; 214226584Sdim 215226584Sdim 216226584Sdim/// IntRecTy - 'int' - Represent an integer value of no particular size 217226584Sdim/// 218226584Sdimclass IntRecTy : public RecTy { 219226584Sdim static IntRecTy Shared; 220226584Sdim IntRecTy() {} 221226584Sdimpublic: 222226584Sdim static IntRecTy *get() { return &Shared; } 223226584Sdim 224226584Sdim virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } 225226584Sdim virtual Init *convertValue( BitInit *BI); 226226584Sdim virtual Init *convertValue( BitsInit *BI); 227226584Sdim virtual Init *convertValue( IntInit *II) { return (Init*)II; } 228226584Sdim virtual Init *convertValue(StringInit *SI) { return 0; } 229226584Sdim virtual Init *convertValue( ListInit *LI) { return 0; } 230226584Sdim virtual Init *convertValue(VarBitInit *VB) { return 0; } 231226584Sdim virtual Init *convertValue( DefInit *DI) { return 0; } 232226584Sdim virtual Init *convertValue( DagInit *DI) { return 0; } 233226584Sdim virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);} 234226584Sdim virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);} 235226584Sdim virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);} 236226584Sdim virtual Init *convertValue( TypedInit *TI); 237226584Sdim virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} 238226584Sdim virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} 239226584Sdim 240226584Sdim std::string getAsString() const { return "int"; } 241226584Sdim 242226584Sdim bool typeIsConvertibleTo(const RecTy *RHS) const { 243226584Sdim return RHS->baseClassOf(this); 244226584Sdim } 245226584Sdim 246226584Sdim virtual bool baseClassOf(const BitRecTy *RHS) const { return true; } 247226584Sdim virtual bool baseClassOf(const BitsRecTy *RHS) const { return true; } 248226584Sdim virtual bool baseClassOf(const IntRecTy *RHS) const { return true; } 249226584Sdim virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } 250226584Sdim virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } 251226584Sdim virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } 252226584Sdim virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } 253226584Sdim 254226584Sdim}; 255226584Sdim 256226584Sdim/// StringRecTy - 'string' - Represent an string value 257226584Sdim/// 258226584Sdimclass StringRecTy : public RecTy { 259226584Sdim static StringRecTy Shared; 260226584Sdim StringRecTy() {} 261226584Sdimpublic: 262226584Sdim static StringRecTy *get() { return &Shared; } 263226584Sdim 264226584Sdim virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } 265226584Sdim virtual Init *convertValue( BitInit *BI) { return 0; } 266226584Sdim virtual Init *convertValue( BitsInit *BI) { return 0; } 267226584Sdim virtual Init *convertValue( IntInit *II) { return 0; } 268226584Sdim virtual Init *convertValue(StringInit *SI) { return (Init*)SI; } 269226584Sdim virtual Init *convertValue( ListInit *LI) { return 0; } 270226584Sdim virtual Init *convertValue( UnOpInit *BO); 271226584Sdim virtual Init *convertValue( BinOpInit *BO); 272226584Sdim virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);} 273226584Sdim 274226584Sdim virtual Init *convertValue(VarBitInit *VB) { return 0; } 275226584Sdim virtual Init *convertValue( DefInit *DI) { return 0; } 276226584Sdim virtual Init *convertValue( DagInit *DI) { return 0; } 277226584Sdim virtual Init *convertValue( TypedInit *TI); 278226584Sdim virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} 279226584Sdim virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} 280226584Sdim 281226584Sdim std::string getAsString() const { return "string"; } 282226584Sdim 283226584Sdim bool typeIsConvertibleTo(const RecTy *RHS) const { 284226584Sdim return RHS->baseClassOf(this); 285226584Sdim } 286226584Sdim 287226584Sdim virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } 288226584Sdim virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; } 289226584Sdim virtual bool baseClassOf(const IntRecTy *RHS) const { return false; } 290226584Sdim virtual bool baseClassOf(const StringRecTy *RHS) const { return true; } 291226584Sdim virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } 292226584Sdim virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } 293226584Sdim virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } 294226584Sdim}; 295226584Sdim 296226584Sdim// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must be of 297226584Sdim// the specified type. 298226584Sdim/// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must 299226584Sdim/// be of the specified type. 300226584Sdim/// 301226584Sdimclass ListRecTy : public RecTy { 302226584Sdim RecTy *Ty; 303226584Sdim explicit ListRecTy(RecTy *T) : Ty(T) {} 304226584Sdim friend ListRecTy *RecTy::getListTy(); 305226584Sdimpublic: 306226584Sdim static ListRecTy *get(RecTy *T) { return T->getListTy(); } 307226584Sdim RecTy *getElementType() const { return Ty; } 308226584Sdim 309226584Sdim virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } 310226584Sdim virtual Init *convertValue( BitInit *BI) { return 0; } 311226584Sdim virtual Init *convertValue( BitsInit *BI) { return 0; } 312226584Sdim virtual Init *convertValue( IntInit *II) { return 0; } 313226584Sdim virtual Init *convertValue(StringInit *SI) { return 0; } 314226584Sdim virtual Init *convertValue( ListInit *LI); 315226584Sdim virtual Init *convertValue(VarBitInit *VB) { return 0; } 316226584Sdim virtual Init *convertValue( DefInit *DI) { return 0; } 317226584Sdim virtual Init *convertValue( DagInit *DI) { return 0; } 318226584Sdim virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);} 319226584Sdim virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);} 320226584Sdim virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);} 321226584Sdim virtual Init *convertValue( TypedInit *TI); 322226584Sdim virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} 323226584Sdim virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} 324226584Sdim 325226584Sdim std::string getAsString() const; 326226584Sdim 327226584Sdim bool typeIsConvertibleTo(const RecTy *RHS) const { 328226584Sdim return RHS->baseClassOf(this); 329226584Sdim } 330226584Sdim 331226584Sdim virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } 332226584Sdim virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; } 333226584Sdim virtual bool baseClassOf(const IntRecTy *RHS) const { return false; } 334226584Sdim virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } 335226584Sdim virtual bool baseClassOf(const ListRecTy *RHS) const { 336226584Sdim return RHS->getElementType()->typeIsConvertibleTo(Ty); 337226584Sdim } 338226584Sdim virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } 339226584Sdim virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } 340226584Sdim}; 341226584Sdim 342226584Sdim/// DagRecTy - 'dag' - Represent a dag fragment 343226584Sdim/// 344226584Sdimclass DagRecTy : public RecTy { 345226584Sdim static DagRecTy Shared; 346226584Sdim DagRecTy() {} 347226584Sdimpublic: 348226584Sdim static DagRecTy *get() { return &Shared; } 349226584Sdim 350226584Sdim virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } 351226584Sdim virtual Init *convertValue( BitInit *BI) { return 0; } 352226584Sdim virtual Init *convertValue( BitsInit *BI) { return 0; } 353226584Sdim virtual Init *convertValue( IntInit *II) { return 0; } 354226584Sdim virtual Init *convertValue(StringInit *SI) { return 0; } 355226584Sdim virtual Init *convertValue( ListInit *LI) { return 0; } 356226584Sdim virtual Init *convertValue(VarBitInit *VB) { return 0; } 357226584Sdim virtual Init *convertValue( DefInit *DI) { return 0; } 358226584Sdim virtual Init *convertValue( UnOpInit *BO); 359226584Sdim virtual Init *convertValue( BinOpInit *BO); 360226584Sdim virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);} 361226584Sdim virtual Init *convertValue( DagInit *CI) { return (Init*)CI; } 362226584Sdim virtual Init *convertValue( TypedInit *TI); 363226584Sdim virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} 364226584Sdim virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} 365226584Sdim 366226584Sdim std::string getAsString() const { return "dag"; } 367226584Sdim 368226584Sdim bool typeIsConvertibleTo(const RecTy *RHS) const { 369226584Sdim return RHS->baseClassOf(this); 370226584Sdim } 371226584Sdim 372226584Sdim virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } 373226584Sdim virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; } 374226584Sdim virtual bool baseClassOf(const IntRecTy *RHS) const { return false; } 375226584Sdim virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } 376226584Sdim virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } 377226584Sdim virtual bool baseClassOf(const DagRecTy *RHS) const { return true; } 378226584Sdim virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; } 379226584Sdim}; 380226584Sdim 381226584Sdim 382226584Sdim/// RecordRecTy - '[classname]' - Represent an instance of a class, such as: 383226584Sdim/// (R32 X = EAX). 384226584Sdim/// 385226584Sdimclass RecordRecTy : public RecTy { 386226584Sdim Record *Rec; 387226584Sdim explicit RecordRecTy(Record *R) : Rec(R) {} 388226584Sdim friend class Record; 389226584Sdimpublic: 390226584Sdim static RecordRecTy *get(Record *R); 391226584Sdim 392226584Sdim Record *getRecord() const { return Rec; } 393226584Sdim 394226584Sdim virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } 395226584Sdim virtual Init *convertValue( BitInit *BI) { return 0; } 396226584Sdim virtual Init *convertValue( BitsInit *BI) { return 0; } 397226584Sdim virtual Init *convertValue( IntInit *II) { return 0; } 398226584Sdim virtual Init *convertValue(StringInit *SI) { return 0; } 399226584Sdim virtual Init *convertValue( ListInit *LI) { return 0; } 400226584Sdim virtual Init *convertValue(VarBitInit *VB) { return 0; } 401226584Sdim virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);} 402226584Sdim virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);} 403226584Sdim virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);} 404226584Sdim virtual Init *convertValue( DefInit *DI); 405226584Sdim virtual Init *convertValue( DagInit *DI) { return 0; } 406226584Sdim virtual Init *convertValue( TypedInit *VI); 407226584Sdim virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} 408226584Sdim virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} 409226584Sdim 410226584Sdim std::string getAsString() const; 411226584Sdim 412226584Sdim bool typeIsConvertibleTo(const RecTy *RHS) const { 413226584Sdim return RHS->baseClassOf(this); 414226584Sdim } 415226584Sdim virtual bool baseClassOf(const BitRecTy *RHS) const { return false; } 416226584Sdim virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; } 417226584Sdim virtual bool baseClassOf(const IntRecTy *RHS) const { return false; } 418226584Sdim virtual bool baseClassOf(const StringRecTy *RHS) const { return false; } 419226584Sdim virtual bool baseClassOf(const ListRecTy *RHS) const { return false; } 420226584Sdim virtual bool baseClassOf(const DagRecTy *RHS) const { return false; } 421226584Sdim virtual bool baseClassOf(const RecordRecTy *RHS) const; 422226584Sdim}; 423226584Sdim 424226584Sdim/// resolveTypes - Find a common type that T1 and T2 convert to. 425226584Sdim/// Return 0 if no such type exists. 426226584Sdim/// 427226584SdimRecTy *resolveTypes(RecTy *T1, RecTy *T2); 428226584Sdim 429226584Sdim//===----------------------------------------------------------------------===// 430226584Sdim// Initializer Classes 431226584Sdim//===----------------------------------------------------------------------===// 432226584Sdim 433226584Sdimclass Init { 434226584Sdim Init(const Init &); // Do not define. 435226584Sdim Init &operator=(const Init &); // Do not define. 436234353Sdim virtual void anchor(); 437226584Sdim 438226584Sdimprotected: 439226584Sdim Init(void) {} 440226584Sdim 441226584Sdimpublic: 442226584Sdim virtual ~Init() {} 443226584Sdim 444226584Sdim /// isComplete - This virtual method should be overridden by values that may 445226584Sdim /// not be completely specified yet. 446226584Sdim virtual bool isComplete() const { return true; } 447226584Sdim 448226584Sdim /// print - Print out this value. 449226584Sdim void print(raw_ostream &OS) const { OS << getAsString(); } 450226584Sdim 451226584Sdim /// getAsString - Convert this value to a string form. 452226584Sdim virtual std::string getAsString() const = 0; 453226584Sdim /// getAsUnquotedString - Convert this value to a string form, 454226584Sdim /// without adding quote markers. This primaruly affects 455226584Sdim /// StringInits where we will not surround the string value with 456226584Sdim /// quotes. 457234982Sdim virtual std::string getAsUnquotedString() const { return getAsString(); } 458226584Sdim 459226584Sdim /// dump - Debugging method that may be called through a debugger, just 460226584Sdim /// invokes print on stderr. 461226584Sdim void dump() const; 462226584Sdim 463226584Sdim /// convertInitializerTo - This virtual function is a simple call-back 464226584Sdim /// function that should be overridden to call the appropriate 465226584Sdim /// RecTy::convertValue method. 466226584Sdim /// 467226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const = 0; 468226584Sdim 469226584Sdim /// convertInitializerBitRange - This method is used to implement the bitrange 470226584Sdim /// selection operator. Given an initializer, it selects the specified bits 471226584Sdim /// out, returning them as a new init of bits type. If it is not legal to use 472226584Sdim /// the bit subscript operator on this initializer, return null. 473226584Sdim /// 474226584Sdim virtual Init * 475226584Sdim convertInitializerBitRange(const std::vector<unsigned> &Bits) const { 476226584Sdim return 0; 477226584Sdim } 478226584Sdim 479226584Sdim /// convertInitListSlice - This method is used to implement the list slice 480226584Sdim /// selection operator. Given an initializer, it selects the specified list 481226584Sdim /// elements, returning them as a new init of list type. If it is not legal 482226584Sdim /// to take a slice of this, return null. 483226584Sdim /// 484226584Sdim virtual Init * 485226584Sdim convertInitListSlice(const std::vector<unsigned> &Elements) const { 486226584Sdim return 0; 487226584Sdim } 488226584Sdim 489226584Sdim /// getFieldType - This method is used to implement the FieldInit class. 490226584Sdim /// Implementors of this method should return the type of the named field if 491226584Sdim /// they are of record type. 492226584Sdim /// 493226584Sdim virtual RecTy *getFieldType(const std::string &FieldName) const { return 0; } 494226584Sdim 495226584Sdim /// getFieldInit - This method complements getFieldType to return the 496226584Sdim /// initializer for the specified field. If getFieldType returns non-null 497226584Sdim /// this method should return non-null, otherwise it returns null. 498226584Sdim /// 499226584Sdim virtual Init *getFieldInit(Record &R, const RecordVal *RV, 500226584Sdim const std::string &FieldName) const { 501226584Sdim return 0; 502226584Sdim } 503226584Sdim 504226584Sdim /// resolveReferences - This method is used by classes that refer to other 505226584Sdim /// variables which may not be defined at the time the expression is formed. 506226584Sdim /// If a value is set for the variable later, this method will be called on 507226584Sdim /// users of the value to allow the value to propagate out. 508226584Sdim /// 509226584Sdim virtual Init *resolveReferences(Record &R, const RecordVal *RV) const { 510226584Sdim return const_cast<Init *>(this); 511226584Sdim } 512226584Sdim}; 513226584Sdim 514226584Sdiminline raw_ostream &operator<<(raw_ostream &OS, const Init &I) { 515226584Sdim I.print(OS); return OS; 516226584Sdim} 517226584Sdim 518226584Sdim/// TypedInit - This is the common super-class of types that have a specific, 519226584Sdim/// explicit, type. 520226584Sdim/// 521226584Sdimclass TypedInit : public Init { 522226584Sdim RecTy *Ty; 523226584Sdim 524226584Sdim TypedInit(const TypedInit &Other); // Do not define. 525226584Sdim TypedInit &operator=(const TypedInit &Other); // Do not define. 526226584Sdim 527226584Sdimprotected: 528226584Sdim explicit TypedInit(RecTy *T) : Ty(T) {} 529226584Sdim 530226584Sdimpublic: 531226584Sdim RecTy *getType() const { return Ty; } 532226584Sdim 533226584Sdim virtual Init * 534226584Sdim convertInitializerBitRange(const std::vector<unsigned> &Bits) const; 535226584Sdim virtual Init * 536226584Sdim convertInitListSlice(const std::vector<unsigned> &Elements) const; 537226584Sdim 538226584Sdim /// getFieldType - This method is used to implement the FieldInit class. 539226584Sdim /// Implementors of this method should return the type of the named field if 540226584Sdim /// they are of record type. 541226584Sdim /// 542226584Sdim virtual RecTy *getFieldType(const std::string &FieldName) const; 543226584Sdim 544226584Sdim /// resolveBitReference - This method is used to implement 545226584Sdim /// VarBitInit::resolveReferences. If the bit is able to be resolved, we 546226584Sdim /// simply return the resolved value, otherwise we return null. 547226584Sdim /// 548226584Sdim virtual Init *resolveBitReference(Record &R, const RecordVal *RV, 549226584Sdim unsigned Bit) const = 0; 550226584Sdim 551226584Sdim /// resolveListElementReference - This method is used to implement 552226584Sdim /// VarListElementInit::resolveReferences. If the list element is resolvable 553226584Sdim /// now, we return the resolved value, otherwise we return null. 554226584Sdim virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, 555226584Sdim unsigned Elt) const = 0; 556226584Sdim}; 557226584Sdim 558226584Sdim 559226584Sdim/// UnsetInit - ? - Represents an uninitialized value 560226584Sdim/// 561226584Sdimclass UnsetInit : public Init { 562226584Sdim UnsetInit() : Init() {} 563226584Sdim UnsetInit(const UnsetInit &); // Do not define. 564226584Sdim UnsetInit &operator=(const UnsetInit &Other); // Do not define. 565234353Sdim virtual void anchor(); 566226584Sdim 567226584Sdimpublic: 568226584Sdim static UnsetInit *get(); 569226584Sdim 570226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 571226584Sdim return Ty->convertValue(const_cast<UnsetInit *>(this)); 572226584Sdim } 573226584Sdim 574226584Sdim virtual bool isComplete() const { return false; } 575226584Sdim virtual std::string getAsString() const { return "?"; } 576226584Sdim}; 577226584Sdim 578226584Sdim 579226584Sdim/// BitInit - true/false - Represent a concrete initializer for a bit. 580226584Sdim/// 581226584Sdimclass BitInit : public Init { 582226584Sdim bool Value; 583226584Sdim 584226584Sdim explicit BitInit(bool V) : Value(V) {} 585226584Sdim BitInit(const BitInit &Other); // Do not define. 586226584Sdim BitInit &operator=(BitInit &Other); // Do not define. 587234353Sdim virtual void anchor(); 588226584Sdim 589226584Sdimpublic: 590226584Sdim static BitInit *get(bool V); 591226584Sdim 592226584Sdim bool getValue() const { return Value; } 593226584Sdim 594226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 595226584Sdim return Ty->convertValue(const_cast<BitInit *>(this)); 596226584Sdim } 597226584Sdim 598226584Sdim virtual std::string getAsString() const { return Value ? "1" : "0"; } 599226584Sdim}; 600226584Sdim 601226584Sdim/// BitsInit - { a, b, c } - Represents an initializer for a BitsRecTy value. 602226584Sdim/// It contains a vector of bits, whose size is determined by the type. 603226584Sdim/// 604226584Sdimclass BitsInit : public Init, public FoldingSetNode { 605226584Sdim std::vector<Init*> Bits; 606226584Sdim 607226584Sdim BitsInit(ArrayRef<Init *> Range) : Bits(Range.begin(), Range.end()) {} 608226584Sdim 609226584Sdim BitsInit(const BitsInit &Other); // Do not define. 610226584Sdim BitsInit &operator=(const BitsInit &Other); // Do not define. 611226584Sdim 612226584Sdimpublic: 613226584Sdim static BitsInit *get(ArrayRef<Init *> Range); 614226584Sdim 615226584Sdim void Profile(FoldingSetNodeID &ID) const; 616226584Sdim 617226584Sdim unsigned getNumBits() const { return Bits.size(); } 618226584Sdim 619226584Sdim Init *getBit(unsigned Bit) const { 620226584Sdim assert(Bit < Bits.size() && "Bit index out of range!"); 621226584Sdim return Bits[Bit]; 622226584Sdim } 623226584Sdim 624226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 625226584Sdim return Ty->convertValue(const_cast<BitsInit *>(this)); 626226584Sdim } 627226584Sdim virtual Init * 628226584Sdim convertInitializerBitRange(const std::vector<unsigned> &Bits) const; 629226584Sdim 630226584Sdim virtual bool isComplete() const { 631226584Sdim for (unsigned i = 0; i != getNumBits(); ++i) 632226584Sdim if (!getBit(i)->isComplete()) return false; 633226584Sdim return true; 634226584Sdim } 635226584Sdim bool allInComplete() const { 636226584Sdim for (unsigned i = 0; i != getNumBits(); ++i) 637226584Sdim if (getBit(i)->isComplete()) return false; 638226584Sdim return true; 639226584Sdim } 640226584Sdim virtual std::string getAsString() const; 641226584Sdim 642226584Sdim virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; 643226584Sdim}; 644226584Sdim 645226584Sdim 646226584Sdim/// IntInit - 7 - Represent an initalization by a literal integer value. 647226584Sdim/// 648226584Sdimclass IntInit : public TypedInit { 649226584Sdim int64_t Value; 650226584Sdim 651226584Sdim explicit IntInit(int64_t V) : TypedInit(IntRecTy::get()), Value(V) {} 652226584Sdim 653226584Sdim IntInit(const IntInit &Other); // Do not define. 654226584Sdim IntInit &operator=(const IntInit &Other); // Do note define. 655226584Sdim 656226584Sdimpublic: 657226584Sdim static IntInit *get(int64_t V); 658226584Sdim 659226584Sdim int64_t getValue() const { return Value; } 660226584Sdim 661226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 662226584Sdim return Ty->convertValue(const_cast<IntInit *>(this)); 663226584Sdim } 664226584Sdim virtual Init * 665226584Sdim convertInitializerBitRange(const std::vector<unsigned> &Bits) const; 666226584Sdim 667226584Sdim virtual std::string getAsString() const; 668226584Sdim 669226584Sdim /// resolveBitReference - This method is used to implement 670226584Sdim /// VarBitInit::resolveReferences. If the bit is able to be resolved, we 671226584Sdim /// simply return the resolved value, otherwise we return null. 672226584Sdim /// 673226584Sdim virtual Init *resolveBitReference(Record &R, const RecordVal *RV, 674226584Sdim unsigned Bit) const { 675234353Sdim llvm_unreachable("Illegal bit reference off int"); 676226584Sdim } 677226584Sdim 678226584Sdim /// resolveListElementReference - This method is used to implement 679226584Sdim /// VarListElementInit::resolveReferences. If the list element is resolvable 680226584Sdim /// now, we return the resolved value, otherwise we return null. 681226584Sdim virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, 682226584Sdim unsigned Elt) const { 683234353Sdim llvm_unreachable("Illegal element reference off int"); 684226584Sdim } 685226584Sdim}; 686226584Sdim 687226584Sdim 688226584Sdim/// StringInit - "foo" - Represent an initialization by a string value. 689226584Sdim/// 690226584Sdimclass StringInit : public TypedInit { 691226584Sdim std::string Value; 692226584Sdim 693226584Sdim explicit StringInit(const std::string &V) 694226584Sdim : TypedInit(StringRecTy::get()), Value(V) {} 695226584Sdim 696226584Sdim StringInit(const StringInit &Other); // Do not define. 697226584Sdim StringInit &operator=(const StringInit &Other); // Do not define. 698234353Sdim virtual void anchor(); 699226584Sdim 700226584Sdimpublic: 701234353Sdim static StringInit *get(StringRef); 702226584Sdim 703226584Sdim const std::string &getValue() const { return Value; } 704226584Sdim 705226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 706226584Sdim return Ty->convertValue(const_cast<StringInit *>(this)); 707226584Sdim } 708226584Sdim 709226584Sdim virtual std::string getAsString() const { return "\"" + Value + "\""; } 710226584Sdim virtual std::string getAsUnquotedString() const { return Value; } 711226584Sdim 712226584Sdim /// resolveBitReference - This method is used to implement 713226584Sdim /// VarBitInit::resolveReferences. If the bit is able to be resolved, we 714226584Sdim /// simply return the resolved value, otherwise we return null. 715226584Sdim /// 716226584Sdim virtual Init *resolveBitReference(Record &R, const RecordVal *RV, 717226584Sdim unsigned Bit) const { 718234353Sdim llvm_unreachable("Illegal bit reference off string"); 719226584Sdim } 720226584Sdim 721226584Sdim /// resolveListElementReference - This method is used to implement 722226584Sdim /// VarListElementInit::resolveReferences. If the list element is resolvable 723226584Sdim /// now, we return the resolved value, otherwise we return null. 724226584Sdim virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, 725226584Sdim unsigned Elt) const { 726234353Sdim llvm_unreachable("Illegal element reference off string"); 727226584Sdim } 728226584Sdim}; 729226584Sdim 730226584Sdim/// ListInit - [AL, AH, CL] - Represent a list of defs 731226584Sdim/// 732226584Sdimclass ListInit : public TypedInit, public FoldingSetNode { 733226584Sdim std::vector<Init*> Values; 734226584Sdimpublic: 735226584Sdim typedef std::vector<Init*>::const_iterator const_iterator; 736226584Sdim 737226584Sdimprivate: 738226584Sdim explicit ListInit(ArrayRef<Init *> Range, RecTy *EltTy) 739226584Sdim : TypedInit(ListRecTy::get(EltTy)), Values(Range.begin(), Range.end()) {} 740226584Sdim 741226584Sdim ListInit(const ListInit &Other); // Do not define. 742226584Sdim ListInit &operator=(const ListInit &Other); // Do not define. 743226584Sdim 744226584Sdimpublic: 745226584Sdim static ListInit *get(ArrayRef<Init *> Range, RecTy *EltTy); 746226584Sdim 747226584Sdim void Profile(FoldingSetNodeID &ID) const; 748226584Sdim 749226584Sdim unsigned getSize() const { return Values.size(); } 750226584Sdim Init *getElement(unsigned i) const { 751226584Sdim assert(i < Values.size() && "List element index out of range!"); 752226584Sdim return Values[i]; 753226584Sdim } 754226584Sdim 755226584Sdim Record *getElementAsRecord(unsigned i) const; 756226584Sdim 757226584Sdim Init *convertInitListSlice(const std::vector<unsigned> &Elements) const; 758226584Sdim 759226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 760226584Sdim return Ty->convertValue(const_cast<ListInit *>(this)); 761226584Sdim } 762226584Sdim 763226584Sdim /// resolveReferences - This method is used by classes that refer to other 764226584Sdim /// variables which may not be defined at the time they expression is formed. 765226584Sdim /// If a value is set for the variable later, this method will be called on 766226584Sdim /// users of the value to allow the value to propagate out. 767226584Sdim /// 768226584Sdim virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; 769226584Sdim 770226584Sdim virtual std::string getAsString() const; 771226584Sdim 772226584Sdim ArrayRef<Init*> getValues() const { return Values; } 773226584Sdim 774226584Sdim inline const_iterator begin() const { return Values.begin(); } 775226584Sdim inline const_iterator end () const { return Values.end(); } 776226584Sdim 777226584Sdim inline size_t size () const { return Values.size(); } 778226584Sdim inline bool empty() const { return Values.empty(); } 779226584Sdim 780226584Sdim /// resolveBitReference - This method is used to implement 781226584Sdim /// VarBitInit::resolveReferences. If the bit is able to be resolved, we 782226584Sdim /// simply return the resolved value, otherwise we return null. 783226584Sdim /// 784226584Sdim virtual Init *resolveBitReference(Record &R, const RecordVal *RV, 785226584Sdim unsigned Bit) const { 786234353Sdim llvm_unreachable("Illegal bit reference off list"); 787226584Sdim } 788226584Sdim 789226584Sdim /// resolveListElementReference - This method is used to implement 790226584Sdim /// VarListElementInit::resolveReferences. If the list element is resolvable 791226584Sdim /// now, we return the resolved value, otherwise we return null. 792226584Sdim virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, 793226584Sdim unsigned Elt) const; 794226584Sdim}; 795226584Sdim 796226584Sdim 797226584Sdim/// OpInit - Base class for operators 798226584Sdim/// 799226584Sdimclass OpInit : public TypedInit { 800226584Sdim OpInit(const OpInit &Other); // Do not define. 801226584Sdim OpInit &operator=(OpInit &Other); // Do not define. 802226584Sdim 803226584Sdimprotected: 804226584Sdim explicit OpInit(RecTy *Type) : TypedInit(Type) {} 805226584Sdim 806226584Sdimpublic: 807226584Sdim // Clone - Clone this operator, replacing arguments with the new list 808226584Sdim virtual OpInit *clone(std::vector<Init *> &Operands) const = 0; 809226584Sdim 810226584Sdim virtual int getNumOperands() const = 0; 811226584Sdim virtual Init *getOperand(int i) const = 0; 812226584Sdim 813226584Sdim // Fold - If possible, fold this to a simpler init. Return this if not 814226584Sdim // possible to fold. 815226584Sdim virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const = 0; 816226584Sdim 817226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 818226584Sdim return Ty->convertValue(const_cast<OpInit *>(this)); 819226584Sdim } 820226584Sdim 821226584Sdim virtual Init *resolveBitReference(Record &R, const RecordVal *RV, 822226584Sdim unsigned Bit) const; 823226584Sdim virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, 824226584Sdim unsigned Elt) const; 825226584Sdim}; 826226584Sdim 827226584Sdim 828226584Sdim/// UnOpInit - !op (X) - Transform an init. 829226584Sdim/// 830226584Sdimclass UnOpInit : public OpInit { 831226584Sdimpublic: 832226584Sdim enum UnaryOp { CAST, HEAD, TAIL, EMPTY }; 833226584Sdimprivate: 834226584Sdim UnaryOp Opc; 835226584Sdim Init *LHS; 836226584Sdim 837226584Sdim UnOpInit(UnaryOp opc, Init *lhs, RecTy *Type) 838226584Sdim : OpInit(Type), Opc(opc), LHS(lhs) {} 839226584Sdim 840226584Sdim UnOpInit(const UnOpInit &Other); // Do not define. 841226584Sdim UnOpInit &operator=(const UnOpInit &Other); // Do not define. 842226584Sdim 843226584Sdimpublic: 844226584Sdim static UnOpInit *get(UnaryOp opc, Init *lhs, RecTy *Type); 845226584Sdim 846226584Sdim // Clone - Clone this operator, replacing arguments with the new list 847226584Sdim virtual OpInit *clone(std::vector<Init *> &Operands) const { 848226584Sdim assert(Operands.size() == 1 && 849226584Sdim "Wrong number of operands for unary operation"); 850226584Sdim return UnOpInit::get(getOpcode(), *Operands.begin(), getType()); 851226584Sdim } 852226584Sdim 853226584Sdim int getNumOperands() const { return 1; } 854226584Sdim Init *getOperand(int i) const { 855226584Sdim assert(i == 0 && "Invalid operand id for unary operator"); 856226584Sdim return getOperand(); 857226584Sdim } 858226584Sdim 859226584Sdim UnaryOp getOpcode() const { return Opc; } 860226584Sdim Init *getOperand() const { return LHS; } 861226584Sdim 862226584Sdim // Fold - If possible, fold this to a simpler init. Return this if not 863226584Sdim // possible to fold. 864226584Sdim Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const; 865226584Sdim 866226584Sdim virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; 867226584Sdim 868226584Sdim virtual std::string getAsString() const; 869226584Sdim}; 870226584Sdim 871226584Sdim/// BinOpInit - !op (X, Y) - Combine two inits. 872226584Sdim/// 873226584Sdimclass BinOpInit : public OpInit { 874226584Sdimpublic: 875226584Sdim enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, EQ }; 876226584Sdimprivate: 877226584Sdim BinaryOp Opc; 878226584Sdim Init *LHS, *RHS; 879226584Sdim 880226584Sdim BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) : 881226584Sdim OpInit(Type), Opc(opc), LHS(lhs), RHS(rhs) {} 882226584Sdim 883226584Sdim BinOpInit(const BinOpInit &Other); // Do not define. 884226584Sdim BinOpInit &operator=(const BinOpInit &Other); // Do not define. 885226584Sdim 886226584Sdimpublic: 887226584Sdim static BinOpInit *get(BinaryOp opc, Init *lhs, Init *rhs, 888226584Sdim RecTy *Type); 889226584Sdim 890226584Sdim // Clone - Clone this operator, replacing arguments with the new list 891226584Sdim virtual OpInit *clone(std::vector<Init *> &Operands) const { 892226584Sdim assert(Operands.size() == 2 && 893226584Sdim "Wrong number of operands for binary operation"); 894226584Sdim return BinOpInit::get(getOpcode(), Operands[0], Operands[1], getType()); 895226584Sdim } 896226584Sdim 897226584Sdim int getNumOperands() const { return 2; } 898226584Sdim Init *getOperand(int i) const { 899226584Sdim assert((i == 0 || i == 1) && "Invalid operand id for binary operator"); 900226584Sdim if (i == 0) { 901226584Sdim return getLHS(); 902226584Sdim } else { 903226584Sdim return getRHS(); 904226584Sdim } 905226584Sdim } 906226584Sdim 907226584Sdim BinaryOp getOpcode() const { return Opc; } 908226584Sdim Init *getLHS() const { return LHS; } 909226584Sdim Init *getRHS() const { return RHS; } 910226584Sdim 911226584Sdim // Fold - If possible, fold this to a simpler init. Return this if not 912226584Sdim // possible to fold. 913226584Sdim Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const; 914226584Sdim 915226584Sdim virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; 916226584Sdim 917226584Sdim virtual std::string getAsString() const; 918226584Sdim}; 919226584Sdim 920226584Sdim/// TernOpInit - !op (X, Y, Z) - Combine two inits. 921226584Sdim/// 922226584Sdimclass TernOpInit : public OpInit { 923226584Sdimpublic: 924226584Sdim enum TernaryOp { SUBST, FOREACH, IF }; 925226584Sdimprivate: 926226584Sdim TernaryOp Opc; 927226584Sdim Init *LHS, *MHS, *RHS; 928226584Sdim 929226584Sdim TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, 930226584Sdim RecTy *Type) : 931226584Sdim OpInit(Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {} 932226584Sdim 933226584Sdim TernOpInit(const TernOpInit &Other); // Do not define. 934226584Sdim TernOpInit &operator=(const TernOpInit &Other); // Do not define. 935226584Sdim 936226584Sdimpublic: 937226584Sdim static TernOpInit *get(TernaryOp opc, Init *lhs, 938226584Sdim Init *mhs, Init *rhs, 939226584Sdim RecTy *Type); 940226584Sdim 941226584Sdim // Clone - Clone this operator, replacing arguments with the new list 942226584Sdim virtual OpInit *clone(std::vector<Init *> &Operands) const { 943226584Sdim assert(Operands.size() == 3 && 944226584Sdim "Wrong number of operands for ternary operation"); 945226584Sdim return TernOpInit::get(getOpcode(), Operands[0], Operands[1], Operands[2], 946226584Sdim getType()); 947226584Sdim } 948226584Sdim 949226584Sdim int getNumOperands() const { return 3; } 950226584Sdim Init *getOperand(int i) const { 951226584Sdim assert((i == 0 || i == 1 || i == 2) && 952226584Sdim "Invalid operand id for ternary operator"); 953226584Sdim if (i == 0) { 954226584Sdim return getLHS(); 955226584Sdim } else if (i == 1) { 956226584Sdim return getMHS(); 957226584Sdim } else { 958226584Sdim return getRHS(); 959226584Sdim } 960226584Sdim } 961226584Sdim 962226584Sdim TernaryOp getOpcode() const { return Opc; } 963226584Sdim Init *getLHS() const { return LHS; } 964226584Sdim Init *getMHS() const { return MHS; } 965226584Sdim Init *getRHS() const { return RHS; } 966226584Sdim 967226584Sdim // Fold - If possible, fold this to a simpler init. Return this if not 968226584Sdim // possible to fold. 969226584Sdim Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const; 970226584Sdim 971226584Sdim virtual bool isComplete() const { return false; } 972226584Sdim 973226584Sdim virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; 974226584Sdim 975226584Sdim virtual std::string getAsString() const; 976226584Sdim}; 977226584Sdim 978226584Sdim 979226584Sdim/// VarInit - 'Opcode' - Represent a reference to an entire variable object. 980226584Sdim/// 981226584Sdimclass VarInit : public TypedInit { 982234353Sdim Init *VarName; 983226584Sdim 984226584Sdim explicit VarInit(const std::string &VN, RecTy *T) 985234353Sdim : TypedInit(T), VarName(StringInit::get(VN)) {} 986234353Sdim explicit VarInit(Init *VN, RecTy *T) 987226584Sdim : TypedInit(T), VarName(VN) {} 988226584Sdim 989226584Sdim VarInit(const VarInit &Other); // Do not define. 990226584Sdim VarInit &operator=(const VarInit &Other); // Do not define. 991226584Sdim 992226584Sdimpublic: 993226584Sdim static VarInit *get(const std::string &VN, RecTy *T); 994226584Sdim static VarInit *get(Init *VN, RecTy *T); 995226584Sdim 996226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 997226584Sdim return Ty->convertValue(const_cast<VarInit *>(this)); 998226584Sdim } 999226584Sdim 1000234353Sdim const std::string &getName() const; 1001234353Sdim Init *getNameInit() const { return VarName; } 1002234353Sdim std::string getNameInitAsString() const { 1003234353Sdim return getNameInit()->getAsUnquotedString(); 1004234353Sdim } 1005226584Sdim 1006226584Sdim virtual Init *resolveBitReference(Record &R, const RecordVal *RV, 1007226584Sdim unsigned Bit) const; 1008226584Sdim virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, 1009226584Sdim unsigned Elt) const; 1010226584Sdim 1011226584Sdim virtual RecTy *getFieldType(const std::string &FieldName) const; 1012226584Sdim virtual Init *getFieldInit(Record &R, const RecordVal *RV, 1013226584Sdim const std::string &FieldName) const; 1014226584Sdim 1015226584Sdim /// resolveReferences - This method is used by classes that refer to other 1016226584Sdim /// variables which may not be defined at the time they expression is formed. 1017226584Sdim /// If a value is set for the variable later, this method will be called on 1018226584Sdim /// users of the value to allow the value to propagate out. 1019226584Sdim /// 1020226584Sdim virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; 1021226584Sdim 1022234353Sdim virtual std::string getAsString() const { return getName(); } 1023226584Sdim}; 1024226584Sdim 1025226584Sdim 1026226584Sdim/// VarBitInit - Opcode{0} - Represent access to one bit of a variable or field. 1027226584Sdim/// 1028226584Sdimclass VarBitInit : public Init { 1029226584Sdim TypedInit *TI; 1030226584Sdim unsigned Bit; 1031226584Sdim 1032226584Sdim VarBitInit(TypedInit *T, unsigned B) : TI(T), Bit(B) { 1033226584Sdim assert(T->getType() && dynamic_cast<BitsRecTy*>(T->getType()) && 1034226584Sdim ((BitsRecTy*)T->getType())->getNumBits() > B && 1035226584Sdim "Illegal VarBitInit expression!"); 1036226584Sdim } 1037226584Sdim 1038226584Sdim VarBitInit(const VarBitInit &Other); // Do not define. 1039226584Sdim VarBitInit &operator=(const VarBitInit &Other); // Do not define. 1040226584Sdim 1041226584Sdimpublic: 1042226584Sdim static VarBitInit *get(TypedInit *T, unsigned B); 1043226584Sdim 1044226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 1045226584Sdim return Ty->convertValue(const_cast<VarBitInit *>(this)); 1046226584Sdim } 1047226584Sdim 1048226584Sdim TypedInit *getVariable() const { return TI; } 1049226584Sdim unsigned getBitNum() const { return Bit; } 1050226584Sdim 1051226584Sdim virtual std::string getAsString() const; 1052226584Sdim virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; 1053226584Sdim}; 1054226584Sdim 1055226584Sdim/// VarListElementInit - List[4] - Represent access to one element of a var or 1056226584Sdim/// field. 1057226584Sdimclass VarListElementInit : public TypedInit { 1058226584Sdim TypedInit *TI; 1059226584Sdim unsigned Element; 1060226584Sdim 1061226584Sdim VarListElementInit(TypedInit *T, unsigned E) 1062226584Sdim : TypedInit(dynamic_cast<ListRecTy*>(T->getType())->getElementType()), 1063226584Sdim TI(T), Element(E) { 1064226584Sdim assert(T->getType() && dynamic_cast<ListRecTy*>(T->getType()) && 1065226584Sdim "Illegal VarBitInit expression!"); 1066226584Sdim } 1067226584Sdim 1068226584Sdim VarListElementInit(const VarListElementInit &Other); // Do not define. 1069226584Sdim VarListElementInit &operator=(const VarListElementInit &Other); // Do 1070226584Sdim // not 1071226584Sdim // define. 1072226584Sdim 1073226584Sdimpublic: 1074226584Sdim static VarListElementInit *get(TypedInit *T, unsigned E); 1075226584Sdim 1076226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 1077226584Sdim return Ty->convertValue(const_cast<VarListElementInit *>(this)); 1078226584Sdim } 1079226584Sdim 1080226584Sdim TypedInit *getVariable() const { return TI; } 1081226584Sdim unsigned getElementNum() const { return Element; } 1082226584Sdim 1083226584Sdim virtual Init *resolveBitReference(Record &R, const RecordVal *RV, 1084226584Sdim unsigned Bit) const; 1085226584Sdim 1086226584Sdim /// resolveListElementReference - This method is used to implement 1087226584Sdim /// VarListElementInit::resolveReferences. If the list element is resolvable 1088226584Sdim /// now, we return the resolved value, otherwise we return null. 1089226584Sdim virtual Init *resolveListElementReference(Record &R, 1090226584Sdim const RecordVal *RV, 1091226584Sdim unsigned Elt) const; 1092226584Sdim 1093226584Sdim virtual std::string getAsString() const; 1094226584Sdim virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; 1095226584Sdim}; 1096226584Sdim 1097226584Sdim/// DefInit - AL - Represent a reference to a 'def' in the description 1098226584Sdim/// 1099226584Sdimclass DefInit : public TypedInit { 1100226584Sdim Record *Def; 1101226584Sdim 1102226584Sdim DefInit(Record *D, RecordRecTy *T) : TypedInit(T), Def(D) {} 1103226584Sdim friend class Record; 1104226584Sdim 1105226584Sdim DefInit(const DefInit &Other); // Do not define. 1106226584Sdim DefInit &operator=(const DefInit &Other); // Do not define. 1107226584Sdim 1108226584Sdimpublic: 1109226584Sdim static DefInit *get(Record*); 1110226584Sdim 1111226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 1112226584Sdim return Ty->convertValue(const_cast<DefInit *>(this)); 1113226584Sdim } 1114226584Sdim 1115226584Sdim Record *getDef() const { return Def; } 1116226584Sdim 1117226584Sdim //virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits); 1118226584Sdim 1119226584Sdim virtual RecTy *getFieldType(const std::string &FieldName) const; 1120226584Sdim virtual Init *getFieldInit(Record &R, const RecordVal *RV, 1121226584Sdim const std::string &FieldName) const; 1122226584Sdim 1123226584Sdim virtual std::string getAsString() const; 1124226584Sdim 1125226584Sdim /// resolveBitReference - This method is used to implement 1126226584Sdim /// VarBitInit::resolveReferences. If the bit is able to be resolved, we 1127226584Sdim /// simply return the resolved value, otherwise we return null. 1128226584Sdim /// 1129226584Sdim virtual Init *resolveBitReference(Record &R, const RecordVal *RV, 1130226584Sdim unsigned Bit) const { 1131234353Sdim llvm_unreachable("Illegal bit reference off def"); 1132226584Sdim } 1133226584Sdim 1134226584Sdim /// resolveListElementReference - This method is used to implement 1135226584Sdim /// VarListElementInit::resolveReferences. If the list element is resolvable 1136226584Sdim /// now, we return the resolved value, otherwise we return null. 1137226584Sdim virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, 1138226584Sdim unsigned Elt) const { 1139234353Sdim llvm_unreachable("Illegal element reference off def"); 1140226584Sdim } 1141226584Sdim}; 1142226584Sdim 1143226584Sdim 1144226584Sdim/// FieldInit - X.Y - Represent a reference to a subfield of a variable 1145226584Sdim/// 1146226584Sdimclass FieldInit : public TypedInit { 1147226584Sdim Init *Rec; // Record we are referring to 1148226584Sdim std::string FieldName; // Field we are accessing 1149226584Sdim 1150226584Sdim FieldInit(Init *R, const std::string &FN) 1151226584Sdim : TypedInit(R->getFieldType(FN)), Rec(R), FieldName(FN) { 1152226584Sdim assert(getType() && "FieldInit with non-record type!"); 1153226584Sdim } 1154226584Sdim 1155226584Sdim FieldInit(const FieldInit &Other); // Do not define. 1156226584Sdim FieldInit &operator=(const FieldInit &Other); // Do not define. 1157226584Sdim 1158226584Sdimpublic: 1159226584Sdim static FieldInit *get(Init *R, const std::string &FN); 1160226584Sdim static FieldInit *get(Init *R, const Init *FN); 1161226584Sdim 1162226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 1163226584Sdim return Ty->convertValue(const_cast<FieldInit *>(this)); 1164226584Sdim } 1165226584Sdim 1166226584Sdim virtual Init *resolveBitReference(Record &R, const RecordVal *RV, 1167226584Sdim unsigned Bit) const; 1168226584Sdim virtual Init *resolveListElementReference(Record &R, 1169226584Sdim const RecordVal *RV, 1170226584Sdim unsigned Elt) const; 1171226584Sdim 1172226584Sdim virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; 1173226584Sdim 1174226584Sdim virtual std::string getAsString() const { 1175226584Sdim return Rec->getAsString() + "." + FieldName; 1176226584Sdim } 1177226584Sdim}; 1178226584Sdim 1179226584Sdim/// DagInit - (v a, b) - Represent a DAG tree value. DAG inits are required 1180226584Sdim/// to have at least one value then a (possibly empty) list of arguments. Each 1181226584Sdim/// argument can have a name associated with it. 1182226584Sdim/// 1183226584Sdimclass DagInit : public TypedInit, public FoldingSetNode { 1184226584Sdim Init *Val; 1185226584Sdim std::string ValName; 1186226584Sdim std::vector<Init*> Args; 1187226584Sdim std::vector<std::string> ArgNames; 1188226584Sdim 1189226584Sdim DagInit(Init *V, const std::string &VN, 1190226584Sdim ArrayRef<Init *> ArgRange, 1191226584Sdim ArrayRef<std::string> NameRange) 1192226584Sdim : TypedInit(DagRecTy::get()), Val(V), ValName(VN), 1193226584Sdim Args(ArgRange.begin(), ArgRange.end()), 1194226584Sdim ArgNames(NameRange.begin(), NameRange.end()) {} 1195226584Sdim 1196226584Sdim DagInit(const DagInit &Other); // Do not define. 1197226584Sdim DagInit &operator=(const DagInit &Other); // Do not define. 1198226584Sdim 1199226584Sdimpublic: 1200226584Sdim static DagInit *get(Init *V, const std::string &VN, 1201226584Sdim ArrayRef<Init *> ArgRange, 1202226584Sdim ArrayRef<std::string> NameRange); 1203226584Sdim static DagInit *get(Init *V, const std::string &VN, 1204226584Sdim const std::vector< 1205226584Sdim std::pair<Init*, std::string> > &args); 1206226584Sdim 1207226584Sdim void Profile(FoldingSetNodeID &ID) const; 1208226584Sdim 1209226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 1210226584Sdim return Ty->convertValue(const_cast<DagInit *>(this)); 1211226584Sdim } 1212226584Sdim 1213226584Sdim Init *getOperator() const { return Val; } 1214226584Sdim 1215226584Sdim const std::string &getName() const { return ValName; } 1216226584Sdim 1217226584Sdim unsigned getNumArgs() const { return Args.size(); } 1218226584Sdim Init *getArg(unsigned Num) const { 1219226584Sdim assert(Num < Args.size() && "Arg number out of range!"); 1220226584Sdim return Args[Num]; 1221226584Sdim } 1222226584Sdim const std::string &getArgName(unsigned Num) const { 1223226584Sdim assert(Num < ArgNames.size() && "Arg number out of range!"); 1224226584Sdim return ArgNames[Num]; 1225226584Sdim } 1226226584Sdim 1227226584Sdim virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; 1228226584Sdim 1229226584Sdim virtual std::string getAsString() const; 1230226584Sdim 1231226584Sdim typedef std::vector<Init*>::const_iterator const_arg_iterator; 1232226584Sdim typedef std::vector<std::string>::const_iterator const_name_iterator; 1233226584Sdim 1234226584Sdim inline const_arg_iterator arg_begin() const { return Args.begin(); } 1235226584Sdim inline const_arg_iterator arg_end () const { return Args.end(); } 1236226584Sdim 1237226584Sdim inline size_t arg_size () const { return Args.size(); } 1238226584Sdim inline bool arg_empty() const { return Args.empty(); } 1239226584Sdim 1240226584Sdim inline const_name_iterator name_begin() const { return ArgNames.begin(); } 1241226584Sdim inline const_name_iterator name_end () const { return ArgNames.end(); } 1242226584Sdim 1243226584Sdim inline size_t name_size () const { return ArgNames.size(); } 1244226584Sdim inline bool name_empty() const { return ArgNames.empty(); } 1245226584Sdim 1246226584Sdim virtual Init *resolveBitReference(Record &R, const RecordVal *RV, 1247226584Sdim unsigned Bit) const { 1248234353Sdim llvm_unreachable("Illegal bit reference off dag"); 1249226584Sdim } 1250226584Sdim 1251226584Sdim virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, 1252226584Sdim unsigned Elt) const { 1253234353Sdim llvm_unreachable("Illegal element reference off dag"); 1254226584Sdim } 1255226584Sdim}; 1256226584Sdim 1257226584Sdim//===----------------------------------------------------------------------===// 1258226584Sdim// High-Level Classes 1259226584Sdim//===----------------------------------------------------------------------===// 1260226584Sdim 1261226584Sdimclass RecordVal { 1262226584Sdim Init *Name; 1263226584Sdim RecTy *Ty; 1264226584Sdim unsigned Prefix; 1265226584Sdim Init *Value; 1266226584Sdimpublic: 1267226584Sdim RecordVal(Init *N, RecTy *T, unsigned P); 1268226584Sdim RecordVal(const std::string &N, RecTy *T, unsigned P); 1269226584Sdim 1270226584Sdim const std::string &getName() const; 1271234353Sdim const Init *getNameInit() const { return Name; } 1272234353Sdim std::string getNameInitAsString() const { 1273234353Sdim return getNameInit()->getAsUnquotedString(); 1274234353Sdim } 1275226584Sdim 1276226584Sdim unsigned getPrefix() const { return Prefix; } 1277226584Sdim RecTy *getType() const { return Ty; } 1278226584Sdim Init *getValue() const { return Value; } 1279226584Sdim 1280226584Sdim bool setValue(Init *V) { 1281226584Sdim if (V) { 1282226584Sdim Value = V->convertInitializerTo(Ty); 1283226584Sdim return Value == 0; 1284226584Sdim } 1285226584Sdim Value = 0; 1286226584Sdim return false; 1287226584Sdim } 1288226584Sdim 1289226584Sdim void dump() const; 1290226584Sdim void print(raw_ostream &OS, bool PrintSem = true) const; 1291226584Sdim}; 1292226584Sdim 1293226584Sdiminline raw_ostream &operator<<(raw_ostream &OS, const RecordVal &RV) { 1294226584Sdim RV.print(OS << " "); 1295226584Sdim return OS; 1296226584Sdim} 1297226584Sdim 1298226584Sdimclass Record { 1299226584Sdim static unsigned LastID; 1300226584Sdim 1301226584Sdim // Unique record ID. 1302226584Sdim unsigned ID; 1303226584Sdim Init *Name; 1304226584Sdim SMLoc Loc; 1305234353Sdim std::vector<Init *> TemplateArgs; 1306226584Sdim std::vector<RecordVal> Values; 1307226584Sdim std::vector<Record*> SuperClasses; 1308226584Sdim 1309226584Sdim // Tracks Record instances. Not owned by Record. 1310226584Sdim RecordKeeper &TrackedRecords; 1311226584Sdim 1312226584Sdim DefInit *TheInit; 1313226584Sdim 1314234353Sdim void init(); 1315226584Sdim void checkName(); 1316226584Sdim 1317226584Sdimpublic: 1318226584Sdim 1319226584Sdim // Constructs a record. 1320226584Sdim explicit Record(const std::string &N, SMLoc loc, RecordKeeper &records) : 1321234353Sdim ID(LastID++), Name(StringInit::get(N)), Loc(loc), TrackedRecords(records), 1322234353Sdim TheInit(0) { 1323234353Sdim init(); 1324234353Sdim } 1325234353Sdim explicit Record(Init *N, SMLoc loc, RecordKeeper &records) : 1326234353Sdim ID(LastID++), Name(N), Loc(loc), TrackedRecords(records), TheInit(0) { 1327234353Sdim init(); 1328234353Sdim } 1329226584Sdim ~Record() {} 1330226584Sdim 1331226584Sdim 1332226584Sdim static unsigned getNewUID() { return LastID++; } 1333226584Sdim 1334226584Sdim 1335226584Sdim unsigned getID() const { return ID; } 1336226584Sdim 1337226584Sdim const std::string &getName() const; 1338234353Sdim Init *getNameInit() const { 1339234353Sdim return Name; 1340234353Sdim } 1341234353Sdim const std::string getNameInitAsString() const { 1342234353Sdim return getNameInit()->getAsUnquotedString(); 1343234353Sdim } 1344234353Sdim 1345226584Sdim void setName(Init *Name); // Also updates RecordKeeper. 1346226584Sdim void setName(const std::string &Name); // Also updates RecordKeeper. 1347226584Sdim 1348226584Sdim SMLoc getLoc() const { return Loc; } 1349226584Sdim 1350226584Sdim /// get the corresponding DefInit. 1351226584Sdim DefInit *getDefInit(); 1352226584Sdim 1353234353Sdim const std::vector<Init *> &getTemplateArgs() const { 1354226584Sdim return TemplateArgs; 1355226584Sdim } 1356226584Sdim const std::vector<RecordVal> &getValues() const { return Values; } 1357226584Sdim const std::vector<Record*> &getSuperClasses() const { return SuperClasses; } 1358226584Sdim 1359234353Sdim bool isTemplateArg(Init *Name) const { 1360226584Sdim for (unsigned i = 0, e = TemplateArgs.size(); i != e; ++i) 1361226584Sdim if (TemplateArgs[i] == Name) return true; 1362226584Sdim return false; 1363226584Sdim } 1364234353Sdim bool isTemplateArg(StringRef Name) const { 1365234353Sdim return isTemplateArg(StringInit::get(Name.str())); 1366234353Sdim } 1367226584Sdim 1368234353Sdim const RecordVal *getValue(const Init *Name) const { 1369226584Sdim for (unsigned i = 0, e = Values.size(); i != e; ++i) 1370234353Sdim if (Values[i].getNameInit() == Name) return &Values[i]; 1371226584Sdim return 0; 1372226584Sdim } 1373234353Sdim const RecordVal *getValue(StringRef Name) const { 1374234353Sdim return getValue(StringInit::get(Name)); 1375234353Sdim } 1376234353Sdim RecordVal *getValue(const Init *Name) { 1377226584Sdim for (unsigned i = 0, e = Values.size(); i != e; ++i) 1378234353Sdim if (Values[i].getNameInit() == Name) return &Values[i]; 1379226584Sdim return 0; 1380226584Sdim } 1381234353Sdim RecordVal *getValue(StringRef Name) { 1382234353Sdim return getValue(StringInit::get(Name)); 1383234353Sdim } 1384226584Sdim 1385234353Sdim void addTemplateArg(Init *Name) { 1386226584Sdim assert(!isTemplateArg(Name) && "Template arg already defined!"); 1387226584Sdim TemplateArgs.push_back(Name); 1388226584Sdim } 1389234353Sdim void addTemplateArg(StringRef Name) { 1390234353Sdim addTemplateArg(StringInit::get(Name.str())); 1391234353Sdim } 1392226584Sdim 1393226584Sdim void addValue(const RecordVal &RV) { 1394234353Sdim assert(getValue(RV.getNameInit()) == 0 && "Value already added!"); 1395226584Sdim Values.push_back(RV); 1396234353Sdim if (Values.size() > 1) 1397234353Sdim // Keep NAME at the end of the list. It makes record dumps a 1398234353Sdim // bit prettier and allows TableGen tests to be written more 1399234353Sdim // naturally. Tests can use CHECK-NEXT to look for Record 1400234353Sdim // fields they expect to see after a def. They can't do that if 1401234353Sdim // NAME is the first Record field. 1402234353Sdim std::swap(Values[Values.size() - 2], Values[Values.size() - 1]); 1403226584Sdim } 1404226584Sdim 1405234353Sdim void removeValue(Init *Name) { 1406226584Sdim for (unsigned i = 0, e = Values.size(); i != e; ++i) 1407234353Sdim if (Values[i].getNameInit() == Name) { 1408226584Sdim Values.erase(Values.begin()+i); 1409226584Sdim return; 1410226584Sdim } 1411234353Sdim llvm_unreachable("Cannot remove an entry that does not exist!"); 1412226584Sdim } 1413226584Sdim 1414234353Sdim void removeValue(StringRef Name) { 1415234353Sdim removeValue(StringInit::get(Name.str())); 1416234353Sdim } 1417234353Sdim 1418226584Sdim bool isSubClassOf(const Record *R) const { 1419226584Sdim for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) 1420226584Sdim if (SuperClasses[i] == R) 1421226584Sdim return true; 1422226584Sdim return false; 1423226584Sdim } 1424226584Sdim 1425226584Sdim bool isSubClassOf(StringRef Name) const { 1426226584Sdim for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) 1427234353Sdim if (SuperClasses[i]->getNameInitAsString() == Name) 1428226584Sdim return true; 1429226584Sdim return false; 1430226584Sdim } 1431226584Sdim 1432226584Sdim void addSuperClass(Record *R) { 1433226584Sdim assert(!isSubClassOf(R) && "Already subclassing record!"); 1434226584Sdim SuperClasses.push_back(R); 1435226584Sdim } 1436226584Sdim 1437226584Sdim /// resolveReferences - If there are any field references that refer to fields 1438226584Sdim /// that have been filled in, we can propagate the values now. 1439226584Sdim /// 1440226584Sdim void resolveReferences() { resolveReferencesTo(0); } 1441226584Sdim 1442226584Sdim /// resolveReferencesTo - If anything in this record refers to RV, replace the 1443226584Sdim /// reference to RV with the RHS of RV. If RV is null, we resolve all 1444226584Sdim /// possible references. 1445226584Sdim void resolveReferencesTo(const RecordVal *RV); 1446226584Sdim 1447226584Sdim RecordKeeper &getRecords() const { 1448226584Sdim return TrackedRecords; 1449226584Sdim } 1450226584Sdim 1451226584Sdim void dump() const; 1452226584Sdim 1453226584Sdim //===--------------------------------------------------------------------===// 1454226584Sdim // High-level methods useful to tablegen back-ends 1455226584Sdim // 1456226584Sdim 1457226584Sdim /// getValueInit - Return the initializer for a value with the specified name, 1458226584Sdim /// or throw an exception if the field does not exist. 1459226584Sdim /// 1460226584Sdim Init *getValueInit(StringRef FieldName) const; 1461226584Sdim 1462226584Sdim /// getValueAsString - This method looks up the specified field and returns 1463226584Sdim /// its value as a string, throwing an exception if the field does not exist 1464226584Sdim /// or if the value is not a string. 1465226584Sdim /// 1466226584Sdim std::string getValueAsString(StringRef FieldName) const; 1467226584Sdim 1468226584Sdim /// getValueAsBitsInit - This method looks up the specified field and returns 1469226584Sdim /// its value as a BitsInit, throwing an exception if the field does not exist 1470226584Sdim /// or if the value is not the right type. 1471226584Sdim /// 1472226584Sdim BitsInit *getValueAsBitsInit(StringRef FieldName) const; 1473226584Sdim 1474226584Sdim /// getValueAsListInit - This method looks up the specified field and returns 1475226584Sdim /// its value as a ListInit, throwing an exception if the field does not exist 1476226584Sdim /// or if the value is not the right type. 1477226584Sdim /// 1478226584Sdim ListInit *getValueAsListInit(StringRef FieldName) const; 1479226584Sdim 1480226584Sdim /// getValueAsListOfDefs - This method looks up the specified field and 1481226584Sdim /// returns its value as a vector of records, throwing an exception if the 1482226584Sdim /// field does not exist or if the value is not the right type. 1483226584Sdim /// 1484226584Sdim std::vector<Record*> getValueAsListOfDefs(StringRef FieldName) const; 1485226584Sdim 1486226584Sdim /// getValueAsListOfInts - This method looks up the specified field and 1487226584Sdim /// returns its value as a vector of integers, throwing an exception if the 1488226584Sdim /// field does not exist or if the value is not the right type. 1489226584Sdim /// 1490226584Sdim std::vector<int64_t> getValueAsListOfInts(StringRef FieldName) const; 1491226584Sdim 1492226584Sdim /// getValueAsListOfStrings - This method looks up the specified field and 1493226584Sdim /// returns its value as a vector of strings, throwing an exception if the 1494226584Sdim /// field does not exist or if the value is not the right type. 1495226584Sdim /// 1496226584Sdim std::vector<std::string> getValueAsListOfStrings(StringRef FieldName) const; 1497226584Sdim 1498226584Sdim /// getValueAsDef - This method looks up the specified field and returns its 1499226584Sdim /// value as a Record, throwing an exception if the field does not exist or if 1500226584Sdim /// the value is not the right type. 1501226584Sdim /// 1502226584Sdim Record *getValueAsDef(StringRef FieldName) const; 1503226584Sdim 1504226584Sdim /// getValueAsBit - This method looks up the specified field and returns its 1505226584Sdim /// value as a bit, throwing an exception if the field does not exist or if 1506226584Sdim /// the value is not the right type. 1507226584Sdim /// 1508226584Sdim bool getValueAsBit(StringRef FieldName) const; 1509226584Sdim 1510226584Sdim /// getValueAsInt - This method looks up the specified field and returns its 1511226584Sdim /// value as an int64_t, throwing an exception if the field does not exist or 1512226584Sdim /// if the value is not the right type. 1513226584Sdim /// 1514226584Sdim int64_t getValueAsInt(StringRef FieldName) const; 1515226584Sdim 1516226584Sdim /// getValueAsDag - This method looks up the specified field and returns its 1517226584Sdim /// value as an Dag, throwing an exception if the field does not exist or if 1518226584Sdim /// the value is not the right type. 1519226584Sdim /// 1520226584Sdim DagInit *getValueAsDag(StringRef FieldName) const; 1521226584Sdim}; 1522226584Sdim 1523226584Sdimraw_ostream &operator<<(raw_ostream &OS, const Record &R); 1524226584Sdim 1525226584Sdimstruct MultiClass { 1526226584Sdim Record Rec; // Placeholder for template args and Name. 1527226584Sdim typedef std::vector<Record*> RecordVector; 1528226584Sdim RecordVector DefPrototypes; 1529226584Sdim 1530226584Sdim void dump() const; 1531226584Sdim 1532234982Sdim MultiClass(const std::string &Name, SMLoc Loc, RecordKeeper &Records) : 1533226584Sdim Rec(Name, Loc, Records) {} 1534226584Sdim}; 1535226584Sdim 1536226584Sdimclass RecordKeeper { 1537226584Sdim std::map<std::string, Record*> Classes, Defs; 1538234353Sdim 1539226584Sdimpublic: 1540226584Sdim ~RecordKeeper() { 1541226584Sdim for (std::map<std::string, Record*>::iterator I = Classes.begin(), 1542226584Sdim E = Classes.end(); I != E; ++I) 1543226584Sdim delete I->second; 1544226584Sdim for (std::map<std::string, Record*>::iterator I = Defs.begin(), 1545226584Sdim E = Defs.end(); I != E; ++I) 1546226584Sdim delete I->second; 1547226584Sdim } 1548226584Sdim 1549226584Sdim const std::map<std::string, Record*> &getClasses() const { return Classes; } 1550226584Sdim const std::map<std::string, Record*> &getDefs() const { return Defs; } 1551226584Sdim 1552226584Sdim Record *getClass(const std::string &Name) const { 1553226584Sdim std::map<std::string, Record*>::const_iterator I = Classes.find(Name); 1554226584Sdim return I == Classes.end() ? 0 : I->second; 1555226584Sdim } 1556226584Sdim Record *getDef(const std::string &Name) const { 1557226584Sdim std::map<std::string, Record*>::const_iterator I = Defs.find(Name); 1558226584Sdim return I == Defs.end() ? 0 : I->second; 1559226584Sdim } 1560226584Sdim void addClass(Record *R) { 1561239462Sdim bool Ins = Classes.insert(std::make_pair(R->getName(), R)).second; 1562239462Sdim (void)Ins; 1563239462Sdim assert(Ins && "Class already exists"); 1564226584Sdim } 1565226584Sdim void addDef(Record *R) { 1566239462Sdim bool Ins = Defs.insert(std::make_pair(R->getName(), R)).second; 1567239462Sdim (void)Ins; 1568239462Sdim assert(Ins && "Record already exists"); 1569226584Sdim } 1570226584Sdim 1571226584Sdim /// removeClass - Remove, but do not delete, the specified record. 1572226584Sdim /// 1573226584Sdim void removeClass(const std::string &Name) { 1574226584Sdim assert(Classes.count(Name) && "Class does not exist!"); 1575226584Sdim Classes.erase(Name); 1576226584Sdim } 1577226584Sdim /// removeDef - Remove, but do not delete, the specified record. 1578226584Sdim /// 1579226584Sdim void removeDef(const std::string &Name) { 1580226584Sdim assert(Defs.count(Name) && "Def does not exist!"); 1581226584Sdim Defs.erase(Name); 1582226584Sdim } 1583226584Sdim 1584226584Sdim //===--------------------------------------------------------------------===// 1585226584Sdim // High-level helper methods, useful for tablegen backends... 1586226584Sdim 1587226584Sdim /// getAllDerivedDefinitions - This method returns all concrete definitions 1588226584Sdim /// that derive from the specified class name. If a class with the specified 1589226584Sdim /// name does not exist, an exception is thrown. 1590226584Sdim std::vector<Record*> 1591226584Sdim getAllDerivedDefinitions(const std::string &ClassName) const; 1592226584Sdim 1593226584Sdim void dump() const; 1594226584Sdim}; 1595226584Sdim 1596226584Sdim/// LessRecord - Sorting predicate to sort record pointers by name. 1597226584Sdim/// 1598226584Sdimstruct LessRecord { 1599226584Sdim bool operator()(const Record *Rec1, const Record *Rec2) const { 1600226584Sdim return StringRef(Rec1->getName()).compare_numeric(Rec2->getName()) < 0; 1601226584Sdim } 1602226584Sdim}; 1603226584Sdim 1604226584Sdim/// LessRecordFieldName - Sorting predicate to sort record pointers by their 1605226584Sdim/// name field. 1606226584Sdim/// 1607226584Sdimstruct LessRecordFieldName { 1608226584Sdim bool operator()(const Record *Rec1, const Record *Rec2) const { 1609226584Sdim return Rec1->getValueAsString("Name") < Rec2->getValueAsString("Name"); 1610226584Sdim } 1611226584Sdim}; 1612226584Sdim 1613226584Sdimraw_ostream &operator<<(raw_ostream &OS, const RecordKeeper &RK); 1614226584Sdim 1615234353Sdim/// QualifyName - Return an Init with a qualifier prefix referring 1616234353Sdim/// to CurRec's name. 1617234353SdimInit *QualifyName(Record &CurRec, MultiClass *CurMultiClass, 1618234353Sdim Init *Name, const std::string &Scoper); 1619234353Sdim 1620234353Sdim/// QualifyName - Return an Init with a qualifier prefix referring 1621234353Sdim/// to CurRec's name. 1622234353SdimInit *QualifyName(Record &CurRec, MultiClass *CurMultiClass, 1623234353Sdim const std::string &Name, const std::string &Scoper); 1624234353Sdim 1625226584Sdim} // End llvm namespace 1626226584Sdim 1627226584Sdim#endif 1628