type.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2000-2001, The University of Queensland
00003  * Copyright (C) 2002-2006, Trent Waddington and Mike Van Emmerik
00004  *
00005  * See the file "LICENSE.TERMS" for information on usage and
00006  * redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
00007  *
00008  */
00009 
00010 /*==============================================================================
00011  * FILE:       type.h
00012  * OVERVIEW:   Definition of the Type class: low level type information
00013  *             Note that we may have a compeltely different system for
00014  *              recording high level types
00015  *============================================================================*/
00016 
00017 /*
00018  * $Revision: 1.64 $
00019  *
00020  * 20 Mar 01 - Mike: Added operator*= (compare, ignore sign, and consider all floats > 64 bits to be the same
00021  * 26 Apr 01 - Mike: Added class typeLessSI
00022  * 08 Apr 02 - Mike: Changes for boomerang
00023  * 25 Sep 04 - Mike: Added UnionType; beginnings of data-flow based type analysis
00024  * 26 Oct 04 - Mike: Added UpperType and LowerType; isCompatible()
00025  */
00026 
00027 #ifndef __TYPE_H__
00028 #define __TYPE_H__
00029 
00030 #include <string>
00031 #include <map>
00032 #include <functional>       // For binary_function
00033 #include <vector>
00034 #include <assert.h>
00035 #include <list>
00036 #include <fstream>
00037 #include "memo.h"
00038 #include "types.h"          // For STD_SIZE
00039 
00040 class Signature;
00041 class UserProc;
00042 class VoidType;
00043 class FuncType;
00044 class BooleanType;
00045 class CharType;
00046 class IntegerType;
00047 class FloatType;
00048 class NamedType;
00049 class PointerType;
00050 class ArrayType;
00051 class CompoundType;
00052 class UnionType;
00053 class SizeType;
00054 class UpperType;
00055 class LowerType;
00056 class Exp;
00057 class XMLProgParser;
00058 class DataIntervalMap;
00059 
00060 enum eType {eVoid, eFunc, eBoolean, eChar, eInteger, eFloat, ePointer, eArray, eNamed, eCompound, eUnion, eSize,
00061         eUpper, eLower};      // For operator< mostly
00062 
00063 // The following two are for Type::compForAddress()
00064 struct ComplexTypeComp {
00065         bool        isArray;
00066         union {
00067             char*   memberName;         // Member name if offset
00068             unsigned index;             // Constant index if array
00069         } u;
00070 };
00071 typedef std::list<ComplexTypeComp> ComplexTypeCompList;
00072 
00073 class Type {
00074 protected:
00075         eType       id;
00076 private:
00077 static  std::map<std::string, Type*> namedTypes;
00078 
00079 public:
00080                     // Constructors
00081                     Type(eType id);
00082 virtual             ~Type();
00083         eType       getId() const {return id;}
00084 
00085 static void         addNamedType(const char *name, Type *type);
00086 static Type         *getNamedType(const char *name);
00087 
00088                     // Return type for given temporary variable name
00089 static Type*        getTempType(const std::string &name);
00090 static Type*        parseType(const char *str); // parse a C type
00091 
00092 bool    isCString();
00093 
00094                     // runtime type information. Deprecated for most situations; use resolvesToTYPE()
00095 virtual bool        isVoid()        const { return false; }
00096 virtual bool        isFunc()        const { return false; }
00097 virtual bool        isBoolean()     const { return false; }
00098 virtual bool        isChar()        const { return false; }
00099 virtual bool        isInteger()     const { return false; }
00100 virtual bool        isFloat()       const { return false; }
00101 virtual bool        isPointer()     const { return false; }
00102 virtual bool        isArray()       const { return false; }
00103 virtual bool        isNamed()       const { return false; }
00104 virtual bool        isCompound()    const { return false; }
00105 virtual bool        isUnion()       const { return false; }
00106 virtual bool        isSize()        const { return false; }
00107 virtual bool        isUpper()       const { return false; }
00108 virtual bool        isLower()       const { return false; }
00109 
00110 // Return false if some info is missing, e.g. unknown sign, size or basic type
00111 virtual bool        isComplete() {return true;}
00112 
00113                     // These replace type casts
00114         VoidType    *asVoid();
00115         FuncType    *asFunc();
00116         BooleanType *asBoolean();
00117         CharType    *asChar();
00118         IntegerType *asInteger();
00119         FloatType   *asFloat();
00120         NamedType   *asNamed();
00121         PointerType *asPointer();
00122         ArrayType   *asArray();
00123         CompoundType *asCompound();
00124         UnionType   *asUnion();
00125         SizeType    *asSize();
00126         UpperType   *asUpper();
00127         LowerType   *asLower();
00128 
00129                     // These replace calls to isNamed() and resolvesTo()
00130         bool        resolvesToVoid();
00131         bool        resolvesToFunc();
00132         bool        resolvesToBoolean();
00133         bool        resolvesToChar();
00134         bool        resolvesToInteger();
00135         bool        resolvesToFloat();
00136         bool        resolvesToPointer();
00137         bool        resolvesToArray();
00138         bool        resolvesToCompound();
00139         bool        resolvesToUnion();
00140         bool        resolvesToSize();
00141         bool        resolvesToUpper();
00142         bool        resolvesToLower();
00143 
00144                     // cloning
00145 virtual Type*       clone() const = 0;
00146 
00147                     // Comparisons
00148 virtual bool        operator==(const Type& other) const = 0;    // Considers sign
00149 virtual bool        operator!=(const Type& other) const;        // Considers sign
00150 //virtual bool      operator-=(const Type& other) const = 0;    // Ignores sign
00151 virtual bool        operator< (const Type& other) const = 0;    // Considers sign
00152         bool        operator*=(const Type& other) const {       // Consider only
00153                         return id == other.id;}                 // broad type
00154 virtual Exp         *match(Type *pattern);
00155                     // Constraint-based TA: merge one type with another, e.g. size16 with integer-of-size-0 -> int16
00156 virtual Type*       mergeWith(Type* other) { assert(0); return 0; }
00157 
00158                     // Acccess functions
00159 virtual unsigned    getSize() const = 0;
00160         unsigned    getBytes() const {return (getSize() + 7) / 8; }
00161 virtual void        setSize(int sz) {assert(0);}
00162 
00163                     // Print and format functions
00164                     // Get the C type, e.g. "unsigned int". If not final, include comment for lack of sign information.
00165                     // When final, choose a signedness etc
00166 virtual const char  *getCtype(bool final = false) const = 0;
00167                     // Print in *i32* format
00168         void        starPrint(std::ostream& os);
00169         const char* prints();           // For debugging
00170         void        dump();             // For debugging
00171 static  void        dumpNames();        // For debugging
00172 
00173 virtual std::string getTempName() const; // Get a temporary name for the type
00174 
00175                     // Clear the named type map. This is necessary when testing; the
00176                     // type for the first parameter to 'main' is different for sparc and pentium
00177 static  void        clearNamedTypes() { namedTypes.clear(); }
00178 
00179         bool        isPointerToAlpha();
00180 
00181                     // For data-flow-based type analysis only: implement the meet operator. Set ch true if any change
00182                     // If bHighestPtr is true, then if this and other are non void* pointers, set the result to the
00183                     // *highest* possible type compatible with both (i.e. this JOIN other)
00184 virtual Type*       meetWith(Type* other, bool& ch, bool bHighestPtr = false) = 0;
00185                     // When all=false (default), return true if can use this and other interchangeably; in particular,
00186                     // if at most one of the types is compound and the first element is compatible with the other, then 
00187                     // the types are considered compatible. With all set to true, if one or both types is compound, all
00188                     // corresponding elements must be compatible
00189 virtual bool        isCompatibleWith(Type* other, bool all = false);
00190                     // isCompatible does most of the work; isCompatibleWith looks for complex types in other, and if so
00191                     // reverses the parameters (this and other) to prevent many tedious repetitions
00192 virtual bool        isCompatible(Type* other, bool all) = 0;
00193                     // Return true if this is a subset or equal to other
00194         bool        isSubTypeOrEqual(Type* other);
00195                     // Create a union of this Type and other. Set ch true if any change
00196         Type*       createUnion(Type* other, bool& ch, bool bHighestPtr = false);
00197 static  Type*       newIntegerLikeType(int size, int signedness);   // Return a new Bool/Char/Int
00198                     // From a complex type like an array of structs with a float, return a list of components so you
00199                     // can construct e.g. myarray1[8].mystruct2.myfloat7
00200         ComplexTypeCompList& compForAddress(ADDRESS addr, DataIntervalMap& dim);
00201                     // Dereference this type. For most cases, return null unless you are a pointer type. But for a
00202                     // union of pointers, return a new union with the dereference of all members. In dfa.cpp
00203         Type*       dereference();
00204 
00205 protected:
00206     friend class XMLProgParser;
00207 };  // class Type
00208 
00209 class VoidType : public Type {
00210 public:
00211                     VoidType();
00212 virtual             ~VoidType();
00213 virtual bool        isVoid() const { return true; }
00214 
00215 virtual Type        *clone() const;
00216 
00217 virtual bool        operator==(const Type& other) const;
00218 //virtual bool      operator-=(const Type& other) const;
00219 virtual bool        operator< (const Type& other) const;
00220 virtual Exp         *match(Type *pattern);
00221 
00222 virtual unsigned    getSize() const;
00223 
00224 virtual const char  *getCtype(bool final = false) const;
00225 
00226 virtual Type*       meetWith(Type* other, bool& ch, bool bHighestPtr);
00227 virtual bool        isCompatible(Type* other, bool all);
00228 
00229 protected:
00230     friend class XMLProgParser;
00231 };
00232 
00233 class FuncType : public Type {
00234 private:
00235     Signature       *signature;
00236 public:
00237                     FuncType(Signature *sig = NULL);
00238 virtual             ~FuncType();
00239 virtual bool        isFunc() const { return true; }
00240 
00241 virtual Type        *clone() const;
00242 
00243         Signature   *getSignature() { return signature; }
00244         void        setSignature(Signature* sig) {signature = sig;}
00245 
00246 virtual bool        operator==(const Type& other) const;
00247 //virtual bool      operator-=(const Type& other) const;
00248 virtual bool        operator< (const Type& other) const;
00249 virtual Exp         *match(Type *pattern);
00250 
00251 virtual unsigned    getSize() const;
00252 
00253 virtual const char  *getCtype(bool final = false) const;
00254 
00255                     // Split the C type into return and parameter parts
00256         void        getReturnAndParam(const char*& ret, const char*& param);
00257 
00258 virtual Type*       meetWith(Type* other, bool& ch, bool bHighestPtr);
00259 virtual bool        isCompatible(Type* other, bool all);
00260 
00261 protected:
00262     friend class XMLProgParser;
00263 };
00264 
00265 class IntegerType : public Type {
00266 private:
00267         unsigned    size;           // Size in bits, e.g. 16
00268         int         signedness;     // pos=signed, neg=unsigned, 0=unknown or evenly matched
00269 
00270 public:
00271                     IntegerType(int sz = STD_SIZE, int sign = 0);
00272 virtual             ~IntegerType();
00273 virtual bool        isInteger() const { return true; }
00274 virtual bool        isComplete() {return signedness != 0 && size != 0;}
00275 
00276 virtual Type*       clone() const;
00277 
00278 virtual bool        operator==(const Type& other) const;
00279 //virtual bool      operator-=(const Type& other) const;
00280 virtual bool        operator< (const Type& other) const;
00281 virtual Type*       mergeWith(Type* other);
00282 virtual Exp         *match(Type *pattern);
00283 
00284 virtual unsigned    getSize() const;            // Get size in bits
00285 virtual void        setSize(int sz) {size = sz;}
00286                     // Is it signed? 0=unknown, pos=yes, neg = no
00287         bool        isSigned() { return signedness >= 0; }      // True if not unsigned
00288         bool        isUnsigned() {return signedness <= 0; }     // True if not definately signed
00289                     // A hint for signedness
00290         void        bumpSigned(int sg) { signedness += sg; }
00291                     // Set absolute signedness
00292         void        setSigned(int sg) {signedness = sg; }
00293                     // Get the signedness
00294         int         getSignedness() {return signedness;}
00295 
00296 // Get the C type as a string. If full, output comments re the lack of sign information (in IntegerTypes).
00297 virtual const char  *getCtype(bool final = false) const;
00298 
00299 virtual std::string getTempName() const;
00300 
00301 virtual Type*       meetWith(Type* other, bool& ch, bool bHighestPtr);
00302 virtual bool        isCompatible(Type* other, bool all);
00303 
00304 protected:
00305     friend class XMLProgParser;
00306 };  // class IntegerType
00307 
00308 class FloatType : public Type {
00309 private:
00310         unsigned    size;               // Size in bits, e.g. 64
00311 
00312 public:
00313                     FloatType(int sz = 64);
00314 virtual             ~FloatType();
00315 virtual bool        isFloat() const { return true; }
00316 
00317 virtual Type*       clone() const;
00318 
00319 virtual bool        operator==(const Type& other) const;
00320 //virtual bool      operator-=(const Type& other) const;
00321 virtual bool        operator< (const Type& other) const;
00322 virtual Exp         *match(Type *pattern);
00323 
00324 virtual unsigned    getSize() const;
00325 virtual void        setSize(int sz) {size = sz;}
00326 
00327 virtual const char  *getCtype(bool final = false) const;
00328 
00329 virtual std::string getTempName() const;
00330 
00331 virtual Type*       meetWith(Type* other, bool& ch, bool bHighestPtr);
00332 virtual bool        isCompatible(Type* other, bool all);
00333 
00334 protected:
00335     friend class XMLProgParser;
00336 };  // class FloatType
00337 
00338 class BooleanType : public Type {
00339 public:
00340                     BooleanType();
00341 virtual             ~BooleanType();
00342 virtual bool        isBoolean() const { return true; }
00343 
00344 virtual Type*       clone() const;
00345 
00346 virtual bool        operator==(const Type& other) const;
00347 //virtual bool      operator-=(const Type& other) const;
00348 virtual bool        operator< (const Type& other) const;
00349 virtual Exp         *match(Type *pattern);
00350 
00351 virtual unsigned    getSize() const;
00352 
00353 virtual const char  *getCtype(bool final = false) const;
00354 
00355 virtual Type*       meetWith(Type* other, bool& ch, bool bHighestPtr);
00356 virtual bool        isCompatible(Type* other, bool all);
00357 
00358 protected:
00359     friend class XMLProgParser;
00360 };
00361 
00362 class CharType : public Type {
00363 public:
00364                     CharType();
00365 virtual             ~CharType();
00366 virtual bool        isChar() const { return true; }
00367 
00368 virtual Type*       clone() const;
00369 
00370 virtual bool        operator==(const Type& other) const;
00371 //virtual bool      operator-=(const Type& other) const;
00372 virtual bool        operator< (const Type& other) const;
00373 virtual Exp         *match(Type *pattern);
00374 
00375 virtual unsigned    getSize() const;
00376 
00377 virtual const char  *getCtype(bool final = false) const;
00378 
00379 virtual Type*       meetWith(Type* other, bool& ch, bool bHighestPtr);
00380 virtual bool        isCompatible(Type* other, bool all);
00381 
00382 protected:
00383     friend class XMLProgParser;
00384 };
00385 
00386 class PointerType : public Type {
00387 private:
00388         Type    *points_to;
00389 
00390 public:
00391                     PointerType(Type *p);
00392 virtual             ~PointerType();
00393 virtual bool        isPointer() const { return true; }
00394         void        setPointsTo(Type *p);
00395         Type        *getPointsTo() { return points_to; }
00396 static  PointerType *newPtrAlpha();
00397         bool        pointsToAlpha();
00398         int         pointerDepth();     // Return 2 for **x
00399         Type*       getFinalPointsTo(); // Return x for **x
00400 
00401 virtual Type*       clone() const;
00402 
00403 virtual bool        operator==(const Type& other) const;
00404 //virtual bool      operator-=(const Type& other) const;
00405 virtual bool        operator< (const Type& other) const;
00406 virtual Exp         *match(Type *pattern);
00407 
00408 virtual unsigned    getSize() const;
00409 virtual void        setSize(int sz) {assert(sz == STD_SIZE);}
00410 
00411 virtual const char  *getCtype(bool final = false) const;
00412 
00413 virtual Type*       meetWith(Type* other, bool& ch, bool bHighestPtr);
00414 virtual bool        isCompatible(Type* other, bool all);
00415 
00416 protected:
00417     friend class XMLProgParser;
00418 };  // class PointerType
00419 
00420 class ArrayType : public Type {
00421 private:
00422         Type        *base_type;
00423         unsigned    length;
00424 
00425 public:
00426                     ArrayType(Type *p, unsigned length);
00427                     ArrayType(Type *p);
00428 virtual             ~ArrayType();
00429 virtual bool        isArray() const { return true; }
00430         Type        *getBaseType() { return base_type; }
00431         void        setBaseType(Type *b);
00432         void        fixBaseType(Type *b);
00433         unsigned    getLength() { return length; }
00434         void        setLength(unsigned n) { length = n; }
00435         bool        isUnbounded() const;
00436 
00437 virtual Type*       clone() const;
00438 
00439 virtual bool        operator==(const Type& other) const;
00440 //virtual bool      operator-=(const Type& other) const;
00441 virtual bool        operator< (const Type& other) const;
00442 virtual Exp         *match(Type *pattern);
00443 
00444 virtual unsigned    getSize() const;
00445 
00446 virtual const char  *getCtype(bool final = false) const;
00447 
00448 virtual Type*       meetWith(Type* other, bool& ch, bool bHighestPtr);
00449 virtual bool        isCompatibleWith(Type* other, bool all = false) {return isCompatible(other, all);}
00450 virtual bool        isCompatible(Type* other, bool all);
00451 
00452 protected:
00453     friend class XMLProgParser;
00454                     ArrayType() : Type(eArray), base_type(NULL), length(0) { }
00455 };  // class ArrayType
00456 
00457 class NamedType : public Type {
00458 private:
00459         std::string name;
00460 static  int         nextAlpha;
00461 
00462 public:
00463                     NamedType(const char *name);
00464 virtual             ~NamedType();
00465 virtual bool        isNamed() const { return true; }
00466         const char  *getName() { return name.c_str(); }
00467         Type        *resolvesTo() const;
00468                     // Get a new type variable, e.g. alpha0, alpha55
00469 static  NamedType   *getAlpha();
00470 
00471 virtual Type*       clone() const;
00472 
00473 virtual bool        operator==(const Type& other) const;
00474 //virtual bool      operator-=(const Type& other) const;
00475 virtual bool        operator< (const Type& other) const;
00476 virtual Exp         *match(Type *pattern);
00477 
00478 virtual unsigned    getSize() const;
00479 
00480 virtual const char  *getCtype(bool final = false) const;
00481 
00482 virtual Type*       meetWith(Type* other, bool& ch, bool bHighestPtr);
00483 virtual bool        isCompatible(Type* other, bool all);
00484 
00485 protected:
00486     friend class XMLProgParser;
00487 };      // class NamedType
00488 
00489 // The compound type represents structures, not unions
00490 class CompoundType : public Type {
00491 private:
00492         std::vector<Type*> types;
00493         std::vector<std::string> names;
00494         int         nextGenericMemberNum;
00495         bool        generic;
00496 public:
00497                     CompoundType(bool generic = false);
00498 virtual             ~CompoundType();
00499 virtual bool        isCompound() const { return true; }
00500 
00501         void        addType(Type *n, const char *str) {
00502                         // check if it is a user defined type (typedef)
00503                         Type *t=getNamedType(n->getCtype());
00504                         if ( t ) n = t;
00505                         types.push_back(n); 
00506                         names.push_back(str);
00507                     }
00508         unsigned    getNumTypes() { return types.size(); }
00509         Type        *getType(unsigned n) { assert(n < getNumTypes()); return types[n]; }
00510         Type        *getType(const char *nam);
00511         const char  *getName(unsigned n) { assert(n < getNumTypes()); return names[n].c_str(); }
00512         void        setTypeAtOffset(unsigned n, Type* ty);
00513         Type        *getTypeAtOffset(unsigned n);
00514         void        setNameAtOffset(unsigned n, const char *nam);
00515         const char  *getNameAtOffset(unsigned n);
00516         bool        isGeneric() {return generic;}
00517         void        updateGenericMember(int off, Type* ty, bool& ch);   // Add a new generic member if necessary
00518         unsigned    getOffsetTo(unsigned n);
00519         unsigned    getOffsetTo(const char *member);
00520         unsigned    getOffsetRemainder(unsigned n);
00521 
00522 virtual Type*       clone() const;
00523 
00524 virtual bool        operator==(const Type& other) const;
00525 //virtual bool      operator-=(const Type& other) const;
00526 virtual bool        operator< (const Type& other) const;
00527 virtual Exp         *match(Type *pattern);
00528 
00529 virtual unsigned    getSize() const;
00530 
00531 virtual const char *getCtype(bool final = false) const;
00532 
00533         bool        isSuperStructOf(Type* other);       // True if this is is a superstructure of other
00534         bool        isSubStructOf(Type* other);         // True if this is is a substructure of other
00535 
00536 virtual Type*       meetWith(Type* other, bool& ch, bool bHighestPtr);
00537 virtual bool        isCompatibleWith(Type* other, bool all = false) {return isCompatible(other, all);}
00538 virtual bool        isCompatible(Type* other, bool all);
00539 
00540 protected:
00541     friend class XMLProgParser;
00542 };  // class CompoundType
00543 
00544 // The union type represents the union of any number of any other types
00545 struct UnionElement {
00546         Type*       type;
00547         std::string name;
00548 };
00549 class UnionType : public Type {
00550 private:
00551         // Note: list, not vector, as it is occasionally desirable to insert elements without affecting iterators
00552         // (e.g. meetWith(another Union))
00553         std::list<UnionElement> li;
00554 
00555 public:
00556                     UnionType();
00557 virtual             ~UnionType();
00558 virtual bool        isUnion() const { return true; }
00559 
00560         void        addType(Type *n, const char *str);
00561         int         getNumTypes() const { return li.size(); }
00562         bool        findType(Type* ty);             // Return true if ty is already in the union
00563         //Type      *getType(int n) { assert(n < getNumTypes()); return types[n]; }
00564         //Type      *getType(const char *nam);
00565         //const     char *getName(int n) { assert(n < getNumTypes()); return names[n].c_str(); }
00566 
00567 virtual Type* clone() const;
00568 
00569 virtual bool        operator==(const Type& other) const;
00570 //virtual bool      operator-=(const Type& other) const;
00571 virtual bool        operator< (const Type& other) const;
00572 virtual Exp         *match(Type *pattern);
00573 
00574 virtual unsigned    getSize() const;
00575 
00576 virtual const char *getCtype(bool final = false) const;
00577 
00578 virtual Type*       meetWith(Type* other, bool& ch, bool bHighestPtr);
00579 virtual bool        isCompatibleWith(Type* other, bool all) {return isCompatible(other, all);}
00580 virtual bool        isCompatible(Type* other, bool all);
00581                     // if this is a union of pointer types, get the union of things they point to. In dfa.cpp
00582         Type*       dereferenceUnion();
00583 
00584 protected:
00585     friend class XMLProgParser;
00586 };  // class UnionType
00587 
00588 // This class is for before type analysis. Typically, you have no info at all, or only know the size (e.g.
00589 // width of a register or memory transfer)
00590 class SizeType : public Type {
00591 private:
00592     unsigned        size;               // Size in bits, e.g. 16
00593 public:
00594                     SizeType() : Type(eSize) {}
00595                     SizeType(unsigned sz) : Type(eSize), size(sz) {}
00596 virtual             ~SizeType() {}
00597 virtual Type*       clone() const;
00598 virtual bool        operator==(const Type& other) const;
00599 virtual bool        operator< (const Type& other) const;
00600 //virtual Exp         *match(Type *pattern);
00601 virtual Type*       mergeWith(Type* other);
00602 
00603 virtual unsigned    getSize() const;
00604 virtual void        setSize(unsigned sz) {size = sz;}
00605 virtual bool        isSize() const { return true; }
00606 virtual bool        isComplete() {return false;}    // Basic type is unknown
00607 virtual const char* getCtype(bool final = false) const;
00608 virtual Type*       meetWith(Type* other, bool& ch, bool bHighestPtr);
00609 virtual bool        isCompatible(Type* other, bool all);
00610 
00611     friend class XMLProgParser;
00612 };  // class SizeType
00613 
00614 // This class represents the upper half of its base type
00615 // Mainly needed to represent the upper and lower half for type double
00616 class UpperType : public Type {
00617         Type*       base_type;
00618 
00619 public:
00620                     UpperType(Type* base) : Type(eUpper), base_type(base) { }
00621 virtual             ~UpperType() { }
00622 virtual Type*       clone() const;
00623 virtual bool        operator==(const Type& other) const;
00624 virtual bool        operator< (const Type& other) const;
00625 //virtual Exp       *match(Type *pattern);
00626 virtual Type*       mergeWith(Type* other);
00627         Type        *getBaseType() { return base_type; }
00628         void        setBaseType(Type *b) { base_type = b; }
00629 
00630 virtual unsigned    getSize() const {return base_type->getSize()/2;}
00631 virtual void        setSize(int sz);        // Does this make sense?
00632 virtual bool        isUpper() const { return true; }
00633 virtual bool        isComplete() {return base_type->isComplete();}
00634 virtual const char* getCtype(bool final = false) const;
00635 virtual Type*       meetWith(Type* other, bool& ch, bool bHighestPtr);
00636 virtual bool        isCompatible(Type* other, bool all);
00637 
00638 };  // class UpperType
00639 
00640 // As above, but stores the lower half
00641 class LowerType : public Type {
00642         Type*       base_type;
00643 
00644 public:
00645                     LowerType(Type* base) : Type(eUpper), base_type(base) { }
00646 virtual             ~LowerType() { }
00647 virtual Type*       clone() const;
00648 virtual bool        operator==(const Type& other) const;
00649 virtual bool        operator< (const Type& other) const;
00650 //virtual Exp       *match(Type *pattern);
00651 virtual Type*       mergeWith(Type* other);
00652         Type        *getBaseType() { return base_type; }
00653         void        setBaseType(Type *b) { base_type = b; }
00654 
00655 virtual unsigned    getSize() const {return base_type->getSize()/2;}
00656 virtual void        setSize(int sz);        // Does this make sense?
00657 virtual bool        isLower() const { return true; }
00658 virtual bool        isComplete() {return base_type->isComplete();}
00659 virtual const char* getCtype(bool final = false) const;
00660 virtual Type*       meetWith(Type* other, bool& ch, bool bHighestPtr);
00661 virtual bool        isCompatible(Type* other, bool all);
00662 
00663 };  // class LowerType
00664 
00665 
00666 /**
00667  * Class DataInterval. This class is used to represent local variables in procedures, and the global variables for
00668  * the program. The concept is that the data space (the current procedure's stack or the global data space) has to
00669  * be partitioned into separate variables of various sizes and types. If a new variable is inserted that would cause
00670  * an overlap, the types have to be reconciled such that they no longer conflict (generally, the smaller type becomes a
00671  * member of the larger type, which has to be a structure or an array).
00672  * Each procedure and the Prog object have a map from ADDRESS (stack offset from sp{0} for locals, or native address for
00673  * globals), to an object of this class. A multimap is not needed, as the type of the entry specifies the overlapping.
00674  */
00675 
00676 struct DataInterval {
00677         unsigned    size;               // The size of this type in bytes
00678         std::string name;               // The name of the variable
00679         Type*       type;               // The type of the variable
00680 };
00681 
00682 typedef std::pair<const ADDRESS, DataInterval> DataIntervalEntry;       // For result of find() below
00683 
00684 class DataIntervalMap {
00685         std::map<ADDRESS, DataInterval> dimap;
00686         UserProc*   proc;                           // If used for locals, has ptr to UserProc, else NULL
00687 public:
00688                     DataIntervalMap() {}
00689 typedef std::map<ADDRESS, DataInterval>::iterator iterator;
00690         void        setProc(UserProc* p) {proc = p;}// Initialise the proc pointer
00691         DataIntervalEntry* find(ADDRESS addr);      // Find the DataInterval at address addr, or NULL if none
00692         iterator    find_it(ADDRESS addr);          // Return an iterator to the entry for it, or end() if none
00693         bool        isClear(ADDRESS addr, unsigned size);       // True if from addr for size bytes is clear
00694         // Add a new data item
00695         void        addItem(ADDRESS addr, char* name, Type* ty, bool forced = false);
00696         void        deleteItem(ADDRESS addr);       // Mainly for testing?
00697         void        expandItem(ADDRESS addr, unsigned size);
00698         char*       prints();                       // For test and debug
00699         void        dump();                         // For debug
00700 
00701 private:
00702         void        enterComponent(DataIntervalEntry* pdie, ADDRESS addr, char* name, Type* ty, bool forced);
00703         void        replaceComponents(ADDRESS addr, char* name, Type* ty, bool forced);
00704         void        checkMatching(DataIntervalEntry* pdie, ADDRESS addr, char* name, Type* ty, bool forced);
00705 };
00706 
00707 // Not part of the Type class, but logically belongs with it:
00708 std::ostream& operator<<(std::ostream& os, Type* t);  // Print the Type pointed to by t
00709 
00710 
00711 #endif  // __TYPE_H__

Generated on Tue Sep 19 21:18:35 2006 for Boomerang by  doxygen 1.4.6