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/AggExpr.cpp --------------------------------------- -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2009, Stephen Wilson 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 // ComponentKey 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 // ComponentKeyList 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 // Calculate the size of the needed ComponentKeyList and allocate the raw 00110 // memory. 00111 unsigned size = sizeof(ComponentKeyList) + sizeof(ComponentKey*) * numKeys; 00112 char *raw = new char[size]; 00113 00114 // Placement operator new using the classes constructor initializes the 00115 // internal structure. 00116 return new (raw) ComponentKeyList(keys, numKeys, expr); 00117 } 00118 00119 void ComponentKeyList::dispose(ComponentKeyList *CKL) 00120 { 00121 // Deallocate the associated AST nodes. 00122 delete CKL->expr; 00123 for (iterator I = CKL->begin(); I != CKL->end(); ++I) 00124 delete *I; 00125 00126 // Cast CKL back to a raw pointer to char and deallocate. 00127 char *raw = reinterpret_cast<char*>(CKL); 00128 delete [] raw; 00129 } 00130 00131 //===----------------------------------------------------------------------===// 00132 // AggregateExpr 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 // Only interrogate the first key since dynamicly sized aggregates can 00163 // only be specified using a single key. 00164 ComponentKey *key = keyedComponents.front()->getKey(0); 00165 return key->isStatic(); 00166 } 00167 00168 // This aggregate is purely positional. 00169 return true; 00170 } 00171 00172 unsigned AggregateExpr::numComponents() const 00173 { 00174 if (!hasStaticIndices()) 00175 return 0; 00176 00177 // FIXME: Use const_key_iterator when available. 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