00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 #include <assert.h>
00028 
00029 #include "types.h"
00030 #include "type.h"
00031 #include "util.h"
00032 #include "exp.h"
00033 #include "cfg.h"
00034 #include "proc.h"
00035 #include "signature.h"
00036 #include "boomerang.h"
00037 #include "log.h"
00038 #if defined(_MSC_VER) && _MSC_VER >= 1400
00039 #pragma warning(disable:4996)       // Warnings about e.g. _strdup deprecated in VS 2005
00040 #endif
00041 
00042 extern char debug_buffer[];      
00043 
00044 bool Type::isCString()
00045 {
00046     if (!resolvesToPointer())
00047         return false;
00048     Type *p = asPointer()->getPointsTo();
00049     if (p->resolvesToChar())
00050         return true;
00051     if (!p->resolvesToArray())
00052         return false;
00053     p = p->asArray()->getBaseType();
00054     return p->resolvesToChar();
00055 }
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 Type::Type(eType id) : id(id) {
00064 }
00065 
00066 VoidType::VoidType() : Type(eVoid) {
00067 }
00068 
00069 FuncType::FuncType(Signature *sig) : Type(eFunc), signature(sig) {
00070 }
00071 
00072 IntegerType::IntegerType(int sz, int sign) : Type(eInteger), size(sz), signedness(sign) {
00073 }
00074 
00075 FloatType::FloatType(int sz) : Type(eFloat), size(sz) {
00076 }
00077 
00078 BooleanType::BooleanType() : Type(eBoolean) {
00079 }
00080 
00081 CharType::CharType() : Type(eChar) {
00082 }
00083 
00084 void PointerType::setPointsTo(Type* p) {
00085     if (p == this) {                    
00086         points_to = new VoidType();     
00087         if (VERBOSE)
00088             LOG << "Warning: attempted to create pointer to self: " << (unsigned)this << "\n";
00089     } else
00090         points_to = p;
00091 }
00092 
00093 PointerType::PointerType(Type *p) : Type(ePointer) {
00094     setPointsTo(p);
00095 }
00096 ArrayType::ArrayType(Type *p, unsigned length) : Type(eArray), base_type(p), length(length)
00097 {
00098 }
00099 
00100 
00101 
00102 
00103 #define NO_BOUND 9999999
00104 
00105 ArrayType::ArrayType(Type *p) : Type(eArray), base_type(p), length(NO_BOUND)
00106 {
00107 }
00108 
00109 bool ArrayType::isUnbounded() const {
00110     return length == NO_BOUND;
00111 }
00112 
00113 void ArrayType::setBaseType(Type* b) {
00114     
00115     if (length != NO_BOUND) {
00116         unsigned baseSize = base_type->getSize()/8; 
00117         if (baseSize == 0) baseSize = 1;            
00118         baseSize *= length;                         
00119         unsigned newSize = b->getSize()/8;
00120         if (newSize == 0) newSize = 1;
00121         length = baseSize / newSize;                
00122     }
00123     base_type = b;
00124 }
00125         
00126 
00127 NamedType::NamedType(const char *name) : Type(eNamed), name(name)
00128 {
00129 }
00130 
00131 CompoundType::CompoundType(bool generic ) : Type(eCompound), nextGenericMemberNum(1), generic(generic)
00132 {
00133 }
00134 
00135 UnionType::UnionType() : Type(eUnion)
00136 {
00137 }
00138 
00139 
00140 
00141 
00142 
00143 
00144 
00145 Type::~Type() { }
00146 VoidType::~VoidType() { }
00147 FuncType::~FuncType() { }
00148 IntegerType::~IntegerType() { }
00149 FloatType::~FloatType() { }
00150 BooleanType::~BooleanType() { }
00151 CharType::~CharType() { }
00152 PointerType::~PointerType() {
00153     
00154 }
00155 ArrayType::~ArrayType() {
00156     
00157 }
00158 NamedType::~NamedType() { }
00159 CompoundType::~CompoundType() { }
00160 UnionType::~UnionType() { }
00161 
00162 
00163 
00164 
00165 
00166 
00167 
00168 Type *IntegerType::clone() const
00169 {
00170     IntegerType *t = new IntegerType(size, signedness);
00171     return t;
00172 }
00173 
00174 Type *FloatType::clone() const
00175 {
00176     FloatType *t = new FloatType(size);
00177     return t;
00178 }
00179 
00180 Type *BooleanType::clone() const
00181 {
00182     BooleanType *t = new BooleanType();
00183     return t;
00184 }
00185 
00186 Type *CharType::clone() const
00187 {
00188     CharType *t = new CharType();
00189     return t;
00190 }
00191 
00192 Type *VoidType::clone() const
00193 {
00194     VoidType *t = new VoidType();
00195     return t;
00196 }
00197 
00198 Type *FuncType::clone() const
00199 {
00200     FuncType *t = new FuncType(signature);
00201     return t;
00202 }
00203 
00204 Type *PointerType::clone() const
00205 {
00206     PointerType *t = new PointerType(points_to->clone());
00207     return t;
00208 }
00209 
00210 Type *ArrayType::clone() const
00211 {
00212     ArrayType *t = new ArrayType(base_type->clone(), length);
00213     return t;
00214 }
00215 
00216 Type *NamedType::clone() const
00217 {
00218     NamedType *t = new NamedType(name.c_str());
00219     return t;
00220 }
00221 
00222 Type *CompoundType::clone() const
00223 {
00224     CompoundType *t = new CompoundType();
00225     for (unsigned i = 0; i < types.size(); i++)
00226         t->addType(types[i]->clone(), names[i].c_str());
00227     return t;
00228 }
00229 
00230 Type *UnionType::clone() const {
00231     UnionType *u = new UnionType();
00232     std::list<UnionElement>::const_iterator it;
00233     for (it = li.begin(); it != li.end(); it++)
00234         u->addType(it->type, it->name.c_str());
00235     return u;
00236 }
00237 
00238 Type *SizeType::clone() const
00239 {
00240     SizeType *t = new SizeType(size);
00241     return t;
00242 }
00243 
00244 Type* UpperType::clone() const
00245 {
00246     UpperType* t = new UpperType(base_type->clone());
00247     return t;
00248 }
00249 
00250 Type* LowerType::clone() const
00251 {
00252     LowerType* t = new LowerType(base_type->clone());
00253     return t;
00254 }
00255 
00256 
00257 
00258 
00259 
00260 
00261 
00262 
00263 unsigned IntegerType::getSize() const { return size; }
00264 unsigned      FloatType::getSize() const { return size; }
00265 unsigned BooleanType::getSize() const { return 1; }
00266 unsigned       CharType::getSize() const { return 8; }
00267 unsigned       VoidType::getSize() const { return 0; }
00268 unsigned       FuncType::getSize() const { return 0;  }
00269 unsigned PointerType::getSize() const {
00270     
00271     return STD_SIZE;
00272 }
00273 unsigned ArrayType::getSize() const {
00274     return base_type->getSize() * length;
00275 }
00276 unsigned NamedType::getSize() const {
00277     Type *ty = resolvesTo();
00278     if (ty)
00279         return ty->getSize();
00280     if (VERBOSE)
00281         LOG << "WARNING: Unknown size for named type " << name.c_str() << "\n";
00282     return 0; 
00283 }
00284 unsigned CompoundType::getSize() const {
00285     int n = 0;
00286     for (unsigned i = 0; i < types.size(); i++)
00287         
00288         n += types[i]->getSize();
00289     return n;
00290 }
00291 unsigned UnionType::getSize() const {
00292     int max = 0;
00293     std::list<UnionElement>::const_iterator it;
00294     for (it = li.begin(); it != li.end(); it++) {
00295         int sz = it->type->getSize();
00296         if (sz > max) max = sz;
00297     }
00298     return max;
00299 }
00300 unsigned SizeType::getSize() const { return size; }
00301 
00302 
00303 
00304 Type *CompoundType::getType(const char *nam)
00305 {
00306     for (unsigned i = 0; i < types.size(); i++)
00307         if (names[i] == nam)
00308             return types[i];
00309     return NULL;
00310 }
00311 
00312 
00313 Type *CompoundType::getTypeAtOffset(unsigned n)
00314 {
00315     unsigned offset = 0;
00316     for (unsigned i = 0; i < types.size(); i++) {
00317         if (offset <= n && n < offset + types[i]->getSize())
00318             return types[i];
00319         offset += types[i]->getSize();
00320     }
00321     return NULL;
00322 }
00323 
00324 
00325 void CompoundType::setTypeAtOffset(unsigned n, Type* ty) {
00326     unsigned offset = 0;
00327     for (unsigned i = 0; i < types.size(); i++) {
00328         if (offset <= n && n < offset + types[i]->getSize()) {
00329             unsigned oldsz = types[i]->getSize();
00330             types[i] = ty;
00331             if (ty->getSize() < oldsz) {
00332                 types.push_back(types[types.size()-1]);
00333                 names.push_back(names[names.size()-1]);
00334                 for (unsigned n = types.size() - 1; n > i; n--) {
00335                     types[n] = types[n-1];
00336                     names[n] = names[n-1];
00337                 }
00338                 types[i+1] = new SizeType(oldsz - ty->getSize());
00339                 names[i+1] = "pad";
00340             }
00341             return;
00342         }
00343         offset += types[i]->getSize();
00344     }
00345 }
00346 
00347 void CompoundType::setNameAtOffset(unsigned n, const char *nam)
00348 {
00349     unsigned offset = 0;
00350     for (unsigned i = 0; i < types.size(); i++) {
00351         if (offset <= n && n < offset + types[i]->getSize()) {
00352             names[i] = nam;
00353             return;
00354         }
00355         offset += types[i]->getSize();
00356     }
00357 }
00358 
00359 
00360 const char *CompoundType::getNameAtOffset(unsigned n)
00361 {
00362     unsigned offset = 0;
00363     for (unsigned i = 0; i < types.size(); i++) {
00364         
00365         if (offset <= n && n < offset + types[i]->getSize())
00366             
00367             return names[i].c_str();
00368         offset += types[i]->getSize();
00369     }
00370     return NULL;
00371 }
00372 
00373 unsigned CompoundType::getOffsetTo(unsigned n)
00374 {
00375     unsigned offset = 0;
00376     for (unsigned i = 0; i < n; i++) {
00377         offset += types[i]->getSize();
00378     }
00379     return offset;
00380 }
00381 
00382 unsigned CompoundType::getOffsetTo(const char *member)
00383 {
00384     unsigned offset = 0;
00385     for (unsigned i = 0; i < types.size(); i++) {
00386         if (names[i] == member)
00387             return offset;
00388         offset += types[i]->getSize();
00389     }
00390     return (unsigned)-1;
00391 }
00392 
00393 unsigned CompoundType::getOffsetRemainder(unsigned n)
00394 {
00395     unsigned r = n;
00396     unsigned offset = 0;
00397     for (unsigned i = 0; i < types.size(); i++) {
00398         offset += types[i]->getSize();
00399         if (offset > n)
00400             break;
00401         r -= types[i]->getSize();
00402     }
00403     return r;
00404 }
00405 
00406 
00407 
00408 
00409 
00410 
00411 
00412 Type *Type::parseType(const char *str)
00413 {
00414     return NULL;
00415 }
00416 
00417 
00418 
00419 
00420 
00421 
00422 
00423 bool IntegerType::operator==(const Type& other) const {
00424     IntegerType& otherInt = (IntegerType&) other;
00425     return other.isInteger() && 
00426         
00427         (size == 0 || otherInt.size == 0 || size == otherInt.size) &&
00428         
00429         ( signedness < 0    && otherInt.signedness < 0 ||
00430           signedness == 0   && otherInt.signedness == 0 ||
00431           signedness > 0    && otherInt.signedness > 0);
00432 }
00433 
00434 bool FloatType::operator==(const Type& other) const {
00435     return other.isFloat() && 
00436       (size == 0 || ((FloatType&)other).size == 0 || 
00437       (size == ((FloatType&)other).size));
00438 }
00439 
00440 bool BooleanType::operator==(const Type& other) const {
00441     return other.isBoolean();
00442 }
00443 
00444 bool CharType::operator==(const Type& other) const {
00445     return other.isChar();
00446 }
00447 
00448 bool VoidType::operator==(const Type& other) const {
00449     return other.isVoid();
00450 }
00451 
00452 bool FuncType::operator==(const Type& other) const {
00453     if (!other.isFunc()) return false;
00454     
00455     if (signature == NULL) return ((FuncType&)other).signature == NULL;
00456     return *signature == *((FuncType&)other).signature;
00457 }
00458 
00459 static int pointerCompareNest = 0;
00460 bool PointerType::operator==(const Type& other) const {
00461 
00462     if (!other.isPointer()) return false;
00463     if (++pointerCompareNest >= 20) {
00464         std::cerr << "PointerType operator== nesting depth exceeded!\n";
00465         return true;
00466     }
00467     bool ret = (*points_to == *((PointerType&)other).points_to);
00468     pointerCompareNest--;
00469     return ret;
00470 }
00471 
00472 bool ArrayType::operator==(const Type& other) const {
00473     return other.isArray() && *base_type == *((ArrayType&)other).base_type &&
00474            ((ArrayType&)other).length == length;
00475 }
00476 
00477 bool NamedType::operator==(const Type& other) const {
00478     return other.isNamed() && (name == ((NamedType&)other).name);
00479 }
00480 
00481 bool CompoundType::operator==(const Type& other) const {
00482     const CompoundType &cother = (CompoundType&)other;
00483     if (other.isCompound() && cother.types.size() == types.size()) {
00484         for (unsigned i = 0; i < types.size(); i++)
00485             if (!(*types[i] == *cother.types[i]))
00486                 return false;
00487         return true;
00488     }
00489     return false;
00490 }
00491 
00492 bool UnionType::operator==(const Type& other) const {
00493     const UnionType &uother = (UnionType&)other;
00494     std::list<UnionElement>::const_iterator it1, it2;
00495     if (other.isUnion() && uother.li.size() == li.size()) {
00496         for (it1 = li.begin(), it2 = uother.li.begin(); it1 != li.end(); it1++, it2++)
00497             if (!(*it1->type == *it2->type))
00498                 return false;
00499         return true;
00500     }
00501     return false;
00502 }
00503 
00504 bool SizeType::operator==(const Type& other) const {
00505     return other.isSize() && (size == ((SizeType&)other).size);
00506 }
00507 bool UpperType::operator==(const Type& other) const {
00508     return other.isUpper() && *base_type == *((UpperType&)other).base_type;
00509 }
00510 
00511 bool LowerType::operator==(const Type& other) const {
00512     return other.isLower() && *base_type == *((LowerType&)other).base_type;
00513 }
00514 
00515 
00516 
00517 
00518 
00519 
00520 
00521 
00522 bool Type::operator!=(const Type& other) const
00523 {
00524     return !(*this == other);
00525 }
00526 
00527 
00528 
00529 
00530 
00531 
00532 
00533 
00534 
00535 
00536 
00537 
00538 
00539 
00540 
00541 
00542 
00543 
00544 
00545 
00546 
00547 
00548 
00549 
00550 
00551 
00552 
00553 
00554 
00555 
00556 
00557 bool IntegerType::operator<(const Type& other) const {
00558     if (id < other.getId()) return true;
00559     if (id > other.getId()) return false;
00560     if (size < ((IntegerType&)other).size) return true;
00561     if (size > ((IntegerType&)other).size) return false;
00562     return (signedness < ((IntegerType&)other).signedness);
00563 }
00564 
00565 bool FloatType::operator<(const Type& other) const {
00566     if (id < other.getId()) return true;
00567     if (id > other.getId()) return false;
00568     return (size < ((FloatType&)other).size);
00569 }
00570 
00571 bool VoidType::operator<(const Type& other) const {
00572     return id < other.getId();
00573 }
00574 
00575 bool FuncType::operator<(const Type& other) const {
00576     if (id < other.getId()) return true;
00577     if (id > other.getId()) return false;
00578     
00579     return true;
00580 }
00581 
00582 bool BooleanType::operator<(const Type& other) const {
00583     if (id < other.getId()) return true;
00584     if (id > other.getId()) return false;
00585     return true;
00586 }
00587 
00588 bool CharType::operator<(const Type& other) const {
00589     return id < other.getId();
00590 }
00591 
00592 bool PointerType::operator<(const Type& other) const {
00593     if (id < other.getId()) return true;
00594     if (id > other.getId()) return false;
00595     return (*points_to < *((PointerType&)other).points_to);
00596 }
00597 
00598 bool ArrayType::operator<(const Type& other) const {
00599     if (id < other.getId()) return true;
00600     if (id > other.getId()) return false;
00601     return (*base_type < *((ArrayType&)other).base_type);
00602 }
00603 
00604 bool NamedType::operator<(const Type& other) const {
00605     if (id < other.getId()) return true;
00606     if (id > other.getId()) return false;
00607     return (name < ((NamedType&)other).name);
00608 }
00609 
00610 bool CompoundType::operator<(const Type& other) const {
00611     if (id < other.getId()) return true;
00612     if (id > other.getId()) return false;
00613     return getSize() < other.getSize();     
00614 }
00615 
00616 bool UnionType::operator<(const Type& other) const {
00617     if (id < other.getId()) return true;
00618     if (id > other.getId()) return false;
00619     return getNumTypes() < ((const UnionType&)other).getNumTypes();
00620 }
00621 
00622 bool SizeType::operator<(const Type& other) const {
00623     if (id < other.getId()) return true;
00624     if (id > other.getId()) return false;
00625     return (size < ((SizeType&)other).size);
00626 }
00627 
00628 bool UpperType::operator<(const Type& other) const {
00629     if (id < other.getId()) return true;
00630     if (id > other.getId()) return false;
00631     return (*base_type < *((UpperType&)other).base_type);
00632 }
00633 
00634 bool LowerType::operator<(const Type& other) const {
00635     if (id < other.getId()) return true;
00636     if (id > other.getId()) return false;
00637     return (*base_type < *((LowerType&)other).base_type);
00638 }
00639 
00640 
00641 
00642 
00643 
00644 
00645 
00646 Exp *Type::match(Type *pattern)
00647 {
00648     if (pattern->isNamed()) {
00649         LOG << "type match: " << this->getCtype() << " to " << pattern->getCtype() << "\n";
00650         return new Binary(opList, 
00651             new Binary(opEquals, 
00652                 new Unary(opVar,
00653                     new Const((char*)pattern->asNamed()->getName())), 
00654                 new TypeVal(this->clone())), 
00655             new Terminal(opNil));
00656     }
00657     return NULL;
00658 }
00659 
00660 Exp *IntegerType::match(Type *pattern)
00661 {
00662     return Type::match(pattern);
00663 }
00664 
00665 Exp *FloatType::match(Type *pattern)
00666 {
00667     return Type::match(pattern);
00668 }
00669 
00670 Exp *BooleanType::match(Type *pattern)
00671 {
00672     return Type::match(pattern);
00673 }
00674 
00675 Exp *CharType::match(Type *pattern)
00676 {
00677     return Type::match(pattern);
00678 }
00679 
00680 Exp *VoidType::match(Type *pattern)
00681 {
00682     return Type::match(pattern);
00683 }
00684 
00685 Exp *FuncType::match(Type *pattern)
00686 {
00687     return Type::match(pattern);
00688 }
00689 
00690 Exp *PointerType::match(Type *pattern)
00691 {
00692     if (pattern->isPointer()) {
00693         LOG << "got pointer match: " << this->getCtype() << " to " << pattern->getCtype() << "\n";
00694         return points_to->match(pattern->asPointer()->getPointsTo());
00695     }
00696     return Type::match(pattern);
00697 }
00698 
00699 Exp *ArrayType::match(Type *pattern)
00700 {
00701     if (pattern->isArray())
00702         return base_type->match(pattern);
00703     return Type::match(pattern);
00704 }
00705 
00706 Exp *NamedType::match(Type *pattern)
00707 {
00708     return Type::match(pattern);
00709 }
00710 
00711 Exp *CompoundType::match(Type *pattern)
00712 {
00713     return Type::match(pattern);
00714 }
00715 
00716 Exp *UnionType::match(Type *pattern)
00717 {
00718     return Type::match(pattern);
00719 }
00720 
00721 
00722 
00723 
00724 
00725 
00726 
00727 
00728 const char *VoidType::getCtype(bool final) const { return "void"; }
00729 
00730 const char *FuncType::getCtype(bool final) const {
00731     if (signature == NULL)
00732     return "void (void)"; 
00733     std::string s; 
00734     if (signature->getNumReturns() == 0)
00735         s += "void";
00736     else 
00737         s += signature->getReturnType(0)->getCtype(final);
00738     s += " (";
00739     for (unsigned i = 0; i < signature->getNumParams(); i++) {
00740        if (i != 0) s += ", ";
00741        s += signature->getParamType(i)->getCtype(final); 
00742     }
00743     s += ")";
00744     return strdup(s.c_str());
00745 }
00746 
00747 
00748 void FuncType::getReturnAndParam(const char*& ret, const char*& param) {
00749     if (signature == NULL) {
00750         ret = "void";
00751         param = "(void)";
00752         return;
00753     }
00754     if (signature->getNumReturns() == 0)
00755         ret = "void";
00756     else 
00757         ret = signature->getReturnType(0)->getCtype();
00758     std::string s; 
00759     s += " (";
00760     for (unsigned i = 0; i < signature->getNumParams(); i++) {
00761        if (i != 0) s += ", ";
00762        s += signature->getParamType(i)->getCtype(); 
00763     }
00764     s += ")";
00765     param = strdup(s.c_str());
00766 }
00767 
00768 const char *IntegerType::getCtype(bool final) const {
00769     if (signedness >= 0) {
00770         std::string s;
00771         if (!final && signedness == 0)
00772             s = "/*signed?*/";
00773         switch(size) {
00774             case 32: s += "int"; break;
00775             case 16: s += "short"; break;
00776             case  8: s += "char"; break;
00777             case  1: s += "bool"; break;
00778             case 64: s += "long long"; break;
00779             default: 
00780                 if (!final) s += "?";   
00781                 s += "int";
00782         }
00783         return strdup(s.c_str());
00784     } else {
00785         switch (size) {
00786             case 32: return "unsigned int"; break;
00787             case 16: return "unsigned short"; break;
00788             case  8: return "unsigned char"; break;
00789             case  1: return "bool"; break;
00790             case 64: return "unsigned long long"; break;
00791             default: if (final) return "unsigned int"; 
00792                 else return "?unsigned int";
00793         }
00794     }
00795 }
00796 
00797 const char *FloatType::getCtype(bool final) const {
00798     switch (size) {
00799         case 32: return "float"; break;
00800         case 64: return "double"; break;
00801         default: return "double"; break;
00802     }
00803 }
00804 
00805 const char *BooleanType::getCtype(bool final) const { return "bool"; }
00806 
00807 const char *CharType::getCtype(bool final) const { return "char"; }
00808 
00809 const char *PointerType::getCtype(bool final) const {
00810      std::string s = points_to->getCtype(final);
00811      if (points_to->isPointer())
00812         s += "*";
00813      else
00814         s += " *";
00815      return strdup(s.c_str()); 
00816 }
00817 
00818 const char *ArrayType::getCtype(bool final) const {
00819     std::string s = base_type->getCtype(final);
00820     std::ostringstream ost;
00821     if (isUnbounded())
00822         ost << "[]";
00823     else
00824         ost << "[" << length << "]";
00825     s += ost.str().c_str();
00826     return strdup(s.c_str()); 
00827 }
00828 
00829 const char *NamedType::getCtype(bool final) const { return name.c_str(); }
00830 
00831 const char *CompoundType::getCtype(bool final) const {
00832     std::string &tmp = *(new std::string("struct { "));
00833     for (unsigned i = 0; i < types.size(); i++) {
00834         tmp += types[i]->getCtype(final);
00835         if (names[i] != "") {
00836             tmp += " ";
00837             tmp += names[i];
00838         }
00839         tmp += "; ";
00840     }
00841     tmp += "}";
00842     return strdup(tmp.c_str());
00843 }
00844 
00845 const char *UnionType::getCtype(bool final) const {
00846     std::string &tmp = *(new std::string("union { "));
00847     std::list<UnionElement>::const_iterator it;
00848     for (it = li.begin(); it != li.end(); it++) {
00849         tmp += it->type->getCtype(final);
00850         if (it->name != "") {
00851             tmp += " ";
00852             tmp += it->name;
00853         }
00854         tmp += "; ";
00855     }
00856     tmp += "}";
00857     return strdup(tmp.c_str());
00858 }
00859 
00860 const char* SizeType::getCtype(bool final) const {
00861     
00862     std::ostringstream ost;
00863     ost << "__size" << std::dec << size;
00864     return strdup(ost.str().c_str());
00865 }
00866 
00867 const char* UpperType::getCtype(bool final) const {
00868     std::ostringstream ost;
00869     ost << "/*upper*/(" << base_type << ")";
00870     return strdup(ost.str().c_str());
00871 }
00872 const char* LowerType::getCtype(bool final) const {
00873     std::ostringstream ost;
00874     ost << "/*lower*/(" << base_type << ")";
00875     return strdup(ost.str().c_str());
00876 }
00877     
00878 const char* Type::prints() {
00879     return getCtype(false);         
00880 }
00881 
00882 void Type::dump() {
00883     std::cerr << getCtype(false);   
00884 }
00885 
00886 std::map<std::string, Type*> Type::namedTypes;
00887 
00888 
00889 void Type::addNamedType(const char *name, Type *type)
00890 {
00891     if (namedTypes.find(name) != namedTypes.end()) {
00892         if (!(*type == *namedTypes[name])) {
00893             
00894             
00895             
00896             std::cerr << "Warning: Type::addNamedType: Redefinition of type " << name << "\n";
00897             std::cerr << " type     = " << type->prints() << "\n";
00898             std::cerr << " previous = " << namedTypes[name]->prints() << "\n";
00899             *type == *namedTypes[name];
00900         }
00901     } else {
00902         
00903         
00904         
00905         
00906         
00907         if (namedTypes.find(type->getCtype()) != namedTypes.end()) {
00908             namedTypes[name] = namedTypes[type->getCtype()]->clone();
00909         } else {
00910             namedTypes[name] = type->clone();
00911         }
00912     }
00913 }
00914 
00915 Type *Type::getNamedType(const char *name)
00916 {
00917     if (namedTypes.find(name) != namedTypes.end())
00918         return namedTypes[name];
00919     return NULL;
00920 }
00921 
00922 void Type::dumpNames() {
00923     std::map<std::string, Type*>::iterator it;
00924     for (it = namedTypes.begin(); it != namedTypes.end(); ++it)
00925         std::cerr << it->first << " -> " << it->second->getCtype() << "\n";
00926 }
00927 
00928 
00929 
00930 
00931 
00932 
00933 
00934 
00935 Type* Type::getTempType(const std::string& name)
00936 {
00937     Type* ty;
00938     char ctype = ' ';
00939     if (name.size() > 3) ctype = name[3];
00940     switch (ctype) {
00941         
00942         case 'f': ty = new FloatType(32); break;
00943         case 'd': ty = new FloatType(64); break;
00944         case 'F': ty = new FloatType(80); break;
00945         case 'D': ty = new FloatType(128); break;
00946         case 'l': ty = new IntegerType(64); break;
00947         case 'h': ty = new IntegerType(16); break;
00948         case 'b': ty = new IntegerType(8); break;
00949         default:  ty = new IntegerType(32); break;
00950     }
00951     return ty;
00952 }
00953 
00954 
00955 
00956 
00957 
00958 
00959 
00960 
00961 
00962 
00963 
00964 std::string IntegerType::getTempName() const
00965 {
00966     switch( size ) {
00967         case 1:  
00968         case 8:  return std::string("tmpb");
00969         case 16: return std::string("tmph");
00970         case 32: return std::string("tmpi");
00971         case 64: return std::string("tmpl");
00972     }
00973     return std::string("tmp");
00974 }
00975 
00976 std::string FloatType::getTempName() const
00977 {
00978     switch( size ) {
00979         case 32: return std::string("tmpf");
00980         case 64: return std::string("tmpd");
00981         case 80: return std::string("tmpF");
00982         case 128:return std::string("tmpD");
00983     }
00984     return std::string("tmp");
00985 }
00986 
00987 std::string Type::getTempName() const
00988 {
00989     return std::string("tmp"); 
00990 }
00991 
00992 int NamedType::nextAlpha = 0;
00993 NamedType* NamedType::getAlpha() {
00994     std::ostringstream ost;
00995     ost << "alpha" << nextAlpha++;
00996     return new NamedType(strdup(ost.str().c_str()));
00997 }
00998 
00999 PointerType* PointerType::newPtrAlpha() {
01000     return new PointerType(NamedType::getAlpha());
01001 }
01002 
01003 
01004 bool PointerType::pointsToAlpha() {
01005     
01006     if (points_to->isVoid()) return true;
01007     if (!points_to->isNamed()) return false;
01008     return strncmp(((NamedType*)points_to)->getName(), "alpha", 5) == 0;
01009 }
01010 
01011 int PointerType::pointerDepth() {
01012     int d = 1;
01013     Type* pt = points_to;
01014     while (pt->isPointer()) {
01015         pt = pt->asPointer()->getPointsTo();
01016         d++;
01017     }
01018     return d;
01019 }
01020 
01021 Type* PointerType::getFinalPointsTo() {
01022     Type* pt = points_to;
01023     while (pt->isPointer()) {
01024         pt = pt->asPointer()->getPointsTo();
01025     }
01026     return pt;
01027 }
01028 
01029 Type *NamedType::resolvesTo() const
01030 {
01031     Type *ty = getNamedType(name.c_str());
01032     if (ty && ty->isNamed())
01033         return ((NamedType*)ty)->resolvesTo();
01034     return ty;
01035 }
01036 
01037 void ArrayType::fixBaseType(Type *b)
01038 {
01039     if (base_type == NULL)
01040         base_type = b;
01041     else {
01042         assert(base_type->isArray());
01043         base_type->asArray()->fixBaseType(b);
01044     }
01045 }
01046 
01047 #define AS_TYPE(x) \
01048 x##Type *Type::as##x() \
01049 {                       \
01050     Type *ty = this;    \
01051     if (isNamed())      \
01052         ty = ((NamedType*)ty)->resolvesTo();    \
01053     x##Type *res = dynamic_cast<x##Type*>(ty);  \
01054     assert(res);        \
01055     return res;         \
01056 }
01057 
01058 AS_TYPE(Void)
01059 AS_TYPE(Func)
01060 AS_TYPE(Boolean)
01061 AS_TYPE(Char)
01062 AS_TYPE(Integer)
01063 AS_TYPE(Float)
01064 AS_TYPE(Pointer)
01065 AS_TYPE(Array)
01066 AS_TYPE(Compound)
01067 AS_TYPE(Size);
01068 AS_TYPE(Union)
01069 AS_TYPE(Upper)
01070 AS_TYPE(Lower)
01071 
01072 
01073 NamedType *Type::asNamed()
01074 {
01075     Type *ty = this;
01076     NamedType *res = dynamic_cast<NamedType*>(ty);
01077     assert(res);
01078     return res;
01079 }
01080 
01081 
01082 
01083 #define RESOLVES_TO_TYPE(x)     \
01084 bool Type::resolvesTo##x()  \
01085 {                           \
01086     Type *ty = this;        \
01087     if (ty->isNamed())      \
01088         ty = ((NamedType*)ty)->resolvesTo(); \
01089     return ty && ty->is##x(); \
01090 }
01091 
01092 RESOLVES_TO_TYPE(Void)
01093 RESOLVES_TO_TYPE(Func)
01094 RESOLVES_TO_TYPE(Boolean)
01095 RESOLVES_TO_TYPE(Char)
01096 RESOLVES_TO_TYPE(Integer)
01097 RESOLVES_TO_TYPE(Float)
01098 RESOLVES_TO_TYPE(Pointer)
01099 RESOLVES_TO_TYPE(Array)
01100 RESOLVES_TO_TYPE(Compound)
01101 RESOLVES_TO_TYPE(Union)
01102 RESOLVES_TO_TYPE(Size)
01103 RESOLVES_TO_TYPE(Upper)
01104 RESOLVES_TO_TYPE(Lower)
01105 
01106 bool Type::isPointerToAlpha() {
01107     return isPointer() && asPointer()->pointsToAlpha();
01108 }
01109 
01110 void Type::starPrint(std::ostream& os) {
01111     os << "*" << this << "*";
01112 }
01113 
01114 
01115 std::ostream& operator<<(std::ostream& os, Type* t) {
01116     if (t == NULL) return os << '0';
01117     switch (t->getId()) {
01118         case eInteger: {
01119             int sg = ((IntegerType*)t)->getSignedness();
01120             
01121             os << (sg == 0 ? 'j' : sg>0 ? 'i' : 'u');
01122             os << std::dec << t->asInteger()->getSize();
01123             break;
01124         }
01125         case eFloat:    os << 'f'; os << std::dec << t->asFloat()->getSize(); break;
01126         case ePointer:  os << t->asPointer()->getPointsTo() << '*'; break;
01127         case eSize:     os << std::dec << t->getSize(); break;
01128         case eChar:     os << 'c'; break;
01129         case eVoid:     os << 'v'; break;
01130         case eBoolean:  os << 'b'; break;
01131         case eCompound: os << "struct"; break; 
01132         case eUnion:    os << "union"; break;
01133         
01134         case eFunc:     os << "func"; break;
01135         case eArray:    os << '[' << t->asArray()->getBaseType(); if (!t->asArray()->isUnbounded()) os << ", " << t->asArray()->getLength(); os << ']'; break;
01136         case eNamed:    os << t->asNamed()->getName(); break;
01137         case eUpper:    os << "U(" << t->asUpper()->getBaseType() << ')'; break;
01138         case eLower:    os << "L(" << t->asLower()->getBaseType() << ')'; break;
01139     }
01140     return os;
01141 }
01142 
01143 
01144 
01145 Type* IntegerType::mergeWith(Type* other) {
01146     if (*this == *other) return this;
01147     if (!other->isInteger()) return NULL;       
01148     IntegerType* oth = (IntegerType*)other;
01149     IntegerType* ret = (IntegerType*)this->clone();
01150     if (size == 0) ret->setSize(oth->getSize());
01151     if (signedness == 0) ret->setSigned(oth->getSignedness());
01152     return ret;
01153 }
01154 
01155 
01156 Type* SizeType::mergeWith(Type* other) {
01157     Type* ret = other->clone();
01158     ret->setSize(size);
01159     return ret;
01160 }
01161 
01162 Type* UpperType::mergeWith(Type* other) {
01163     
01164     return this;
01165 }
01166 
01167 Type* LowerType::mergeWith(Type* other) {
01168     
01169     return this;
01170 }
01171 
01172 
01173 bool CompoundType::isSuperStructOf(Type* other) {
01174     if (!other->isCompound()) return false;
01175     CompoundType* otherCmp = other->asCompound();
01176     unsigned n = otherCmp->types.size();
01177     if (n > types.size()) return false;
01178     for (unsigned i=0; i < n; i++)
01179         if (otherCmp->types[i] != types[i]) return false;
01180     return true;
01181 }
01182 
01183 
01184 bool CompoundType::isSubStructOf(Type* other) {
01185     if (!other->isCompound()) return false;
01186     CompoundType* otherCmp = other->asCompound();
01187     unsigned n = types.size();
01188     if (n > otherCmp->types.size()) return false;
01189     for (unsigned i=0; i < n; i++)
01190         if (otherCmp->types[i] != types[i]) return false;
01191     return true;
01192 }
01193 
01194 
01195 bool UnionType::findType(Type* ty) {
01196     std::list<UnionElement>::iterator it;
01197     for (it = li.begin(); it != li.end(); it++) {
01198         if (*it->type == *ty)
01199             return true;
01200     }
01201     return false;
01202 }
01203 
01204 void UpperType::setSize(int size) {
01205     
01206     assert(0);
01207 }
01208 
01209 void LowerType::setSize(int size) {
01210     
01211     assert(0);
01212 }
01213 
01214 Type* Type::newIntegerLikeType(int size, int signedness) {
01215     if (size == 1)
01216         return new BooleanType();
01217     if (size == 8 && signedness >= 0)
01218         return new CharType();
01219     return new IntegerType(size, signedness);
01220 }
01221 
01222 
01223 
01224 DataIntervalMap::iterator DataIntervalMap::find_it(ADDRESS addr) {
01225     iterator it = dimap.upper_bound(addr);  
01226     if (it == dimap.begin())
01227         return dimap.end();                 
01228     it--;                                   
01229     if (it->first <= addr && it->first+it->second.size > addr)
01230         
01231         return it;
01232     return dimap.end();
01233 }
01234 
01235 DataIntervalEntry* DataIntervalMap::find(ADDRESS addr) {
01236     iterator it = find_it(addr);
01237     if (it == dimap.end())
01238         return NULL;
01239     return &*it;
01240 }
01241 
01242 bool DataIntervalMap::isClear(ADDRESS addr, unsigned size) {
01243     iterator it = dimap.upper_bound(addr+size-1);   
01244     if (it == dimap.begin())
01245         return true;                        
01246     it--;                                   
01247     
01248     ADDRESS end;
01249     if (it->first + it->second.size < it->first)
01250         
01251         end = 0xFFFFFFFF;       
01252     else
01253         end = it->first + it->second.size;
01254     if (end <= addr)
01255         return true;
01256     if (it->second.type->isArray() && it->second.type->asArray()->isUnbounded()) {
01257         it->second.size = addr - it->first;
01258         LOG << "shrinking size of unbound array to " << it->second.size << " bytes\n";
01259         return true;
01260     }
01261     return false;
01262 }
01263 
01264 
01265 void DataIntervalMap::addItem(ADDRESS addr, char* name, Type* ty, bool forced ) {
01266     if (name == NULL)
01267         name = "<noname>";
01268     DataIntervalEntry* pdie = find(addr);
01269     if (pdie == NULL) {
01270         
01271         replaceComponents(addr, name, ty, forced);
01272         return;
01273     }
01274     
01275     if (pdie->first < addr) {
01276         
01277         if (pdie->first + pdie->second.size < addr+ty->getSize()/8) {
01278             LOG << "TYPE ERROR: attempt to insert item " << name << " at " << addr << " of type " <<
01279                 ty->getCtype() << " which weaves after " << pdie->second.name << " at " << pdie->first <<
01280                 " of type " << pdie->second.type->getCtype() << "\n";
01281             return;
01282         }
01283         enterComponent(pdie, addr, name, ty, forced);
01284     } else if (pdie->first == addr) {
01285         
01286         unsigned endOfCurrent = pdie->first + pdie->second.size;
01287         unsigned endOfNew = addr+ty->getSize()/8;
01288         if (endOfCurrent < endOfNew)
01289             replaceComponents(addr, name, ty, forced);
01290         else if (endOfCurrent == endOfNew)
01291             checkMatching(pdie, addr, name, ty, forced);        
01292         else
01293             enterComponent(pdie, addr, name, ty, forced);
01294     } else {
01295         
01296         if (pdie->first + pdie->second.size > addr+ty->getSize()/8) {
01297             LOG << "TYPE ERROR: attempt to insert item " << name << " at " << addr << " of type " <<
01298                 ty->getCtype() << " which weaves before " << pdie->second.name << " at " << pdie->first <<
01299                 " of type " << pdie->second.type->getCtype() << "\n";
01300             return;
01301         }
01302         replaceComponents(addr, name, ty, forced);
01303     }
01304 }
01305 
01306 
01307 void DataIntervalMap::enterComponent(DataIntervalEntry* pdie, ADDRESS addr, char* name, Type* ty, bool forced) {
01308     if (pdie->second.type->resolvesToCompound()) {
01309         unsigned bitOffset = (addr - pdie->first)*8;
01310         Type* memberType = pdie->second.type->asCompound()->getTypeAtOffset(bitOffset);
01311         if (memberType->isCompatibleWith(ty)) {
01312             bool ch;
01313             memberType = memberType->meetWith(ty, ch);
01314             pdie->second.type->asCompound()->setTypeAtOffset(bitOffset, memberType);
01315         } else
01316             LOG << "TYPE ERROR: At address " << addr << " type " << ty->getCtype() << " is not compatible with "
01317                 "existing structure member type " << memberType->getCtype() << "\n";
01318     }
01319     else if (pdie->second.type->resolvesToArray()) {
01320         Type* memberType = pdie->second.type->asArray()->getBaseType();
01321         if (memberType->isCompatibleWith(ty)) {
01322             bool ch;
01323             memberType = memberType->meetWith(ty, ch);
01324             pdie->second.type->asArray()->setBaseType(memberType);
01325         } else
01326             LOG << "TYPE ERROR: At address " << addr << " type " << ty->getCtype() << " is not compatible with "
01327                 "existing array member type " << memberType->getCtype() << "\n";
01328     } else
01329         LOG << "TYPE ERROR: Existing type at address " << pdie->first << " is not structure or array type\n";
01330 }
01331 
01332 
01333 
01334 void DataIntervalMap::replaceComponents(ADDRESS addr, char* name, Type* ty, bool forced) {
01335     iterator it;
01336     unsigned pastLast = addr + ty->getSize()/8;     
01337     
01338     if (ty->resolvesToCompound()) {
01339         iterator it1 = dimap.lower_bound(addr);         
01340                                                         
01341         iterator it2 = dimap.upper_bound(pastLast-1);   
01342         for (it = it1; it != it2; ++it) {
01343             unsigned bitOffset = (it->first - addr) * 8;
01344             Type* memberType = ty->asCompound()->getTypeAtOffset(bitOffset);
01345             if (memberType->isCompatibleWith(it->second.type, true)) {
01346                 bool ch;
01347                 memberType = it->second.type->meetWith(memberType, ch);
01348                 ty->asCompound()->setTypeAtOffset(bitOffset, memberType);
01349             } else {
01350                 LOG << "TYPE ERROR: At address " << addr << " struct type " << ty->getCtype() << " is not compatible "
01351                     "with existing type " << it->second.type->getCtype() << "\n";
01352                 return;
01353             }
01354         }
01355     } else if (ty->resolvesToArray()) {
01356         Type* memberType = ty->asArray()->getBaseType();
01357         iterator it1 = dimap.lower_bound(addr);
01358         iterator it2 = dimap.upper_bound(pastLast-1);
01359         for (it = it1; it != it2; ++it) {
01360             if (memberType->isCompatibleWith(it->second.type, true)) {
01361                 bool ch;
01362                 memberType = memberType->meetWith(it->second.type, ch);
01363                 ty->asArray()->setBaseType(memberType);
01364             } else {
01365                 LOG << "TYPE ERROR: At address " << addr << " array type " << ty->getCtype() << " is not compatible "
01366                     "with existing type " << it->second.type->getCtype() << "\n";
01367                 return;
01368             }
01369         }
01370     } else {
01371         
01372         if (!isClear(addr, (ty->getSize()+7)/8)) {
01373             LOG << "TYPE ERROR: at address " << addr << ", overlapping type " << ty->getCtype() << " does not resolve "
01374                 "to compound or array\n";
01375             return;
01376         }
01377     }
01378 
01379     
01380     iterator it1 = dimap.lower_bound(addr);
01381     iterator it2 = dimap.upper_bound(pastLast-1);
01382 
01383     
01384     if (ty->resolvesToCompound() || ty->resolvesToArray()) {
01385         Exp* rsp = Location::regOf(proc->getSignature()->getStackRegister());
01386         RefExp* rsp0 = new RefExp(rsp, proc->getCFG()->findTheImplicitAssign(rsp)); 
01387         for (it = it1; it != it2; ++it) {
01388             
01389             Exp* locl = Location::memOf(
01390                 new Binary(opPlus,
01391                     rsp0->clone(),
01392                     new Const(it->first)));
01393             locl->simplifyArith();                      
01394             Type* elemTy;
01395             int bitOffset = (it->first - addr) / 8;
01396             if (ty->resolvesToCompound())
01397                 elemTy = ty->asCompound()->getTypeAtOffset(bitOffset);
01398             else
01399                 elemTy = ty->asArray()->getBaseType();
01400             char* locName = proc->findLocal(locl, elemTy);
01401             if (locName && ty->resolvesToCompound()) {
01402                 CompoundType* c = ty->asCompound();
01403                 
01404                 char* memName = (char*)c->getNameAtOffset(bitOffset);
01405                 Exp* s = Location::memOf(
01406                     new Binary(opPlus,
01407                         rsp0->clone(),
01408                         new Const(addr)));
01409                 s->simplifyArith();
01410                 Exp* memberExp = new Binary(opMemberAccess,
01411                     s,
01412                     new Const(memName));
01413                 proc->mapSymbolTo(locl, memberExp);
01414             } else {
01415                 
01416             }
01417         }
01418     }
01419 
01420     for (it = it1; it != it2 && it != dimap.end();  )
01421         
01422         
01423         
01424         dimap.erase(it++);
01425 
01426     DataInterval* pdi = &dimap[addr];               
01427     pdi->size = ty->getBytes();
01428     pdi->name = name;
01429     pdi->type = ty;
01430 }
01431 
01432 void DataIntervalMap::checkMatching(DataIntervalEntry* pdie, ADDRESS addr, char* name, Type* ty, bool forced) {
01433     if (pdie->second.type->isCompatibleWith(ty)) {
01434         
01435         bool ch;
01436         pdie->second.type = pdie->second.type->meetWith(ty, ch);
01437         return;
01438     }
01439     LOG << "TYPE DIFFERENCE (could be OK): At address " << addr << " existing type " << pdie->second.type->getCtype() <<
01440          " but added type " << ty->getCtype() << "\n";
01441 }
01442 
01443 void DataIntervalMap::deleteItem(ADDRESS addr) {
01444     iterator it = dimap.find(addr);
01445     if (it == dimap.end())
01446         return;
01447     dimap.erase(it);
01448 }
01449 
01450 void DataIntervalMap::dump() {
01451     std::cerr << prints();
01452 }
01453 
01454 char* DataIntervalMap::prints() {
01455     iterator it;
01456     std::ostringstream ost;
01457     for (it = dimap.begin(); it != dimap.end(); ++it)
01458         ost << std::hex << "0x" << it->first << std::dec << " " << it->second.name << " " << it->second.type->getCtype()
01459             << "\n";
01460     strncpy(debug_buffer, ost.str().c_str(), DEBUG_BUFSIZE-1);
01461     debug_buffer[DEBUG_BUFSIZE-1] = '\0';
01462     return debug_buffer;
01463 }
01464 
01465 ComplexTypeCompList& Type::compForAddress(ADDRESS addr, DataIntervalMap& dim) {
01466     DataIntervalEntry* pdie = dim.find(addr);
01467     ComplexTypeCompList* res = new ComplexTypeCompList;
01468     if (pdie == NULL) return *res;
01469     ADDRESS startCurrent = pdie->first;
01470     Type* curType = pdie->second.type;
01471     while (startCurrent < addr) {
01472         unsigned bitOffset = (addr - startCurrent) * 8;
01473         if (curType->isCompound()) {
01474             CompoundType* compCurType = curType->asCompound();
01475             unsigned rem = compCurType->getOffsetRemainder(bitOffset);
01476             startCurrent = addr - (rem/8);
01477             ComplexTypeComp ctc;
01478             ctc.isArray = false;
01479             ctc.u.memberName = strdup(compCurType->getNameAtOffset(bitOffset));
01480             res->push_back(ctc);
01481             curType = compCurType->getTypeAtOffset(bitOffset);
01482         } else if (curType->isArray()) {
01483             curType = curType->asArray()->getBaseType();
01484             unsigned baseSize = curType->getSize();
01485             unsigned index = bitOffset / baseSize;
01486             startCurrent += index * baseSize/8;
01487             ComplexTypeComp ctc;
01488             ctc.isArray = true;
01489             ctc.u.index = index;
01490             res->push_back(ctc);
01491         } else {
01492             LOG << "TYPE ERROR: no struct or array at byte address " << addr << "\n";
01493             return *res;
01494         }
01495     }
01496     return *res;
01497 }
01498 
01499 void UnionType::addType(Type *n, const char *str) {
01500     if (n->isUnion()) {
01501         UnionType* utp = (UnionType*)n;
01502         
01503         li.insert(li.end(), utp->li.begin(), utp->li.end());
01504     } else {
01505         if (n->isPointer() && n->asPointer()->getPointsTo() == this) {      
01506             n = new PointerType(new VoidType);
01507             if (VERBOSE)
01508                 LOG << "Warning: attempt to union with pointer to self!\n";
01509         }
01510         UnionElement ue;
01511         ue.type = n;
01512         ue.name = str;
01513         li.push_back(ue);
01514     }
01515 }
01516 
01517 
01518 void CompoundType::updateGenericMember(int off, Type* ty, bool& ch) {
01519     assert(generic);
01520     Type* existingType = getTypeAtOffset(off);
01521     if (existingType) {
01522         existingType = existingType->meetWith(ty, ch);
01523     } else {
01524         std::ostringstream ost;
01525         ost << "member" << std::dec << nextGenericMemberNum++;
01526         setTypeAtOffset(off*8, ty);
01527         setNameAtOffset(off*8, ost.str().c_str());
01528     }
01529 }
01530 
01531 
01532 #if USING_MEMO
01533 class FuncTypeMemo : public Memo {
01534 public:
01535     FuncTypeMemo(int m) : Memo(m) { }
01536     Signature *signature;
01537 };
01538 
01539 Memo *FuncType::makeMemo(int mId)
01540 {
01541     FuncTypeMemo *m = new FuncTypeMemo(mId);
01542     m->signature = signature;
01543 
01544     signature->takeMemo(mId);
01545     return m;
01546 }
01547 
01548 void FuncType::readMemo(Memo *mm, bool dec)
01549 {
01550     FuncTypeMemo *m = dynamic_cast<FuncTypeMemo*>(mm);
01551     signature = m->signature;
01552 
01553     
01554 }
01555 
01556 class IntegerTypeMemo : public Memo {
01557 public:
01558     IntegerTypeMemo(int m) : Memo(m) { }
01559     int size;
01560     int signedness;
01561 };
01562 
01563 Memo *IntegerType::makeMemo(int mId)
01564 {
01565     IntegerTypeMemo *m = new IntegerTypeMemo(mId);
01566     m->size = size;
01567     m->signedness = signedness;
01568     return m;
01569 }
01570 
01571 void IntegerType::readMemo(Memo *mm, bool dec)
01572 {
01573     IntegerTypeMemo *m = dynamic_cast<IntegerTypeMemo*>(mm);
01574     size = m->size;
01575     signedness = m->signedness;
01576 }
01577 
01578 class FloatTypeMemo : public Memo {
01579 public:
01580     FloatTypeMemo(int m) : Memo(m) { }
01581     int size;
01582 };
01583 
01584 Memo *FloatType::makeMemo(int mId)
01585 {
01586     FloatTypeMemo *m = new FloatTypeMemo(mId);
01587     m->size = size;
01588     return m;
01589 }
01590 
01591 void FloatType::readMemo(Memo *mm, bool dec)
01592 {
01593     FloatTypeMemo *m = dynamic_cast<FloatTypeMemo*>(mm);
01594     size = m->size;
01595 }
01596 
01597 class PointerTypeMemo : public Memo {
01598 public:
01599     PointerTypeMemo(int m) : Memo(m) { }
01600     Type *points_to;
01601 };
01602 
01603 Memo *PointerType::makeMemo(int mId)
01604 {
01605     PointerTypeMemo *m = new PointerTypeMemo(mId);
01606     m->points_to = points_to;
01607 
01608     points_to->takeMemo(mId);
01609 
01610     return m;
01611 }
01612 
01613 void PointerType::readMemo(Memo *mm, bool dec)
01614 {
01615     PointerTypeMemo *m = dynamic_cast<PointerTypeMemo*>(mm);
01616     points_to = m->points_to;
01617 
01618     points_to->restoreMemo(m->mId, dec);
01619 }
01620 
01621 class ArrayTypeMemo : public Memo {
01622 public:
01623     ArrayTypeMemo(int m) : Memo(m) { }
01624     Type *base_type;
01625     unsigned length;
01626 };
01627 
01628 Memo *ArrayType::makeMemo(int mId)
01629 {
01630     ArrayTypeMemo *m = new ArrayTypeMemo(mId);
01631     m->base_type = base_type;
01632     m->length = length;
01633 
01634     base_type->takeMemo(mId);
01635 
01636     return m;
01637 }
01638 
01639 void ArrayType::readMemo(Memo *mm, bool dec)
01640 {
01641     ArrayTypeMemo *m = dynamic_cast<ArrayTypeMemo*>(mm);
01642     length = m->length;
01643     base_type = m->base_type;
01644 
01645     base_type->restoreMemo(m->mId, dec);
01646 }
01647 
01648 class NamedTypeMemo : public Memo {
01649 public:
01650     NamedTypeMemo(int m) : Memo(m) { }
01651     std::string name;
01652     int nextAlpha;
01653 };
01654 
01655 Memo *NamedType::makeMemo(int mId)
01656 {
01657     NamedTypeMemo *m = new NamedTypeMemo(mId);
01658     m->name = name;
01659     m->nextAlpha = nextAlpha;
01660     return m;
01661 }
01662 
01663 void NamedType::readMemo(Memo *mm, bool dec)
01664 {
01665     NamedTypeMemo *m = dynamic_cast<NamedTypeMemo*>(mm);
01666     name = m->name;
01667     nextAlpha = m->nextAlpha;
01668 }
01669 
01670 class CompoundTypeMemo : public Memo {
01671 public:
01672     CompoundTypeMemo(int m) : Memo(m) { }
01673     std::vector<Type*> types;
01674     std::vector<std::string> names;
01675 };
01676 
01677 Memo *CompoundType::makeMemo(int mId)
01678 {
01679     CompoundTypeMemo *m = new CompoundTypeMemo(mId);
01680     m->types = types;
01681     m->names = names;
01682 
01683     for (std::vector<Type*>::iterator it = types.begin(); it != types.end(); it++)
01684         (*it)->takeMemo(mId);
01685     return m;
01686 }
01687 
01688 void CompoundType::readMemo(Memo *mm, bool dec)
01689 {
01690     CompoundTypeMemo *m = dynamic_cast<CompoundTypeMemo*>(mm);
01691     types = m->types;
01692     names = m->names;
01693 
01694     for (std::vector<Type*>::iterator it = types.begin(); it != types.end(); it++)
01695         (*it)->restoreMemo(m->mId, dec);
01696 }
01697 
01698 class UnionTypeMemo : public Memo {
01699 public:
01700     UnionTypeMemo(int m) : Memo(m) { }
01701     std::list<UnionElement> li;
01702 };
01703 
01704 Memo *UnionType::makeMemo(int mId)
01705 {
01706     UnionTypeMemo *m = new UnionTypeMemo(mId);
01707     m->li = li;
01708 
01709     for (std::list<UnionElement>::iterator it = li.begin(); it != li.end(); it++)
01710         it->type->takeMemo(mId);        
01711     return m;
01712 }
01713 
01714 void UnionType::readMemo(Memo *mm, bool dec)
01715 {
01716     UnionTypeMemo *m = dynamic_cast<UnionTypeMemo*>(mm);
01717     li = m->li;
01718 
01719     for (std::list<UnionElement>::iterator it = li.begin(); it != li.end(); it++)
01720         it->type->restoreMemo(m->mId, dec);
01721 }
01722 
01723 
01724 
01725 #endif          // #if USING_MEMO