00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #ifndef COMMA_AST_DECL_HDR_GUARD
00010 #define COMMA_AST_DECL_HDR_GUARD
00011 
00012 #include "comma/ast/AstBase.h"
00013 #include "comma/ast/DeclRegion.h"
00014 #include "comma/ast/Pragma.h"
00015 #include "comma/ast/SignatureSet.h"
00016 #include "comma/ast/Type.h"
00017 #include "comma/basic/ParameterModes.h"
00018 #include "comma/basic/Pragmas.h"
00019 #include "comma/basic/PrimitiveOps.h"
00020 
00021 #include "llvm/ADT/ilist.h"
00022 #include "llvm/ADT/FoldingSet.h"
00023 #include "llvm/ADT/PointerIntPair.h"
00024 #include "llvm/ADT/PointerUnion.h"
00025 
00026 namespace comma {
00027 
00028 
00029 
00030 
00031 
00032 class Decl : public Ast {
00033 
00034 public:
00035     virtual ~Decl() { };
00036 
00037     
00038     
00039     IdentifierInfo *getIdInfo() const { return idInfo; }
00040 
00041     
00042     
00043     const char *getString() const {
00044         return idInfo ? idInfo->getString() : 0;
00045     }
00046 
00047     
00048     Location getLocation() const { return location; }
00049 
00050     
00051     
00052     void setDeclRegion(DeclRegion *region) {
00053         assert(context == 0 && "Cannot reset a decl's declarative region!");
00054         context = region;
00055     }
00056 
00057     
00058     
00059     
00060     DeclRegion *getDeclRegion() { return context; }
00061     const DeclRegion *getDeclRegion() const { return context; }
00062 
00063     
00064     bool isDeclaredIn(const DeclRegion *region) const {
00065         return region == context;
00066     }
00067 
00070     DeclRegion *asDeclRegion();
00071 
00081     Decl *getOrigin() { return origin; }
00082     const Decl *getOrigin() const { return origin; }
00083 
00085     bool hasOrigin() const { return origin != 0; }
00086 
00088     void setOrigin(Decl *decl) {
00089         assert(decl->getKind() == this->getKind() && "Kind mismatch!");
00090         origin = decl;
00091     }
00092 
00094     Decl *resolveOrigin();
00095     const Decl *resolveOrigin() const {
00096         return const_cast<Decl*>(this)->resolveOrigin();
00097     }
00098 
00105     bool isImmediate() const { return !hasOrigin(); }
00106 
00107     
00108     static bool classof(const Decl *node) { return true; }
00109     static bool classof(const Ast *node) {
00110         return node->denotesDecl();
00111     }
00112 
00113 protected:
00114     Decl(AstKind kind, IdentifierInfo *info = 0, Location loc = 0,
00115          DeclRegion *region = 0)
00116         : Ast(kind),
00117           idInfo(info),
00118           location(loc),
00119           context(region),
00120           origin(0) {
00121         assert(this->denotesDecl());
00122         deletable = false;
00123     }
00124 
00125     IdentifierInfo *idInfo;
00126     Location location;
00127     DeclRegion *context;
00128     Decl *origin;
00129 };
00130 
00131 
00132 
00133 
00134 
00135 class ImportDecl : public Decl {
00136 
00137 public:
00138     ImportDecl(Type *target, Location loc)
00139         : Decl(AST_ImportDecl, 0, loc),
00140           targetType(target) { }
00141 
00142     Type *getImportedType() { return targetType; }
00143     const Type *getImportedType() const { return targetType; }
00144 
00145     static bool classof(const ImportDecl *node) { return true; }
00146     static bool classof(const Ast *node) {
00147         return node->getKind() == AST_ImportDecl;
00148     }
00149 
00150 private:
00151     Type *targetType;
00152 };
00153 
00154 
00155 
00156 
00163 class ExceptionDecl : public Decl {
00164 
00165 public:
00168     enum ExceptionKind {
00169         User,                   
00170         Program_Error,          
00171         Constraint_Error,       
00172         Assertion_Error         
00173     };
00174 
00175     ExceptionKind getID() const { return static_cast<ExceptionKind>(bits); }
00176 
00177     
00178     static bool classof(const ExceptionDecl *node) { return true; }
00179     static bool classof(const Ast *node) {
00180         return node->getKind() == AST_ExceptionDecl;
00181     }
00182 
00183 private:
00184     ExceptionDecl(ExceptionKind ID, IdentifierInfo *name, Location loc,
00185                   DeclRegion *region)
00186         : Decl(AST_ExceptionDecl, name, loc, region) {
00187         bits = ID;
00188     }
00189 
00190     
00191     friend class AstResource;
00192 };
00193 
00194 
00195 
00196 
00197 
00198 
00199 class ModelDecl : public Decl {
00200 
00201 public:
00202     virtual ~ModelDecl();
00203 
00205     bool isParameterized() const {
00206         return kind == AST_VarietyDecl || kind == AST_FunctorDecl;
00207     }
00208 
00210     virtual unsigned getArity() const;
00211 
00213 
00214 
00215 
00216 
00217     const AbstractDomainDecl *getFormalDecl(unsigned i) const {
00218         return const_cast<ModelDecl*>(this)->getFormalDecl(i);
00219     }
00220     virtual AbstractDomainDecl *getFormalDecl(unsigned i);
00222 
00226     unsigned getFormalIndex(const AbstractDomainDecl *ADDecl) const;
00227 
00229 
00230 
00231     const DomainType *getFormalType(unsigned i) const {
00232         return const_cast<ModelDecl*>(this)->getFormalType(i);
00233     }
00234     DomainType *getFormalType(unsigned i);
00236 
00240     SigInstanceDecl *getFormalSignature(unsigned i) const;
00241 
00244     IdentifierInfo *getFormalIdInfo(unsigned i) const;
00245 
00249     int getKeywordIndex(IdentifierInfo *keyword) const;
00250 
00252     PercentDecl *getPercent() const { return percent; }
00253 
00255 
00256     const DomainType *getPercentType() const;
00257     DomainType *getPercentType();
00259 
00261     const SignatureSet &getSignatureSet() const;
00262 
00265     bool addDirectSignature(SigInstanceDecl *signature);
00266 
00271     AstResource &getAstResource() { return resource; }
00272 
00273     
00274     static bool classof(const ModelDecl *node) { return true; }
00275     static bool classof(const Ast *node) {
00276         return node->denotesModelDecl();
00277     }
00278 
00279 protected:
00280     ModelDecl(AstResource &resource,
00281               AstKind kind, IdentifierInfo *name, Location loc);
00282 
00283     
00284     PercentDecl *percent;
00285 
00286     
00287     AstResource &resource;
00288 };
00289 
00290 
00291 
00292 
00293 
00294 
00295 class Sigoid : public ModelDecl {
00296 
00297 public:
00298     
00299     Sigoid(AstResource &resource,
00300            AstKind kind, IdentifierInfo *name, Location loc)
00301         : ModelDecl(resource, kind, name, loc) { }
00302 
00303     virtual ~Sigoid() { }
00304 
00305     
00306     
00307     SignatureDecl *getSignature();
00308 
00309     
00310     
00311     VarietyDecl *getVariety();
00312 
00313     static bool classof(const Sigoid *node) { return true; }
00314     static bool classof(const Ast *node) {
00315         AstKind kind = node->getKind();
00316         return kind == AST_SignatureDecl || kind == AST_VarietyDecl;
00317     }
00318 };
00319 
00320 
00321 
00322 
00323 
00324 class SignatureDecl : public Sigoid {
00325 
00326 public:
00327     
00328     SignatureDecl(AstResource &resource,
00329                   IdentifierInfo *name, const Location &loc);
00330 
00331     SigInstanceDecl *getInstance() { return theInstance; }
00332     const SigInstanceDecl *getInstance() const { return theInstance; }
00333 
00334     
00335     static bool classof(const SignatureDecl *node) { return true; }
00336     static bool classof(const Ast *node) {
00337         return node->getKind() == AST_SignatureDecl;
00338     }
00339 
00340 private:
00341     
00342     SigInstanceDecl *theInstance;
00343 };
00344 
00345 
00346 
00347 
00348 
00349 class VarietyDecl : public Sigoid {
00350 
00351 public:
00352     
00353     
00354     VarietyDecl(AstResource &resource,
00355                 IdentifierInfo *name, Location loc,
00356                 AbstractDomainDecl **formals, unsigned arity);
00357 
00359 
00360 
00361     SigInstanceDecl *getInstance(DomainTypeDecl **args, unsigned numArgs);
00362     const SigInstanceDecl *getInstance(DomainTypeDecl **args,
00363                                        unsigned numArgs) const {
00364         return const_cast<VarietyDecl*>(this)->getInstance(args, numArgs);
00365     }
00367 
00369     int getKeywordIndex(IdentifierInfo *keyword) const;
00370 
00372     unsigned getArity() const { return arity; }
00373 
00375     AbstractDomainDecl *getFormalDecl(unsigned i) {
00376         assert(i < arity && "Index out of range!");
00377         return formalDecls[i];
00378     }
00379 
00382     typedef llvm::FoldingSet<SigInstanceDecl>::iterator instance_iterator;
00383     instance_iterator begin_instances() { return instances.begin(); }
00384     instance_iterator end_instances() { return instances.end(); }
00385 
00386     
00387     static bool classof(const VarietyDecl *node) { return true; }
00388     static bool classof(const Ast *node) {
00389         return node->getKind() == AST_VarietyDecl;
00390     }
00391 
00392 private:
00395     mutable llvm::FoldingSet<SigInstanceDecl>  instances;
00396 
00397     unsigned arity;                   
00398     AbstractDomainDecl **formalDecls; 
00399 };
00400 
00401 
00402 
00403 
00404 
00405 
00406 
00407 class Domoid : public ModelDecl {
00408 
00409 public:
00410     virtual ~Domoid() { }
00411 
00412     
00413     DomainDecl *getDomain();
00414 
00415     
00416     FunctorDecl *getFunctor();
00417 
00418     
00419     
00420     
00421     virtual void finalize() = 0;
00422 
00423     
00424     virtual bool isFinalized() const = 0;
00425 
00427 
00428     virtual AddDecl *getImplementation() = 0;
00429     const AddDecl *getImplementation() const {
00430         return const_cast<Domoid*>(this)->getImplementation();
00431     }
00433 
00434     static bool classof(const Domoid *node) { return true; }
00435     static bool classof(const Ast *node) {
00436         AstKind kind = node->getKind();
00437         return (kind == AST_DomainDecl or kind == AST_FunctorDecl);
00438     }
00439 
00440 protected:
00441     Domoid(AstResource &resource,
00442            AstKind kind, IdentifierInfo *idInfo, Location loc);
00443 };
00444 
00445 
00446 
00447 
00453 class AddDecl : public Decl, public DeclRegion {
00454 
00455 public:
00457     AddDecl(PercentDecl *percent);
00458 
00460     bool implementsDomain() const;
00461 
00463     bool implementsFunctor() const;
00464 
00465     
00467     const Domoid *getImplementedDomoid() const {
00468         return const_cast<AddDecl*>(this)->getImplementedDomoid();
00469     }
00470     Domoid *getImplementedDomoid();
00472 
00474 
00475 
00476     const DomainDecl *getImplementedDomain() const {
00477         return const_cast<AddDecl*>(this)->getImplementedDomain();
00478     }
00479     DomainDecl *getImplementedDomain();
00481 
00483 
00484 
00485     const FunctorDecl *getImplementedFunctor() const {
00486         return const_cast<AddDecl*>(this)->getImplementedFunctor();
00487     }
00488     FunctorDecl *getImplementedFunctor();
00490 
00492     bool hasCarrier() const { return carrier != 0; }
00493 
00495     void setCarrier(CarrierDecl *carrier) {
00496         assert(!hasCarrier() && "Cannot reset carrier declaration!");
00497         this->carrier = carrier;
00498     }
00499 
00501 
00502 
00503     CarrierDecl *getCarrier() { return carrier; }
00504     const CarrierDecl *getCarrier() const { return carrier; }
00506 
00507     
00508     static bool classof(const AddDecl *node) { return true; }
00509     static bool classof(const Ast *node) {
00510         return node->getKind() == AST_AddDecl;
00511     }
00512 
00513 private:
00514     
00515     CarrierDecl *carrier;
00516 };
00517 
00518 
00519 
00520 
00521 class DomainDecl : public Domoid {
00522 
00523 public:
00524     DomainDecl(AstResource &resource,
00525                IdentifierInfo *name, const Location &loc);
00526 
00527     DomainInstanceDecl *getInstance();
00528     const DomainInstanceDecl *getInstance() const {
00529         return const_cast<DomainDecl*>(this)->getInstance();
00530     }
00531 
00533     void finalize();
00534 
00536     bool isFinalized() const;
00537 
00539     AddDecl *getImplementation() { return implementation; }
00540 
00541     
00542     static bool classof(const DomainDecl *node) { return true; }
00543     static bool classof(const Ast *node) {
00544         return node->getKind() == AST_DomainDecl;
00545     }
00546 
00547 private:
00548     DomainInstanceDecl *instance;
00549     AddDecl *implementation;
00550 };
00551 
00552 
00553 
00554 
00555 
00556 class FunctorDecl : public Domoid {
00557 
00558 public:
00559     FunctorDecl(AstResource &resource,
00560                 IdentifierInfo *name, Location loc,
00561                 AbstractDomainDecl **formals, unsigned arity);
00562 
00563     
00564     
00565     
00566     
00567     DomainInstanceDecl *getInstance(DomainTypeDecl **args, unsigned numArgs);
00568 
00569     const DomainInstanceDecl *getInstance(DomainTypeDecl **args,
00570                                           unsigned numArgs) const {
00571         FunctorDecl *fdecl = const_cast<FunctorDecl*>(this);
00572         return fdecl->getInstance(args, numArgs);
00573     }
00574 
00575     
00576     AddDecl *getImplementation() { return implementation; }
00577 
00579     unsigned getArity() const { return arity; }
00580 
00582     AbstractDomainDecl *getFormalDecl(unsigned i) {
00583         assert(i < arity && "Index out of range!");
00584         return formalDecls[i];
00585     }
00586 
00588     void finalize();
00589 
00591     bool isFinalized() const;
00592 
00593     
00594     static bool classof(const FunctorDecl *node) { return true; }
00595     static bool classof(const Ast *node) {
00596         return node->getKind() == AST_FunctorDecl;
00597     }
00598 
00599 private:
00602     typedef llvm::FoldingSet<DomainInstanceDecl> InstanceSet;
00603     mutable InstanceSet instances;
00604 
00605     unsigned arity;                   
00606     AbstractDomainDecl **formalDecls; 
00607     AddDecl *implementation;          
00608 };
00609 
00610 
00611 
00612 
00613 class SigInstanceDecl : public Decl, public llvm::FoldingSetNode {
00614 
00615 public:
00616     Sigoid *getSigoid() { return underlyingSigoid; }
00617     const Sigoid *getSigoid() const { return underlyingSigoid; }
00618 
00619     SignatureDecl *getSignature() const;
00620 
00621     VarietyDecl *getVariety() const;
00622 
00624     bool isParameterized() const { return getVariety() != 0; }
00625 
00628     unsigned getArity() const;
00629 
00632     DomainTypeDecl *getActualParam(unsigned n) const {
00633         assert(isParameterized() &&
00634                "Cannot fetch parameter from non-parameterized type!");
00635         assert(n < getArity() && "Parameter index out of range!");
00636         return arguments[n];
00637     }
00638 
00640     DomainType *getActualParamType(unsigned n) const;
00641 
00642     typedef DomainTypeDecl **arg_iterator;
00643     arg_iterator beginArguments() const { return arguments; }
00644     arg_iterator endArguments() const { return &arguments[getArity()]; }
00645 
00647     void Profile(llvm::FoldingSetNodeID &id) {
00648         Profile(id, &arguments[0], getArity());
00649     }
00650 
00651     static bool classof(const SigInstanceDecl *node) { return true; }
00652     static bool classof(const Ast *node) {
00653         return node->getKind() == AST_SigInstanceDecl;
00654     }
00655 
00656 private:
00657     friend class SignatureDecl;
00658     friend class VarietyDecl;
00659 
00660     SigInstanceDecl(SignatureDecl *decl);
00661 
00662     SigInstanceDecl(VarietyDecl *decl, DomainTypeDecl **args, unsigned numArgs);
00663 
00664     
00665     static void
00666     Profile(llvm::FoldingSetNodeID &id,
00667             DomainTypeDecl **args, unsigned numArgs);
00668 
00669     
00670     Sigoid *underlyingSigoid;
00671 
00672     
00673     
00674     DomainTypeDecl **arguments;
00675 };
00676 
00677 
00678 
00679 
00680 
00681 
00682 class ValueDecl : public Decl {
00683 
00684 protected:
00685     ValueDecl(AstKind kind, IdentifierInfo *name, Type *type, Location loc)
00686         : Decl(kind, name, loc),
00687           correspondingType(type) {
00688         assert(this->denotesValueDecl());
00689     }
00690 
00691 public:
00693 
00694     const Type *getType() const { return correspondingType; }
00695     Type *getType() { return correspondingType; }
00697 
00698     static bool classof(const ValueDecl *node) { return true; }
00699     static bool classof(const Ast *node) {
00700         return node->denotesValueDecl();
00701     }
00702 
00703 protected:
00704     Type *correspondingType;
00705 };
00706 
00707 
00708 
00709 
00710 
00711 
00712 
00713 class ParamValueDecl : public ValueDecl {
00714 
00715 public:
00716     ParamValueDecl(IdentifierInfo *name,
00717                    Type *type,
00718                    PM::ParameterMode mode,
00719                    Location loc)
00720         : ValueDecl(AST_ParamValueDecl, name, type, loc) {
00721         
00722         
00723         
00724         
00725         
00726         
00727         
00728         bits = mode;
00729     }
00730 
00734     bool parameterModeSpecified() const;
00735 
00740     PM::ParameterMode getParameterMode() const;
00741 
00743     PM::ParameterMode getExplicitParameterMode() const;
00744 
00746     void setParameterMode(PM::ParameterMode mode);
00747 
00748     static bool classof(const ParamValueDecl *node) { return true; }
00749     static bool classof(const Ast *node) {
00750         return node->getKind() == AST_ParamValueDecl;
00751     }
00752 };
00753 
00754 
00755 
00756 
00757 
00758 
00759 class ObjectDecl : public ValueDecl {
00760 
00761 public:
00762     ObjectDecl(IdentifierInfo *name,
00763                Type           *type,
00764                Location        loc,
00765                Expr           *init = 0)
00766         : ValueDecl(AST_ObjectDecl, name, type, loc),
00767           initialization(init) { }
00768 
00769     
00770     
00771     bool hasInitializer() const { return initialization != 0; }
00772 
00773     
00774     
00775     Expr *getInitializer() const { return initialization; }
00776 
00777     
00778     
00779     void setInitializer(Expr *init) { initialization = init; }
00780 
00781     
00782     static bool classof(const ObjectDecl *node) { return true; }
00783     static bool classof(const Ast *node) {
00784         return node->getKind() == AST_ObjectDecl;
00785     }
00786 
00787 private:
00788     Expr *initialization;
00789 };
00790 
00791 
00792 
00793 
00797 class RenamedObjectDecl : public ValueDecl {
00798 
00799 public:
00800     RenamedObjectDecl(IdentifierInfo *name, Type *type, Location loc,
00801                       Expr *expr)
00802         : ValueDecl(AST_RenamedObjectDecl, name, type, loc),
00803           renamedExpr(expr) { }
00804 
00806 
00807     const Expr *getRenamedExpr() const { return renamedExpr; }
00808     Expr *getRenamedExpr() { return renamedExpr; }
00810 
00812     void setRenamedExpr(Expr *expr) { renamedExpr = expr; }
00813 
00814     
00815     static bool classof(const RenamedObjectDecl *node) { return true; }
00816     static bool classof(const Ast *node) {
00817         return node->getKind() == AST_RenamedObjectDecl;
00818     }
00819 
00820 private:
00821     Expr *renamedExpr;
00822 };
00823 
00824 
00825 
00826 
00828 class LoopDecl : public ValueDecl {
00829 
00830 public:
00831     LoopDecl(IdentifierInfo *name, DiscreteType *type, Location loc)
00832         : ValueDecl(AST_LoopDecl, name, type, loc) { }
00833 
00835 
00836     const DiscreteType *getType() const {
00837         return llvm::cast<DiscreteType>(ValueDecl::getType());
00838     }
00839     DiscreteType *getType() {
00840         return llvm::cast<DiscreteType>(ValueDecl::getType());
00841     }
00843 
00844     
00845     static bool classof(const LoopDecl *node) { return true; }
00846     static bool classof(const Ast *node) {
00847         return node->getKind() == AST_LoopDecl;
00848     }
00849 };
00850 
00851 
00852 
00853 
00854 
00855 class SubroutineDecl : public Decl, public DeclRegion {
00856 
00857 public:
00858     virtual ~SubroutineDecl();
00859 
00861 
00862     virtual SubroutineType *getType() = 0;
00863     virtual const SubroutineType *getType() const = 0;
00865 
00867     unsigned getArity() const { return numParameters; }
00868 
00870     ParamValueDecl *getParam(unsigned i) {
00871         assert(i < getArity() && "Index out of range!");
00872         return parameters[i];
00873     }
00874 
00876     const ParamValueDecl *getParam(unsigned i) const {
00877         assert(i < getArity() && "Index out of range!");
00878         return parameters[i];
00879     }
00880 
00882     Type *getParamType(unsigned i) const {
00883         return getType()->getArgType(i);
00884     }
00885 
00890     PM::ParameterMode getParamMode(unsigned i) const {
00891         return getParam(i)->getParameterMode();
00892     }
00893 
00895     PM::ParameterMode getExplicitParamMode(unsigned i) const {
00896         return getParam(i)->getExplicitParameterMode();
00897     }
00898 
00900     IdentifierInfo *getParamKeyword(unsigned i) const {
00901         return getParam(i)->getIdInfo();
00902     }
00903 
00906     int getKeywordIndex(IdentifierInfo *key) const;
00907 
00910     int getKeywordIndex(KeywordSelector *key) const;
00911 
00915     bool keywordsMatch(const SubroutineDecl *SRDecl) const;
00916 
00920     bool paramModesMatch(const SubroutineDecl *SRDecl) const;
00921 
00923 
00924     SubroutineDecl *getOrigin() {
00925         return llvm::cast<SubroutineDecl>(Decl::getOrigin());
00926     }
00927     const SubroutineDecl *getOrigin() const {
00928         return llvm::cast<SubroutineDecl>(Decl::getOrigin());
00929     }
00931 
00933 
00934     SubroutineDecl *resolveOrigin() {
00935         return llvm::cast<SubroutineDecl>(Decl::resolveOrigin());
00936     }
00937     const SubroutineDecl *resolveOrigin() const {
00938         return llvm::cast<SubroutineDecl>(Decl::resolveOrigin());
00939     }
00941 
00945     typedef ParamValueDecl **param_iterator;
00946     param_iterator begin_params() { return parameters; }
00947     param_iterator end_params() { return parameters + getArity(); }
00948 
00949     typedef ParamValueDecl *const *const_param_iterator;
00950     const_param_iterator begin_params() const { return parameters; }
00951     const_param_iterator end_params() const { return parameters + getArity(); }
00953 
00954     void setDefiningDeclaration(SubroutineDecl *routineDecl);
00955 
00956     bool hasDefiningDeclaration() const {
00957         return getDefiningDeclaration() != 0;
00958     }
00959 
00960     SubroutineDecl *getDefiningDeclaration() {
00961         if (declarationLink.getInt() == DEFINITION_TAG)
00962             return declarationLink.getPointer();
00963         return 0;
00964     }
00965 
00966     const SubroutineDecl *getDefiningDeclaration() const {
00967         if (declarationLink.getInt() == DEFINITION_TAG)
00968             return declarationLink.getPointer();
00969         return 0;
00970     }
00971 
00972     SubroutineDecl *getForwardDeclaration() {
00973         if (declarationLink.getInt() == FORWARD_TAG)
00974             return declarationLink.getPointer();
00975         return 0;
00976     }
00977 
00978     const SubroutineDecl *getForwardDeclaration() const {
00979         if (declarationLink.getInt() == FORWARD_TAG)
00980             return declarationLink.getPointer();
00981         return 0;
00982     }
00983 
00984     const bool hasForwardDeclaration() const {
00985         return getForwardDeclaration() != 0;
00986     }
00987 
00988     const bool isForwardDeclaration() const {
00989         return getDefiningDeclaration() != 0;
00990     }
00991 
00992     bool hasBody() const;
00993     void setBody(BlockStmt *block) { body = block; }
00994     BlockStmt *getBody();
00995     const BlockStmt *getBody() const {
00996         return const_cast<SubroutineDecl*>(this)->getBody();
00997     }
00998 
01000     bool isPrimitive() const { return opID != PO::NotPrimitive; }
01001 
01003     void setAsPrimitive(PO::PrimitiveID ID) { opID = ID; }
01004 
01006     PO::PrimitiveID getPrimitiveID() const { return opID; }
01007 
01010     void attachPragma(Pragma *P) { pragmas.push_front(P); }
01011 
01013     const Pragma *findPragma(pragma::PragmaID ID) const;
01014 
01017     bool hasPragma(pragma::PragmaID ID) const { return findPragma(ID) != 0; }
01018 
01020 
01021     typedef llvm::iplist<Pragma>::iterator pragma_iterator;
01022     pragma_iterator begin_pragmas() { return pragmas.begin(); }
01023     pragma_iterator end_pragmas() { return pragmas.end(); }
01024 
01025     typedef llvm::iplist<Pragma>::const_iterator const_pragma_iterator;
01026     const_pragma_iterator begin_pragmas() const { return pragmas.begin(); }
01027     const_pragma_iterator end_pragmas() const { return pragmas.end(); }
01029 
01030     
01031     static bool classof(const SubroutineDecl *node) { return true; }
01032     static bool classof(const Ast *node) {
01033         return node->denotesSubroutineDecl();
01034     }
01035 
01036 protected:
01037     
01038     
01039     SubroutineDecl(AstKind kind, IdentifierInfo *name, Location loc,
01040                    ParamValueDecl **params, unsigned numParams,
01041                    DeclRegion *parent);
01042 
01043     SubroutineDecl(AstKind kind, IdentifierInfo *name, Location loc,
01044                    IdentifierInfo **keywords, SubroutineType *type,
01045                    DeclRegion *parent);
01046 
01047     SubroutineDecl(AstKind kind, IdentifierInfo *name, Location loc,
01048                    DeclRegion *parent);
01049 
01050     PO::PrimitiveID opID : 8;   
01051 
01052     unsigned numParameters;
01053     ParamValueDecl **parameters;
01054     BlockStmt *body;
01055 
01057     enum DeclLinkTag {
01058         FORWARD_TAG,            
01059         DEFINITION_TAG          
01060     };
01061 
01062     llvm::PointerIntPair<SubroutineDecl*, 1, DeclLinkTag> declarationLink;
01063     llvm::iplist<Pragma> pragmas;
01064 };
01065 
01066 
01067 
01068 
01069 
01070 class ProcedureDecl : public SubroutineDecl {
01071 
01072 public:
01073     ProcedureDecl(AstResource &resource,
01074                   IdentifierInfo *name, Location loc,
01075                   ParamValueDecl **params, unsigned numParams,
01076                   DeclRegion *parent);
01077 
01086     ProcedureDecl(IdentifierInfo *name, Location loc,
01087                   IdentifierInfo **keywords, ProcedureType *type,
01088                   DeclRegion *parent)
01089         : SubroutineDecl(AST_ProcedureDecl, name, loc, keywords, type, parent),
01090           correspondingType(type) { }
01091 
01092     ProcedureDecl(IdentifierInfo *name, Location loc,
01093                   ProcedureType *type, DeclRegion *parent);
01094 
01096 
01097     const ProcedureType *getType() const { return correspondingType; }
01098     ProcedureType *getType() { return correspondingType; }
01100 
01101     ProcedureDecl *getDefiningDeclaration() {
01102         SubroutineDecl *definition = SubroutineDecl::getDefiningDeclaration();
01103         return llvm::cast_or_null<ProcedureDecl>(definition);
01104     }
01105 
01106     const ProcedureDecl *getDefiningDeclaration() const {
01107         const SubroutineDecl *definition;
01108         definition = SubroutineDecl::getDefiningDeclaration();
01109         return llvm::cast_or_null<ProcedureDecl>(definition);
01110     }
01111 
01112     ProcedureDecl *getForwardDeclaration() {
01113         SubroutineDecl *forward = SubroutineDecl::getForwardDeclaration();
01114         return llvm::cast_or_null<ProcedureDecl>(forward);
01115     }
01116 
01117     const ProcedureDecl *getForwardDeclaration() const {
01118         const SubroutineDecl *forward;
01119         forward = SubroutineDecl::getForwardDeclaration();
01120         return llvm::cast_or_null<ProcedureDecl>(forward);
01121     }
01122 
01123     
01124     static bool classof(const ProcedureDecl *node) { return true; }
01125     static bool classof(const Ast *node) {
01126         return node->getKind() == AST_ProcedureDecl;
01127     }
01128 
01129 private:
01130     ProcedureType *correspondingType;
01131 };
01132 
01133 
01134 
01135 
01136 
01137 class FunctionDecl : public SubroutineDecl {
01138 
01139 public:
01140     FunctionDecl(AstResource &resource,
01141                  IdentifierInfo *name, Location loc,
01142                  ParamValueDecl **params, unsigned numParams,
01143                  Type *returnType, DeclRegion *parent);
01144 
01153     FunctionDecl(IdentifierInfo *name, Location loc,
01154                  IdentifierInfo **keywords, FunctionType *type,
01155                  DeclRegion *parent)
01156         : SubroutineDecl(AST_FunctionDecl, name, loc, keywords, type, parent),
01157           correspondingType(type) { }
01158 
01160 
01161     const FunctionType *getType() const { return correspondingType; }
01162     FunctionType *getType() { return correspondingType; }
01164 
01165     FunctionDecl *getDefiningDeclaration() {
01166         SubroutineDecl *definition = SubroutineDecl::getDefiningDeclaration();
01167         return llvm::cast_or_null<FunctionDecl>(definition);
01168     }
01169 
01170     const FunctionDecl *getDefiningDeclaration() const {
01171         const SubroutineDecl *definition;
01172         definition = SubroutineDecl::getDefiningDeclaration();
01173         return llvm::cast_or_null<FunctionDecl>(definition);
01174     }
01175 
01176     FunctionDecl *getForwardDeclaration() {
01177         SubroutineDecl *forward = SubroutineDecl::getForwardDeclaration();
01178         return llvm::cast_or_null<FunctionDecl>(forward);
01179     }
01180 
01181     const FunctionDecl *getForwardDeclaration() const {
01182         const SubroutineDecl *forward;
01183         forward = SubroutineDecl::getForwardDeclaration();
01184         return llvm::cast_or_null<FunctionDecl>(forward);
01185     }
01186 
01188 
01189     const Type *getReturnType() const { return getType()->getReturnType(); }
01190     Type *getReturnType() { return getType()->getReturnType(); }
01192 
01193     
01194     static bool classof(const FunctionDecl *node) { return true; }
01195     static bool classof(const Ast *node) { return denotesFunctionDecl(node); }
01196 
01197 protected:
01198     
01199     FunctionDecl(AstKind kind, AstResource &resource,
01200                  IdentifierInfo *name, Location loc,
01201                  EnumerationType *returnType, DeclRegion *parent);
01202 
01203     
01204     FunctionDecl(AstKind kind, IdentifierInfo *name, Location loc,
01205                  IdentifierInfo **keywords, FunctionType *type,
01206                  DeclRegion *parent)
01207         : SubroutineDecl(kind, name, loc, keywords, type, parent),
01208           correspondingType(type) { }
01209 
01210 private:
01211     FunctionType *correspondingType;
01212 
01213     void initializeCorrespondingType(AstResource &resource, Type *returnType);
01214 
01215     static bool denotesFunctionDecl(const Ast *node) {
01216         AstKind kind = node->getKind();
01217         return (kind == AST_FunctionDecl || kind == AST_EnumLiteral ||
01218                 kind == AST_PosAD || kind == AST_ValAD);
01219     }
01220 };
01221 
01222 
01223 
01224 
01225 
01226 class EnumLiteral : public FunctionDecl {
01227 
01228 public:
01230     unsigned getIndex() const { return index; }
01231 
01233 
01234     const EnumerationType *getReturnType() const {
01235         return llvm::cast<EnumerationType>(FunctionDecl::getReturnType());
01236     }
01237     EnumerationType *getReturnType() {
01238         return llvm::cast<EnumerationType>(FunctionDecl::getReturnType());
01239     }
01241 
01243 
01244     EnumerationDecl *getDeclRegion() {
01245         return llvm::cast<EnumerationDecl>(context);
01246     }
01247     const EnumerationDecl *getDeclRegion() const {
01248         return llvm::cast<EnumerationDecl>(context);
01249     }
01251 
01252     
01253     static bool classof(const EnumLiteral *node) { return true; }
01254     static bool classof(const Ast *node) {
01255         return node->getKind() == AST_EnumLiteral;
01256     }
01257 
01258 private:
01259     
01260     
01261     EnumLiteral(AstResource &resource, IdentifierInfo *name, Location loc,
01262                 unsigned index, EnumerationType *type, EnumerationDecl *parent);
01263 
01264     friend class EnumerationDecl;
01265 
01266     unsigned index;
01267 };
01268 
01269 
01270 
01271 
01272 
01273 class TypeDecl : public Decl {
01274 
01275 public:
01277 
01278     const PrimaryType *getType() const { return CorrespondingType; }
01279     PrimaryType *getType() { return CorrespondingType; }
01281 
01282     static bool classof(const TypeDecl *node) { return true; }
01283     static bool classof(const Ast *node) {
01284         return node->denotesTypeDecl();
01285     }
01286 
01287 protected:
01288     
01289     TypeDecl(AstKind kind, IdentifierInfo *name, PrimaryType *type,
01290              Location loc, DeclRegion *region = 0)
01291         : Decl(kind, name, loc, region),
01292           CorrespondingType(type) {
01293         assert(this->denotesTypeDecl());
01294     }
01295 
01296     
01297     
01298     TypeDecl(AstKind kind, IdentifierInfo *name, Location loc,
01299              DeclRegion *region = 0)
01300         : Decl(kind, name, loc, region),
01301           CorrespondingType(0) {
01302         assert(this->denotesTypeDecl());
01303     }
01304 
01305     PrimaryType *CorrespondingType;
01306 };
01307 
01308 
01309 
01310 
01314 class IncompleteTypeDecl : public TypeDecl {
01315 
01316 public:
01318     bool hasCompletion() const { return completion != 0; }
01319 
01321     void setCompletion(TypeDecl *decl) { completion = decl; }
01322 
01324 
01325     const IncompleteType *getType() const {
01326         return llvm::cast<IncompleteType>(CorrespondingType);
01327     }
01328     IncompleteType *getType() {
01329         return llvm::cast<IncompleteType>(CorrespondingType);
01330     }
01332 
01334 
01335 
01336     const TypeDecl *getCompletion() const { return completion; }
01337     TypeDecl *getCompletion() { return completion; }
01339 
01352     bool isCompatibleCompletion(const TypeDecl *decl) const;
01353 
01354 
01357     bool completionIsVisibleIn(const DeclRegion *region) const;
01358 
01359     
01360     static bool classof(const IncompleteTypeDecl *node) { return true; }
01361     static bool classof(const Ast *node) {
01362         return node->getKind() == AST_IncompleteTypeDecl;
01363     }
01364 
01365 private:
01366     
01367     IncompleteTypeDecl(AstResource &resource,
01368                        IdentifierInfo *name, Location loc, DeclRegion *region);
01369 
01370     
01371     friend class AstResource;
01372 
01373     TypeDecl *completion;
01374 };
01375 
01376 
01377 
01378 
01379 
01380 class CarrierDecl : public TypeDecl {
01381 
01382 public:
01383     CarrierDecl(AstResource &resource, IdentifierInfo *name,
01384                 PrimaryType *type, Location loc)
01385         : TypeDecl(AST_CarrierDecl, name, type, loc) { }
01386 
01388 
01389 
01390 
01391 
01392     const PrimaryType *getRepresentationType() const {
01393         return getType()->getRootType();
01394     }
01395     PrimaryType *getRepresentationType() {
01396         return getType()->getRootType();
01397     }
01399 
01400     
01401     static bool classof(const CarrierDecl *node) { return true; }
01402     static bool classof(const Ast *node) {
01403         return node->getKind() == AST_CarrierDecl;
01404     }
01405 };
01406 
01407 
01408 
01409 class EnumerationDecl : public TypeDecl, public DeclRegion {
01410 
01413     enum PropertyFlag {
01414         Subtype_FLAG   = 1 << 0, 
01415         Character_FLAG = 1 << 1  
01416     };
01417 
01418 public:
01420     bool isSubtypeDeclaration() const { return bits & Subtype_FLAG; }
01421 
01425     void generateImplicitDeclarations(AstResource &resource);
01426 
01428 
01429     const EnumerationType *getType() const {
01430         return llvm::cast<EnumerationType>(CorrespondingType);
01431     }
01432     EnumerationType *getType() {
01433         return llvm::cast<EnumerationType>(CorrespondingType);
01434     }
01436 
01438 
01439     const EnumerationType *getBaseSubtype() const {
01440         return getType()->getRootType()->getBaseSubtype();
01441     }
01442     EnumerationType *getBaseSubtype() {
01443         return getType()->getRootType()->getBaseSubtype();
01444     }
01446 
01447     
01448     unsigned getNumLiterals() const { return numLiterals; }
01449 
01450     
01451     
01452     unsigned genBitsNeeded() const;
01453 
01454     
01455     
01456     EnumLiteral *findLiteral(IdentifierInfo *name);
01457 
01459 
01460     const EnumLiteral *getFirstLiteral() const;
01461     EnumLiteral *getFirstLiteral();
01463 
01465 
01466     const EnumLiteral *getLastLiteral() const;
01467     EnumLiteral *getLastLiteral();
01469 
01470     
01471     
01472     
01473     
01474     void markAsCharacterType() { bits |= Character_FLAG; }
01475 
01476     
01477     bool isCharacterType() const { return bits & Character_FLAG; }
01478 
01479     
01480     
01481     const EnumLiteral *findCharacterLiteral(char ch) const;
01482 
01483     
01484     
01485     bool hasEncoding(char ch) const {
01486         return findCharacterLiteral(ch) != 0;
01487     }
01488 
01489     
01490     
01491     unsigned getEncoding(char ch) const {
01492         const EnumLiteral *lit = findCharacterLiteral(ch);
01493         assert(lit && "No encoding exists for the given character!");
01494         return lit->getIndex();
01495     }
01496 
01498     PosAD *getPosAttribute() { return posAttribute; }
01499 
01501     ValAD *getValAttribute() { return valAttribute; }
01502 
01507     FunctionAttribDecl *getAttribute(attrib::AttributeID ID);
01508 
01509     static bool classof(const EnumerationDecl *node) { return true; }
01510     static bool classof(const Ast *node) {
01511         return node->getKind() == AST_EnumerationDecl;
01512     }
01513 
01514 private:
01515     
01516 
01521     EnumerationDecl(AstResource &resource,
01522                     IdentifierInfo *name, Location loc,
01523                     std::pair<IdentifierInfo*, Location> *elems,
01524                     unsigned numElems, DeclRegion *parent);
01525 
01527     EnumerationDecl(AstResource &resource, IdentifierInfo *name, Location loc,
01528                     EnumerationType *subtype, DeclRegion *region);
01529 
01531     EnumerationDecl(AstResource &resource, IdentifierInfo *name, Location loc,
01532                     EnumerationType *subtype, Expr *lower, Expr *upper,
01533                     DeclRegion *region);
01534 
01535     friend class AstResource;
01536 
01537     
01538     
01539     
01540     void generateBooleanDeclarations(AstResource &resource);
01541 
01542     
01543     uint32_t numLiterals;
01544 
01545     PosAD *posAttribute;        
01546     ValAD *valAttribute;        
01547 };
01548 
01549 
01550 
01551 
01552 
01553 class IntegerDecl : public TypeDecl, public DeclRegion {
01554 
01555 public:
01557     bool isSubtypeDeclaration() const { return bits; }
01558 
01562     void generateImplicitDeclarations(AstResource &resource);
01563 
01565 
01566 
01567 
01568 
01569     const IntegerType *getType() const {
01570         return llvm::cast<IntegerType>(CorrespondingType);
01571     }
01572     IntegerType *getType() {
01573         return llvm::cast<IntegerType>(CorrespondingType);
01574     }
01576 
01578 
01579     const IntegerType *getBaseSubtype() const {
01580         return getType()->getRootType()->getBaseSubtype();
01581     }
01582     IntegerType *getBaseSubtype() {
01583         return getType()->getRootType()->getBaseSubtype();
01584     }
01586 
01588 
01589 
01590     Expr *getLowBoundExpr() { return lowExpr; }
01591     const Expr *getLowBoundExpr() const { return lowExpr; }
01593 
01595 
01596 
01597     Expr *getHighBoundExpr() { return highExpr; }
01598     const Expr *getHighBoundExpr() const { return highExpr; }
01600 
01602     PosAD *getPosAttribute() { return posAttribute; }
01603 
01605     ValAD *getValAttribute() { return valAttribute; }
01606 
01611     FunctionAttribDecl *getAttribute(attrib::AttributeID ID);
01612 
01613     static bool classof(const IntegerDecl *node) { return true; }
01614     static bool classof(const Ast *node) {
01615         return node->getKind() == AST_IntegerDecl;
01616     }
01617 
01618 private:
01635     IntegerDecl(AstResource &resource,
01636                 IdentifierInfo *name, Location loc,
01637                 Expr *lower, Expr *upper, DeclRegion *parent);
01638 
01640     IntegerDecl(AstResource &resource,
01641                 IdentifierInfo *name, Location loc,
01642                 IntegerType *subtype, DeclRegion *parent);
01643 
01645     IntegerDecl(AstResource &resource,
01646                 IdentifierInfo *name, Location loc,
01647                 IntegerType *subtype,
01648                 Expr *lower, Expr *upper, DeclRegion *parent);
01649 
01650     friend class AstResource;
01651 
01652     Expr *lowExpr;              
01653     Expr *highExpr;             
01654 
01655     PosAD *posAttribute;        
01656     ValAD *valAttribute;        
01657 };
01658 
01659 
01660 
01661 
01662 
01663 class ArrayDecl : public TypeDecl, public DeclRegion {
01664 
01665     
01666     typedef llvm::SmallVector<DSTDefinition*, 4> IndexVec;
01667 
01668 public:
01670 
01671     const ArrayType *getType() const {
01672         return llvm::cast<ArrayType>(CorrespondingType);
01673     }
01674     ArrayType *getType() {
01675         return llvm::cast<ArrayType>(CorrespondingType);
01676     }
01678 
01680     unsigned getRank() const { return getType()->getRank(); }
01681 
01683 
01684     const DiscreteType *getIndexType(unsigned i) const {
01685         return getType()->getIndexType(i);
01686     }
01687     DiscreteType *getIndexType(unsigned i) {
01688         return getType()->getIndexType(i);
01689     }
01691 
01693 
01694     const Type *getComponentType() const {
01695         return getType()->getComponentType();
01696     }
01697     Type *getComponentType() { return getType()->getComponentType(); }
01699 
01701     bool isConstrained() const { return getType()->isConstrained(); }
01702 
01704 
01705     typedef ArrayType::iterator index_iterator;
01706     index_iterator begin_indices() { return getType()->begin(); }
01707     index_iterator end_indices() { return getType()->end(); }
01709 
01710     
01711     static bool classof(const ArrayDecl *node) { return true; }
01712     static bool classof(const Ast *node) {
01713         return node->getKind() == AST_ArrayDecl;
01714     }
01715 
01716 private:
01718     ArrayDecl(AstResource &resource,
01719               IdentifierInfo *name, Location loc,
01720               unsigned rank, DSTDefinition **indices,
01721               Type *component, bool isConstrained, DeclRegion *parent);
01722 
01723     friend class AstResource;
01724 
01725     IndexVec indices;
01726 };
01727 
01728 
01729 
01730 
01731 class RecordDecl : public TypeDecl, public DeclRegion {
01732 
01733 public:
01735 
01736 
01737     const RecordType *getType() const {
01738         return llvm::cast<RecordType>(CorrespondingType);
01739     }
01740     RecordType *getType() {
01741         return llvm::cast<RecordType>(CorrespondingType);
01742     }
01744 
01749     ComponentDecl *addComponent(IdentifierInfo *name, Location loc,
01750                                 Type *type);
01751 
01753     unsigned numComponents() const { return componentCount; }
01754 
01756 
01757 
01758 
01759     const ComponentDecl *getComponent(IdentifierInfo *name) const {
01760         return const_cast<RecordDecl*>(this)->getComponent(name);
01761     }
01762     ComponentDecl *getComponent(IdentifierInfo *name);
01764 
01766 
01767     const ComponentDecl *getComponent(unsigned i) const {
01768         return const_cast<RecordDecl*>(this)->getComponent(i);
01769     }
01770     ComponentDecl *getComponent(unsigned i);
01772 
01773     static bool classof(const RecordDecl *node) { return true; }
01774     static bool classof(const Ast *node) {
01775         return node->getKind() == AST_RecordDecl;
01776     }
01777 
01778 private:
01780     RecordDecl(AstResource &resource, IdentifierInfo *name, Location loc,
01781                DeclRegion *parent);
01782 
01783     friend class AstResource;
01784 
01785     
01786     unsigned componentCount;
01787 };
01788 
01789 
01790 
01791 
01795 class ComponentDecl : public Decl {
01796 
01797 public:
01799 
01800     const Type *getType() const { return CorrespondingType; }
01801     Type *getType() { return CorrespondingType; }
01803 
01805 
01806     RecordDecl *getDeclRegion() {
01807         return llvm::cast<RecordDecl>(context);
01808     }
01809     const RecordDecl *getDeclRegion() const {
01810         return llvm::cast<RecordDecl>(context);
01811     }
01813 
01819     unsigned getIndex() const { return index; }
01820 
01821     
01822     static bool classof(const ComponentDecl *node) { return true; }
01823     static bool classof(const Ast *node) {
01824         return node->getKind() == AST_ComponentDecl;
01825     }
01826 
01827 private:
01828     
01829     ComponentDecl(IdentifierInfo *name, Location loc,
01830                   Type *type, unsigned index, RecordDecl *parent)
01831         : Decl(AST_ComponentDecl, name, loc, parent),
01832           CorrespondingType(type), index(index) { }
01833 
01834     friend class RecordDecl;
01835 
01836     Type *CorrespondingType;    
01837     unsigned index;             
01838 };
01839 
01840 
01841 
01842 
01846 class AccessDecl : public TypeDecl, public DeclRegion {
01847 
01848 public:
01852     void generateImplicitDeclarations(AstResource &resource);
01853 
01855 
01856 
01857     const AccessType *getType() const {
01858         return llvm::cast<AccessType>(CorrespondingType);
01859     }
01860     AccessType *getType() {
01861         return llvm::cast<AccessType>(CorrespondingType);
01862     }
01864 
01865     
01866     static bool classof(const AccessDecl *node) { return true; }
01867     static bool classof(const Ast *node) {
01868         return node->getKind() == AST_AccessDecl;
01869     }
01870 
01871 private:
01872     AccessDecl(AstResource &resource, IdentifierInfo *name, Location loc,
01873                Type *targetType, DeclRegion *parent);
01874 
01875     
01876     friend class AstResource;
01877 };
01878 
01879 
01880 
01881 
01882 
01883 
01884 
01885 
01886 
01887 
01888 
01889 
01890 
01891 
01892 
01893 
01894 
01895 
01896 
01897 
01898 
01899 
01900 
01901 class DomainTypeDecl : public TypeDecl, public DeclRegion {
01902 
01903 protected:
01904     DomainTypeDecl(AstKind kind, AstResource &resource,
01905                    IdentifierInfo *name, Location loc = 0);
01906 
01907 public:
01908     virtual ~DomainTypeDecl() { }
01909 
01917     virtual const SignatureSet &getSignatureSet() const = 0;
01918 
01920 
01921     const DomainType *getType() const {
01922         return llvm::cast<DomainType>(CorrespondingType);
01923     }
01924     DomainType *getType() {
01925         return llvm::cast<DomainType>(CorrespondingType);
01926     }
01928 
01929     static bool classof(const DomainTypeDecl *node) { return true; }
01930     static bool classof(const Ast *node) {
01931         return node->denotesDomainTypeDecl();
01932     }
01933 };
01934 
01935 
01936 
01937 class AbstractDomainDecl : public DomainTypeDecl {
01938 
01939 public:
01940     AbstractDomainDecl(AstResource &resource,
01941                        IdentifierInfo *name, Location loc,
01942                        SigInstanceDecl *sig);
01943 
01944     AbstractDomainDecl(AstResource &resource,
01945                        IdentifierInfo *name, Location loc)
01946         : DomainTypeDecl(AST_AbstractDomainDecl, resource, name, loc) { }
01947 
01949     const SignatureSet &getSignatureSet() const { return sigset; }
01950 
01953     bool hasPrincipleSignature() const { return !sigset.empty(); }
01954 
01956     SigInstanceDecl *getPrincipleSignature() const {
01957         assert(hasPrincipleSignature());
01958         return *sigset.beginDirect();
01959     }
01960 
01961     static bool classof(const AbstractDomainDecl *node) { return true; }
01962     static bool classof(const Ast* node) {
01963         return node->getKind() == AST_AbstractDomainDecl;
01964     }
01965 
01966 private:
01967     SignatureSet sigset;
01968 };
01969 
01970 
01971 
01972 class DomainInstanceDecl : public DomainTypeDecl, public llvm::FoldingSetNode {
01973 
01974 public:
01975     DomainInstanceDecl(AstResource &resource, DomainDecl *domain);
01976 
01977     DomainInstanceDecl(AstResource &resource, FunctorDecl *functor,
01978                        DomainTypeDecl **args, unsigned numArgs);
01979 
01981     Domoid *getDefinition() { return definition; }
01982     const Domoid *getDefinition() const { return definition; }
01983 
01986     DomainDecl *getDefiningDomain() const;
01987 
01990     FunctorDecl *getDefiningFunctor() const;
01991 
01993     const SignatureSet &getSignatureSet() const { return sigset; }
01994 
01998     bool isDependent() const;
01999 
02001     bool isParameterized() const { return getArity() != 0; }
02002 
02004     unsigned getArity() const;
02005 
02008     DomainTypeDecl *getActualParam(unsigned n) const {
02009         assert(isParameterized() && "Not a parameterized instance!");
02010         assert(n < getArity() && "Index out of range!");
02011         return arguments[n];
02012     }
02013 
02015 
02016 
02017 
02018 
02019     const DomainType *getActualParamType(unsigned n) const {
02020         return getActualParam(n)->getType();
02021     }
02022     DomainType *getActualParamType(unsigned n) {
02023         return getActualParam(n)->getType();
02024     }
02026 
02028     typedef DomainTypeDecl **arg_iterator;
02029     arg_iterator beginArguments() const { return arguments; }
02030     arg_iterator endArguments() const { return &arguments[getArity()]; }
02031 
02039 
02040 
02041     const PrimaryType *getRepresentationType() const {
02042         return representationType;
02043     }
02044     PrimaryType *getRepresentationType() { return representationType; }
02046 
02048     void Profile(llvm::FoldingSetNodeID &id) {
02049         Profile(id, &arguments[0], getArity());
02050     }
02051 
02053     static void
02054     Profile(llvm::FoldingSetNodeID &id,
02055             DomainTypeDecl **args, unsigned numArgs);
02056 
02057     static bool classof(const DomainInstanceDecl *node) { return true; }
02058     static bool classof(const Ast *node) {
02059         return node->getKind() == AST_DomainInstanceDecl;
02060     }
02061 
02062 private:
02063     Domoid *definition;
02064     DomainTypeDecl **arguments;
02065     SignatureSet sigset;
02066 
02067     typedef llvm::PointerUnion<CarrierDecl*, DeclRewriter*> CarrierRewrite;
02068     CarrierRewrite carrier;
02069     PrimaryType *representationType;
02070 
02071     friend class DomainDecl;
02072     friend class FunctorDecl;
02073 
02074     
02075     
02076     void finalize();
02077 
02078     
02079     void initializeInstance(Domoid *definition);
02080 
02081     
02082     void initializeRepresentation(DeclRewriter &rewriter);
02083 
02084     
02085     
02086     void notifyAddDecl(Decl *decl);
02087     void notifyRemoveDecl(Decl *decl);
02088 };
02089 
02090 
02091 
02092 
02093 class PercentDecl : public DomainTypeDecl {
02094 
02095 public:
02097     ModelDecl *getDefinition() { return underlyingModel; }
02098     const ModelDecl *getDefinition() const { return underlyingModel; }
02099 
02101     const SignatureSet &getSignatureSet() const { return sigset; }
02102 
02103     static bool classof(const PercentDecl *node) { return true; }
02104     static bool classof(const Ast *node) {
02105         return node->getKind() == AST_PercentDecl;
02106     }
02107 
02108 private:
02109     friend class ModelDecl;
02110 
02111     PercentDecl(AstResource &resource, ModelDecl *model);
02112 
02113     ModelDecl *underlyingModel;
02114     SignatureSet sigset;
02115 };
02116 
02117 
02118 
02119 
02120 inline const DomainType *ModelDecl::getPercentType() const
02121 {
02122     return percent->getType();
02123 }
02124 
02125 inline DomainType *ModelDecl::getPercentType()
02126 {
02127     return percent->getType();
02128 }
02129 
02130 inline SignatureDecl *Sigoid::getSignature()
02131 {
02132     return llvm::dyn_cast<SignatureDecl>(this);
02133 }
02134 
02135 inline VarietyDecl *Sigoid::getVariety()
02136 {
02137     return llvm::dyn_cast<VarietyDecl>(this);
02138 }
02139 
02140 inline DomainDecl *Domoid::getDomain()
02141 {
02142     return llvm::dyn_cast<DomainDecl>(this);
02143 }
02144 
02145 inline FunctorDecl *Domoid::getFunctor()
02146 {
02147     return llvm::dyn_cast<FunctorDecl>(this);
02148 }
02149 
02150 inline DomainDecl *DomainInstanceDecl::getDefiningDomain() const
02151 {
02152     return llvm::dyn_cast<DomainDecl>(definition);
02153 }
02154 
02155 inline FunctorDecl *DomainInstanceDecl::getDefiningFunctor() const
02156 {
02157     return llvm::dyn_cast<FunctorDecl>(definition);
02158 }
02159 
02160 inline DomainType *SigInstanceDecl::getActualParamType(unsigned n) const {
02161     return getActualParam(n)->getType();
02162 }
02163 
02164 } 
02165 
02166 #endif