This machine mirrors various open-source projects.
20 Gbit/s uplink.
If there are any issues or you want another project mirrored, please contact
mirror-service -=AT=- netcologne DOT de !
00001 //===-- ast/Decl.h -------------------------------------------- -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2008-2010, Stephen Wilson 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 // Decl. 00030 // 00031 // Decl nodes represent declarations within a Comma program. 00032 class Decl : public Ast { 00033 00034 public: 00035 virtual ~Decl() { }; 00036 00037 // Returns the IdentifierInfo object associated with this decl, or NULL if 00038 // this is an anonymous decl. 00039 IdentifierInfo *getIdInfo() const { return idInfo; } 00040 00041 // Returns the name of this decl as a c string, or NULL if this is an 00042 // anonymous decl. 00043 const char *getString() const { 00044 return idInfo ? idInfo->getString() : 0; 00045 } 00046 00047 // Returns the location associated with this decl. 00048 Location getLocation() const { return location; } 00049 00050 // Sets the declarative region for this decl. This function can only be 00051 // called once to initialize the decl. 00052 void setDeclRegion(DeclRegion *region) { 00053 assert(context == 0 && "Cannot reset a decl's declarative region!"); 00054 context = region; 00055 } 00056 00057 // Returns the declarative region for this decl. Sometimes decls are 00058 // created before their associated regions exist, so this method may return 00059 // null. 00060 DeclRegion *getDeclRegion() { return context; } 00061 const DeclRegion *getDeclRegion() const { return context; } 00062 00063 // Returns true if this decl was declared in the given region. 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 // Support isa and dyn_cast. 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 // ImportDecl 00133 // 00134 // Represents import declarations. 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 // ExceptionDecl 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 // Support isa/dyn_cast. 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 // Only AstResource is allowed to construct ExceptionDecl's. 00191 friend class AstResource; 00192 }; 00193 00194 //===----------------------------------------------------------------------===// 00195 // ModelDecl 00196 // 00197 // Models represent those attributes and characteristics which both signatures 00198 // and domains share. 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 // Support isa and dyn_cast. 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 // The unique PercentDecl representing this model. 00284 PercentDecl *percent; 00285 00286 // The AstResource we use to construct sub-nodes. 00287 AstResource &resource; 00288 }; 00289 00290 //===----------------------------------------------------------------------===// 00291 // Sigoid 00292 // 00293 // This is the common base class for "signature like" objects: i.e. signatures 00294 // and varieties. 00295 class Sigoid : public ModelDecl { 00296 00297 public: 00298 // Creates a named signature. 00299 Sigoid(AstResource &resource, 00300 AstKind kind, IdentifierInfo *name, Location loc) 00301 : ModelDecl(resource, kind, name, loc) { } 00302 00303 virtual ~Sigoid() { } 00304 00305 // If this is a SignatureDecl, returns this cast to the refined type, 00306 // otherwise returns NULL. 00307 SignatureDecl *getSignature(); 00308 00309 // If this is a VarietyDecl, returns this cast to the refined type, 00310 // otherwise returns NULL. 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 // SignatureDecl 00322 // 00323 // This class defines (non-parameterized) signature declarations. 00324 class SignatureDecl : public Sigoid { 00325 00326 public: 00327 // Creates a named signature. 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 // Support for isa and dyn_cast. 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 // The unique instance decl representing this signature. 00342 SigInstanceDecl *theInstance; 00343 }; 00344 00345 //===----------------------------------------------------------------------===// 00346 // VarietyDecl 00347 // 00348 // Repesentation of parameterized signatures. 00349 class VarietyDecl : public Sigoid { 00350 00351 public: 00352 // Creates a VarietyDecl with the given name, location of definition, and 00353 // list of AbstractDomainTypes which serve as the formal parameters. 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 // Support for isa and dyn_cast. 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 // Domoid 00404 // 00405 // This is the common base class for domain-like objects: i.e. domains 00406 // and functors. 00407 class Domoid : public ModelDecl { 00408 00409 public: 00410 virtual ~Domoid() { } 00411 00412 // Returns non-null if this domoid is a DomainDecl. 00413 DomainDecl *getDomain(); 00414 00415 // Returns non-null if this domoid is a FunctorDecl. 00416 FunctorDecl *getFunctor(); 00417 00418 // Once a domoid has been constructed (all declarations and sub-components 00419 // have been registered) this method must be called to ensure all internal 00420 // state of the node is consistent. 00421 virtual void finalize() = 0; 00422 00423 // Returns true if this domoid has been finalized. 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 // AddDecl 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 // Support isa/dyn_cast. 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 // Non-null if a carrier has been associated with this declaration. 00515 CarrierDecl *carrier; 00516 }; 00517 00518 //===----------------------------------------------------------------------===// 00519 // DomainDecl 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 // Support for isa and dyn_cast. 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 // FunctorDecl 00554 // 00555 // Representation of parameterized domains. 00556 class FunctorDecl : public Domoid { 00557 00558 public: 00559 FunctorDecl(AstResource &resource, 00560 IdentifierInfo *name, Location loc, 00561 AbstractDomainDecl **formals, unsigned arity); 00562 00563 // Returns an instance declaration corresponding to this functor applied 00564 // over the given set of arguments. Such instance declarations are 00565 // memoized, and for a given set of arguments this method always returns the 00566 // same declaration node. 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 // Returns the AddDecl which implements this functor. 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 // Support for isa and dyn_cast. 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 // SigInstanceDecl 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 // Called by VarietyDecl when memoizing. 00665 static void 00666 Profile(llvm::FoldingSetNodeID &id, 00667 DomainTypeDecl **args, unsigned numArgs); 00668 00669 // The Sigoid supporing this type. 00670 Sigoid *underlyingSigoid; 00671 00672 // If the supporting declaration is a variety, then this array contains the 00673 // actual arguments defining this instance. 00674 DomainTypeDecl **arguments; 00675 }; 00676 00677 //===----------------------------------------------------------------------===// 00678 // ValueDecl 00679 // 00680 // This class is intentionally generic. It will become a virtual base for a 00681 // more extensive hierarchy of value declarations later on. 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 // ParamValueDecl 00709 // 00710 // Declaration nodes which represent the formal parameters of a function or 00711 // procedure. These nodes are owned by the function declaration to which they 00712 // are attached. 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 // Store the mode for this decl in the bit field provided by our 00722 // base Ast instance. 00723 // 00724 // FIXME: This is bad practice, really. But the bits are available so 00725 // we use them. Eventually, a better interface/convention should be 00726 // established to help protect against the bit field being trashed, or 00727 // this data should be moved into the class itself. 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 // ObjectDecl 00756 // 00757 // Object declarations denote objects of a given type. They may optionally be 00758 // associated with an initial value given by an expression. 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 // Returns true if this object declaration is associated with an 00770 // initialization expression. 00771 bool hasInitializer() const { return initialization != 0; } 00772 00773 // Returns the initialization expression associated with this object decl, 00774 // or NULL if there is no such association. 00775 Expr *getInitializer() const { return initialization; } 00776 00777 // Sets the initialization expression for this declaration. Owership of the 00778 // expression is passed to the declaration. 00779 void setInitializer(Expr *init) { initialization = init; } 00780 00781 // Support isa and dyn_cast. 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 // RenamedObjectDecl 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 // Support isa/dyn_cast. 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 // LoopDecl 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 // Support isa/dyn_cast. 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 // SubroutineDecl 00853 // 00854 // Base class for representing procedures and functions. 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 // Support for isa and dyn_cast. 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 // Subroutine decls take ownership of any ParamValueDecls supplied (but not 01038 // the array they are passed in). 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, // Link points to a forward declaration. 01059 DEFINITION_TAG // Link points to a completion. 01060 }; 01061 01062 llvm::PointerIntPair<SubroutineDecl*, 1, DeclLinkTag> declarationLink; 01063 llvm::iplist<Pragma> pragmas; 01064 }; 01065 01066 //===----------------------------------------------------------------------===// 01067 // ProcedureDecl 01068 // 01069 // Representation of procedure declarations. 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 // Support for isa and dyn_cast. 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 // FunctionDecl 01135 // 01136 // Representation of function declarations. 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 // Support for isa and dyn_cast. 01194 static bool classof(const FunctionDecl *node) { return true; } 01195 static bool classof(const Ast *node) { return denotesFunctionDecl(node); } 01196 01197 protected: 01198 // Constructor for use by EnumLiteral. 01199 FunctionDecl(AstKind kind, AstResource &resource, 01200 IdentifierInfo *name, Location loc, 01201 EnumerationType *returnType, DeclRegion *parent); 01202 01203 // Constructor for use by FunctionAttribDecl. 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 // EnumLiteral 01224 // 01225 // Instances of this class represent the elements of an EnumerationDecl. 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 // Support isa/dyn_cast. 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 // Enumeration literals are constructed by their containing enumeration decl 01260 // node. 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 // TypeDecl 01271 // 01272 // All nodes which declare types inherit from this class. 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 // Constructs a TypeDecl node when a type is immediately available. 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 // Constructs a TypeDecl node when a type is not immediately available. 01297 // Users of this constructor must set the corresponding type. 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 // IncompleteTypeDecl 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 // Support isa/dyn_cast. 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 // Constructs an incomplete type declaration node. 01367 IncompleteTypeDecl(AstResource &resource, 01368 IdentifierInfo *name, Location loc, DeclRegion *region); 01369 01370 // Incomplete type declarations are constructed an managed by AstResource. 01371 friend class AstResource; 01372 01373 TypeDecl *completion; 01374 }; 01375 01376 //===----------------------------------------------------------------------===// 01377 // CarrierDecl 01378 // 01379 // Declaration of a domains carrier type. 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 // Support isa/dyn_cast. 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 // EnumerationDecl 01409 class EnumerationDecl : public TypeDecl, public DeclRegion { 01410 01413 enum PropertyFlag { 01414 Subtype_FLAG = 1 << 0, // Set when this is a subtype decl. 01415 Character_FLAG = 1 << 1 // Set when this is a character decl. 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 // Returns the number of EnumLiteral's associated with this enumeration. 01448 unsigned getNumLiterals() const { return numLiterals; } 01449 01450 // Returns the minimum number of bits needed to represent elements of this 01451 // enumeration. 01452 unsigned genBitsNeeded() const; 01453 01454 // Returns the literal with the given name, or null if no such literal is a 01455 // member of this enumeration. 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 // Marks this declaration as a character enumeration. 01471 // 01472 // This method should be called if any of the literals constituting this 01473 // declaration are character literals. 01474 void markAsCharacterType() { bits |= Character_FLAG; } 01475 01476 // Returns true if this declaration denotes a character enumeration. 01477 bool isCharacterType() const { return bits & Character_FLAG; } 01478 01479 // Locates the EnumLiteral corresponding to the given character, or null if 01480 // no such literal exists. 01481 const EnumLiteral *findCharacterLiteral(char ch) const; 01482 01483 // Returns true if an enumeration literal exists which maps to the given 01484 // character. 01485 bool hasEncoding(char ch) const { 01486 return findCharacterLiteral(ch) != 0; 01487 } 01488 01489 // Returns the encoding of the given character. This method is only valid 01490 // if hasEncoding() returns true for the given character. 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 // Private constructors for use by AstResource. 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 // Generates the implicit declarations that must be attached to the 01538 // primitive Boolean type and that type alone. This method is for use by 01539 // AstResource when it establishes the fundamental type nodes. 01540 void generateBooleanDeclarations(AstResource &resource); 01541 01542 // The number of EnumLiteral's associated with this enumeration. 01543 uint32_t numLiterals; 01544 01545 PosAD *posAttribute; // Declaration node for the Pos attribute. 01546 ValAD *valAttribute; // Declaration node for the Val attribute. 01547 }; 01548 01549 //===----------------------------------------------------------------------===// 01550 // IntegerDecl 01551 // 01552 // These nodes represent integer type declarations. 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; // Expr forming the lower bound. 01653 Expr *highExpr; // Expr forming the high bound. 01654 01655 PosAD *posAttribute; // Declaration node for the Pos attribute. 01656 ValAD *valAttribute; // Declaration node for the Val attribute. 01657 }; 01658 01659 //===----------------------------------------------------------------------===// 01660 // ArrayDecl 01661 // 01662 // This node represents array type declarations. 01663 class ArrayDecl : public TypeDecl, public DeclRegion { 01664 01665 // Type used to store the DSTDefinitions defining the indices of this array. 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 // Support isa and dyn_cast. 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 // RecordDecl 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 // Total number of components defined by this record. 01786 unsigned componentCount; 01787 }; 01788 01789 //===----------------------------------------------------------------------===// 01790 // ComponentDecl 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 // Support isa/dyn_cast. 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 // ComponentDecl's are constructed by their enclosing record declaration. 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; // Type of this component. 01837 unsigned index; // Relative position of this component. 01838 }; 01839 01840 //===----------------------------------------------------------------------===// 01841 // AccessDecl 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 // Support isa/dyn_cast. 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 // AccessDecl's are constructed and managed by AstResource. 01876 friend class AstResource; 01877 }; 01878 01879 //===----------------------------------------------------------------------===// 01880 // DomainTypeDecl 01881 // 01882 // This class represents implicit domain declarations which correspond to a 01883 // particular instance. There are three main subclasses: 01884 // 01885 // - DomainInstanceDecl's represent the public or external view of a domain. 01886 // All references to formal parameters are replaced by the actuals for a 01887 // particular instance, and all percent nodes are mapped to the type of this 01888 // instance. 01889 // 01890 // - AbstractDomainDecl's represent the formal parameters of a model. They 01891 // provide a view of a domain as restricted by their principle signature. 01892 // These types of declarations are only visible in the bodies of generic 01893 // models. Such domains provide a rewritten interface to the principle 01894 // signature where the signatures percent node is replaced by references to 01895 // this type, and where the formal arguments of a variety are replaced by 01896 // the actuals. 01897 // 01898 // - PercentDecl's are the nodes which encapsulate the internal view of a 01899 // model. 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 // AbstractDomainDecl 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 // DomainInstanceDecl 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 // Called by the defining domain or functor to notify an instance that the 02075 // definition is complete. 02076 void finalize(); 02077 02078 // Helper function called by the constructors. 02079 void initializeInstance(Domoid *definition); 02080 02081 // Helper function called bby the constructors and finalize. 02082 void initializeRepresentation(DeclRewriter &rewriter); 02083 02084 // The following call-backs are invoked when the declarative region of the 02085 // defining declaration changes. 02086 void notifyAddDecl(Decl *decl); 02087 void notifyRemoveDecl(Decl *decl); 02088 }; 02089 02090 //===----------------------------------------------------------------------===// 02091 // PercentDecl 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 // Inline methods, now that the decl hierarchy is in place. 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 } // End comma namespace 02165 02166 #endif