00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #include "comma/ast/AggExpr.h"
00010 
00011 using namespace comma;
00012 using llvm::dyn_cast;
00013 using llvm::cast;
00014 using llvm::isa;
00015 
00016 
00017 
00018 
00019 bool ComponentKey::isStatic() const
00020 {
00021     if (const Range *range = getAsRange())
00022         return range->isStatic();
00023 
00024     if (const Expr *expr = getAsExpr())
00025         return expr->isStaticDiscreteExpr();
00026 
00027     if (const DiscreteType *type = getAsDiscreteType()) {
00028         if (type->isConstrained())
00029             return type->getConstraint()->isStatic();
00030         else
00031             return true;
00032     }
00033 
00034     assert(denotesIdentifier() || denotesComponent());
00035     return true;
00036 }
00037 
00038 Expr *ComponentKey::getLowerExpr()
00039 {
00040     if (Range *range = getAsRange())
00041         return range->getLowerBound();
00042     else
00043         return getAsExpr();
00044 }
00045 
00046 Expr *ComponentKey::getUpperExpr()
00047 {
00048     if (Range *range = getAsRange())
00049         return range->getUpperBound();
00050     else
00051         return getAsExpr();
00052 }
00053 
00054 void ComponentKey::getLowerValue(llvm::APInt &value) const
00055 {
00056     if (const Range *range = getAsRange())
00057         value = range->getStaticLowerBound();
00058     else
00059         getAsExpr()->staticDiscreteValue(value);
00060 }
00061 
00062 void ComponentKey::getUpperValue(llvm::APInt &value) const
00063 {
00064     if (const Range *range = getAsRange())
00065         value = range->getStaticUpperBound();
00066     else
00067         getAsExpr()->staticDiscreteValue(value);
00068 }
00069 
00070 bool ComponentKey::compareKeysU(const ComponentKey *X, const ComponentKey *Y)
00071 {
00072     assert(X->isComparable() && Y->isComparable() && "Keys not comparable!");
00073 
00074     llvm::APInt boundX;
00075     llvm::APInt boundY;
00076     X->getLowerValue(boundX);
00077     Y->getLowerValue(boundY);
00078     return boundX.getZExtValue() < boundY.getZExtValue();
00079 }
00080 
00081 bool ComponentKey::compareKeysS(const ComponentKey *X, const ComponentKey *Y)
00082 {
00083     assert(X->isComparable() && Y->isComparable() && "Keys not comparable!");
00084 
00085     llvm::APInt boundX;
00086     llvm::APInt boundY;
00087     X->getLowerValue(boundX);
00088     Y->getLowerValue(boundY);
00089     return boundX.getSExtValue() < boundY.getSExtValue();
00090 }
00091 
00092 
00093 
00094 
00095 ComponentKeyList::ComponentKeyList(ComponentKey **keys, unsigned numKeys,
00096                                    Expr *expr)
00097   : keys(reinterpret_cast<ComponentKey**>(this + 1)),
00098     keyCount(numKeys),
00099     expr(expr)
00100 {
00101     std::copy(keys, keys + numKeys, this->keys);
00102 }
00103 
00104 ComponentKeyList *ComponentKeyList::create(ComponentKey **keys,
00105                                            unsigned numKeys, Expr *expr)
00106 {
00107     assert(numKeys != 0 && "At leaast one key must be present!");
00108 
00109     
00110     
00111     unsigned size = sizeof(ComponentKeyList) + sizeof(ComponentKey*) * numKeys;
00112     char *raw = new char[size];
00113 
00114     
00115     
00116     return new (raw) ComponentKeyList(keys, numKeys, expr);
00117 }
00118 
00119 void ComponentKeyList::dispose(ComponentKeyList *CKL)
00120 {
00121     
00122     delete CKL->expr;
00123     for (iterator I = CKL->begin(); I != CKL->end(); ++I)
00124         delete *I;
00125 
00126     
00127     char *raw = reinterpret_cast<char*>(CKL);
00128     delete [] raw;
00129 }
00130 
00131 
00132 
00133 
00134 AggregateExpr::~AggregateExpr()
00135 {
00136     for (pos_iterator I = pos_begin(); I != pos_end(); ++I)
00137         delete *I;
00138 
00139     for (kl_iterator I = kl_begin(); I != kl_end(); ++I)
00140         ComponentKeyList::dispose(*I);
00141 
00142     if (Expr *others = getOthersExpr())
00143         delete others;
00144 }
00145 
00146 bool AggregateExpr::empty() const
00147 {
00148     return !(hasOthers() || hasKeyedComponents() || hasPositionalComponents());
00149 }
00150 
00151 unsigned AggregateExpr::numKeys() const
00152 {
00153     unsigned result = 0;
00154     for (const_kl_iterator I = kl_begin(); I != kl_end(); ++I)
00155         result += (*I)->numKeys();
00156     return result;
00157 }
00158 
00159 bool AggregateExpr::hasStaticIndices() const
00160 {
00161     if (hasKeyedComponents()) {
00162         
00163         
00164         ComponentKey *key = keyedComponents.front()->getKey(0);
00165         return key->isStatic();
00166     }
00167 
00168     
00169     return true;
00170 }
00171 
00172 unsigned AggregateExpr::numComponents() const
00173 {
00174     if (!hasStaticIndices())
00175         return 0;
00176 
00177     
00178     AggregateExpr *AE = const_cast<AggregateExpr*>(this);
00179 
00180     unsigned count = 0;
00181     key_iterator I = AE->key_begin();
00182     key_iterator E = AE->key_end();
00183     for ( ; I != E; ++I) {
00184         const ComponentKey *key = *I;
00185         if (const Range *range = key->getAsRange())
00186             count += range->length();
00187         else if (const DiscreteType *type = key->getAsDiscreteType())
00188             count += type->length();
00189         else {
00190             assert((key->denotesExpr() || key->denotesIdentifier()) &&
00191                    "Unexpected key!");
00192             count++;
00193         }
00194     }
00195 
00196     return count + numPositionalComponents();
00197 }
00198 
00199