00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef COMMA_AST_TYPE_HDR_GUARD
00010 #define COMMA_AST_TYPE_HDR_GUARD
00011
00012 #include "comma/ast/AstBase.h"
00013 #include "comma/ast/Range.h"
00014 #include "comma/basic/ParameterModes.h"
00015
00016 #include "llvm/ADT/APInt.h"
00017 #include "llvm/ADT/FoldingSet.h"
00018 #include "llvm/ADT/SmallPtrSet.h"
00019 #include "llvm/ADT/PointerIntPair.h"
00020 #include "llvm/ADT/PointerUnion.h"
00021 #include "llvm/Support/Casting.h"
00022
00023 namespace comma {
00024
00025
00026
00027
00028 class Type : public Ast {
00029
00030 public:
00031 virtual ~Type() { }
00032
00035 enum Classification {
00036 CLASS_Scalar,
00037 CLASS_Discrete,
00038 CLASS_Enum,
00039 CLASS_Integer,
00040 CLASS_Composite,
00041 CLASS_Array,
00042 CLASS_String,
00043 CLASS_Access,
00044 CLASS_Record
00045 };
00046
00048 bool memberOf(Classification ID) const;
00049
00051 bool isScalarType() const;
00052
00054 bool isDiscreteType() const;
00055
00057 bool isIntegerType() const;
00058
00060 bool isEnumType() const;
00061
00063 bool isCompositeType() const;
00064
00066 bool isArrayType() const;
00067
00069 bool isRecordType() const;
00070
00072 bool isStringType() const;
00073
00075 bool isAccessType() const;
00076
00078 bool isFatAccessType() const;
00079
00081 bool isThinAccessType() const;
00082
00084 bool isUniversalType() const;
00085
00087 bool isUniversalIntegerType() const;
00088
00090 bool isUniversalAccessType() const;
00091
00093 bool isUniversalFixedType() const;
00094
00096 bool isUniversalRealType() const;
00097
00100 bool isUniversalTypeOf(const Type *type) const;
00101
00102 ArrayType *getAsArrayType();
00103 IntegerType *getAsIntegerType();
00104 EnumerationType *getAsEnumType();
00105
00111 bool involvesPercent() const;
00112
00118 bool isIndefiniteType() const;
00119
00124 bool isDefiniteType() const { return !isIndefiniteType(); }
00125
00126 static bool classof(const Type *node) { return true; }
00127 static bool classof(const Ast *node) {
00128 return node->denotesType();
00129 }
00130
00131 protected:
00132 Type(AstKind kind) : Ast(kind) {
00133
00134
00135 deletable = false;
00136 assert(this->denotesType());
00137 }
00138
00139 private:
00140 Type(const Type &);
00141 };
00142
00143
00144
00145 class SubroutineType : public Type {
00146
00147 public:
00148 virtual ~SubroutineType() { delete[] argumentTypes; }
00149
00151 unsigned getArity() const { return numArguments; }
00152
00154 Type *getArgType(unsigned i) const { return argumentTypes[i]; }
00155
00157 typedef Type **arg_type_iterator;
00158 arg_type_iterator begin() const { return argumentTypes; }
00159 arg_type_iterator end() const {
00160 return argumentTypes + numArguments; }
00161
00162
00163 static bool classof(const SubroutineType *node) { return true; }
00164 static bool classof(const Ast *node) {
00165 return node->denotesSubroutineType();
00166 }
00167
00168 protected:
00169 SubroutineType(AstKind kind, Type **argTypes, unsigned numArgs);
00170
00171 Type **argumentTypes;
00172 unsigned numArguments;
00173 };
00174
00175
00176
00177 class FunctionType : public SubroutineType, public llvm::FoldingSetNode {
00178
00179 public:
00181 Type *getReturnType() const { return returnType; }
00182
00184 void Profile(llvm::FoldingSetNodeID &ID) {
00185 Profile(ID, argumentTypes, numArguments, returnType);
00186 }
00187
00188
00189 static bool classof(const FunctionType *node) { return true; }
00190 static bool classof(const Ast *node) {
00191 return node->getKind() == AST_FunctionType;
00192 }
00193
00194 private:
00195 Type *returnType;
00196
00198 friend class AstResource;
00199
00200 FunctionType(Type **argTypes, unsigned numArgs, Type *returnType)
00201 : SubroutineType(AST_FunctionType, argTypes, numArgs),
00202 returnType(returnType) { }
00203
00205 static void Profile(llvm::FoldingSetNodeID &ID,
00206 Type **argTypes, unsigned numArgs,
00207 Type *returnType) {
00208 for (unsigned i = 0; i < numArgs; ++i)
00209 ID.AddPointer(argTypes[i]);
00210 ID.AddPointer(returnType);
00211 }
00212 };
00213
00214
00215
00216 class ProcedureType : public SubroutineType, public llvm::FoldingSetNode {
00217
00218 public:
00220 void Profile(llvm::FoldingSetNodeID &ID) {
00221 Profile(ID, argumentTypes, numArguments);
00222 }
00223
00224
00225 static bool classof(const ProcedureType *node) { return true; }
00226 static bool classof(const Ast *node) {
00227 return node->getKind() == AST_ProcedureType;
00228 }
00229
00230 private:
00232 friend class AstResource;
00233
00234 ProcedureType(Type **argTypes, unsigned numArgs)
00235 : SubroutineType(AST_ProcedureType, argTypes, numArgs) { }
00236
00238 static void Profile(llvm::FoldingSetNodeID &ID,
00239 Type **argTypes, unsigned numArgs) {
00240 if (numArgs)
00241 for (unsigned i = 0; i < numArgs; ++i)
00242 ID.AddPointer(argTypes[i]);
00243 else
00244 ID.AddPointer(0);
00245 }
00246 };
00247
00248
00249
00250
00253 class UniversalType : public Type {
00254
00255 public:
00256
00258
00259 static UniversalType *getUniversalInteger() {
00260 if (universal_integer)
00261 return universal_integer;
00262 universal_integer = new UniversalType();
00263 return universal_integer;
00264 }
00265
00266 static UniversalType *getUniversalAccess() {
00267 if (universal_access)
00268 return universal_access;
00269 universal_access = new UniversalType();
00270 return universal_access;
00271 }
00272
00273 static UniversalType *getUniversalFixed() {
00274 if (universal_fixed)
00275 return universal_fixed;
00276 universal_fixed = new UniversalType();
00277 return universal_fixed;
00278 }
00279
00280 static UniversalType *getUniversalReal() {
00281 if (universal_real)
00282 return universal_real;
00283 universal_real = new UniversalType();
00284 return universal_real;
00285 }
00287
00289
00290 bool isUniversalIntegerType() const { return this == universal_integer; }
00291 bool isUniversalAccessType() const { return this == universal_access; }
00292 bool isUniversalFixedType() const { return this == universal_fixed; }
00293 bool isUniversalRealType() const { return this == universal_real; }
00295
00297 Classification getClassification() const {
00298
00299 if (isUniversalIntegerType())
00300 return CLASS_Integer;
00301 assert(isUniversalAccessType() && "Unexpected universal type!");
00302 return CLASS_Access;
00303 }
00304
00305
00306 static bool classof(const UniversalType *node) { return true; }
00307 static bool classof(const Ast *node) {
00308 return node->getKind() == AST_UniversalType;
00309 }
00310
00311 private:
00312 UniversalType() : Type(AST_UniversalType) { }
00313
00316 static UniversalType *universal_integer;
00317 static UniversalType *universal_access;
00318 static UniversalType *universal_fixed;
00319 static UniversalType *universal_real;
00320 };
00321
00322
00323
00324
00328 class PrimaryType : public Type {
00329
00330 public:
00332 bool isSubtype() const { return typeChain.getInt(); }
00333
00335 bool isRootType() const { return !isSubtype(); }
00336
00338
00339
00340 const PrimaryType *getRootType() const {
00341 return const_cast<PrimaryType*>(this)->getRootType();
00342 }
00343 PrimaryType *getRootType() {
00344 PrimaryType *cursor = this;
00345 while (cursor->isSubtype())
00346 cursor = cursor->typeChain.getPointer();
00347 return cursor;
00348 }
00350
00352 bool isDerivedType() const {
00353 const PrimaryType *root = getRootType();
00354 return root->typeChain.getPointer() != 0;
00355 }
00356
00358
00359
00360 PrimaryType *getParentType() {
00361 PrimaryType *root = getRootType();
00362 return root->typeChain.getPointer();
00363 }
00364 const PrimaryType *getParentType() const {
00365 const PrimaryType *root = getRootType();
00366 return root->typeChain.getPointer();
00367 }
00369
00371
00372
00373 const PrimaryType *getAncestorType() const {
00374 return typeChain.getPointer();
00375 }
00376 PrimaryType *getAncestorType() { return typeChain.getPointer(); }
00378
00382 virtual bool isConstrained() const { return false; }
00383
00385 bool isUnconstrained() const { return !isConstrained(); }
00386
00390 bool isSubtypeOf(const PrimaryType *type) const {
00391 const PrimaryType *cursor = this;
00392 while (cursor->isSubtype()) {
00393 if (cursor == type)
00394 return true;
00395 cursor = cursor->typeChain.getPointer();
00396 }
00397 return cursor == type;
00398 }
00399
00400
00401 static bool classof(const PrimaryType *node) { return true; }
00402 static bool classof(const Ast *node) {
00403 return node->denotesPrimaryType();
00404 }
00405
00406 protected:
00418 PrimaryType(AstKind kind, PrimaryType *rootOrParent, bool subtype)
00419 : Type(kind) {
00420 assert(this->denotesPrimaryType());
00421 typeChain.setPointer(rootOrParent);
00422 typeChain.setInt(subtype);
00423 }
00424
00425 private:
00433 llvm::PointerIntPair<PrimaryType*, 1, bool> typeChain;
00434 };
00435
00436
00437
00438
00441 class IncompleteType : public PrimaryType {
00442
00443 public:
00445 IdentifierInfo *getIdInfo() const;
00446
00448 const char *getString() const { return getIdInfo()->getString(); }
00449
00451
00452 const IncompleteTypeDecl *getDefiningDecl() const {
00453 return const_cast<IncompleteType*>(this)->getDefiningDecl();
00454 }
00455 IncompleteTypeDecl *getDefiningDecl();
00457
00459 bool hasCompletion() const;
00460
00462
00463 const PrimaryType *getCompleteType() const {
00464 return const_cast<IncompleteType*>(this)->getCompleteType();
00465 }
00466 PrimaryType *getCompleteType();
00468
00470
00471 IncompleteType *getRootType() {
00472 return llvm::cast<IncompleteType>(PrimaryType::getRootType());
00473 }
00474 const IncompleteType *getRootType() const {
00475 return llvm::cast<IncompleteType>(PrimaryType::getRootType());
00476 }
00478
00479
00480 static bool classof(const IncompleteType *node) { return true; }
00481 static bool classof(const Ast *node) {
00482 return node->getKind() == AST_IncompleteType;
00483 }
00484
00485 private:
00488 IncompleteType(IncompleteTypeDecl *decl)
00489 : PrimaryType(AST_IncompleteType, 0, false),
00490 definingDecl(decl) { }
00491
00493 IncompleteType(IncompleteType *rootType, IdentifierInfo *name)
00494 : PrimaryType(AST_IncompleteType, rootType, true),
00495 definingDecl(name) { }
00496
00498 friend class AstResource;
00499
00503 llvm::PointerUnion<IncompleteTypeDecl *, IdentifierInfo *> definingDecl;
00504 };
00505
00506
00507
00508
00509 class DomainType : public PrimaryType {
00510
00511 public:
00513 IdentifierInfo *getIdInfo() const;
00514
00516 const char *getString() const { return getIdInfo()->getString(); }
00517
00519 bool denotesPercent() const { return getPercentDecl() != 0; }
00520
00522 bool isConcrete() const { return getInstanceDecl() != 0; }
00523
00525 bool isAbstract() const { return getAbstractDecl() != 0; }
00526
00527
00529 const DomainTypeDecl *getDomainTypeDecl() const;
00530 DomainTypeDecl *getDomainTypeDecl();
00532
00534
00535 const PercentDecl *getPercentDecl() const;
00536 PercentDecl *getPercentDecl();
00538
00539
00542 const DomainInstanceDecl *getInstanceDecl() const;
00543 DomainInstanceDecl *getInstanceDecl();
00545
00547
00548
00549 const AbstractDomainDecl *getAbstractDecl() const;
00550 AbstractDomainDecl *getAbstractDecl();
00552
00554
00555
00556 const PrimaryType *getRepresentationType() const {
00557 return const_cast<DomainType*>(this)->getRepresentationType();
00558 }
00559 PrimaryType *getRepresentationType();
00561
00563
00564 DomainType *getRootType() {
00565 return llvm::cast<DomainType>(PrimaryType::getRootType());
00566 }
00567 const DomainType *getRootType() const {
00568 return llvm::cast<DomainType>(PrimaryType::getRootType());
00569 }
00571
00573 static bool classof(const DomainType *node) { return true; }
00574 static bool classof(const Ast *node) {
00575 return node->getKind() == AST_DomainType;
00576 }
00577
00578 private:
00580 DomainType(DomainTypeDecl *DTDecl);
00581
00583 DomainType(DomainType *rootType, IdentifierInfo *name);
00584
00586 friend class AstResource;
00587
00591 llvm::PointerUnion<DomainTypeDecl*, IdentifierInfo*> definingDecl;
00592 };
00593
00594
00595
00596
00599 class DiscreteType : public PrimaryType {
00600
00601 public:
00603 virtual IdentifierInfo *getIdInfo() const = 0;
00604
00610 virtual void getUpperLimit(llvm::APInt &res) const = 0;
00611
00617 virtual void getLowerLimit(llvm::APInt &res) const = 0;
00618
00625 virtual uint64_t getSize() const = 0;
00626
00631 uint64_t length() const;
00632
00635 enum ContainmentResult {
00636 Is_Contained,
00637 Not_Contained,
00638 Maybe_Contained
00639 };
00640
00661 ContainmentResult contains(const DiscreteType *target) const;
00662
00664 ContainmentResult contains(const llvm::APInt &value) const;
00665
00669 bool isSigned() const;
00670
00672
00673 const DiscreteType *getRootType() const {
00674 return llvm::cast<DiscreteType>(PrimaryType::getRootType());
00675 }
00676 DiscreteType *getRootType() {
00677 return llvm::cast<DiscreteType>(PrimaryType::getRootType());
00678 }
00680
00682
00683
00684 virtual Range *getConstraint() = 0;
00685 virtual const Range *getConstraint() const = 0;
00687
00689 bool isStaticallyConstrained() const {
00690 if (const Range *range = getConstraint())
00691 return range->isStatic();
00692 return false;
00693 }
00694
00697 bool isDynamicallyConstrained() const {
00698 if (const Range *range = getConstraint())
00699 return !range->isStatic();
00700 return false;
00701 }
00702
00705 virtual PosAD *getPosAttribute() = 0;
00706
00709 virtual ValAD *getValAttribute() = 0;
00710
00711
00712 static bool classof(const DiscreteType *node) { return true; }
00713 static bool classof(const Ast *node) {
00714 return denotesDiscreteType(node->getKind());
00715 }
00716
00717 protected:
00718 DiscreteType(AstKind kind, DiscreteType *rootOrParent, bool subtype)
00719 : PrimaryType(kind, rootOrParent, subtype) {
00720 assert(denotesDiscreteType(kind));
00721 }
00722
00723
00724
00725
00726 static unsigned getPreferredSize(uint64_t bits);
00727
00728 private:
00729 static bool denotesDiscreteType(AstKind kind) {
00730 return (kind == AST_EnumerationType || kind == AST_IntegerType);
00731 }
00732 };
00733
00734
00735
00736 class EnumerationType : public DiscreteType {
00737
00738 public:
00739 virtual ~EnumerationType() { }
00740
00744 void getLowerLimit(llvm::APInt &res) const;
00745
00749 void getUpperLimit(llvm::APInt &res) const;
00750
00754 uint64_t getSize() const;
00755
00757 uint64_t getNumLiterals() const;
00758
00760 bool isCharacterType() const;
00761
00763 bool isConstrained() const { return getConstraint() != 0; }
00764
00766
00767
00768 Range *getConstraint();
00769 const Range *getConstraint() const;
00771
00773
00774 EnumerationType *getRootType() {
00775 return llvm::cast<EnumerationType>(PrimaryType::getRootType());
00776 }
00777 const EnumerationType *getRootType() const {
00778 return llvm::cast<EnumerationType>(PrimaryType::getRootType());
00779 }
00781
00783
00784 EnumerationType *getBaseSubtype();
00785 const EnumerationType *getBaseSubtype() const;
00787
00789
00790 const EnumerationDecl *getDefiningDecl() const {
00791 return const_cast<EnumerationType*>(this)->getDefiningDecl();
00792 }
00793 EnumerationDecl *getDefiningDecl();
00795
00798 PosAD *getPosAttribute();
00799
00802 ValAD *getValAttribute();
00803
00804
00805 static bool classof(const EnumerationType *node) { return true; }
00806 static bool classof(const Ast *node) {
00807 return node->getKind() == AST_EnumerationType;
00808 }
00809
00810 private:
00815
00817 static EnumerationType *create(AstResource &resource,
00818 EnumerationDecl *decl);
00819
00821 static EnumerationType *createSubtype(EnumerationType *rootType,
00822 EnumerationDecl *decl = 0);
00823
00825 static EnumerationType *createConstrainedSubtype(EnumerationType *rootType,
00826 Expr *lower, Expr *upper,
00827 EnumerationDecl *decl);
00829 friend class AstResource;
00830
00831 protected:
00833
00834
00835
00836 enum EnumKind {
00837 RootEnumType_KIND,
00838 UnconstrainedEnumType_KIND,
00839 ConstrainedEnumType_KIND
00840 };
00841
00843 static bool isSubtypeKind(EnumKind kind) {
00844 return (kind == UnconstrainedEnumType_KIND ||
00845 kind == ConstrainedEnumType_KIND);
00846 }
00847
00849 EnumerationType(EnumKind kind, EnumerationType *rootOrParent)
00850 : DiscreteType(AST_EnumerationType, rootOrParent, isSubtypeKind(kind)) {
00851 bits = kind;
00852 }
00853
00854 public:
00856 EnumKind getEnumKind() const { return EnumKind(bits); }
00857 };
00858
00859
00860
00861
00862
00863
00864 class IntegerType : public DiscreteType {
00865
00866 public:
00867 virtual ~IntegerType() { }
00868
00872 void getLowerLimit(llvm::APInt &res) const;
00873
00877 void getUpperLimit(llvm::APInt &res) const;
00878
00881 bool baseContains(const llvm::APInt &value) const;
00882
00886 uint64_t getSize() const;
00887
00889
00890
00891
00892
00893 const IntegerType *getBaseSubtype() const {
00894 return const_cast<IntegerType*>(this)->getBaseSubtype();
00895 }
00896 IntegerType *getBaseSubtype();
00898
00900 bool isConstrained() const { return getConstraint() != 0; }
00901
00903
00904
00905 Range *getConstraint();
00906 const Range *getConstraint() const;
00908
00910
00911 IntegerType *getRootType() {
00912 return llvm::cast<IntegerType>(PrimaryType::getRootType());
00913 }
00914 const IntegerType *getRootType() const {
00915 return llvm::cast<IntegerType>(PrimaryType::getRootType());
00916 }
00918
00921 PosAD *getPosAttribute();
00922
00925 ValAD *getValAttribute();
00926
00928 static bool classof(const IntegerType *node) { return true; }
00929 static bool classof(const Ast *node) {
00930 return node->getKind() == AST_IntegerType;
00931 }
00932
00933 private:
00938
00939
00941 static IntegerType *create(AstResource &resource, IntegerDecl *decl,
00942 const llvm::APInt &lower,
00943 const llvm::APInt &upper);
00944
00946 static IntegerType *createSubtype(IntegerType *rootType,
00947 IntegerDecl *decl = 0);
00948
00953 static IntegerType *createConstrainedSubtype(IntegerType *rootType,
00954 Expr *lower, Expr *upper,
00955 IntegerDecl *decl);
00956
00958 friend class AstResource;
00959
00961
00962 const IntegerDecl *getDefiningDecl() const {
00963 return const_cast<IntegerType*>(this)->getDefiningDecl();
00964 }
00965 virtual IntegerDecl *getDefiningDecl() = 0;
00967
00968 protected:
00973 enum IntegerKind {
00974 RootIntegerType_KIND,
00975 UnconstrainedIntegerType_KIND,
00976 ConstrainedIntegerType_KIND
00977 };
00978
00980 static bool isSubtypeKind(IntegerKind kind) {
00981 return (kind == UnconstrainedIntegerType_KIND ||
00982 kind == ConstrainedIntegerType_KIND);
00983 }
00984
00986 IntegerType(IntegerKind kind, IntegerType *rootOrParent)
00987 : DiscreteType(AST_IntegerType, rootOrParent, isSubtypeKind(kind)) {
00988 bits = kind;
00989 }
00990
00991 public:
00993 IntegerKind getIntegerKind() const { return IntegerKind(bits); }
00994 };
00995
00996
00997
00998
01002 class CompositeType : public PrimaryType {
01003
01004 public:
01005 static bool classof(const CompositeType *node) { return true; }
01006 static bool classof(const Ast *node) {
01007 return node->denotesCompositeType();
01008 }
01009
01010 protected:
01011 CompositeType(AstKind kind, CompositeType *rootOrParent, bool subtype)
01012 : PrimaryType(kind, rootOrParent, subtype) {
01013 assert(this->denotesCompositeType());
01014 }
01015 };
01016
01017
01018
01019
01020
01021
01022 class ArrayType : public CompositeType {
01023
01025 typedef llvm::SmallVector<DiscreteType*, 4> IndexVec;
01026
01027 public:
01029 IdentifierInfo *getIdInfo() const;
01030
01032 unsigned getRank() const { return indices.size(); }
01033
01035 bool isVector() const { return getRank() == 1; }
01036
01039 uint64_t length() const;
01040
01042
01043 const DiscreteType *getIndexType(unsigned i) const { return indices[i]; }
01044 DiscreteType *getIndexType(unsigned i) { return indices[i]; }
01046
01050
01051 typedef IndexVec::iterator iterator;
01052 iterator begin() { return indices.begin(); }
01053 iterator end() { return indices.end(); }
01054
01055 typedef IndexVec::const_iterator const_iterator;
01056 const_iterator begin() const { return indices.begin(); }
01057 const_iterator end() const { return indices.end(); }
01059
01061 Type *getComponentType() const { return componentType; }
01062
01064 bool isConstrained() const { return constraintBit(); }
01065
01067 bool isStaticallyConstrained() const;
01068
01070
01071 ArrayType *getRootType() {
01072 return llvm::cast<ArrayType>(PrimaryType::getRootType());
01073 }
01074 const ArrayType *getRootType() const {
01075 return llvm::cast<ArrayType>(PrimaryType::getRootType());
01076 }
01078
01080
01081 const ArrayDecl *getDefiningDecl() const {
01082 return getRootType()->definingDecl.get<ArrayDecl*>();
01083 }
01084 ArrayDecl *getDefiningDecl() {
01085 return getRootType()->definingDecl.get<ArrayDecl*>();
01086 }
01088
01089
01090 static bool classof(const ArrayType *node) { return true; }
01091 static bool classof(const Ast *node) {
01092 return node->getKind() == AST_ArrayType;
01093 }
01094
01095 private:
01097 ArrayType(ArrayDecl *decl, unsigned rank, DiscreteType **indices,
01098 Type *component, bool isConstrained);
01099
01101 ArrayType(IdentifierInfo *name, ArrayType *rootType,
01102 DiscreteType **indices);
01103
01105 ArrayType(IdentifierInfo *name, ArrayType *rootType);
01106
01107 friend class AstResource;
01108
01111 enum PropertyTags {
01113 Constrained_PROP = 1,
01114 };
01115
01117 bool constraintBit() const { return bits & Constrained_PROP; }
01118
01120 void setConstraintBit() { bits |= Constrained_PROP; }
01121
01123 IndexVec indices;
01124
01126 Type *componentType;
01127
01133 llvm::PointerUnion<ArrayDecl*, IdentifierInfo*> definingDecl;
01134 };
01135
01136
01137
01138 class RecordType : public CompositeType {
01139
01140 public:
01142 IdentifierInfo *getIdInfo() const;
01143
01145
01146 RecordType *getRootType() {
01147 return llvm::cast<RecordType>(PrimaryType::getRootType());
01148 }
01149 const RecordType *getRootType() const {
01150 return llvm::cast<RecordType>(PrimaryType::getRootType());
01151 }
01153
01155
01156 const RecordDecl *getDefiningDecl() const {
01157 return const_cast<RecordType*>(this)->getDefiningDecl();
01158 }
01159 RecordDecl *getDefiningDecl();
01161
01163 unsigned numComponents() const;
01164
01166
01167 const Type *getComponentType(unsigned i) const {
01168 return const_cast<RecordType*>(this)->getComponentType(i);
01169 }
01170 Type *getComponentType(unsigned i);
01172
01174 bool isConstrained() const { return true; }
01175
01176
01177 static bool classof(const RecordType *node) { return true; }
01178 static bool classof(const Ast *node) {
01179 return node->getKind() == AST_RecordType;
01180 }
01181
01182 private:
01183 RecordType(RecordDecl *decl);
01184 RecordType(RecordType *rootType, IdentifierInfo *name);
01185
01186 friend class AstResource;
01187
01193 llvm::PointerUnion<RecordDecl*, IdentifierInfo*> definingDecl;
01194 };
01195
01196
01197
01198 class AccessType : public PrimaryType {
01199
01200 public:
01202 IdentifierInfo *getIdInfo() const;
01203
01205 const char *getString() const { return getIdInfo()->getString(); }
01206
01208
01209 const AccessDecl *getDefiningDecl() const {
01210 return const_cast<AccessType*>(this)->getDefiningDecl();
01211 }
01212 AccessDecl *getDefiningDecl();
01214
01215
01217 const Type *getTargetType() const { return targetType; }
01218 Type *getTargetType() { return targetType; }
01220
01222
01223 AccessType *getRootType() {
01224 return llvm::cast<AccessType>(PrimaryType::getRootType());
01225 }
01226 const AccessType *getRootType() const {
01227 return llvm::cast<AccessType>(PrimaryType::getRootType());
01228 }
01230
01231
01232 static bool classof(const AccessType *node) { return true; }
01233 static bool classof(const Ast *node) {
01234 return node->getKind() == AST_AccessType;
01235 }
01236
01237 private:
01240 AccessType(AccessDecl *decl, Type *targetType);
01241
01243 AccessType(AccessType *rootType, IdentifierInfo *name);
01244
01246 friend class AstResource;
01247
01248 Type *targetType;
01249
01252 llvm::PointerUnion<AccessDecl*, IdentifierInfo*> definingDecl;
01253 };
01254
01255 }
01256
01257 #endif