00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #ifndef COMMA_AST_AGGEXPR_HDR_GUARD
00010 #define COMMA_AST_AGGEXPR_HDR_GUARD
00011 
00012 
00017 
00018 
00019 #include "comma/ast/Expr.h"
00020 #include "comma/ast/Type.h"
00021 #include "comma/ast/TypeRef.h"
00022 
00023 namespace comma {
00024 
00025 
00026 
00027 
00055 class Identifier : public Ast {
00056 
00057 public:
00058     Identifier(IdentifierInfo *name, Location loc)
00059         : Ast(AST_Identifier), name(name), loc(loc) { }
00060 
00062     IdentifierInfo *getIdInfo() const { return name; }
00063 
00065     Location getLocation() const { return loc; }
00066 
00068     void setIdInfo(IdentifierInfo *name) { this->name = name; }
00069 
00071     void setLocation(Location loc) { this->loc = loc; }
00072 
00073     
00074     static bool classof(const Identifier *node) { return true; }
00075     static bool classof(const Ast *node) {
00076         return node->getKind() == AST_Identifier;
00077     }
00078 
00079 private:
00080     IdentifierInfo *name;
00081     Location loc;
00082 };
00083 
00084 
00085 
00086 
00094 class ComponentKey : public Ast {
00095 
00096 public:
00098 
00099     ComponentKey(Expr *node)
00100         : Ast(AST_ComponentKey), rep(node), loc(node->getLocation()) { }
00101     ComponentKey(Identifier *node)
00102         : Ast(AST_ComponentKey), rep(node), loc(node->getLocation()) { }
00103     ComponentKey(Range *node)
00104         : Ast(AST_ComponentKey), rep(node), loc(node->getLowerLocation()) { }
00105     ComponentKey(TypeRef *node)
00106         : Ast(AST_ComponentKey), rep(node), loc(node->getLocation()) { }
00107     ComponentKey(ComponentDecl *node, Location loc)
00108         : Ast(AST_ComponentKey), rep(node), loc(loc) { }
00110 
00112 
00113     bool denotesExpr()       const { return llvm::isa<Expr>(rep);           }
00114     bool denotesIdentifier() const { return llvm::isa<Identifier>(rep);     }
00115     bool denotesRange()      const { return llvm::isa<Range>(rep);          }
00116     bool denotesType()       const { return llvm::isa<TypeRef>(rep);        }
00117     bool denotesComponent()  const { return llvm::isa<ComponentDecl>(rep) ; }
00119 
00121     Location getLocation() const { return loc; }
00122 
00124     void setLocation(Location loc) { this->loc = loc; }
00125 
00127 
00128 
00129 
00130     Expr *getAsExpr() {
00131         return llvm::dyn_cast<Expr>(rep);
00132     }
00133     Identifier *getAsIdentifier() {
00134         return llvm::dyn_cast<Identifier>(rep);
00135     }
00136     Range *getAsRange() {
00137         return llvm::dyn_cast<Range>(rep);
00138     }
00139     TypeRef *getAsTypeRef() {
00140         return llvm::dyn_cast<TypeRef>(rep);
00141     }
00142     DiscreteType *getAsDiscreteType() {
00143         if (TypeRef *ref = getAsTypeRef()) {
00144             return llvm::cast<DiscreteType>(ref->getTypeDecl()->getType());
00145         }
00146         return 0;
00147     }
00148     ComponentDecl *getAsComponent() {
00149         return llvm::dyn_cast<ComponentDecl>(rep);
00150     }
00151 
00152     const Expr *getAsExpr() const {
00153         return llvm::dyn_cast<Expr>(rep);
00154     }
00155     const Identifier *getAsIdentifier() const {
00156         return llvm::dyn_cast<Identifier>(rep);
00157     }
00158     const Range *getAsRange() const {
00159         return llvm::dyn_cast<Range>(rep);
00160     }
00161     const TypeRef *getAsTypeRef() const {
00162         return llvm::dyn_cast<TypeRef>(rep);
00163     }
00164     const DiscreteType *getAsDiscreteType() const {
00165         if (const TypeRef *ref = getAsTypeRef()) {
00166             return llvm::cast<DiscreteType>(ref->getTypeDecl()->getType());
00167         }
00168         return 0;
00169     }
00170     const ComponentDecl *getAsComponent() const {
00171         return llvm::dyn_cast<ComponentDecl>(rep);
00172     }
00173 
00175     Ast *&getRep() { return rep; }
00176     const Ast *getRep() const { return rep; }
00178 
00180 
00181     void setKey(Expr          *node) { rep = node; }
00182     void setKey(Range         *node) { rep = node; }
00183     void setKey(TypeRef       *node) { rep = node; }
00184     void setKey(Identifier    *node) { rep = node; }
00185     void setKey(ComponentDecl *node) { rep = node; }
00187 
00193     bool isStatic() const;
00194 
00201 
00202     Expr *getLowerExpr();
00203     Expr *getUpperExpr();
00204 
00205     void getLowerValue(llvm::APInt &value) const;
00206     void getUpperValue(llvm::APInt &value) const;
00208 
00210 
00211 
00217     bool isComparable() const { return !denotesIdentifier() && isStatic(); }
00218 
00224     static bool compareKeysU(const ComponentKey *X, const ComponentKey *Y);
00225 
00231     static bool compareKeysS(const ComponentKey *X, const ComponentKey *Y);
00233 
00234     
00235     static bool classof(const ComponentKey *node) { return true; }
00236     static bool classof(const Ast *node) {
00237         return node->getKind() == AST_ComponentKey;
00238     }
00239 
00240 private:
00241     Ast *rep;
00242     Location loc;
00243 };
00244 
00245 
00246 
00247 
00251 class ComponentKeyList {
00252 
00253 public:
00256     static ComponentKeyList *create(ComponentKey **keys, unsigned numKeys,
00257                                     Expr *expr);
00258 
00260     static void dispose(ComponentKeyList *CL);
00261 
00263 
00264     const Expr *getExpr() const { return expr; }
00265     Expr *getExpr() { return expr; }
00267 
00269     void setExpr(Expr *expr) { this->expr = expr; }
00270 
00272     unsigned numKeys() const { return keyCount; }
00273 
00275     Location getLocation() const { return keys[0]->getLocation(); }
00276 
00278 
00279 
00281     const ComponentKey *getKey(unsigned i) const {
00282         assert(i < keyCount && "Index out of range!");
00283         return keys[i];
00284     }
00285     ComponentKey *&getKey(unsigned i) {
00286         assert(i < keyCount && "Index out of range!");
00287         return keys[i];
00288     }
00289 
00295     template <class T>
00296     T *resolveKey(unsigned i) {
00297         assert(i < keyCount && "Index out of range!");
00298         return llvm::dyn_cast<T>(keys[i]->getRep());
00299     }
00300 
00301     template <class T>
00302     const T *resolveKey(unsigned i) const {
00303         assert(i < keyCount && "Index out of range!");
00304         return llvm::dyn_cast<T>(keys[i]->getRep());
00305     }
00306 
00308     Ast *&getRawKey(unsigned i) {
00309         assert(i < keyCount && "Index out of range!");
00310         return keys[i]->getRep();
00311     }
00312     const Ast *getRawKey(unsigned i) const {
00313         assert(i < keyCount && "Index out of range!");
00314         return keys[i]->getRep();
00315     }
00317 
00319 
00320     void setKey(unsigned i, Expr *node) {
00321         assert(i < keyCount && "Index out of range!");
00322         keys[i]->setKey(node);
00323     }
00324     void setKey(unsigned i, Identifier *node) {
00325         assert(i < keyCount && "Index out of range!");
00326         keys[i]->setKey(node);
00327     }
00328     void setKey(unsigned i, Range *node) {
00329         assert(i < keyCount && "Index out of range!");
00330         keys[i]->setKey(node);
00331     }
00332     void setKey(unsigned i, TypeRef *node) {
00333         assert(i < keyCount && "Index out of range!");
00334         keys[i]->setKey(node);
00335     }
00337 
00339 
00340 
00341 
00342     typedef ComponentKey **iterator;
00343     iterator begin() { return keys; }
00344     iterator end() { return &keys[keyCount]; }
00345 
00346     typedef ComponentKey *const *const_iterator;
00347     const_iterator begin() const { return keys; }
00348     const_iterator end() const { return &keys[keyCount]; }
00350 
00351 private:
00353     ComponentKeyList(ComponentKey **keys, unsigned numKeys, Expr *expr);
00354 
00355     ComponentKeyList(const ComponentKeyList &CL); 
00356     ComponentKeyList &operator =(const ComponentKeyList &CL); 
00357 
00361     ComponentKey **keys;
00362     unsigned keyCount;
00363     Expr *expr;
00364 };
00365 
00366 
00367 
00368 
00378 class AggregateExpr : public Expr {
00379 
00380 public:
00381     ~AggregateExpr();
00382 
00385     AggregateExpr(Location loc) : Expr(AST_AggregateExpr, loc), others(0) { }
00386 
00392     bool empty() const;
00393 
00403     bool hasStaticIndices() const;
00404 
00414     unsigned numComponents() const;
00415 
00421     bool isPurelyPositional() const { return !hasKeyedComponents(); }
00422 
00428     bool isPurelyKeyed() const { return !hasPositionalComponents(); }
00429 
00434 
00435 
00437     bool hasPositionalComponents() const {
00438         return !positionalComponents.empty();
00439     }
00440 
00442     unsigned numPositionalComponents() const {
00443         return positionalComponents.size();
00444     }
00445 
00450     void addComponent(Expr *expr) {
00451         positionalComponents.push_back(expr);
00452     }
00453 
00455 
00456     typedef std::vector<Expr*>::iterator pos_iterator;
00457     pos_iterator pos_begin() { return positionalComponents.begin(); }
00458     pos_iterator pos_end() { return positionalComponents.end(); }
00459 
00460     typedef std::vector<Expr*>::const_iterator const_pos_iterator;
00461     const_pos_iterator pos_begin() const {
00462         return positionalComponents.begin();
00463     }
00464     const_pos_iterator pos_end() const {
00465         return positionalComponents.end();
00466     }
00468 
00469 
00471 
00472 
00474     void addComponent(ComponentKeyList *keyList) {
00475         this->keyedComponents.push_back(keyList);
00476     }
00477 
00479     bool hasKeyedComponents() const { return !keyedComponents.empty(); }
00480 
00482     unsigned numKeyLists() const { return keyedComponents.size(); }
00483 
00485     unsigned numKeys() const;
00486 
00490 
00491     typedef std::vector<ComponentKeyList*>::iterator kl_iterator;
00492     kl_iterator kl_begin() { return keyedComponents.begin(); }
00493     kl_iterator kl_end() { return keyedComponents.end(); }
00494 
00495     typedef std::vector<ComponentKeyList*>::const_iterator const_kl_iterator;
00496     const_kl_iterator kl_begin() const { return keyedComponents.begin(); }
00497     const_kl_iterator kl_end() const { return keyedComponents.end(); }
00499 
00500 private:
00505     class KeyIterator {
00506         typedef std::vector<ComponentKeyList*> CKLVector;
00507 
00508         CKLVector &keys;
00509         unsigned keyIdx;        
00510         unsigned listIdx;       
00511 
00513         KeyIterator(CKLVector &keys,
00514                     unsigned keyIdx, unsigned listIdx)
00515             : keys(keys), keyIdx(keyIdx), listIdx(listIdx) { }
00516 
00518         KeyIterator(CKLVector &keys)
00519             : keys(keys), keyIdx(0), listIdx(0) { }
00520 
00522         static KeyIterator getSentinel(CKLVector &keys) {
00523             return KeyIterator(keys, keys.size(), 0);
00524         }
00525 
00526         friend class AggregateExpr;
00527 
00528     public:
00529         typedef ptrdiff_t difference_type;
00530         typedef ComponentKey *value_type;
00531         typedef value_type pointer;
00532         typedef value_type &reference;
00533         typedef std::forward_iterator_tag iterator_category;
00534 
00535         bool operator ==(const KeyIterator &iter) const {
00536             return keyIdx == iter.keyIdx && listIdx == iter.listIdx;
00537         }
00538 
00539         bool operator !=(const KeyIterator &iter) const {
00540             return !this->operator==(iter);
00541         }
00542 
00543         KeyIterator &operator++() {
00544             listIdx = listIdx + 1;
00545             if (listIdx == keys[keyIdx]->numKeys()) {
00546                 keyIdx = keyIdx + 1;
00547                 listIdx = 0;
00548             }
00549             return *this;
00550         }
00551 
00552         KeyIterator operator++(int) {
00553             KeyIterator res = *this;
00554             this->operator++();
00555             return res;
00556         }
00557 
00558         reference operator*() {
00559             return keys[keyIdx]->getKey(listIdx);
00560         }
00561 
00562         pointer operator->() {
00563             return keys[keyIdx]->getKey(listIdx);
00564         }
00565 
00567         Expr *getExpr() { return keys[keyIdx]->getExpr(); }
00568     };
00569 
00570 public:
00577 
00578     typedef KeyIterator key_iterator;
00579     key_iterator key_begin() { return KeyIterator(keyedComponents); }
00580     key_iterator key_end() {
00581         return KeyIterator::getSentinel(keyedComponents);
00582     }
00584 
00585 
00587     bool hasOthers() const { return others != 0; }
00588 
00590 
00591 
00592     Expr *getOthersExpr() { return others; }
00593     const Expr *getOthersExpr() const { return others; }
00595 
00598     Location getOthersLoc() const { return othersLoc; }
00599 
00608     void addOthersExpr(Location loc, Expr *component) {
00609         assert(!hasOthers() && "Others component already set!");
00610         othersLoc = loc;
00611         others = component;
00612     }
00613 
00615     void setOthersExpr(Expr *expr) {
00616         assert(hasOthers() &&
00617                "Cannot reset the others expr of this kind of aggregate!");
00618         others = expr;
00619     }
00621 
00622     
00623     static bool classof(const AggregateExpr *node) { return true; }
00624     static bool classof(const Ast *node) {
00625         return node->getKind() == AST_AggregateExpr;
00626     }
00627 
00628 private:
00629     
00630     
00631     
00632     std::vector<Expr*> positionalComponents;
00633 
00634     
00635     
00636     std::vector<ComponentKeyList*> keyedComponents;
00637 
00638     
00639     Location othersLoc;
00640 
00641     
00642     
00643     Expr *others;
00644 };
00645 
00646 } 
00647 
00648 #endif