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" 21243830Sdim#include "llvm/Support/Casting.h" 22226584Sdim#include "llvm/Support/DataTypes.h" 23234353Sdim#include "llvm/Support/ErrorHandling.h" 24249423Sdim#include "llvm/Support/SourceMgr.h" 25226584Sdim#include "llvm/Support/raw_ostream.h" 26226584Sdim#include <map> 27226584Sdim 28226584Sdimnamespace llvm { 29226584Sdimclass raw_ostream; 30226584Sdim 31226584Sdim// RecTy subclasses. 32226584Sdimclass BitRecTy; 33226584Sdimclass BitsRecTy; 34226584Sdimclass IntRecTy; 35226584Sdimclass StringRecTy; 36226584Sdimclass ListRecTy; 37226584Sdimclass DagRecTy; 38226584Sdimclass RecordRecTy; 39226584Sdim 40226584Sdim// Init subclasses. 41226584Sdimclass Init; 42226584Sdimclass UnsetInit; 43226584Sdimclass BitInit; 44226584Sdimclass BitsInit; 45226584Sdimclass IntInit; 46226584Sdimclass StringInit; 47226584Sdimclass ListInit; 48226584Sdimclass UnOpInit; 49226584Sdimclass BinOpInit; 50226584Sdimclass TernOpInit; 51226584Sdimclass DefInit; 52226584Sdimclass DagInit; 53226584Sdimclass TypedInit; 54226584Sdimclass VarInit; 55226584Sdimclass FieldInit; 56226584Sdimclass VarBitInit; 57226584Sdimclass VarListElementInit; 58226584Sdim 59226584Sdim// Other classes. 60226584Sdimclass Record; 61226584Sdimclass RecordVal; 62226584Sdimstruct MultiClass; 63226584Sdimclass RecordKeeper; 64226584Sdim 65226584Sdim//===----------------------------------------------------------------------===// 66226584Sdim// Type Classes 67226584Sdim//===----------------------------------------------------------------------===// 68226584Sdim 69226584Sdimclass RecTy { 70243830Sdimpublic: 71243830Sdim /// \brief Subclass discriminator (for dyn_cast<> et al.) 72243830Sdim enum RecTyKind { 73243830Sdim BitRecTyKind, 74243830Sdim BitsRecTyKind, 75243830Sdim IntRecTyKind, 76243830Sdim StringRecTyKind, 77243830Sdim ListRecTyKind, 78243830Sdim DagRecTyKind, 79243830Sdim RecordRecTyKind 80243830Sdim }; 81243830Sdim 82243830Sdimprivate: 83243830Sdim RecTyKind Kind; 84226584Sdim ListRecTy *ListTy; 85234353Sdim virtual void anchor(); 86243830Sdim 87226584Sdimpublic: 88243830Sdim RecTyKind getRecTyKind() const { return Kind; } 89243830Sdim 90243830Sdim RecTy(RecTyKind K) : Kind(K), ListTy(0) {} 91226584Sdim virtual ~RecTy() {} 92226584Sdim 93226584Sdim virtual std::string getAsString() const = 0; 94226584Sdim void print(raw_ostream &OS) const { OS << getAsString(); } 95226584Sdim void dump() const; 96226584Sdim 97226584Sdim /// typeIsConvertibleTo - Return true if all values of 'this' type can be 98226584Sdim /// converted to the specified type. 99226584Sdim virtual bool typeIsConvertibleTo(const RecTy *RHS) const = 0; 100226584Sdim 101226584Sdim /// getListTy - Returns the type representing list<this>. 102226584Sdim ListRecTy *getListTy(); 103226584Sdim 104226584Sdimpublic: // These methods should only be called from subclasses of Init 105226584Sdim virtual Init *convertValue( UnsetInit *UI) { return 0; } 106226584Sdim virtual Init *convertValue( BitInit *BI) { return 0; } 107226584Sdim virtual Init *convertValue( BitsInit *BI) { return 0; } 108226584Sdim virtual Init *convertValue( IntInit *II) { return 0; } 109226584Sdim virtual Init *convertValue(StringInit *SI) { return 0; } 110226584Sdim virtual Init *convertValue( ListInit *LI) { return 0; } 111226584Sdim virtual Init *convertValue( UnOpInit *UI) { 112226584Sdim return convertValue((TypedInit*)UI); 113226584Sdim } 114226584Sdim virtual Init *convertValue( BinOpInit *UI) { 115226584Sdim return convertValue((TypedInit*)UI); 116226584Sdim } 117226584Sdim virtual Init *convertValue( TernOpInit *UI) { 118226584Sdim return convertValue((TypedInit*)UI); 119226584Sdim } 120226584Sdim virtual Init *convertValue(VarBitInit *VB) { return 0; } 121226584Sdim virtual Init *convertValue( DefInit *DI) { return 0; } 122226584Sdim virtual Init *convertValue( DagInit *DI) { return 0; } 123226584Sdim virtual Init *convertValue( TypedInit *TI) { return 0; } 124226584Sdim virtual Init *convertValue( VarInit *VI) { 125226584Sdim return convertValue((TypedInit*)VI); 126226584Sdim } 127226584Sdim virtual Init *convertValue( FieldInit *FI) { 128226584Sdim return convertValue((TypedInit*)FI); 129226584Sdim } 130226584Sdim 131249423Sdimpublic: 132249423Sdim virtual bool baseClassOf(const RecTy*) const; 133226584Sdim}; 134226584Sdim 135226584Sdiminline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) { 136226584Sdim Ty.print(OS); 137226584Sdim return OS; 138226584Sdim} 139226584Sdim 140226584Sdim 141226584Sdim/// BitRecTy - 'bit' - Represent a single bit 142226584Sdim/// 143226584Sdimclass BitRecTy : public RecTy { 144226584Sdim static BitRecTy Shared; 145243830Sdim BitRecTy() : RecTy(BitRecTyKind) {} 146226584Sdimpublic: 147243830Sdim static bool classof(const RecTy *RT) { 148243830Sdim return RT->getRecTyKind() == BitRecTyKind; 149243830Sdim } 150243830Sdim 151226584Sdim static BitRecTy *get() { return &Shared; } 152226584Sdim 153226584Sdim virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } 154226584Sdim virtual Init *convertValue( BitInit *BI) { return (Init*)BI; } 155226584Sdim virtual Init *convertValue( BitsInit *BI); 156226584Sdim virtual Init *convertValue( IntInit *II); 157226584Sdim virtual Init *convertValue(StringInit *SI) { return 0; } 158226584Sdim virtual Init *convertValue( ListInit *LI) { return 0; } 159226584Sdim virtual Init *convertValue(VarBitInit *VB) { return (Init*)VB; } 160226584Sdim virtual Init *convertValue( DefInit *DI) { return 0; } 161226584Sdim virtual Init *convertValue( DagInit *DI) { return 0; } 162226584Sdim virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);} 163226584Sdim virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);} 164226584Sdim virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);} 165226584Sdim virtual Init *convertValue( TypedInit *TI); 166226584Sdim virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} 167226584Sdim virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} 168226584Sdim 169243830Sdim virtual std::string getAsString() const { return "bit"; } 170226584Sdim 171243830Sdim virtual bool typeIsConvertibleTo(const RecTy *RHS) const { 172226584Sdim return RHS->baseClassOf(this); 173226584Sdim } 174249423Sdim virtual bool baseClassOf(const RecTy*) const; 175226584Sdim}; 176226584Sdim 177226584Sdim 178249423Sdim/// BitsRecTy - 'bits<n>' - Represent a fixed number of bits 179226584Sdim/// 180226584Sdimclass BitsRecTy : public RecTy { 181226584Sdim unsigned Size; 182243830Sdim explicit BitsRecTy(unsigned Sz) : RecTy(BitsRecTyKind), Size(Sz) {} 183226584Sdimpublic: 184243830Sdim static bool classof(const RecTy *RT) { 185243830Sdim return RT->getRecTyKind() == BitsRecTyKind; 186243830Sdim } 187243830Sdim 188226584Sdim static BitsRecTy *get(unsigned Sz); 189226584Sdim 190226584Sdim unsigned getNumBits() const { return Size; } 191226584Sdim 192226584Sdim virtual Init *convertValue( UnsetInit *UI); 193226584Sdim virtual Init *convertValue( BitInit *UI); 194226584Sdim virtual Init *convertValue( BitsInit *BI); 195226584Sdim virtual Init *convertValue( IntInit *II); 196226584Sdim virtual Init *convertValue(StringInit *SI) { return 0; } 197226584Sdim virtual Init *convertValue( ListInit *LI) { return 0; } 198226584Sdim virtual Init *convertValue(VarBitInit *VB) { return 0; } 199226584Sdim virtual Init *convertValue( DefInit *DI) { return 0; } 200226584Sdim virtual Init *convertValue( DagInit *DI) { return 0; } 201226584Sdim virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);} 202226584Sdim virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);} 203226584Sdim virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);} 204226584Sdim virtual Init *convertValue( TypedInit *TI); 205226584Sdim virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} 206226584Sdim virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} 207226584Sdim 208243830Sdim virtual std::string getAsString() const; 209226584Sdim 210243830Sdim virtual bool typeIsConvertibleTo(const RecTy *RHS) const { 211226584Sdim return RHS->baseClassOf(this); 212226584Sdim } 213249423Sdim virtual bool baseClassOf(const RecTy*) const; 214226584Sdim}; 215226584Sdim 216226584Sdim 217226584Sdim/// IntRecTy - 'int' - Represent an integer value of no particular size 218226584Sdim/// 219226584Sdimclass IntRecTy : public RecTy { 220226584Sdim static IntRecTy Shared; 221243830Sdim IntRecTy() : RecTy(IntRecTyKind) {} 222226584Sdimpublic: 223243830Sdim static bool classof(const RecTy *RT) { 224243830Sdim return RT->getRecTyKind() == IntRecTyKind; 225243830Sdim } 226243830Sdim 227226584Sdim static IntRecTy *get() { return &Shared; } 228226584Sdim 229226584Sdim virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } 230226584Sdim virtual Init *convertValue( BitInit *BI); 231226584Sdim virtual Init *convertValue( BitsInit *BI); 232226584Sdim virtual Init *convertValue( IntInit *II) { return (Init*)II; } 233226584Sdim virtual Init *convertValue(StringInit *SI) { return 0; } 234226584Sdim virtual Init *convertValue( ListInit *LI) { return 0; } 235226584Sdim virtual Init *convertValue(VarBitInit *VB) { return 0; } 236226584Sdim virtual Init *convertValue( DefInit *DI) { return 0; } 237226584Sdim virtual Init *convertValue( DagInit *DI) { return 0; } 238226584Sdim virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);} 239226584Sdim virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);} 240226584Sdim virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);} 241226584Sdim virtual Init *convertValue( TypedInit *TI); 242226584Sdim virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} 243226584Sdim virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} 244226584Sdim 245243830Sdim virtual std::string getAsString() const { return "int"; } 246226584Sdim 247243830Sdim virtual bool typeIsConvertibleTo(const RecTy *RHS) const { 248226584Sdim return RHS->baseClassOf(this); 249226584Sdim } 250226584Sdim 251249423Sdim virtual bool baseClassOf(const RecTy*) const; 252226584Sdim}; 253226584Sdim 254226584Sdim/// StringRecTy - 'string' - Represent an string value 255226584Sdim/// 256226584Sdimclass StringRecTy : public RecTy { 257226584Sdim static StringRecTy Shared; 258243830Sdim StringRecTy() : RecTy(StringRecTyKind) {} 259226584Sdimpublic: 260243830Sdim static bool classof(const RecTy *RT) { 261243830Sdim return RT->getRecTyKind() == StringRecTyKind; 262243830Sdim } 263243830Sdim 264226584Sdim static StringRecTy *get() { return &Shared; } 265226584Sdim 266226584Sdim virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } 267226584Sdim virtual Init *convertValue( BitInit *BI) { return 0; } 268226584Sdim virtual Init *convertValue( BitsInit *BI) { return 0; } 269226584Sdim virtual Init *convertValue( IntInit *II) { return 0; } 270226584Sdim virtual Init *convertValue(StringInit *SI) { return (Init*)SI; } 271226584Sdim virtual Init *convertValue( ListInit *LI) { return 0; } 272226584Sdim virtual Init *convertValue( UnOpInit *BO); 273226584Sdim virtual Init *convertValue( BinOpInit *BO); 274226584Sdim virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);} 275226584Sdim 276226584Sdim virtual Init *convertValue(VarBitInit *VB) { return 0; } 277226584Sdim virtual Init *convertValue( DefInit *DI) { return 0; } 278226584Sdim virtual Init *convertValue( DagInit *DI) { return 0; } 279226584Sdim virtual Init *convertValue( TypedInit *TI); 280226584Sdim virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} 281226584Sdim virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} 282226584Sdim 283243830Sdim virtual std::string getAsString() const { return "string"; } 284226584Sdim 285243830Sdim virtual bool typeIsConvertibleTo(const RecTy *RHS) const { 286226584Sdim return RHS->baseClassOf(this); 287226584Sdim } 288226584Sdim}; 289226584Sdim 290249423Sdim/// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must be of 291249423Sdim/// the specified type. 292226584Sdim/// 293226584Sdimclass ListRecTy : public RecTy { 294226584Sdim RecTy *Ty; 295243830Sdim explicit ListRecTy(RecTy *T) : RecTy(ListRecTyKind), Ty(T) {} 296226584Sdim friend ListRecTy *RecTy::getListTy(); 297226584Sdimpublic: 298243830Sdim static bool classof(const RecTy *RT) { 299243830Sdim return RT->getRecTyKind() == ListRecTyKind; 300243830Sdim } 301243830Sdim 302226584Sdim static ListRecTy *get(RecTy *T) { return T->getListTy(); } 303226584Sdim RecTy *getElementType() const { return Ty; } 304226584Sdim 305226584Sdim virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } 306226584Sdim virtual Init *convertValue( BitInit *BI) { return 0; } 307226584Sdim virtual Init *convertValue( BitsInit *BI) { return 0; } 308226584Sdim virtual Init *convertValue( IntInit *II) { return 0; } 309226584Sdim virtual Init *convertValue(StringInit *SI) { return 0; } 310226584Sdim virtual Init *convertValue( ListInit *LI); 311226584Sdim virtual Init *convertValue(VarBitInit *VB) { return 0; } 312226584Sdim virtual Init *convertValue( DefInit *DI) { return 0; } 313226584Sdim virtual Init *convertValue( DagInit *DI) { return 0; } 314226584Sdim virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);} 315226584Sdim virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);} 316226584Sdim virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);} 317226584Sdim virtual Init *convertValue( TypedInit *TI); 318226584Sdim virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} 319226584Sdim virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} 320226584Sdim 321243830Sdim virtual std::string getAsString() const; 322226584Sdim 323243830Sdim virtual bool typeIsConvertibleTo(const RecTy *RHS) const { 324226584Sdim return RHS->baseClassOf(this); 325226584Sdim } 326226584Sdim 327249423Sdim virtual bool baseClassOf(const RecTy*) const; 328226584Sdim}; 329226584Sdim 330226584Sdim/// DagRecTy - 'dag' - Represent a dag fragment 331226584Sdim/// 332226584Sdimclass DagRecTy : public RecTy { 333226584Sdim static DagRecTy Shared; 334243830Sdim DagRecTy() : RecTy(DagRecTyKind) {} 335226584Sdimpublic: 336243830Sdim static bool classof(const RecTy *RT) { 337243830Sdim return RT->getRecTyKind() == DagRecTyKind; 338243830Sdim } 339243830Sdim 340226584Sdim static DagRecTy *get() { return &Shared; } 341226584Sdim 342226584Sdim virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } 343226584Sdim virtual Init *convertValue( BitInit *BI) { return 0; } 344226584Sdim virtual Init *convertValue( BitsInit *BI) { return 0; } 345226584Sdim virtual Init *convertValue( IntInit *II) { return 0; } 346226584Sdim virtual Init *convertValue(StringInit *SI) { return 0; } 347226584Sdim virtual Init *convertValue( ListInit *LI) { return 0; } 348226584Sdim virtual Init *convertValue(VarBitInit *VB) { return 0; } 349226584Sdim virtual Init *convertValue( DefInit *DI) { return 0; } 350226584Sdim virtual Init *convertValue( UnOpInit *BO); 351226584Sdim virtual Init *convertValue( BinOpInit *BO); 352226584Sdim virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);} 353226584Sdim virtual Init *convertValue( DagInit *CI) { return (Init*)CI; } 354226584Sdim virtual Init *convertValue( TypedInit *TI); 355226584Sdim virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} 356226584Sdim virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} 357226584Sdim 358243830Sdim virtual std::string getAsString() const { return "dag"; } 359226584Sdim 360243830Sdim virtual bool typeIsConvertibleTo(const RecTy *RHS) const { 361226584Sdim return RHS->baseClassOf(this); 362226584Sdim } 363226584Sdim}; 364226584Sdim 365226584Sdim 366226584Sdim/// RecordRecTy - '[classname]' - Represent an instance of a class, such as: 367226584Sdim/// (R32 X = EAX). 368226584Sdim/// 369226584Sdimclass RecordRecTy : public RecTy { 370226584Sdim Record *Rec; 371243830Sdim explicit RecordRecTy(Record *R) : RecTy(RecordRecTyKind), Rec(R) {} 372226584Sdim friend class Record; 373226584Sdimpublic: 374243830Sdim static bool classof(const RecTy *RT) { 375243830Sdim return RT->getRecTyKind() == RecordRecTyKind; 376243830Sdim } 377243830Sdim 378226584Sdim static RecordRecTy *get(Record *R); 379226584Sdim 380226584Sdim Record *getRecord() const { return Rec; } 381226584Sdim 382226584Sdim virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } 383226584Sdim virtual Init *convertValue( BitInit *BI) { return 0; } 384226584Sdim virtual Init *convertValue( BitsInit *BI) { return 0; } 385226584Sdim virtual Init *convertValue( IntInit *II) { return 0; } 386226584Sdim virtual Init *convertValue(StringInit *SI) { return 0; } 387226584Sdim virtual Init *convertValue( ListInit *LI) { return 0; } 388226584Sdim virtual Init *convertValue(VarBitInit *VB) { return 0; } 389226584Sdim virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);} 390226584Sdim virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);} 391226584Sdim virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);} 392226584Sdim virtual Init *convertValue( DefInit *DI); 393226584Sdim virtual Init *convertValue( DagInit *DI) { return 0; } 394226584Sdim virtual Init *convertValue( TypedInit *VI); 395226584Sdim virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);} 396226584Sdim virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} 397226584Sdim 398243830Sdim virtual std::string getAsString() const; 399226584Sdim 400243830Sdim virtual bool typeIsConvertibleTo(const RecTy *RHS) const { 401226584Sdim return RHS->baseClassOf(this); 402226584Sdim } 403249423Sdim virtual bool baseClassOf(const RecTy*) const; 404226584Sdim}; 405226584Sdim 406226584Sdim/// resolveTypes - Find a common type that T1 and T2 convert to. 407226584Sdim/// Return 0 if no such type exists. 408226584Sdim/// 409226584SdimRecTy *resolveTypes(RecTy *T1, RecTy *T2); 410226584Sdim 411226584Sdim//===----------------------------------------------------------------------===// 412226584Sdim// Initializer Classes 413226584Sdim//===----------------------------------------------------------------------===// 414226584Sdim 415226584Sdimclass Init { 416243830Sdimprotected: 417243830Sdim /// \brief Discriminator enum (for isa<>, dyn_cast<>, et al.) 418243830Sdim /// 419243830Sdim /// This enum is laid out by a preorder traversal of the inheritance 420243830Sdim /// hierarchy, and does not contain an entry for abstract classes, as per 421243830Sdim /// the recommendation in docs/HowToSetUpLLVMStyleRTTI.rst. 422243830Sdim /// 423243830Sdim /// We also explicitly include "first" and "last" values for each 424243830Sdim /// interior node of the inheritance tree, to make it easier to read the 425243830Sdim /// corresponding classof(). 426243830Sdim /// 427243830Sdim /// We could pack these a bit tighter by not having the IK_FirstXXXInit 428243830Sdim /// and IK_LastXXXInit be their own values, but that would degrade 429243830Sdim /// readability for really no benefit. 430243830Sdim enum InitKind { 431243830Sdim IK_BitInit, 432243830Sdim IK_BitsInit, 433243830Sdim IK_FirstTypedInit, 434243830Sdim IK_DagInit, 435243830Sdim IK_DefInit, 436243830Sdim IK_FieldInit, 437243830Sdim IK_IntInit, 438243830Sdim IK_ListInit, 439243830Sdim IK_FirstOpInit, 440243830Sdim IK_BinOpInit, 441243830Sdim IK_TernOpInit, 442243830Sdim IK_UnOpInit, 443243830Sdim IK_LastOpInit, 444243830Sdim IK_StringInit, 445243830Sdim IK_VarInit, 446243830Sdim IK_VarListElementInit, 447243830Sdim IK_LastTypedInit, 448243830Sdim IK_UnsetInit, 449243830Sdim IK_VarBitInit 450243830Sdim }; 451243830Sdim 452243830Sdimprivate: 453243830Sdim const InitKind Kind; 454243830Sdim Init(const Init &) LLVM_DELETED_FUNCTION; 455243830Sdim Init &operator=(const Init &) LLVM_DELETED_FUNCTION; 456234353Sdim virtual void anchor(); 457226584Sdim 458243830Sdimpublic: 459243830Sdim InitKind getKind() const { return Kind; } 460243830Sdim 461226584Sdimprotected: 462243830Sdim explicit Init(InitKind K) : Kind(K) {} 463226584Sdim 464226584Sdimpublic: 465226584Sdim virtual ~Init() {} 466226584Sdim 467226584Sdim /// isComplete - This virtual method should be overridden by values that may 468226584Sdim /// not be completely specified yet. 469226584Sdim virtual bool isComplete() const { return true; } 470226584Sdim 471226584Sdim /// print - Print out this value. 472226584Sdim void print(raw_ostream &OS) const { OS << getAsString(); } 473226584Sdim 474226584Sdim /// getAsString - Convert this value to a string form. 475226584Sdim virtual std::string getAsString() const = 0; 476226584Sdim /// getAsUnquotedString - Convert this value to a string form, 477226584Sdim /// without adding quote markers. This primaruly affects 478226584Sdim /// StringInits where we will not surround the string value with 479226584Sdim /// quotes. 480234982Sdim virtual std::string getAsUnquotedString() const { return getAsString(); } 481226584Sdim 482226584Sdim /// dump - Debugging method that may be called through a debugger, just 483226584Sdim /// invokes print on stderr. 484226584Sdim void dump() const; 485226584Sdim 486226584Sdim /// convertInitializerTo - This virtual function is a simple call-back 487226584Sdim /// function that should be overridden to call the appropriate 488226584Sdim /// RecTy::convertValue method. 489226584Sdim /// 490226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const = 0; 491226584Sdim 492226584Sdim /// convertInitializerBitRange - This method is used to implement the bitrange 493226584Sdim /// selection operator. Given an initializer, it selects the specified bits 494226584Sdim /// out, returning them as a new init of bits type. If it is not legal to use 495226584Sdim /// the bit subscript operator on this initializer, return null. 496226584Sdim /// 497226584Sdim virtual Init * 498226584Sdim convertInitializerBitRange(const std::vector<unsigned> &Bits) const { 499226584Sdim return 0; 500226584Sdim } 501226584Sdim 502226584Sdim /// convertInitListSlice - This method is used to implement the list slice 503226584Sdim /// selection operator. Given an initializer, it selects the specified list 504226584Sdim /// elements, returning them as a new init of list type. If it is not legal 505226584Sdim /// to take a slice of this, return null. 506226584Sdim /// 507226584Sdim virtual Init * 508226584Sdim convertInitListSlice(const std::vector<unsigned> &Elements) const { 509226584Sdim return 0; 510226584Sdim } 511226584Sdim 512226584Sdim /// getFieldType - This method is used to implement the FieldInit class. 513226584Sdim /// Implementors of this method should return the type of the named field if 514226584Sdim /// they are of record type. 515226584Sdim /// 516226584Sdim virtual RecTy *getFieldType(const std::string &FieldName) const { return 0; } 517226584Sdim 518226584Sdim /// getFieldInit - This method complements getFieldType to return the 519226584Sdim /// initializer for the specified field. If getFieldType returns non-null 520226584Sdim /// this method should return non-null, otherwise it returns null. 521226584Sdim /// 522226584Sdim virtual Init *getFieldInit(Record &R, const RecordVal *RV, 523226584Sdim const std::string &FieldName) const { 524226584Sdim return 0; 525226584Sdim } 526226584Sdim 527226584Sdim /// resolveReferences - This method is used by classes that refer to other 528226584Sdim /// variables which may not be defined at the time the expression is formed. 529226584Sdim /// If a value is set for the variable later, this method will be called on 530226584Sdim /// users of the value to allow the value to propagate out. 531226584Sdim /// 532226584Sdim virtual Init *resolveReferences(Record &R, const RecordVal *RV) const { 533226584Sdim return const_cast<Init *>(this); 534226584Sdim } 535243830Sdim 536243830Sdim /// getBit - This method is used to return the initializer for the specified 537243830Sdim /// bit. 538243830Sdim virtual Init *getBit(unsigned Bit) const = 0; 539243830Sdim 540243830Sdim /// getBitVar - This method is used to retrieve the initializer for bit 541243830Sdim /// reference. For non-VarBitInit, it simply returns itself. 542243830Sdim virtual Init *getBitVar() const { return const_cast<Init*>(this); } 543243830Sdim 544243830Sdim /// getBitNum - This method is used to retrieve the bit number of a bit 545243830Sdim /// reference. For non-VarBitInit, it simply returns 0. 546243830Sdim virtual unsigned getBitNum() const { return 0; } 547226584Sdim}; 548226584Sdim 549226584Sdiminline raw_ostream &operator<<(raw_ostream &OS, const Init &I) { 550226584Sdim I.print(OS); return OS; 551226584Sdim} 552226584Sdim 553226584Sdim/// TypedInit - This is the common super-class of types that have a specific, 554226584Sdim/// explicit, type. 555226584Sdim/// 556226584Sdimclass TypedInit : public Init { 557226584Sdim RecTy *Ty; 558226584Sdim 559243830Sdim TypedInit(const TypedInit &Other) LLVM_DELETED_FUNCTION; 560243830Sdim TypedInit &operator=(const TypedInit &Other) LLVM_DELETED_FUNCTION; 561226584Sdim 562226584Sdimprotected: 563243830Sdim explicit TypedInit(InitKind K, RecTy *T) : Init(K), Ty(T) {} 564226584Sdim 565226584Sdimpublic: 566243830Sdim static bool classof(const Init *I) { 567243830Sdim return I->getKind() >= IK_FirstTypedInit && 568243830Sdim I->getKind() <= IK_LastTypedInit; 569243830Sdim } 570226584Sdim RecTy *getType() const { return Ty; } 571226584Sdim 572226584Sdim virtual Init * 573226584Sdim convertInitializerBitRange(const std::vector<unsigned> &Bits) const; 574226584Sdim virtual Init * 575226584Sdim convertInitListSlice(const std::vector<unsigned> &Elements) const; 576226584Sdim 577226584Sdim /// getFieldType - This method is used to implement the FieldInit class. 578226584Sdim /// Implementors of this method should return the type of the named field if 579226584Sdim /// they are of record type. 580226584Sdim /// 581226584Sdim virtual RecTy *getFieldType(const std::string &FieldName) const; 582226584Sdim 583226584Sdim /// resolveListElementReference - This method is used to implement 584226584Sdim /// VarListElementInit::resolveReferences. If the list element is resolvable 585226584Sdim /// now, we return the resolved value, otherwise we return null. 586226584Sdim virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, 587226584Sdim unsigned Elt) const = 0; 588226584Sdim}; 589226584Sdim 590226584Sdim 591226584Sdim/// UnsetInit - ? - Represents an uninitialized value 592226584Sdim/// 593226584Sdimclass UnsetInit : public Init { 594243830Sdim UnsetInit() : Init(IK_UnsetInit) {} 595243830Sdim UnsetInit(const UnsetInit &) LLVM_DELETED_FUNCTION; 596243830Sdim UnsetInit &operator=(const UnsetInit &Other) LLVM_DELETED_FUNCTION; 597234353Sdim virtual void anchor(); 598226584Sdim 599226584Sdimpublic: 600243830Sdim static bool classof(const Init *I) { 601243830Sdim return I->getKind() == IK_UnsetInit; 602243830Sdim } 603226584Sdim static UnsetInit *get(); 604226584Sdim 605226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 606226584Sdim return Ty->convertValue(const_cast<UnsetInit *>(this)); 607226584Sdim } 608226584Sdim 609243830Sdim virtual Init *getBit(unsigned Bit) const { 610243830Sdim return const_cast<UnsetInit*>(this); 611243830Sdim } 612243830Sdim 613226584Sdim virtual bool isComplete() const { return false; } 614226584Sdim virtual std::string getAsString() const { return "?"; } 615226584Sdim}; 616226584Sdim 617226584Sdim 618226584Sdim/// BitInit - true/false - Represent a concrete initializer for a bit. 619226584Sdim/// 620226584Sdimclass BitInit : public Init { 621226584Sdim bool Value; 622226584Sdim 623243830Sdim explicit BitInit(bool V) : Init(IK_BitInit), Value(V) {} 624243830Sdim BitInit(const BitInit &Other) LLVM_DELETED_FUNCTION; 625243830Sdim BitInit &operator=(BitInit &Other) LLVM_DELETED_FUNCTION; 626234353Sdim virtual void anchor(); 627226584Sdim 628226584Sdimpublic: 629243830Sdim static bool classof(const Init *I) { 630243830Sdim return I->getKind() == IK_BitInit; 631243830Sdim } 632226584Sdim static BitInit *get(bool V); 633226584Sdim 634226584Sdim bool getValue() const { return Value; } 635226584Sdim 636226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 637226584Sdim return Ty->convertValue(const_cast<BitInit *>(this)); 638226584Sdim } 639226584Sdim 640243830Sdim virtual Init *getBit(unsigned Bit) const { 641243830Sdim assert(Bit < 1 && "Bit index out of range!"); 642243830Sdim return const_cast<BitInit*>(this); 643243830Sdim } 644243830Sdim 645226584Sdim virtual std::string getAsString() const { return Value ? "1" : "0"; } 646226584Sdim}; 647226584Sdim 648226584Sdim/// BitsInit - { a, b, c } - Represents an initializer for a BitsRecTy value. 649226584Sdim/// It contains a vector of bits, whose size is determined by the type. 650226584Sdim/// 651226584Sdimclass BitsInit : public Init, public FoldingSetNode { 652226584Sdim std::vector<Init*> Bits; 653226584Sdim 654243830Sdim BitsInit(ArrayRef<Init *> Range) 655243830Sdim : Init(IK_BitsInit), Bits(Range.begin(), Range.end()) {} 656226584Sdim 657243830Sdim BitsInit(const BitsInit &Other) LLVM_DELETED_FUNCTION; 658243830Sdim BitsInit &operator=(const BitsInit &Other) LLVM_DELETED_FUNCTION; 659226584Sdim 660226584Sdimpublic: 661243830Sdim static bool classof(const Init *I) { 662243830Sdim return I->getKind() == IK_BitsInit; 663243830Sdim } 664226584Sdim static BitsInit *get(ArrayRef<Init *> Range); 665226584Sdim 666226584Sdim void Profile(FoldingSetNodeID &ID) const; 667226584Sdim 668226584Sdim unsigned getNumBits() const { return Bits.size(); } 669226584Sdim 670226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 671226584Sdim return Ty->convertValue(const_cast<BitsInit *>(this)); 672226584Sdim } 673226584Sdim virtual Init * 674226584Sdim convertInitializerBitRange(const std::vector<unsigned> &Bits) const; 675226584Sdim 676226584Sdim virtual bool isComplete() const { 677226584Sdim for (unsigned i = 0; i != getNumBits(); ++i) 678226584Sdim if (!getBit(i)->isComplete()) return false; 679226584Sdim return true; 680226584Sdim } 681226584Sdim bool allInComplete() const { 682226584Sdim for (unsigned i = 0; i != getNumBits(); ++i) 683226584Sdim if (getBit(i)->isComplete()) return false; 684226584Sdim return true; 685226584Sdim } 686226584Sdim virtual std::string getAsString() const; 687226584Sdim 688226584Sdim virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; 689243830Sdim 690243830Sdim virtual Init *getBit(unsigned Bit) const { 691243830Sdim assert(Bit < Bits.size() && "Bit index out of range!"); 692243830Sdim return Bits[Bit]; 693243830Sdim } 694226584Sdim}; 695226584Sdim 696226584Sdim 697226584Sdim/// IntInit - 7 - Represent an initalization by a literal integer value. 698226584Sdim/// 699226584Sdimclass IntInit : public TypedInit { 700226584Sdim int64_t Value; 701226584Sdim 702243830Sdim explicit IntInit(int64_t V) 703243830Sdim : TypedInit(IK_IntInit, IntRecTy::get()), Value(V) {} 704226584Sdim 705243830Sdim IntInit(const IntInit &Other) LLVM_DELETED_FUNCTION; 706243830Sdim IntInit &operator=(const IntInit &Other) LLVM_DELETED_FUNCTION; 707226584Sdim 708226584Sdimpublic: 709243830Sdim static bool classof(const Init *I) { 710243830Sdim return I->getKind() == IK_IntInit; 711243830Sdim } 712226584Sdim static IntInit *get(int64_t V); 713226584Sdim 714226584Sdim int64_t getValue() const { return Value; } 715226584Sdim 716226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 717226584Sdim return Ty->convertValue(const_cast<IntInit *>(this)); 718226584Sdim } 719226584Sdim virtual Init * 720226584Sdim convertInitializerBitRange(const std::vector<unsigned> &Bits) const; 721226584Sdim 722226584Sdim virtual std::string getAsString() const; 723226584Sdim 724226584Sdim /// resolveListElementReference - This method is used to implement 725226584Sdim /// VarListElementInit::resolveReferences. If the list element is resolvable 726226584Sdim /// now, we return the resolved value, otherwise we return null. 727226584Sdim virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, 728226584Sdim unsigned Elt) const { 729234353Sdim llvm_unreachable("Illegal element reference off int"); 730226584Sdim } 731243830Sdim 732243830Sdim virtual Init *getBit(unsigned Bit) const { 733243830Sdim return BitInit::get((Value & (1ULL << Bit)) != 0); 734243830Sdim } 735226584Sdim}; 736226584Sdim 737226584Sdim 738226584Sdim/// StringInit - "foo" - Represent an initialization by a string value. 739226584Sdim/// 740226584Sdimclass StringInit : public TypedInit { 741226584Sdim std::string Value; 742226584Sdim 743226584Sdim explicit StringInit(const std::string &V) 744243830Sdim : TypedInit(IK_StringInit, StringRecTy::get()), Value(V) {} 745226584Sdim 746243830Sdim StringInit(const StringInit &Other) LLVM_DELETED_FUNCTION; 747243830Sdim StringInit &operator=(const StringInit &Other) LLVM_DELETED_FUNCTION; 748234353Sdim virtual void anchor(); 749226584Sdim 750226584Sdimpublic: 751243830Sdim static bool classof(const Init *I) { 752243830Sdim return I->getKind() == IK_StringInit; 753243830Sdim } 754234353Sdim static StringInit *get(StringRef); 755226584Sdim 756226584Sdim const std::string &getValue() const { return Value; } 757226584Sdim 758226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 759226584Sdim return Ty->convertValue(const_cast<StringInit *>(this)); 760226584Sdim } 761226584Sdim 762226584Sdim virtual std::string getAsString() const { return "\"" + Value + "\""; } 763226584Sdim virtual std::string getAsUnquotedString() const { return Value; } 764226584Sdim 765226584Sdim /// resolveListElementReference - This method is used to implement 766226584Sdim /// VarListElementInit::resolveReferences. If the list element is resolvable 767226584Sdim /// now, we return the resolved value, otherwise we return null. 768226584Sdim virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, 769226584Sdim unsigned Elt) const { 770234353Sdim llvm_unreachable("Illegal element reference off string"); 771226584Sdim } 772243830Sdim 773243830Sdim virtual Init *getBit(unsigned Bit) const { 774243830Sdim llvm_unreachable("Illegal bit reference off string"); 775243830Sdim } 776226584Sdim}; 777226584Sdim 778226584Sdim/// ListInit - [AL, AH, CL] - Represent a list of defs 779226584Sdim/// 780226584Sdimclass ListInit : public TypedInit, public FoldingSetNode { 781226584Sdim std::vector<Init*> Values; 782226584Sdimpublic: 783226584Sdim typedef std::vector<Init*>::const_iterator const_iterator; 784226584Sdim 785226584Sdimprivate: 786226584Sdim explicit ListInit(ArrayRef<Init *> Range, RecTy *EltTy) 787243830Sdim : TypedInit(IK_ListInit, ListRecTy::get(EltTy)), 788243830Sdim Values(Range.begin(), Range.end()) {} 789226584Sdim 790243830Sdim ListInit(const ListInit &Other) LLVM_DELETED_FUNCTION; 791243830Sdim ListInit &operator=(const ListInit &Other) LLVM_DELETED_FUNCTION; 792226584Sdim 793226584Sdimpublic: 794243830Sdim static bool classof(const Init *I) { 795243830Sdim return I->getKind() == IK_ListInit; 796243830Sdim } 797226584Sdim static ListInit *get(ArrayRef<Init *> Range, RecTy *EltTy); 798226584Sdim 799226584Sdim void Profile(FoldingSetNodeID &ID) const; 800226584Sdim 801226584Sdim unsigned getSize() const { return Values.size(); } 802226584Sdim Init *getElement(unsigned i) const { 803226584Sdim assert(i < Values.size() && "List element index out of range!"); 804226584Sdim return Values[i]; 805226584Sdim } 806226584Sdim 807226584Sdim Record *getElementAsRecord(unsigned i) const; 808226584Sdim 809243830Sdim virtual Init * 810243830Sdim convertInitListSlice(const std::vector<unsigned> &Elements) const; 811226584Sdim 812226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 813226584Sdim return Ty->convertValue(const_cast<ListInit *>(this)); 814226584Sdim } 815226584Sdim 816226584Sdim /// resolveReferences - This method is used by classes that refer to other 817226584Sdim /// variables which may not be defined at the time they expression is formed. 818226584Sdim /// If a value is set for the variable later, this method will be called on 819226584Sdim /// users of the value to allow the value to propagate out. 820226584Sdim /// 821226584Sdim virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; 822226584Sdim 823226584Sdim virtual std::string getAsString() const; 824226584Sdim 825226584Sdim ArrayRef<Init*> getValues() const { return Values; } 826226584Sdim 827226584Sdim inline const_iterator begin() const { return Values.begin(); } 828226584Sdim inline const_iterator end () const { return Values.end(); } 829226584Sdim 830226584Sdim inline size_t size () const { return Values.size(); } 831226584Sdim inline bool empty() const { return Values.empty(); } 832226584Sdim 833226584Sdim /// resolveListElementReference - This method is used to implement 834226584Sdim /// VarListElementInit::resolveReferences. If the list element is resolvable 835226584Sdim /// now, we return the resolved value, otherwise we return null. 836226584Sdim virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, 837226584Sdim unsigned Elt) const; 838243830Sdim 839243830Sdim virtual Init *getBit(unsigned Bit) const { 840243830Sdim llvm_unreachable("Illegal bit reference off list"); 841243830Sdim } 842226584Sdim}; 843226584Sdim 844226584Sdim 845226584Sdim/// OpInit - Base class for operators 846226584Sdim/// 847226584Sdimclass OpInit : public TypedInit { 848243830Sdim OpInit(const OpInit &Other) LLVM_DELETED_FUNCTION; 849243830Sdim OpInit &operator=(OpInit &Other) LLVM_DELETED_FUNCTION; 850226584Sdim 851226584Sdimprotected: 852243830Sdim explicit OpInit(InitKind K, RecTy *Type) : TypedInit(K, Type) {} 853226584Sdim 854226584Sdimpublic: 855243830Sdim static bool classof(const Init *I) { 856243830Sdim return I->getKind() >= IK_FirstOpInit && 857243830Sdim I->getKind() <= IK_LastOpInit; 858243830Sdim } 859226584Sdim // Clone - Clone this operator, replacing arguments with the new list 860226584Sdim virtual OpInit *clone(std::vector<Init *> &Operands) const = 0; 861226584Sdim 862226584Sdim virtual int getNumOperands() const = 0; 863226584Sdim virtual Init *getOperand(int i) const = 0; 864226584Sdim 865226584Sdim // Fold - If possible, fold this to a simpler init. Return this if not 866226584Sdim // possible to fold. 867226584Sdim virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const = 0; 868226584Sdim 869226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 870226584Sdim return Ty->convertValue(const_cast<OpInit *>(this)); 871226584Sdim } 872226584Sdim 873226584Sdim virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, 874226584Sdim unsigned Elt) const; 875243830Sdim 876243830Sdim virtual Init *getBit(unsigned Bit) const; 877226584Sdim}; 878226584Sdim 879226584Sdim 880226584Sdim/// UnOpInit - !op (X) - Transform an init. 881226584Sdim/// 882226584Sdimclass UnOpInit : public OpInit { 883226584Sdimpublic: 884226584Sdim enum UnaryOp { CAST, HEAD, TAIL, EMPTY }; 885226584Sdimprivate: 886226584Sdim UnaryOp Opc; 887226584Sdim Init *LHS; 888226584Sdim 889226584Sdim UnOpInit(UnaryOp opc, Init *lhs, RecTy *Type) 890243830Sdim : OpInit(IK_UnOpInit, Type), Opc(opc), LHS(lhs) {} 891226584Sdim 892243830Sdim UnOpInit(const UnOpInit &Other) LLVM_DELETED_FUNCTION; 893243830Sdim UnOpInit &operator=(const UnOpInit &Other) LLVM_DELETED_FUNCTION; 894226584Sdim 895226584Sdimpublic: 896243830Sdim static bool classof(const Init *I) { 897243830Sdim return I->getKind() == IK_UnOpInit; 898243830Sdim } 899226584Sdim static UnOpInit *get(UnaryOp opc, Init *lhs, RecTy *Type); 900226584Sdim 901226584Sdim // Clone - Clone this operator, replacing arguments with the new list 902226584Sdim virtual OpInit *clone(std::vector<Init *> &Operands) const { 903226584Sdim assert(Operands.size() == 1 && 904226584Sdim "Wrong number of operands for unary operation"); 905226584Sdim return UnOpInit::get(getOpcode(), *Operands.begin(), getType()); 906226584Sdim } 907226584Sdim 908243830Sdim virtual int getNumOperands() const { return 1; } 909243830Sdim virtual Init *getOperand(int i) const { 910226584Sdim assert(i == 0 && "Invalid operand id for unary operator"); 911226584Sdim return getOperand(); 912226584Sdim } 913226584Sdim 914226584Sdim UnaryOp getOpcode() const { return Opc; } 915226584Sdim Init *getOperand() const { return LHS; } 916226584Sdim 917226584Sdim // Fold - If possible, fold this to a simpler init. Return this if not 918226584Sdim // possible to fold. 919243830Sdim virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const; 920226584Sdim 921226584Sdim virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; 922226584Sdim 923226584Sdim virtual std::string getAsString() const; 924226584Sdim}; 925226584Sdim 926226584Sdim/// BinOpInit - !op (X, Y) - Combine two inits. 927226584Sdim/// 928226584Sdimclass BinOpInit : public OpInit { 929226584Sdimpublic: 930249423Sdim enum BinaryOp { ADD, SHL, SRA, SRL, STRCONCAT, CONCAT, EQ }; 931226584Sdimprivate: 932226584Sdim BinaryOp Opc; 933226584Sdim Init *LHS, *RHS; 934226584Sdim 935226584Sdim BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) : 936243830Sdim OpInit(IK_BinOpInit, Type), Opc(opc), LHS(lhs), RHS(rhs) {} 937226584Sdim 938243830Sdim BinOpInit(const BinOpInit &Other) LLVM_DELETED_FUNCTION; 939243830Sdim BinOpInit &operator=(const BinOpInit &Other) LLVM_DELETED_FUNCTION; 940226584Sdim 941226584Sdimpublic: 942243830Sdim static bool classof(const Init *I) { 943243830Sdim return I->getKind() == IK_BinOpInit; 944243830Sdim } 945226584Sdim static BinOpInit *get(BinaryOp opc, Init *lhs, Init *rhs, 946226584Sdim RecTy *Type); 947226584Sdim 948226584Sdim // Clone - Clone this operator, replacing arguments with the new list 949226584Sdim virtual OpInit *clone(std::vector<Init *> &Operands) const { 950226584Sdim assert(Operands.size() == 2 && 951226584Sdim "Wrong number of operands for binary operation"); 952226584Sdim return BinOpInit::get(getOpcode(), Operands[0], Operands[1], getType()); 953226584Sdim } 954226584Sdim 955243830Sdim virtual int getNumOperands() const { return 2; } 956243830Sdim virtual Init *getOperand(int i) const { 957226584Sdim assert((i == 0 || i == 1) && "Invalid operand id for binary operator"); 958226584Sdim if (i == 0) { 959226584Sdim return getLHS(); 960226584Sdim } else { 961226584Sdim return getRHS(); 962226584Sdim } 963226584Sdim } 964226584Sdim 965226584Sdim BinaryOp getOpcode() const { return Opc; } 966226584Sdim Init *getLHS() const { return LHS; } 967226584Sdim Init *getRHS() const { return RHS; } 968226584Sdim 969226584Sdim // Fold - If possible, fold this to a simpler init. Return this if not 970226584Sdim // possible to fold. 971243830Sdim virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const; 972226584Sdim 973226584Sdim virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; 974226584Sdim 975226584Sdim virtual std::string getAsString() const; 976226584Sdim}; 977226584Sdim 978226584Sdim/// TernOpInit - !op (X, Y, Z) - Combine two inits. 979226584Sdim/// 980226584Sdimclass TernOpInit : public OpInit { 981226584Sdimpublic: 982226584Sdim enum TernaryOp { SUBST, FOREACH, IF }; 983226584Sdimprivate: 984226584Sdim TernaryOp Opc; 985226584Sdim Init *LHS, *MHS, *RHS; 986226584Sdim 987226584Sdim TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, 988226584Sdim RecTy *Type) : 989243830Sdim OpInit(IK_TernOpInit, Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {} 990226584Sdim 991243830Sdim TernOpInit(const TernOpInit &Other) LLVM_DELETED_FUNCTION; 992243830Sdim TernOpInit &operator=(const TernOpInit &Other) LLVM_DELETED_FUNCTION; 993226584Sdim 994226584Sdimpublic: 995243830Sdim static bool classof(const Init *I) { 996243830Sdim return I->getKind() == IK_TernOpInit; 997243830Sdim } 998226584Sdim static TernOpInit *get(TernaryOp opc, Init *lhs, 999226584Sdim Init *mhs, Init *rhs, 1000226584Sdim RecTy *Type); 1001226584Sdim 1002226584Sdim // Clone - Clone this operator, replacing arguments with the new list 1003226584Sdim virtual OpInit *clone(std::vector<Init *> &Operands) const { 1004226584Sdim assert(Operands.size() == 3 && 1005226584Sdim "Wrong number of operands for ternary operation"); 1006226584Sdim return TernOpInit::get(getOpcode(), Operands[0], Operands[1], Operands[2], 1007226584Sdim getType()); 1008226584Sdim } 1009226584Sdim 1010243830Sdim virtual int getNumOperands() const { return 3; } 1011243830Sdim virtual Init *getOperand(int i) const { 1012226584Sdim assert((i == 0 || i == 1 || i == 2) && 1013226584Sdim "Invalid operand id for ternary operator"); 1014226584Sdim if (i == 0) { 1015226584Sdim return getLHS(); 1016226584Sdim } else if (i == 1) { 1017226584Sdim return getMHS(); 1018226584Sdim } else { 1019226584Sdim return getRHS(); 1020226584Sdim } 1021226584Sdim } 1022226584Sdim 1023226584Sdim TernaryOp getOpcode() const { return Opc; } 1024226584Sdim Init *getLHS() const { return LHS; } 1025226584Sdim Init *getMHS() const { return MHS; } 1026226584Sdim Init *getRHS() const { return RHS; } 1027226584Sdim 1028226584Sdim // Fold - If possible, fold this to a simpler init. Return this if not 1029226584Sdim // possible to fold. 1030243830Sdim virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const; 1031226584Sdim 1032226584Sdim virtual bool isComplete() const { return false; } 1033226584Sdim 1034226584Sdim virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; 1035226584Sdim 1036226584Sdim virtual std::string getAsString() const; 1037226584Sdim}; 1038226584Sdim 1039226584Sdim 1040226584Sdim/// VarInit - 'Opcode' - Represent a reference to an entire variable object. 1041226584Sdim/// 1042226584Sdimclass VarInit : public TypedInit { 1043234353Sdim Init *VarName; 1044226584Sdim 1045226584Sdim explicit VarInit(const std::string &VN, RecTy *T) 1046243830Sdim : TypedInit(IK_VarInit, T), VarName(StringInit::get(VN)) {} 1047234353Sdim explicit VarInit(Init *VN, RecTy *T) 1048243830Sdim : TypedInit(IK_VarInit, T), VarName(VN) {} 1049226584Sdim 1050243830Sdim VarInit(const VarInit &Other) LLVM_DELETED_FUNCTION; 1051243830Sdim VarInit &operator=(const VarInit &Other) LLVM_DELETED_FUNCTION; 1052226584Sdim 1053226584Sdimpublic: 1054243830Sdim static bool classof(const Init *I) { 1055243830Sdim return I->getKind() == IK_VarInit; 1056243830Sdim } 1057226584Sdim static VarInit *get(const std::string &VN, RecTy *T); 1058226584Sdim static VarInit *get(Init *VN, RecTy *T); 1059226584Sdim 1060226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 1061226584Sdim return Ty->convertValue(const_cast<VarInit *>(this)); 1062226584Sdim } 1063226584Sdim 1064234353Sdim const std::string &getName() const; 1065234353Sdim Init *getNameInit() const { return VarName; } 1066234353Sdim std::string getNameInitAsString() const { 1067234353Sdim return getNameInit()->getAsUnquotedString(); 1068234353Sdim } 1069226584Sdim 1070226584Sdim virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, 1071226584Sdim unsigned Elt) const; 1072226584Sdim 1073226584Sdim virtual RecTy *getFieldType(const std::string &FieldName) const; 1074226584Sdim virtual Init *getFieldInit(Record &R, const RecordVal *RV, 1075226584Sdim const std::string &FieldName) const; 1076226584Sdim 1077226584Sdim /// resolveReferences - This method is used by classes that refer to other 1078226584Sdim /// variables which may not be defined at the time they expression is formed. 1079226584Sdim /// If a value is set for the variable later, this method will be called on 1080226584Sdim /// users of the value to allow the value to propagate out. 1081226584Sdim /// 1082226584Sdim virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; 1083226584Sdim 1084243830Sdim virtual Init *getBit(unsigned Bit) const; 1085243830Sdim 1086234353Sdim virtual std::string getAsString() const { return getName(); } 1087226584Sdim}; 1088226584Sdim 1089226584Sdim 1090226584Sdim/// VarBitInit - Opcode{0} - Represent access to one bit of a variable or field. 1091226584Sdim/// 1092226584Sdimclass VarBitInit : public Init { 1093226584Sdim TypedInit *TI; 1094226584Sdim unsigned Bit; 1095226584Sdim 1096243830Sdim VarBitInit(TypedInit *T, unsigned B) : Init(IK_VarBitInit), TI(T), Bit(B) { 1097243830Sdim assert(T->getType() && 1098243830Sdim (isa<IntRecTy>(T->getType()) || 1099243830Sdim (isa<BitsRecTy>(T->getType()) && 1100243830Sdim cast<BitsRecTy>(T->getType())->getNumBits() > B)) && 1101226584Sdim "Illegal VarBitInit expression!"); 1102226584Sdim } 1103226584Sdim 1104243830Sdim VarBitInit(const VarBitInit &Other) LLVM_DELETED_FUNCTION; 1105243830Sdim VarBitInit &operator=(const VarBitInit &Other) LLVM_DELETED_FUNCTION; 1106226584Sdim 1107226584Sdimpublic: 1108243830Sdim static bool classof(const Init *I) { 1109243830Sdim return I->getKind() == IK_VarBitInit; 1110243830Sdim } 1111226584Sdim static VarBitInit *get(TypedInit *T, unsigned B); 1112226584Sdim 1113226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 1114226584Sdim return Ty->convertValue(const_cast<VarBitInit *>(this)); 1115226584Sdim } 1116226584Sdim 1117243830Sdim virtual Init *getBitVar() const { return TI; } 1118243830Sdim virtual unsigned getBitNum() const { return Bit; } 1119226584Sdim 1120226584Sdim virtual std::string getAsString() const; 1121226584Sdim virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; 1122243830Sdim 1123243830Sdim virtual Init *getBit(unsigned B) const { 1124243830Sdim assert(B < 1 && "Bit index out of range!"); 1125243830Sdim return const_cast<VarBitInit*>(this); 1126243830Sdim } 1127226584Sdim}; 1128226584Sdim 1129226584Sdim/// VarListElementInit - List[4] - Represent access to one element of a var or 1130226584Sdim/// field. 1131226584Sdimclass VarListElementInit : public TypedInit { 1132226584Sdim TypedInit *TI; 1133226584Sdim unsigned Element; 1134226584Sdim 1135226584Sdim VarListElementInit(TypedInit *T, unsigned E) 1136243830Sdim : TypedInit(IK_VarListElementInit, 1137243830Sdim cast<ListRecTy>(T->getType())->getElementType()), 1138243830Sdim TI(T), Element(E) { 1139243830Sdim assert(T->getType() && isa<ListRecTy>(T->getType()) && 1140226584Sdim "Illegal VarBitInit expression!"); 1141226584Sdim } 1142226584Sdim 1143243830Sdim VarListElementInit(const VarListElementInit &Other) LLVM_DELETED_FUNCTION; 1144243830Sdim void operator=(const VarListElementInit &Other) LLVM_DELETED_FUNCTION; 1145226584Sdim 1146226584Sdimpublic: 1147243830Sdim static bool classof(const Init *I) { 1148243830Sdim return I->getKind() == IK_VarListElementInit; 1149243830Sdim } 1150226584Sdim static VarListElementInit *get(TypedInit *T, unsigned E); 1151226584Sdim 1152226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 1153226584Sdim return Ty->convertValue(const_cast<VarListElementInit *>(this)); 1154226584Sdim } 1155226584Sdim 1156226584Sdim TypedInit *getVariable() const { return TI; } 1157226584Sdim unsigned getElementNum() const { return Element; } 1158226584Sdim 1159226584Sdim /// resolveListElementReference - This method is used to implement 1160226584Sdim /// VarListElementInit::resolveReferences. If the list element is resolvable 1161226584Sdim /// now, we return the resolved value, otherwise we return null. 1162226584Sdim virtual Init *resolveListElementReference(Record &R, 1163226584Sdim const RecordVal *RV, 1164226584Sdim unsigned Elt) const; 1165226584Sdim 1166226584Sdim virtual std::string getAsString() const; 1167226584Sdim virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; 1168243830Sdim 1169243830Sdim virtual Init *getBit(unsigned Bit) const; 1170226584Sdim}; 1171226584Sdim 1172226584Sdim/// DefInit - AL - Represent a reference to a 'def' in the description 1173226584Sdim/// 1174226584Sdimclass DefInit : public TypedInit { 1175226584Sdim Record *Def; 1176226584Sdim 1177243830Sdim DefInit(Record *D, RecordRecTy *T) : TypedInit(IK_DefInit, T), Def(D) {} 1178226584Sdim friend class Record; 1179226584Sdim 1180243830Sdim DefInit(const DefInit &Other) LLVM_DELETED_FUNCTION; 1181243830Sdim DefInit &operator=(const DefInit &Other) LLVM_DELETED_FUNCTION; 1182226584Sdim 1183226584Sdimpublic: 1184243830Sdim static bool classof(const Init *I) { 1185243830Sdim return I->getKind() == IK_DefInit; 1186243830Sdim } 1187226584Sdim static DefInit *get(Record*); 1188226584Sdim 1189226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 1190226584Sdim return Ty->convertValue(const_cast<DefInit *>(this)); 1191226584Sdim } 1192226584Sdim 1193226584Sdim Record *getDef() const { return Def; } 1194226584Sdim 1195226584Sdim //virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits); 1196226584Sdim 1197226584Sdim virtual RecTy *getFieldType(const std::string &FieldName) const; 1198226584Sdim virtual Init *getFieldInit(Record &R, const RecordVal *RV, 1199226584Sdim const std::string &FieldName) const; 1200226584Sdim 1201226584Sdim virtual std::string getAsString() const; 1202226584Sdim 1203243830Sdim virtual Init *getBit(unsigned Bit) const { 1204234353Sdim llvm_unreachable("Illegal bit reference off def"); 1205226584Sdim } 1206226584Sdim 1207226584Sdim /// resolveListElementReference - This method is used to implement 1208226584Sdim /// VarListElementInit::resolveReferences. If the list element is resolvable 1209226584Sdim /// now, we return the resolved value, otherwise we return null. 1210226584Sdim virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, 1211226584Sdim unsigned Elt) const { 1212234353Sdim llvm_unreachable("Illegal element reference off def"); 1213226584Sdim } 1214226584Sdim}; 1215226584Sdim 1216226584Sdim 1217226584Sdim/// FieldInit - X.Y - Represent a reference to a subfield of a variable 1218226584Sdim/// 1219226584Sdimclass FieldInit : public TypedInit { 1220226584Sdim Init *Rec; // Record we are referring to 1221226584Sdim std::string FieldName; // Field we are accessing 1222226584Sdim 1223226584Sdim FieldInit(Init *R, const std::string &FN) 1224243830Sdim : TypedInit(IK_FieldInit, R->getFieldType(FN)), Rec(R), FieldName(FN) { 1225226584Sdim assert(getType() && "FieldInit with non-record type!"); 1226226584Sdim } 1227226584Sdim 1228243830Sdim FieldInit(const FieldInit &Other) LLVM_DELETED_FUNCTION; 1229243830Sdim FieldInit &operator=(const FieldInit &Other) LLVM_DELETED_FUNCTION; 1230226584Sdim 1231226584Sdimpublic: 1232243830Sdim static bool classof(const Init *I) { 1233243830Sdim return I->getKind() == IK_FieldInit; 1234243830Sdim } 1235226584Sdim static FieldInit *get(Init *R, const std::string &FN); 1236226584Sdim static FieldInit *get(Init *R, const Init *FN); 1237226584Sdim 1238226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 1239226584Sdim return Ty->convertValue(const_cast<FieldInit *>(this)); 1240226584Sdim } 1241226584Sdim 1242243830Sdim virtual Init *getBit(unsigned Bit) const; 1243243830Sdim 1244226584Sdim virtual Init *resolveListElementReference(Record &R, 1245226584Sdim const RecordVal *RV, 1246226584Sdim unsigned Elt) const; 1247226584Sdim 1248226584Sdim virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; 1249226584Sdim 1250226584Sdim virtual std::string getAsString() const { 1251226584Sdim return Rec->getAsString() + "." + FieldName; 1252226584Sdim } 1253226584Sdim}; 1254226584Sdim 1255226584Sdim/// DagInit - (v a, b) - Represent a DAG tree value. DAG inits are required 1256226584Sdim/// to have at least one value then a (possibly empty) list of arguments. Each 1257226584Sdim/// argument can have a name associated with it. 1258226584Sdim/// 1259226584Sdimclass DagInit : public TypedInit, public FoldingSetNode { 1260226584Sdim Init *Val; 1261226584Sdim std::string ValName; 1262226584Sdim std::vector<Init*> Args; 1263226584Sdim std::vector<std::string> ArgNames; 1264226584Sdim 1265226584Sdim DagInit(Init *V, const std::string &VN, 1266226584Sdim ArrayRef<Init *> ArgRange, 1267226584Sdim ArrayRef<std::string> NameRange) 1268243830Sdim : TypedInit(IK_DagInit, DagRecTy::get()), Val(V), ValName(VN), 1269226584Sdim Args(ArgRange.begin(), ArgRange.end()), 1270226584Sdim ArgNames(NameRange.begin(), NameRange.end()) {} 1271226584Sdim 1272243830Sdim DagInit(const DagInit &Other) LLVM_DELETED_FUNCTION; 1273243830Sdim DagInit &operator=(const DagInit &Other) LLVM_DELETED_FUNCTION; 1274226584Sdim 1275226584Sdimpublic: 1276243830Sdim static bool classof(const Init *I) { 1277243830Sdim return I->getKind() == IK_DagInit; 1278243830Sdim } 1279226584Sdim static DagInit *get(Init *V, const std::string &VN, 1280226584Sdim ArrayRef<Init *> ArgRange, 1281226584Sdim ArrayRef<std::string> NameRange); 1282226584Sdim static DagInit *get(Init *V, const std::string &VN, 1283226584Sdim const std::vector< 1284226584Sdim std::pair<Init*, std::string> > &args); 1285226584Sdim 1286226584Sdim void Profile(FoldingSetNodeID &ID) const; 1287226584Sdim 1288226584Sdim virtual Init *convertInitializerTo(RecTy *Ty) const { 1289226584Sdim return Ty->convertValue(const_cast<DagInit *>(this)); 1290226584Sdim } 1291226584Sdim 1292226584Sdim Init *getOperator() const { return Val; } 1293226584Sdim 1294226584Sdim const std::string &getName() const { return ValName; } 1295226584Sdim 1296226584Sdim unsigned getNumArgs() const { return Args.size(); } 1297226584Sdim Init *getArg(unsigned Num) const { 1298226584Sdim assert(Num < Args.size() && "Arg number out of range!"); 1299226584Sdim return Args[Num]; 1300226584Sdim } 1301226584Sdim const std::string &getArgName(unsigned Num) const { 1302226584Sdim assert(Num < ArgNames.size() && "Arg number out of range!"); 1303226584Sdim return ArgNames[Num]; 1304226584Sdim } 1305226584Sdim 1306226584Sdim virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; 1307226584Sdim 1308226584Sdim virtual std::string getAsString() const; 1309226584Sdim 1310226584Sdim typedef std::vector<Init*>::const_iterator const_arg_iterator; 1311226584Sdim typedef std::vector<std::string>::const_iterator const_name_iterator; 1312226584Sdim 1313226584Sdim inline const_arg_iterator arg_begin() const { return Args.begin(); } 1314226584Sdim inline const_arg_iterator arg_end () const { return Args.end(); } 1315226584Sdim 1316226584Sdim inline size_t arg_size () const { return Args.size(); } 1317226584Sdim inline bool arg_empty() const { return Args.empty(); } 1318226584Sdim 1319226584Sdim inline const_name_iterator name_begin() const { return ArgNames.begin(); } 1320226584Sdim inline const_name_iterator name_end () const { return ArgNames.end(); } 1321226584Sdim 1322226584Sdim inline size_t name_size () const { return ArgNames.size(); } 1323226584Sdim inline bool name_empty() const { return ArgNames.empty(); } 1324226584Sdim 1325243830Sdim virtual Init *getBit(unsigned Bit) const { 1326234353Sdim llvm_unreachable("Illegal bit reference off dag"); 1327226584Sdim } 1328226584Sdim 1329226584Sdim virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, 1330226584Sdim unsigned Elt) const { 1331234353Sdim llvm_unreachable("Illegal element reference off dag"); 1332226584Sdim } 1333226584Sdim}; 1334226584Sdim 1335226584Sdim//===----------------------------------------------------------------------===// 1336226584Sdim// High-Level Classes 1337226584Sdim//===----------------------------------------------------------------------===// 1338226584Sdim 1339226584Sdimclass RecordVal { 1340226584Sdim Init *Name; 1341226584Sdim RecTy *Ty; 1342226584Sdim unsigned Prefix; 1343226584Sdim Init *Value; 1344226584Sdimpublic: 1345226584Sdim RecordVal(Init *N, RecTy *T, unsigned P); 1346226584Sdim RecordVal(const std::string &N, RecTy *T, unsigned P); 1347226584Sdim 1348226584Sdim const std::string &getName() const; 1349234353Sdim const Init *getNameInit() const { return Name; } 1350234353Sdim std::string getNameInitAsString() const { 1351234353Sdim return getNameInit()->getAsUnquotedString(); 1352234353Sdim } 1353226584Sdim 1354226584Sdim unsigned getPrefix() const { return Prefix; } 1355226584Sdim RecTy *getType() const { return Ty; } 1356226584Sdim Init *getValue() const { return Value; } 1357226584Sdim 1358226584Sdim bool setValue(Init *V) { 1359226584Sdim if (V) { 1360226584Sdim Value = V->convertInitializerTo(Ty); 1361226584Sdim return Value == 0; 1362226584Sdim } 1363226584Sdim Value = 0; 1364226584Sdim return false; 1365226584Sdim } 1366226584Sdim 1367226584Sdim void dump() const; 1368226584Sdim void print(raw_ostream &OS, bool PrintSem = true) const; 1369226584Sdim}; 1370226584Sdim 1371226584Sdiminline raw_ostream &operator<<(raw_ostream &OS, const RecordVal &RV) { 1372226584Sdim RV.print(OS << " "); 1373226584Sdim return OS; 1374226584Sdim} 1375226584Sdim 1376226584Sdimclass Record { 1377226584Sdim static unsigned LastID; 1378226584Sdim 1379226584Sdim // Unique record ID. 1380226584Sdim unsigned ID; 1381226584Sdim Init *Name; 1382243830Sdim // Location where record was instantiated, followed by the location of 1383243830Sdim // multiclass prototypes used. 1384243830Sdim SmallVector<SMLoc, 4> Locs; 1385234353Sdim std::vector<Init *> TemplateArgs; 1386226584Sdim std::vector<RecordVal> Values; 1387249423Sdim std::vector<Record *> SuperClasses; 1388249423Sdim std::vector<SMRange> SuperClassRanges; 1389226584Sdim 1390226584Sdim // Tracks Record instances. Not owned by Record. 1391226584Sdim RecordKeeper &TrackedRecords; 1392226584Sdim 1393226584Sdim DefInit *TheInit; 1394249423Sdim bool IsAnonymous; 1395226584Sdim 1396234353Sdim void init(); 1397226584Sdim void checkName(); 1398226584Sdim 1399226584Sdimpublic: 1400226584Sdim 1401226584Sdim // Constructs a record. 1402243830Sdim explicit Record(const std::string &N, ArrayRef<SMLoc> locs, 1403249423Sdim RecordKeeper &records, bool Anonymous = false) : 1404243830Sdim ID(LastID++), Name(StringInit::get(N)), Locs(locs.begin(), locs.end()), 1405249423Sdim TrackedRecords(records), TheInit(0), IsAnonymous(Anonymous) { 1406234353Sdim init(); 1407234353Sdim } 1408249423Sdim explicit Record(Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records, 1409249423Sdim bool Anonymous = false) : 1410243830Sdim ID(LastID++), Name(N), Locs(locs.begin(), locs.end()), 1411249423Sdim TrackedRecords(records), TheInit(0), IsAnonymous(Anonymous) { 1412234353Sdim init(); 1413234353Sdim } 1414243830Sdim 1415243830Sdim // When copy-constructing a Record, we must still guarantee a globally unique 1416243830Sdim // ID number. All other fields can be copied normally. 1417243830Sdim Record(const Record &O) : 1418243830Sdim ID(LastID++), Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs), 1419243830Sdim Values(O.Values), SuperClasses(O.SuperClasses), 1420249423Sdim SuperClassRanges(O.SuperClassRanges), TrackedRecords(O.TrackedRecords), 1421249423Sdim TheInit(O.TheInit), IsAnonymous(O.IsAnonymous) { } 1422243830Sdim 1423226584Sdim ~Record() {} 1424226584Sdim 1425226584Sdim 1426226584Sdim static unsigned getNewUID() { return LastID++; } 1427226584Sdim 1428226584Sdim 1429226584Sdim unsigned getID() const { return ID; } 1430226584Sdim 1431226584Sdim const std::string &getName() const; 1432234353Sdim Init *getNameInit() const { 1433234353Sdim return Name; 1434234353Sdim } 1435234353Sdim const std::string getNameInitAsString() const { 1436234353Sdim return getNameInit()->getAsUnquotedString(); 1437234353Sdim } 1438234353Sdim 1439226584Sdim void setName(Init *Name); // Also updates RecordKeeper. 1440226584Sdim void setName(const std::string &Name); // Also updates RecordKeeper. 1441226584Sdim 1442243830Sdim ArrayRef<SMLoc> getLoc() const { return Locs; } 1443226584Sdim 1444226584Sdim /// get the corresponding DefInit. 1445226584Sdim DefInit *getDefInit(); 1446226584Sdim 1447234353Sdim const std::vector<Init *> &getTemplateArgs() const { 1448226584Sdim return TemplateArgs; 1449226584Sdim } 1450226584Sdim const std::vector<RecordVal> &getValues() const { return Values; } 1451226584Sdim const std::vector<Record*> &getSuperClasses() const { return SuperClasses; } 1452249423Sdim ArrayRef<SMRange> getSuperClassRanges() const { return SuperClassRanges; } 1453226584Sdim 1454234353Sdim bool isTemplateArg(Init *Name) const { 1455226584Sdim for (unsigned i = 0, e = TemplateArgs.size(); i != e; ++i) 1456226584Sdim if (TemplateArgs[i] == Name) return true; 1457226584Sdim return false; 1458226584Sdim } 1459234353Sdim bool isTemplateArg(StringRef Name) const { 1460234353Sdim return isTemplateArg(StringInit::get(Name.str())); 1461234353Sdim } 1462226584Sdim 1463234353Sdim const RecordVal *getValue(const Init *Name) const { 1464226584Sdim for (unsigned i = 0, e = Values.size(); i != e; ++i) 1465234353Sdim if (Values[i].getNameInit() == Name) return &Values[i]; 1466226584Sdim return 0; 1467226584Sdim } 1468234353Sdim const RecordVal *getValue(StringRef Name) const { 1469234353Sdim return getValue(StringInit::get(Name)); 1470234353Sdim } 1471234353Sdim RecordVal *getValue(const Init *Name) { 1472226584Sdim for (unsigned i = 0, e = Values.size(); i != e; ++i) 1473234353Sdim if (Values[i].getNameInit() == Name) return &Values[i]; 1474226584Sdim return 0; 1475226584Sdim } 1476234353Sdim RecordVal *getValue(StringRef Name) { 1477234353Sdim return getValue(StringInit::get(Name)); 1478234353Sdim } 1479226584Sdim 1480234353Sdim void addTemplateArg(Init *Name) { 1481226584Sdim assert(!isTemplateArg(Name) && "Template arg already defined!"); 1482226584Sdim TemplateArgs.push_back(Name); 1483226584Sdim } 1484234353Sdim void addTemplateArg(StringRef Name) { 1485234353Sdim addTemplateArg(StringInit::get(Name.str())); 1486234353Sdim } 1487226584Sdim 1488226584Sdim void addValue(const RecordVal &RV) { 1489234353Sdim assert(getValue(RV.getNameInit()) == 0 && "Value already added!"); 1490226584Sdim Values.push_back(RV); 1491234353Sdim if (Values.size() > 1) 1492234353Sdim // Keep NAME at the end of the list. It makes record dumps a 1493234353Sdim // bit prettier and allows TableGen tests to be written more 1494234353Sdim // naturally. Tests can use CHECK-NEXT to look for Record 1495234353Sdim // fields they expect to see after a def. They can't do that if 1496234353Sdim // NAME is the first Record field. 1497234353Sdim std::swap(Values[Values.size() - 2], Values[Values.size() - 1]); 1498226584Sdim } 1499226584Sdim 1500234353Sdim void removeValue(Init *Name) { 1501226584Sdim for (unsigned i = 0, e = Values.size(); i != e; ++i) 1502234353Sdim if (Values[i].getNameInit() == Name) { 1503226584Sdim Values.erase(Values.begin()+i); 1504226584Sdim return; 1505226584Sdim } 1506234353Sdim llvm_unreachable("Cannot remove an entry that does not exist!"); 1507226584Sdim } 1508226584Sdim 1509234353Sdim void removeValue(StringRef Name) { 1510234353Sdim removeValue(StringInit::get(Name.str())); 1511234353Sdim } 1512234353Sdim 1513226584Sdim bool isSubClassOf(const Record *R) const { 1514226584Sdim for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) 1515226584Sdim if (SuperClasses[i] == R) 1516226584Sdim return true; 1517226584Sdim return false; 1518226584Sdim } 1519226584Sdim 1520226584Sdim bool isSubClassOf(StringRef Name) const { 1521226584Sdim for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) 1522234353Sdim if (SuperClasses[i]->getNameInitAsString() == Name) 1523226584Sdim return true; 1524226584Sdim return false; 1525226584Sdim } 1526226584Sdim 1527249423Sdim void addSuperClass(Record *R, SMRange Range) { 1528226584Sdim assert(!isSubClassOf(R) && "Already subclassing record!"); 1529226584Sdim SuperClasses.push_back(R); 1530249423Sdim SuperClassRanges.push_back(Range); 1531226584Sdim } 1532226584Sdim 1533226584Sdim /// resolveReferences - If there are any field references that refer to fields 1534226584Sdim /// that have been filled in, we can propagate the values now. 1535226584Sdim /// 1536226584Sdim void resolveReferences() { resolveReferencesTo(0); } 1537226584Sdim 1538226584Sdim /// resolveReferencesTo - If anything in this record refers to RV, replace the 1539226584Sdim /// reference to RV with the RHS of RV. If RV is null, we resolve all 1540226584Sdim /// possible references. 1541226584Sdim void resolveReferencesTo(const RecordVal *RV); 1542226584Sdim 1543226584Sdim RecordKeeper &getRecords() const { 1544226584Sdim return TrackedRecords; 1545226584Sdim } 1546226584Sdim 1547249423Sdim bool isAnonymous() const { 1548249423Sdim return IsAnonymous; 1549249423Sdim } 1550249423Sdim 1551226584Sdim void dump() const; 1552226584Sdim 1553226584Sdim //===--------------------------------------------------------------------===// 1554226584Sdim // High-level methods useful to tablegen back-ends 1555226584Sdim // 1556226584Sdim 1557226584Sdim /// getValueInit - Return the initializer for a value with the specified name, 1558226584Sdim /// or throw an exception if the field does not exist. 1559226584Sdim /// 1560226584Sdim Init *getValueInit(StringRef FieldName) const; 1561226584Sdim 1562249423Sdim /// Return true if the named field is unset. 1563249423Sdim bool isValueUnset(StringRef FieldName) const { 1564249423Sdim return getValueInit(FieldName) == UnsetInit::get(); 1565249423Sdim } 1566249423Sdim 1567226584Sdim /// getValueAsString - This method looks up the specified field and returns 1568226584Sdim /// its value as a string, throwing an exception if the field does not exist 1569226584Sdim /// or if the value is not a string. 1570226584Sdim /// 1571226584Sdim std::string getValueAsString(StringRef FieldName) const; 1572226584Sdim 1573226584Sdim /// getValueAsBitsInit - This method looks up the specified field and returns 1574226584Sdim /// its value as a BitsInit, throwing an exception if the field does not exist 1575226584Sdim /// or if the value is not the right type. 1576226584Sdim /// 1577226584Sdim BitsInit *getValueAsBitsInit(StringRef FieldName) const; 1578226584Sdim 1579226584Sdim /// getValueAsListInit - This method looks up the specified field and returns 1580226584Sdim /// its value as a ListInit, throwing an exception if the field does not exist 1581226584Sdim /// or if the value is not the right type. 1582226584Sdim /// 1583226584Sdim ListInit *getValueAsListInit(StringRef FieldName) const; 1584226584Sdim 1585226584Sdim /// getValueAsListOfDefs - This method looks up the specified field and 1586226584Sdim /// returns its value as a vector of records, throwing an exception if the 1587226584Sdim /// field does not exist or if the value is not the right type. 1588226584Sdim /// 1589226584Sdim std::vector<Record*> getValueAsListOfDefs(StringRef FieldName) const; 1590226584Sdim 1591226584Sdim /// getValueAsListOfInts - This method looks up the specified field and 1592226584Sdim /// returns its value as a vector of integers, throwing an exception if the 1593226584Sdim /// field does not exist or if the value is not the right type. 1594226584Sdim /// 1595226584Sdim std::vector<int64_t> getValueAsListOfInts(StringRef FieldName) const; 1596226584Sdim 1597226584Sdim /// getValueAsListOfStrings - This method looks up the specified field and 1598226584Sdim /// returns its value as a vector of strings, throwing an exception if the 1599226584Sdim /// field does not exist or if the value is not the right type. 1600226584Sdim /// 1601226584Sdim std::vector<std::string> getValueAsListOfStrings(StringRef FieldName) const; 1602226584Sdim 1603226584Sdim /// getValueAsDef - This method looks up the specified field and returns its 1604226584Sdim /// value as a Record, throwing an exception if the field does not exist or if 1605226584Sdim /// the value is not the right type. 1606226584Sdim /// 1607226584Sdim Record *getValueAsDef(StringRef FieldName) const; 1608226584Sdim 1609226584Sdim /// getValueAsBit - This method looks up the specified field and returns its 1610226584Sdim /// value as a bit, throwing an exception if the field does not exist or if 1611226584Sdim /// the value is not the right type. 1612226584Sdim /// 1613226584Sdim bool getValueAsBit(StringRef FieldName) const; 1614226584Sdim 1615243830Sdim /// getValueAsBitOrUnset - This method looks up the specified field and 1616243830Sdim /// returns its value as a bit. If the field is unset, sets Unset to true and 1617243830Sdim /// retunrs false. 1618243830Sdim /// 1619243830Sdim bool getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const; 1620243830Sdim 1621226584Sdim /// getValueAsInt - This method looks up the specified field and returns its 1622226584Sdim /// value as an int64_t, throwing an exception if the field does not exist or 1623226584Sdim /// if the value is not the right type. 1624226584Sdim /// 1625226584Sdim int64_t getValueAsInt(StringRef FieldName) const; 1626226584Sdim 1627226584Sdim /// getValueAsDag - This method looks up the specified field and returns its 1628226584Sdim /// value as an Dag, throwing an exception if the field does not exist or if 1629226584Sdim /// the value is not the right type. 1630226584Sdim /// 1631226584Sdim DagInit *getValueAsDag(StringRef FieldName) const; 1632226584Sdim}; 1633226584Sdim 1634226584Sdimraw_ostream &operator<<(raw_ostream &OS, const Record &R); 1635226584Sdim 1636226584Sdimstruct MultiClass { 1637226584Sdim Record Rec; // Placeholder for template args and Name. 1638226584Sdim typedef std::vector<Record*> RecordVector; 1639226584Sdim RecordVector DefPrototypes; 1640226584Sdim 1641226584Sdim void dump() const; 1642226584Sdim 1643234982Sdim MultiClass(const std::string &Name, SMLoc Loc, RecordKeeper &Records) : 1644226584Sdim Rec(Name, Loc, Records) {} 1645226584Sdim}; 1646226584Sdim 1647226584Sdimclass RecordKeeper { 1648226584Sdim std::map<std::string, Record*> Classes, Defs; 1649234353Sdim 1650226584Sdimpublic: 1651226584Sdim ~RecordKeeper() { 1652226584Sdim for (std::map<std::string, Record*>::iterator I = Classes.begin(), 1653226584Sdim E = Classes.end(); I != E; ++I) 1654226584Sdim delete I->second; 1655226584Sdim for (std::map<std::string, Record*>::iterator I = Defs.begin(), 1656226584Sdim E = Defs.end(); I != E; ++I) 1657226584Sdim delete I->second; 1658226584Sdim } 1659226584Sdim 1660226584Sdim const std::map<std::string, Record*> &getClasses() const { return Classes; } 1661226584Sdim const std::map<std::string, Record*> &getDefs() const { return Defs; } 1662226584Sdim 1663226584Sdim Record *getClass(const std::string &Name) const { 1664226584Sdim std::map<std::string, Record*>::const_iterator I = Classes.find(Name); 1665226584Sdim return I == Classes.end() ? 0 : I->second; 1666226584Sdim } 1667226584Sdim Record *getDef(const std::string &Name) const { 1668226584Sdim std::map<std::string, Record*>::const_iterator I = Defs.find(Name); 1669226584Sdim return I == Defs.end() ? 0 : I->second; 1670226584Sdim } 1671226584Sdim void addClass(Record *R) { 1672239462Sdim bool Ins = Classes.insert(std::make_pair(R->getName(), R)).second; 1673239462Sdim (void)Ins; 1674239462Sdim assert(Ins && "Class already exists"); 1675226584Sdim } 1676226584Sdim void addDef(Record *R) { 1677239462Sdim bool Ins = Defs.insert(std::make_pair(R->getName(), R)).second; 1678239462Sdim (void)Ins; 1679239462Sdim assert(Ins && "Record already exists"); 1680226584Sdim } 1681226584Sdim 1682226584Sdim /// removeClass - Remove, but do not delete, the specified record. 1683226584Sdim /// 1684226584Sdim void removeClass(const std::string &Name) { 1685226584Sdim assert(Classes.count(Name) && "Class does not exist!"); 1686226584Sdim Classes.erase(Name); 1687226584Sdim } 1688226584Sdim /// removeDef - Remove, but do not delete, the specified record. 1689226584Sdim /// 1690226584Sdim void removeDef(const std::string &Name) { 1691226584Sdim assert(Defs.count(Name) && "Def does not exist!"); 1692226584Sdim Defs.erase(Name); 1693226584Sdim } 1694226584Sdim 1695226584Sdim //===--------------------------------------------------------------------===// 1696226584Sdim // High-level helper methods, useful for tablegen backends... 1697226584Sdim 1698226584Sdim /// getAllDerivedDefinitions - This method returns all concrete definitions 1699226584Sdim /// that derive from the specified class name. If a class with the specified 1700226584Sdim /// name does not exist, an exception is thrown. 1701226584Sdim std::vector<Record*> 1702226584Sdim getAllDerivedDefinitions(const std::string &ClassName) const; 1703226584Sdim 1704226584Sdim void dump() const; 1705226584Sdim}; 1706226584Sdim 1707226584Sdim/// LessRecord - Sorting predicate to sort record pointers by name. 1708226584Sdim/// 1709226584Sdimstruct LessRecord { 1710226584Sdim bool operator()(const Record *Rec1, const Record *Rec2) const { 1711226584Sdim return StringRef(Rec1->getName()).compare_numeric(Rec2->getName()) < 0; 1712226584Sdim } 1713226584Sdim}; 1714226584Sdim 1715243830Sdim/// LessRecordByID - Sorting predicate to sort record pointers by their 1716243830Sdim/// unique ID. If you just need a deterministic order, use this, since it 1717243830Sdim/// just compares two `unsigned`; the other sorting predicates require 1718243830Sdim/// string manipulation. 1719243830Sdimstruct LessRecordByID { 1720243830Sdim bool operator()(const Record *LHS, const Record *RHS) const { 1721243830Sdim return LHS->getID() < RHS->getID(); 1722243830Sdim } 1723243830Sdim}; 1724243830Sdim 1725226584Sdim/// LessRecordFieldName - Sorting predicate to sort record pointers by their 1726226584Sdim/// name field. 1727226584Sdim/// 1728226584Sdimstruct LessRecordFieldName { 1729226584Sdim bool operator()(const Record *Rec1, const Record *Rec2) const { 1730226584Sdim return Rec1->getValueAsString("Name") < Rec2->getValueAsString("Name"); 1731226584Sdim } 1732226584Sdim}; 1733226584Sdim 1734226584Sdimraw_ostream &operator<<(raw_ostream &OS, const RecordKeeper &RK); 1735226584Sdim 1736234353Sdim/// QualifyName - Return an Init with a qualifier prefix referring 1737234353Sdim/// to CurRec's name. 1738234353SdimInit *QualifyName(Record &CurRec, MultiClass *CurMultiClass, 1739234353Sdim Init *Name, const std::string &Scoper); 1740234353Sdim 1741234353Sdim/// QualifyName - Return an Init with a qualifier prefix referring 1742234353Sdim/// to CurRec's name. 1743234353SdimInit *QualifyName(Record &CurRec, MultiClass *CurMultiClass, 1744234353Sdim const std::string &Name, const std::string &Scoper); 1745234353Sdim 1746226584Sdim} // End llvm namespace 1747226584Sdim 1748226584Sdim#endif 1749