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