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