Type.C

Go to the documentation of this file.
00001 /*
00002  * See the dyninst/COPYRIGHT file for copyright information.
00003  * 
00004  * We provide the Paradyn Tools (below described as "Paradyn")
00005  * on an AS IS basis, and do not warrant its validity or performance.
00006  * We reserve the right to update, modify, or discontinue this
00007  * software at any time.  We shall have no obligation to supply such
00008  * updates or modifications or any other form of support to you.
00009  * 
00010  * By your use of Paradyn, you understand and agree that we (or any
00011  * other person or entity with proprietary rights in Paradyn) are
00012  * under no obligation to provide either maintenance services,
00013  * update services, notices of latent defects, or correction of
00014  * defects for Paradyn.
00015  * 
00016  * This library is free software; you can redistribute it and/or
00017  * modify it under the terms of the GNU Lesser General Public
00018  * License as published by the Free Software Foundation; either
00019  * version 2.1 of the License, or (at your option) any later version.
00020  * 
00021  * This library is distributed in the hope that it will be useful,
00022  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00024  * Lesser General Public License for more details.
00025  * 
00026  * You should have received a copy of the GNU Lesser General Public
00027  * License along with this library; if not, write to the Free Software
00028  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00029  */
00030 
00031 #include <string.h>
00032                  
00033 #include <stdio.h>
00034 
00035 #include "symutil.h"
00036 #include "Type.h"
00037 #include "Symtab.h"
00038 #include "Module.h"
00039 #include "Collections.h"
00040 #include "Function.h"
00041 #include "common/h/serialize.h"
00042 
00043 #include "Type-mem.h"
00044 #include <iostream>
00045 
00046 using namespace Dyninst;
00047 using namespace Dyninst::SymtabAPI;
00048 using namespace std;
00049 
00050 //#include "collections.h"
00051 //#include "debug.h" TODO: We want such behaviour. LATER!
00052 
00053 #if defined(_MSC_VER)
00054 #define snprintf _snprintf
00055 #endif
00056 
00057 
00058 static int findIntrensicType(std::string &name);
00059 
00060 // This is the ID that is decremented for each type a user defines. It is
00061 // Global so that every type that the user defines has a unique ID.
00062 typeId_t Type::USER_TYPE_ID = -10000;
00063 
00064 namespace Dyninst {
00065   namespace SymtabAPI {
00066     std::map<void *, size_t> type_memory;
00067   }
00068 }
00069 
00070 /* These are the wrappers for constructing a type.  Since we can create
00071    types six ways to Sunday, let's do them all in one centralized place. */
00072 
00073 
00074 Type *Type::createFake(std::string name) 
00075 {
00076    // Creating a fake type without a name is just silly
00077    assert(name != std::string(""));
00078 
00079    Type *t = new Type(name);
00080    t->type_ = dataNullType;
00081 
00082    return t;
00083 }
00084 
00085 #if !defined MAX
00086 #define MAX(x, y) ((x) > (y) ? (x) : (y))
00087 #endif
00088 
00089 Type *Type::createPlaceholder(typeId_t ID, std::string name)
00090 {
00091   static size_t max_size = 0;
00092   if (!max_size) {
00093     max_size = sizeof(Type);
00094     max_size = MAX(sizeof(fieldListType), max_size);
00095     max_size = MAX(sizeof(rangedType), max_size);
00096     max_size = MAX(sizeof(derivedType), max_size);
00097     max_size = MAX(sizeof(typeEnum), max_size);
00098     max_size = MAX(sizeof(typeFunction), max_size);
00099     max_size = MAX(sizeof(typeScalar), max_size);
00100     max_size = MAX(sizeof(typeCommon), max_size);
00101     max_size = MAX(sizeof(typeStruct), max_size);
00102     max_size = MAX(sizeof(typeUnion), max_size);
00103     max_size = MAX(sizeof(typePointer), max_size);
00104     max_size = MAX(sizeof(typeTypedef), max_size);
00105     max_size = MAX(sizeof(typeRef), max_size);
00106     max_size = MAX(sizeof(typeSubrange), max_size);
00107     max_size = MAX(sizeof(typeArray), max_size);
00108     max_size += 32; //Some safey padding
00109   }
00110 
00111   void *mem = malloc(max_size);
00112   assert(mem);
00113   type_memory[mem] = max_size;
00114   
00115   Type *placeholder_type = new(mem) Type(name, ID, dataUnknownType);
00116   return placeholder_type;
00117 }
00118 
00119 /*
00120  * Type::Type
00121  *
00122  * EMPTY Constructor for type.  
00123  * 
00124  */
00125 Type::Type(std::string name, typeId_t ID, dataClass dataTyp) :
00126    ID_(ID), 
00127    name_(name), 
00128    size_(sizeof(int)), 
00129    type_(dataTyp), 
00130    updatingSize(false), 
00131    refCount(1)
00132 {
00133     if (!name.length()) 
00134         name = std::string("unnamed_") + std::string(dataClass2Str(type_));
00135 }
00136 
00137 Type::Type(std::string name, dataClass dataTyp) :
00138    ID_(USER_TYPE_ID--), 
00139    name_(name), 
00140    size_(sizeof(/*long*/ int)), 
00141    type_(dataTyp), 
00142    updatingSize(false), 
00143    refCount(1)
00144 {
00145     if (!name.length()) 
00146         name = std::string("unnamed_") + std::string(dataClass2Str(type_));
00147 }
00148 
00149 /* type destructor
00150  * Basic destructor for proper memory management.
00151  */
00152 Type::~Type()
00153 {
00154 }
00155 
00156 const char *Dyninst::SymtabAPI::dataClass2Str(dataClass dc)
00157 {
00158    switch(dc) {
00159       CASE_RETURN_STR(dataEnum);
00160       CASE_RETURN_STR(dataPointer);
00161       CASE_RETURN_STR(dataFunction);
00162       CASE_RETURN_STR(dataSubrange);
00163       CASE_RETURN_STR(dataArray);
00164       CASE_RETURN_STR(dataStructure);
00165       CASE_RETURN_STR(dataUnion);
00166       CASE_RETURN_STR(dataCommon);
00167       CASE_RETURN_STR(dataScalar);
00168       CASE_RETURN_STR(dataTypedef);
00169       CASE_RETURN_STR(dataReference);
00170       CASE_RETURN_STR(dataUnknownType);
00171       CASE_RETURN_STR(dataNullType);
00172       CASE_RETURN_STR(dataTypeClass);
00173    };
00174    return "bad_data_class";
00175 }
00176 
00177 namespace Dyninst {
00178 namespace SymtabAPI {
00179 
00180 const char *visibility2Str(visibility_t v) 
00181 {
00182    switch(v) {
00183       CASE_RETURN_STR(visPrivate);
00184       CASE_RETURN_STR(visProtected);
00185       CASE_RETURN_STR(visPublic);
00186       CASE_RETURN_STR(visUnknown);
00187    };
00188    return "bad_visibility";
00189 }
00190 }
00191 }
00192 
00193 bool Type::operator==(const Type &otype) const 
00194 {
00195     return (ID_ == otype.ID_ && name_ == otype.name_ && size_== otype.size_ && type_ == otype.type_);
00196 }
00197 
00198 unsigned int Type::getSize()
00199 {
00200     if (!size_) 
00201         const_cast<Type *>(this)->updateSize(); 
00202     return size_;
00203 }
00204 
00205 bool Type::setSize(unsigned int size)
00206 {
00207     size_ = size;
00208     return true;
00209 }
00210 
00211 void Type::incrRefCount() 
00212 {
00213     ++refCount;
00214 }
00215 
00216 void Type::decrRefCount() 
00217 {
00218     //assert(refCount > 0);
00219     if (refCount > 0)
00220         refCount--;
00221     //if (0 == refCount)
00222 //      fprintf(stderr, "%s[%d]:  REMOVED DELETE\n", FILE__, __LINE__);
00223 #if 0
00224     if (!--refCount)
00225         delete this;
00226 #endif
00227 }
00228 
00229 std::string &Type::getName()
00230 {
00231     return name_;
00232 }
00233 
00234 bool Type::setName(std::string name)
00235 {
00236     if (!name.length()) return false;
00237     name_ = std::string(name);
00238     return true;
00239 }
00240 
00241 typeId_t Type::getID() const
00242 {
00243     return ID_;
00244 }
00245 
00246 dataClass Type::getDataClass() const
00247 {
00248     return type_;
00249 }
00250 
00251 void Type::fixupUnknowns(Module *){
00252 }
00253 
00254 typeEnum *Type::getEnumType(){
00255     return dynamic_cast<typeEnum *>(this);
00256 }
00257 
00258 typePointer *Type::getPointerType(){
00259     return dynamic_cast<typePointer *>(this);
00260 }
00261  
00262 typeFunction *Type::getFunctionType(){
00263     return dynamic_cast<typeFunction *>(this);
00264 }
00265  
00266 typeSubrange *Type::getSubrangeType(){
00267     return dynamic_cast<typeSubrange *>(this);
00268 }
00269        
00270 typeArray *Type::getArrayType(){
00271     return dynamic_cast<typeArray *>(this);
00272 }
00273 
00274 typeStruct *Type::getStructType(){
00275     return dynamic_cast<typeStruct *>(this);
00276 }
00277 
00278 typeUnion *Type::getUnionType(){
00279     return dynamic_cast<typeUnion *>(this);
00280 }
00281 
00282 typeScalar *Type::getScalarType(){
00283     return dynamic_cast<typeScalar *>(this);
00284 }
00285 
00286 typeCommon *Type::getCommonType(){
00287     return dynamic_cast<typeCommon *>(this);
00288 }
00289 
00290 typeTypedef *Type::getTypedefType(){
00291     return dynamic_cast<typeTypedef *>(this);
00292 }
00293     
00294 typeRef *Type::getRefType(){
00295     return dynamic_cast<typeRef *>(this);
00296 }
00297 
00298 std::string Type::specificType()
00299 {
00300     if (getEnumType()) return std::string("typeEnum");
00301     if (getPointerType()) return std::string("typePointer");
00302     if (getFunctionType()) return std::string("typeFunction");
00303     if (getSubrangeType()) return std::string("typeSubrange");
00304     if (getArrayType()) return std::string("typeArray");
00305     if (getStructType()) return std::string("typeStruct");
00306     if (getUnionType()) return std::string("typeUnion");
00307     if (getScalarType()) return std::string("typeScalar");
00308     if (getCommonType()) return std::string("typeCommon");
00309     if (getTypedefType()) return std::string("typeTypedef");
00310     if (getRefType()) return std::string("typeRef");
00311     return std::string("badType");
00312 }
00313 bool Type::isCompatible(Type * /*oType*/)
00314 {
00315    return true;
00316 }
00317 
00318 /*
00319  * ENUM
00320  */
00321 typeEnum::typeEnum(int ID, std::string name)
00322     : Type(name, ID, dataEnum)
00323 {
00324     size_ = sizeof(int);
00325 }
00326 
00327 typeEnum::typeEnum(std::string name)
00328    : Type(name, USER_TYPE_ID--, dataEnum)
00329 {
00330    size_ = sizeof(int);
00331 }
00332 
00333 typeEnum *typeEnum::create(std::string &name, std::vector< std::pair<std::string, int> *> &constants, Symtab *obj)
00334 {
00335    typeEnum *typ = new typeEnum(name);
00336    for(unsigned i=0; i<constants.size();i++)
00337     typ->addConstant(constants[i]->first, constants[i]->second);
00338     
00339     if(obj)
00340        obj->addType(typ);
00341     //obj->addType(typ); TODO: declare a static container if obj is NULL and add to it.
00342     //Symtab::noObjTypes->push_back(typ); ??
00343     return typ; 
00344 }
00345 
00346 typeEnum *typeEnum::create(std::string &name, std::vector<std::string> &constNames, Symtab *obj)
00347 {
00348    typeEnum *typ = new typeEnum(name);
00349    for(unsigned i=0; i<constNames.size();i++)
00350     typ->addConstant(constNames[i], i);
00351     if(obj)
00352        obj->addType(typ);
00353     //obj->addType(typ); TODO: declare a static container if obj is NULL and add to it.
00354     //Symtab::noObjTypes->push_back(typ); ??
00355     return typ; 
00356 }   
00357 
00358 std::vector<std::pair<std::string, int> > &typeEnum::getConstants()
00359 {
00360    return consts;
00361 }
00362 
00363 bool typeEnum::addConstant(const std::string &constName, int value)
00364 {
00365    consts.push_back(std::pair<std::string, int>(constName, value));
00366    return true;
00367 }
00368 
00369 bool typeEnum::isCompatible(Type *otype) 
00370 {
00371    if((otype->getDataClass() == dataUnknownType) || (otype->getDataClass() == dataNullType))
00372        return true;
00373    typeTypedef *otypedef = dynamic_cast<typeTypedef *>(otype);
00374    if (otypedef != NULL) return isCompatible(otypedef->getConstituentType());
00375 
00376    typeEnum *oEnumtype = dynamic_cast<typeEnum *>(otype);
00377 
00378    if (oEnumtype == NULL)
00379       return false;
00380       
00381    if ( (name_ != "") &&( oEnumtype->name_ != "") && (name_ == oEnumtype->name_) && (ID_ == oEnumtype->ID_))
00382       return true;
00383    
00384    const std::vector< std::pair<std::string, int> > &fields1 = this->getConstants();
00385    const std::vector< std::pair<std::string, int> > &fields2 = oEnumtype->getConstants();
00386    
00387    if ( fields1.size() != fields2.size()) 
00388    {
00389       //reportError(BPatchWarning, 112, "enumerated type mismatch ");
00390       return false;
00391    }
00392    
00393    //need to compare componment by component to verify compatibility
00394 
00395    for (unsigned int i=0;i<fields1.size();i++)
00396    {
00397       const std::pair<std::string, int> &field1 = fields1[i];
00398       const std::pair<std::string, int> &field2 = fields2[i];
00399       if ( (field1.second != field2.second) ||
00400           (field1.first != field2.first))
00401       {
00402          // reportError(BPatchWarning, 112, "enum element mismatch ");
00403      return false;
00404       } 
00405    }
00406    // Everything matched so they are the same
00407    return true;
00408 }
00409 
00410 /* 
00411  * POINTER
00412  */
00413 
00414 typePointer::typePointer(int ID, Type *ptr, std::string name) 
00415    : derivedType(name, ID, 0, dataPointer) {
00416    size_ = sizeof(void *);
00417    if (ptr)
00418      setPtr(ptr);
00419 }
00420 
00421 typePointer::typePointer(Type *ptr, std::string name) 
00422    : derivedType(name, USER_TYPE_ID--, 0, dataPointer) {
00423    size_ = sizeof(void *);
00424    if (ptr)
00425      setPtr(ptr);
00426 }
00427 
00428 typePointer *typePointer::create(std::string &name, Type *ptr, Symtab *obj)
00429 {
00430    if(!ptr)
00431     return NULL;
00432    typePointer *typ = new typePointer(ptr, name);
00433 
00434    if(obj)
00435     obj->addType(typ);
00436    //obj->addType(typ); TODO: declare a static container if obj is NULL and add to it.
00437    //Symtab::noObjTypes->push_back(typ); ??
00438                    
00439    return typ;  
00440 }
00441 
00442 typePointer *typePointer::create(std::string &name, Type *ptr, int size, Symtab *obj)
00443 {
00444    if(!ptr)
00445     return NULL;
00446    typePointer *typ = new typePointer(ptr, name);
00447    typ->setSize(size);
00448 
00449    if(obj)
00450     obj->addType(typ);
00451    //obj->addType(typ); TODO: declare a static container if obj is NULL and add to it.
00452    //Symtab::noObjTypes->push_back(typ); ??
00453                    
00454    return typ;  
00455 }
00456 
00457 bool typePointer::setPtr(Type *ptr) { 
00458   assert(ptr);
00459   baseType_ = ptr; 
00460   baseType_->incrRefCount(); 
00461 
00462   if (name_ == "" && ptr->getName() != "") {
00463      name_ = std::string(ptr->getName())+" *";
00464   }
00465   return true;
00466 }
00467 
00468 bool typePointer::isCompatible(Type *otype) {
00469    if((otype->getDataClass() == dataUnknownType) || (otype->getDataClass() == dataNullType))
00470        return true;
00471    typeTypedef *otypedef = dynamic_cast<typeTypedef *>(otype);
00472    if (otypedef != NULL) return isCompatible(otypedef->getConstituentType());
00473 
00474    typePointer *oPointertype = dynamic_cast<typePointer *>(otype);
00475 
00476    if (oPointertype == NULL) {
00477       //reportError(BPatchWarning, 112, 
00478       //                   "Pointer and non-Pointer are not type compatible");
00479       return false;
00480    }
00481    // verify type that each one points to is compatible
00482    return baseType_->isCompatible(oPointertype->baseType_);
00483 }
00484 
00485 void typePointer::fixupUnknowns(Module *module) 
00486 {
00487    if (baseType_->getDataClass() == dataUnknownType) 
00488    {
00489       Type *optr = baseType_;
00490       typeCollection *tc = typeCollection::getModTypeCollection(module);
00491       assert(tc);
00492       baseType_ = tc->findType(baseType_->getID());
00493       baseType_->incrRefCount();
00494       optr->decrRefCount();
00495    }
00496 }
00497 
00498 /*
00499  * FUNCTION
00500  */
00501 
00502 typeFunction::typeFunction(typeId_t ID, Type *retType, std::string name) :
00503     Type(name, ID, dataFunction), 
00504     retType_(retType) 
00505 {
00506    size_ = sizeof(void *);
00507    if (retType)
00508      retType->incrRefCount();
00509 }
00510 
00511 typeFunction::typeFunction(Type *retType, std::string name) :
00512     Type(name, USER_TYPE_ID--, dataFunction), 
00513     retType_(retType) 
00514 {
00515    size_ = sizeof(void *);
00516    if (retType)
00517      retType->incrRefCount();
00518 }
00519 
00520 typeFunction *typeFunction::create(std::string &name, Type *retType, std::vector<Type *> &paramTypes, Symtab *obj)
00521 {
00522     typeFunction *type = new typeFunction(retType, name);
00523     for(unsigned i=0;i<paramTypes.size();i++)
00524     type->addParam(paramTypes[i]);
00525     if(obj)
00526         obj->addType(type);
00527     //obj->addType(type); TODO: declare a static container if obj is NULL and add to it.
00528     //Symtab::noObjTypes->push_back(type); ??
00529     return type;
00530 }
00531 
00532 Type *typeFunction::getReturnType() const{
00533     return retType_;
00534 }
00535 
00536 bool typeFunction::setRetType(Type *rtype) {
00537     if(retType_)
00538         retType_->decrRefCount();
00539     retType_ = rtype;
00540     retType_->incrRefCount();
00541     return true;
00542 }
00543 
00544 bool typeFunction::addParam(Type *paramType){
00545     paramType->incrRefCount();
00546     params_.push_back(paramType);
00547     return true;
00548 }
00549 
00550 std::vector<Type *> &typeFunction::getParams(){
00551     return params_;
00552 }
00553 
00554 bool typeFunction::isCompatible(Type *otype) {
00555    if((otype->getDataClass() == dataUnknownType) || (otype->getDataClass() == dataNullType))
00556        return true;
00557    typeTypedef *otypedef = dynamic_cast<typeTypedef *>(otype);
00558    if (otypedef != NULL) return isCompatible(otypedef->getConstituentType());
00559 
00560    typeFunction *oFunctiontype = dynamic_cast<typeFunction *>(otype);
00561 
00562    if (oFunctiontype == NULL)
00563       return false;
00564 
00565    if (retType_ != oFunctiontype->retType_)
00566       return false;
00567 
00568    std::vector<Type *> fields1 = this->getParams();
00569    std::vector<Type *> fields2 = oFunctiontype->getParams();
00570    //const std::vector<Field *> * fields2 = (std::vector<Field *> *) &(otype->fieldList);
00571    
00572    if (fields1.size() != fields2.size()) {
00573       //reportError(BPatchWarning, 112, 
00574       //                   "function number of params mismatch ");
00575       return false;
00576    }
00577     
00578    //need to compare componment by component to verify compatibility
00579    for (unsigned int i=0;i<fields1.size();i++) {
00580       Type * ftype1 = fields1[i];
00581       Type * ftype2 = fields2[i];
00582       
00583       if(!(ftype1->isCompatible(ftype2))) {
00584          //reportError(BPatchWarning, 112, 
00585          //                   "function param type mismatch ");
00586          return false;
00587       }
00588    }
00589    return true;
00590 }   
00591 
00592 void typeFunction::fixupUnknowns(Module *module) 
00593 {
00594     typeCollection *tc = typeCollection::getModTypeCollection(module);
00595     assert(tc);
00596 
00597     if (retType_->getDataClass() == dataUnknownType) 
00598    {
00599       Type *otype = retType_;
00600       retType_ = tc->findType(retType_->getID());
00601       retType_->incrRefCount();
00602       otype->decrRefCount();
00603    }
00604 
00605    for (unsigned int i = 0; i < params_.size(); i++)
00606    {
00607       Type *otype = params_[i];
00608       params_[i] = tc->findType(params_[i]->getID());
00609       params_[i]->incrRefCount();
00610       otype->decrRefCount();
00611    }     
00612 }
00613 
00614 typeFunction::~typeFunction()
00615 { 
00616     retType_->decrRefCount(); 
00617 }
00618 
00619 /*
00620  * RANGE
00621  */
00622 
00623 //typeSubRange::typeSubRange(int ID, int size, const char *_low, const char *_hi, const char *_name)
00624 //   : rangedType(_name, _ID, BPatchSymTypeRange, _size, _low, _hi) 
00625 //{
00626 //}
00627 
00628 typeSubrange::typeSubrange(typeId_t ID, int size, long low, long hi, std::string name)
00629   : rangedType(name, ID, dataSubrange, size, low, hi)
00630 {
00631 }
00632 
00633 typeSubrange::typeSubrange(int size, long low, long hi, std::string name)
00634   : rangedType(name, USER_TYPE_ID--, dataSubrange, size, low, hi)
00635 {
00636 }
00637 
00638 typeSubrange *typeSubrange::create(std::string &name, int size, long low, long hi, Symtab *obj)
00639 {
00640    typeSubrange *typ = new typeSubrange(size, low, hi, name);
00641 
00642    if(obj)
00643        obj->addType(typ);
00644    return typ;
00645 }
00646 
00647 bool typeSubrange::isCompatible(Type *otype) {
00648    if((otype->getDataClass() == dataUnknownType) || (otype->getDataClass() == dataNullType))
00649        return true;
00650    typeTypedef *otypedef = dynamic_cast<typeTypedef *>(otype);
00651    if (otypedef != NULL) return isCompatible(otypedef->getConstituentType());
00652 
00653    typeSubrange *oRangetype = dynamic_cast<typeSubrange *>(otype);
00654 
00655    if (oRangetype == NULL)
00656       return false;
00657 
00658    return getSize() == oRangetype->getSize();
00659 }
00660 
00661 /*
00662  * ARRAY
00663  */
00664 
00665 typeArray::typeArray(typeId_t ID,
00666         Type *base,
00667         long low,
00668         long hi,
00669         std::string name,
00670         unsigned int sizeHint) :
00671     rangedType(name, ID, dataArray, 0, low, hi), 
00672     arrayElem(base), 
00673     sizeHint_(sizeHint) 
00674 {
00675     //if (!base) arrayElem = Symtab::type_Error;
00676     if (base) arrayElem->incrRefCount();
00677 }
00678 
00679 typeArray::typeArray(Type *base,
00680         long low,
00681         long hi,
00682         std::string name,
00683         unsigned int sizeHint) :
00684     rangedType(name, USER_TYPE_ID--, dataArray, 0, low, hi), 
00685     arrayElem(base), 
00686     sizeHint_(sizeHint) 
00687 {
00688     assert(base != NULL);
00689     arrayElem->incrRefCount();
00690 }
00691 
00692 typeArray *typeArray::create(std::string &name, Type *type, long low, long hi, Symtab *obj)
00693 {
00694     typeArray *typ = new typeArray(type, low, hi, name);
00695 
00696     if(obj)
00697         obj->addType(typ);
00698 
00699     return typ; 
00700 }
00701 
00702 bool typeArray::operator==(const Type &otype) const 
00703 {
00704     try {
00705         const typeArray &oArraytype = dynamic_cast<const typeArray &>(otype);
00706         if (sizeHint_ != oArraytype.sizeHint_) return false;
00707         if (arrayElem && !oArraytype.arrayElem) return false;
00708         if (!arrayElem && oArraytype.arrayElem) return false;
00709         if (arrayElem)
00710         {
00711             if (arrayElem->getID() != oArraytype.arrayElem->getID()) return false;
00712         }
00713         return (rangedType::operator==(otype)); 
00714     } catch (...) 
00715     {
00716         return false;
00717     }
00718 }
00719 
00720 void typeArray::merge(Type *other) 
00721 {
00722     // There are wierd cases where we may define an array with an element
00723     // that is a forward reference
00724 
00725     typeArray *otherarray = dynamic_cast<typeArray *>(other);
00726 
00727     if ( otherarray == NULL || this->ID_ != otherarray->ID_ || 
00728             this->arrayElem->getDataClass() != dataUnknownType) 
00729     {
00730         //bperr( "Ignoring attempt to merge dissimilar types.\n" );
00731         return;
00732     }
00733 
00734     arrayElem->decrRefCount();
00735     otherarray->arrayElem->incrRefCount();
00736     arrayElem = otherarray->arrayElem;
00737 }
00738 
00739 Type *typeArray::getBaseType() const
00740 {
00741     return arrayElem;
00742 }
00743 
00744 void typeArray::updateSize()
00745 {    
00746     if (updatingSize) 
00747     {
00748         size_ = 0;
00749         return;
00750     }
00751 
00752     updatingSize = true;
00753     // Is our array element's Type still a placeholder?
00754     if (arrayElem->getDataClass() == dataUnknownType)
00755         size_ = 0;
00756 
00757     // Otherwise we can now calculate the array type's size
00758     else 
00759     {
00760         // Calculate the size of a single element
00761         unsigned int elemSize = sizeHint_ ? sizeHint_ : arrayElem->getSize();
00762 
00763         // Calculate the size of the whole array
00764         size_ = elemSize * (hi_ ? hi_ - low_ + 1 : 1);
00765     }
00766     updatingSize = false;
00767 }
00768 
00769 bool typeArray::isCompatible(Type *otype) 
00770 {
00771     if (  (otype->getDataClass() == dataUnknownType) 
00772             || (otype->getDataClass() == dataNullType))
00773         return true;
00774 
00775     typeTypedef *otypedef = dynamic_cast<typeTypedef *>(otype);
00776 
00777     if (otypedef != NULL) 
00778     {
00779         return isCompatible(otypedef->getConstituentType());
00780     }
00781 
00782     typeArray *oArraytype = dynamic_cast<typeArray *>(otype);
00783 
00784     if (oArraytype == NULL) 
00785     {
00786         //reportError(BPatchWarning, 112, 
00787         //                   "Array and non-array are not type compatible");
00788         return false;      
00789     }
00790     unsigned int ec1, ec2;
00791 
00792    ec1 = hi_ - low_ + 1;
00793    ec2 = oArraytype->hi_ - oArraytype->low_ + 1;
00794 
00795    if (ec1 != ec2) 
00796    {
00797       char message[80];
00798       sprintf(message, "Incompatible number of elements [%lu..%lu] vs. [%lu..%lu]",
00799           this->low_, this->hi_, oArraytype->low_, oArraytype->hi_);
00800       //reportError(BPatchWarning, 112, message);
00801       return false;
00802    }
00803 
00804    return arrayElem->isCompatible(oArraytype->arrayElem);
00805 }
00806 
00807 void typeArray::fixupUnknowns(Module *module) 
00808 {
00809    if (arrayElem->getDataClass() == dataUnknownType) 
00810    {
00811       Type *otype = arrayElem;
00812       typeCollection *tc = typeCollection::getModTypeCollection(module);
00813       assert(tc);
00814       arrayElem = tc->findType(arrayElem->getID());
00815       arrayElem->incrRefCount();
00816       otype->decrRefCount();
00817    }
00818 }
00819 
00820 /*
00821  * STRUCT
00822  */
00823 
00824 typeStruct::typeStruct(typeId_t ID, std::string name) :
00825     fieldListType(name, ID, dataStructure) 
00826 { 
00827 }
00828 
00829 typeStruct::typeStruct(std::string name)  :
00830     fieldListType(name, USER_TYPE_ID--, dataStructure) 
00831 {
00832 }
00833 
00834 typeStruct *typeStruct::create(std::string &name, std::vector< std::pair<std::string, Type *> *> &flds,
00835                                                                 Symtab *obj)
00836 {
00837    int offset = 0;
00838    typeStruct *typ = new typeStruct(name);
00839    for(unsigned i=0;i<flds.size();i++)
00840    {
00841        typ->addField(flds[i]->first, flds[i]->second, offset);
00842        // Calculate next offset (in bits) into the struct
00843        offset += (flds[i]->second->getSize() * 8);
00844    }
00845    if(obj)
00846     obj->addType(typ);
00847    //obj->addType(typ); TODO: declare a static container if obj is NULL and add to it.
00848    //Symtab::noObjTypes->push_back(typ); ??
00849                    
00850    return typ;  
00851 }
00852 
00853 typeStruct *typeStruct::create(std::string &name, std::vector<Field *> &flds, Symtab *obj)
00854 {
00855    typeStruct *typ = new typeStruct(name);
00856    for(unsigned i=0;i<flds.size();i++)
00857     typ->addField(flds[i]);
00858    if(obj)
00859     obj->addType(typ);
00860    //obj->addType(typ); TODO: declare a static container if obj is NULL and add to it.
00861    //Symtab::noObjTypes->push_back(typ); ??
00862                    
00863    return typ;  
00864 }
00865 
00866 void typeStruct::merge(Type *other) {
00867    // Merging is only for forward references
00868 //   assert(!fieldList.size());
00869 
00870    typeStruct *otherstruct = dynamic_cast<typeStruct *>(other);
00871 
00872    if( otherstruct == NULL || this->ID_ != otherstruct->ID_) {
00873       //bperr( "Ignoring attempt to merge dissimilar types.\n" );
00874       return;
00875    }
00876 
00877    if (otherstruct->name_ != "")
00878       name_ = std::string(otherstruct->name_);
00879    size_ = otherstruct->size_;
00880 
00881    fieldList = otherstruct->fieldList;
00882 
00883    if (otherstruct->derivedFieldList) {
00884       derivedFieldList = new std::vector<Field *>;
00885       *derivedFieldList = *otherstruct->derivedFieldList;
00886    }
00887 }
00888 
00889 void typeStruct::updateSize()
00890 {
00891    if (updatingSize) {
00892       size_ = 0;
00893       return;
00894    }
00895    updatingSize = true;
00896 
00897     // Calculate the size of the entire structure
00898     size_ = 0;
00899     for(unsigned int i = 0; i < fieldList.size(); ++i) {
00900     size_ += fieldList[i]->getSize();
00901 
00902     // Is the type of this field still a placeholder?
00903     if(fieldList[i]->getType()->getDataClass() == dataUnknownType) {
00904         size_ = 0;
00905          break;
00906     }
00907     }
00908    updatingSize = false;
00909 }
00910 
00911 void typeStruct::postFieldInsert(int nsize) 
00912 {
00913     size_ += nsize; 
00914 }
00915 
00916 bool typeStruct::isCompatible(Type *otype) 
00917 {
00918    if((otype->getDataClass() == dataUnknownType) || (otype->getDataClass() == dataNullType))
00919        return true;
00920    typeTypedef *otypedef = dynamic_cast<typeTypedef *>(otype);
00921    if (otypedef != NULL) return isCompatible(otypedef->getConstituentType());
00922 
00923    typeStruct *oStructtype = dynamic_cast<typeStruct *>(otype);
00924 
00925    if (oStructtype == NULL)
00926       return false;
00927 
00928    const std::vector<Field *> * fields1 = this->getComponents();
00929    const std::vector<Field *> * fields2 = oStructtype->getComponents();
00930    //const std::vector<Field *> * fields2 = (std::vector<Field *> *) &(otype->fieldList);
00931    
00932    if (fields1->size() != fields2->size()) {
00933       //reportError(BPatchWarning, 112, 
00934       //                   "struct/union numer of elements mismatch ");
00935       return false;
00936    }
00937     
00938    //need to compare componment by component to verify compatibility
00939    for (unsigned int i=0;i<fields1->size();i++) {
00940       Field * field1 = (*fields1)[i];
00941       Field * field2 = (*fields2)[i];
00942       
00943       Type * ftype1 = (Type *)field1->getType();
00944       Type * ftype2 = (Type *)field2->getType();
00945       
00946       if(!(ftype1->isCompatible(ftype2))) {
00947          //reportError(BPatchWarning, 112, 
00948          //                   "struct/union field type mismatch ");
00949          return false;
00950       }
00951    }
00952    return true;
00953 }
00954 
00955 void typeStruct::fixupUnknowns(Module *module) 
00956 {
00957    for (unsigned int i = 0; i < fieldList.size(); i++)
00958       fieldList[i]->fixupUnknown(module);
00959 }
00960 
00961 /*
00962  * UNION
00963  */
00964 
00965 typeUnion::typeUnion(typeId_t ID, std::string name) :
00966     fieldListType(name, ID, dataUnion) 
00967 { 
00968 }
00969 
00970 typeUnion::typeUnion(std::string name)  :
00971     fieldListType(name, USER_TYPE_ID--, dataUnion) 
00972 {
00973 }
00974 
00975 typeUnion *typeUnion::create(std::string &name, std::vector< std::pair<std::string, Type *> *> &flds,
00976                                                                 Symtab *obj)
00977 {
00978    typeUnion *typ = new typeUnion(name);
00979    for(unsigned i=0;i<flds.size();i++)
00980     typ->addField(flds[i]->first, flds[i]->second, 0);
00981    if(obj)
00982     obj->addType(typ);
00983    //obj->addType(typ); TODO: declare a static container if obj is NULL and add to it.
00984    //Symtab::noObjTypes->push_back(typ); ??
00985                    
00986    return typ;  
00987 }
00988 
00989 typeUnion *typeUnion::create(std::string &name, std::vector<Field *> &flds, Symtab *obj)
00990 {
00991    typeUnion *typ = new typeUnion(name);
00992    for(unsigned i=0;i<flds.size();i++)
00993     typ->addField(flds[i]);
00994    if(obj)
00995     obj->addType(typ);
00996    //obj->addType(typ); TODO: declare a static container if obj is NULL and add to it.
00997    //Symtab::noObjTypes->push_back(typ); ??
00998                    
00999    return typ;  
01000 }
01001 
01002 void typeUnion::merge(Type *other) {
01003    typeUnion *otherunion = dynamic_cast<typeUnion *>(other);
01004 
01005    if( otherunion == NULL || this->ID_ != otherunion->ID_) {
01006       //bperr( "Ignoring attempt to merge dissimilar types.\n" );
01007       return;
01008    }
01009 
01010    if (!fieldList.size())
01011       return;
01012 
01013    if (otherunion->name_ != "")
01014       name_ = std::string(otherunion->name_);
01015    size_ = otherunion->size_;
01016 
01017    fieldList = otherunion->fieldList;
01018 
01019    if (otherunion->derivedFieldList) {
01020       derivedFieldList = new std::vector<Field *>;
01021       *derivedFieldList = *otherunion->derivedFieldList;
01022    }
01023 }
01024 
01025 void typeUnion::updateSize()
01026 {
01027    if (updatingSize) {
01028       size_ = 0;
01029       return;
01030    }
01031    updatingSize = true;
01032 
01033     // Calculate the size of the union
01034     size_ = 0;
01035     for(unsigned int i = 0; i < fieldList.size(); ++i) {
01036     if(fieldList[i]->getSize() > size_)
01037         size_ = fieldList[i]->getSize();
01038 
01039     // Is the type of this field still a placeholder?
01040         if(fieldList[i]->getType()->getDataClass() == dataUnknownType) {
01041             size_ = 0;
01042          break;
01043         }
01044     }
01045    updatingSize = false;
01046 }
01047 
01048 void typeUnion::postFieldInsert(int nsize) {
01049     if ((unsigned int) nsize > size_) size_ = nsize; 
01050 }
01051 
01052 bool typeUnion::isCompatible(Type *otype) {
01053    if((otype->getDataClass() == dataUnknownType) || (otype->getDataClass() == dataNullType))
01054        return true;
01055    typeTypedef *otypedef = dynamic_cast<typeTypedef *>(otype);
01056    if (otypedef != NULL) return isCompatible(otypedef->getConstituentType());
01057 
01058    typeUnion *oUniontype = dynamic_cast<typeUnion *>(otype);
01059 
01060    if (oUniontype == NULL)
01061       return false;
01062 
01063    const std::vector<Field *> * fields1 = this->getComponents();
01064    const std::vector<Field *> * fields2 = oUniontype->getComponents();
01065    //const std::vector<Field *> * fields2 = (std::vector<Field *> *) &(otype->fieldList);
01066    
01067    if (fields1->size() != fields2->size()) {
01068       //reportError(BPatchWarning, 112, 
01069       //                   "struct/union numer of elements mismatch ");
01070       return false;
01071    }
01072     
01073    //need to compare componment by component to verify compatibility
01074    for (unsigned int i=0;i<fields1->size();i++) {
01075       Field * field1 = (*fields1)[i];
01076       Field * field2 = (*fields2)[i];
01077       
01078       Type * ftype1 = (Type *)field1->getType();
01079       Type * ftype2 = (Type *)field2->getType();
01080       
01081       if(!(ftype1->isCompatible(ftype2))) {
01082          //reportError(BPatchWarning, 112, 
01083          //                   "struct/union field type mismatch ");
01084          return false;
01085       }
01086    }
01087    return true;
01088 }
01089 
01090 void typeUnion::fixupUnknowns(Module *module) {
01091    for (unsigned int i = 0; i < fieldList.size(); i++)
01092       fieldList[i]->fixupUnknown(module);
01093 }
01094 
01095 /*
01096  * SCALAR
01097  */
01098 
01099    
01100 typeScalar::typeScalar(typeId_t ID, unsigned int size, std::string name, bool isSigned) :
01101     Type(name, ID, dataScalar), isSigned_(isSigned) 
01102 {
01103    size_ = size;
01104 }
01105 
01106 typeScalar::typeScalar(unsigned int size, std::string name, bool isSigned) :
01107     Type(name, USER_TYPE_ID--, dataScalar), isSigned_(isSigned) 
01108 {
01109    size_ = size;
01110 }
01111 
01112 typeScalar *typeScalar::create(std::string &name, int size, Symtab *obj)
01113 {
01114    typeScalar *typ = new typeScalar(size, name);
01115    
01116    if(obj)
01117     obj->addType(typ);
01118    //obj->addType(typ); TODO: declare a static container if obj is NULL and add to it.
01119    //Symtab::noObjTypes->push_back(typ); ??
01120                    
01121    return typ;  
01122 }
01123 
01124 bool typeScalar::isSigned(){
01125     return isSigned_;
01126 }
01127 
01128 bool typeScalar::isCompatible(Type *otype) {
01129    if((otype->getDataClass() == dataUnknownType) || (otype->getDataClass() == dataNullType))
01130        return true;
01131    bool ret = false;
01132    const typeTypedef *otypedef = dynamic_cast<const typeTypedef *>(otype);
01133    if (otypedef != NULL)  {
01134       ret =  isCompatible(otypedef->getConstituentType());
01135       return ret;
01136    }
01137 
01138    typeScalar *oScalartype = dynamic_cast<typeScalar *>(otype);
01139    if (oScalartype == NULL) {
01140       //  Check to see if we have a range type, which can be compatible.
01141       typeSubrange *oSubrangeType = dynamic_cast<typeSubrange *>(otype);
01142       if (oSubrangeType != NULL) {
01143         if ( name_ == "" || oSubrangeType->getName() == "")
01144            return size_ == oSubrangeType->getSize();
01145         else if (name_ == oSubrangeType->getName())
01146            return size_ == oSubrangeType->getSize();
01147         else if (size_ == oSubrangeType->getSize()) {
01148           int t1 = findIntrensicType(name_);
01149           int t2 = findIntrensicType(oSubrangeType->getName());
01150           if (t1 & t2 & (t1 == t2)) {
01151             return true;
01152           }
01153         }
01154       }
01155       return false;
01156    }
01157 
01158    if ( name_ == "" || oScalartype->name_ == "")
01159       return size_ == oScalartype->size_;
01160    else if (name_ == oScalartype->name_)
01161       return size_ == oScalartype->size_;
01162    else if (size_ == oScalartype->size_) {
01163       int t1 = findIntrensicType(name_);
01164       int t2 = findIntrensicType(oScalartype->name_);
01165       if (t1 & t2 & (t1 == t2)) {
01166          return true;
01167       }
01168    }
01169    return false;
01170 }
01171 
01172 /* 
01173  * COMMON BLOCK
01174  */
01175 
01176 typeCommon::typeCommon(int ID, std::string name) :
01177     fieldListType(name, ID, dataCommon) 
01178 {}
01179 
01180 typeCommon::typeCommon(std::string name) :
01181     fieldListType(name, USER_TYPE_ID--, dataCommon) 
01182 {}
01183 
01184 void typeCommon::beginCommonBlock() 
01185 {
01186     std::vector<Field*> emptyList;
01187 
01188     // null out field list
01189     fieldList = emptyList;
01190 }
01191 
01192 void typeCommon::endCommonBlock(Symbol *func, void *baseAddr) 
01193 {
01194     unsigned int i, j;
01195 
01196     // create local variables in func's scope for each field of common block
01197     for (j=0; j < fieldList.size(); j++) {
01198 
01199         localVar *locVar;
01200         locVar = new localVar(fieldList[j]->getName(), 
01201                              fieldList[j]->getType(), "", 0, (Function *) func);
01202 #if 0
01203         VariableLocation *loc = (VariableLocation *)malloc(sizeof(VariableLocation));
01204 #endif
01205         VariableLocation loc;
01206         loc.stClass = storageAddr;
01207         loc.refClass = storageNoRef;
01208         loc.frameOffset = fieldList[j]->getOffset()+(Offset) baseAddr;
01209         locVar->addLocation(loc);
01210 
01211     // localVar->addField() TODO????
01212     //fieldList[j]->getOffset()+(Offset) baseAddr, -1, storageAddr);
01213     
01214       if (!func->getFunction()->addLocalVar(locVar)) 
01215       {
01216          fprintf(stderr, "%s[%d]:  FIXME\n", FILE__, __LINE__);
01217       }
01218     }
01219 
01220     // look to see if the field list matches an existing block
01221     for (i=0; i < cblocks.size(); i++) {
01222     CBlock *curr = cblocks[i];
01223     for (j=0; j < fieldList.size(); j++) {
01224         if ((fieldList[j]->getName() == curr->fieldList[j]->getName()) ||
01225         (fieldList[j]->getOffset() !=curr->fieldList[j]->getOffset()) ||
01226         (fieldList[j]->getSize() != curr->fieldList[j]->getSize())) {
01227         break; // no match
01228         }
01229     }
01230     if (j == fieldList.size() && (j == curr->fieldList.size())) {
01231         // match
01232         curr->functions.push_back(func);
01233         return;
01234     }
01235     }
01236 
01237     // this one is unique
01238     CBlock *newBlock = new CBlock();
01239     newBlock->fieldList = fieldList;
01240     newBlock->functions.push_back(func);
01241     cblocks.push_back(newBlock);
01242 }
01243 
01244 void typeCommon::fixupUnknowns(Module *module) {
01245    for (unsigned int i = 0; i < cblocks.size(); i++)
01246       cblocks[i]->fixupUnknowns(module);   
01247 }
01248 
01249 std::vector<CBlock *> *typeCommon::getCblocks() const 
01250 {
01251     return const_cast<std::vector<CBlock*>*>(&cblocks); 
01252 }
01253 
01254 /*
01255  * TYPEDEF
01256  */
01257 
01258 typeTypedef::typeTypedef(typeId_t ID, Type *base, std::string name, unsigned int sizeHint) :
01259     derivedType(name, ID, 0, dataTypedef) 
01260 {
01261     baseType_ = base;
01262 #if 0
01263     if (NULL == base)
01264         baseType_ = Symtab::type_Error;
01265     else
01266         baseType_ = base;
01267 #endif
01268     sizeHint_ = sizeHint / 8;
01269     if (baseType_) baseType_->incrRefCount();
01270 }
01271 
01272 typeTypedef::typeTypedef(Type *base, std::string name, unsigned int sizeHint) :
01273     derivedType(name, USER_TYPE_ID--, 0, dataTypedef) 
01274 {
01275    assert(base != NULL);
01276    baseType_ = base;
01277    sizeHint_ = sizeHint / 8;
01278    baseType_->incrRefCount();
01279 }
01280 
01281 typeTypedef *typeTypedef::create(std::string &name, Type *baseType, Symtab *obj)
01282 {
01283    if(!baseType)
01284     return NULL;
01285    typeTypedef *typ = new typeTypedef(baseType, name);
01286 
01287    if(obj)
01288     obj->addType(typ);
01289    //obj->addType(typ); TODO: declare a static container if obj is NULL and add to it.
01290    //Symtab::noObjTypes->push_back(typ); ??
01291                    
01292    return typ;  
01293 }
01294 
01295 bool typeTypedef::operator==(const Type &otype) const {
01296    try {
01297       const typeTypedef &oDeftype = dynamic_cast<const typeTypedef &>(otype);
01298       return baseType_==oDeftype.baseType_;
01299    } catch (...) {
01300       return false;
01301    }
01302 }
01303 
01304 bool typeTypedef::isCompatible(Type *otype){
01305     return baseType_->isCompatible(otype);
01306 }
01307 
01308 void typeTypedef::updateSize()
01309 {
01310    if (updatingSize) {
01311       size_ = 0;
01312       return;
01313    }
01314    updatingSize = true;
01315 
01316     // Is our base type still a placeholder?
01317     if(baseType_->getDataClass() == dataUnknownType)
01318     size_ = 0;
01319 
01320     // Otherwise we can now calculate the type definition's size
01321     else {
01322     // Calculate the size of the type definition
01323     size_ = sizeHint_ ? sizeHint_ : baseType_->getSize();
01324     }
01325    updatingSize = false;
01326 }
01327 
01328 void typeTypedef::fixupUnknowns(Module *module) 
01329 {
01330    if (baseType_->getDataClass() == dataUnknownType) 
01331    {
01332       Type *otype = baseType_;
01333       typeCollection *tc = typeCollection::getModTypeCollection(module);
01334       assert(tc);
01335       baseType_ = tc->findType(baseType_->getID());
01336       baseType_->incrRefCount();
01337       otype->decrRefCount();
01338    }
01339 }
01340 
01341 /*
01342  * REFERENCE
01343  */
01344 
01345 typeRef::typeRef(int ID, Type *refType, std::string name) :
01346     derivedType(name, ID, 0, dataReference) 
01347 {
01348    baseType_ = refType;
01349    if (refType)
01350     refType->incrRefCount();
01351 }
01352 
01353 typeRef::typeRef(Type *refType, std::string name) :
01354     derivedType(name, USER_TYPE_ID--, 0, dataReference) 
01355 {
01356    baseType_ = refType;
01357    if(refType)
01358     refType->incrRefCount();
01359 }
01360 
01361 typeRef *typeRef::create(std::string &name, Type *ref, Symtab *obj)
01362 {
01363    typeRef *typ = new typeRef(ref, name);
01364 
01365    if(obj)
01366     obj->addType(typ);
01367    //obj->addType(typ); TODO: declare a static container if obj is NULL and add to it.
01368    //Symtab::noObjTypes->push_back(typ); ??
01369                    
01370    return typ;  
01371 }
01372 
01373 bool typeRef::operator==(const Type &otype) const {
01374    try {
01375       const typeRef &oReftype = dynamic_cast<const typeRef &>(otype);
01376       return baseType_== oReftype.baseType_;
01377    } catch (...) {
01378       return false;
01379    }
01380 }
01381 
01382 bool typeRef::isCompatible(Type *otype) {
01383    if((otype->getDataClass() == dataUnknownType) || (otype->getDataClass() == dataNullType))
01384        return true;
01385    typeTypedef *otypedef = dynamic_cast<typeTypedef *>(otype);
01386    if (otypedef != NULL) return isCompatible(otypedef->getConstituentType());
01387 
01388    typeRef *oReftype = dynamic_cast< typeRef *>(otype);
01389    if (oReftype == NULL) {
01390       return false;
01391    }
01392    return baseType_->isCompatible(const_cast<Type *>(oReftype->getConstituentType()));
01393 }   
01394 
01395 void typeRef::fixupUnknowns(Module *module) 
01396 {
01397    if (baseType_->getDataClass() == dataUnknownType) 
01398    {
01399       Type *otype = baseType_;
01400       typeCollection *tc = typeCollection::getModTypeCollection(module);
01401       assert(tc);
01402       baseType_ = tc->findType(baseType_->getID());
01403       baseType_->incrRefCount();
01404       otype->decrRefCount();
01405    }
01406 }
01407               
01408 /* 
01409  * Subclasses of class Type, with interfaces
01410  */
01411 
01412 /*
01413  * FIELD LIST Type
01414  */
01415 
01416 fieldListType::fieldListType(std::string &name, typeId_t ID, dataClass typeDes) :
01417     Type(name, ID, typeDes), derivedFieldList(NULL)
01418 {   
01419    size_ = 0;
01420 }
01421 
01422 fieldListType::~fieldListType() 
01423 {
01424    if (derivedFieldList != NULL)
01425    {
01426        fprintf(stderr, "%s[%d]:  REMOVED DELETE\n", FILE__, __LINE__);
01427       //delete derivedFieldList;
01428    }
01429    fieldList.clear();
01430 }
01431 
01432 bool fieldListType::operator==(const Type &otype) const 
01433 {
01434    try 
01435    {
01436       const fieldListType &oFieldtype = dynamic_cast<const fieldListType &>(otype);
01437       if (fieldList.size() != oFieldtype.fieldList.size())
01438          return false;
01439       for (unsigned int i = 0; i < fieldList.size(); i++) 
01440       {
01441           Field *f1 = fieldList[i];
01442           Field *f2 = oFieldtype.fieldList[i];
01443           if (f1 && !f2) return false;
01444           if (!f1 && f2) return false;
01445           if (f1)
01446           {
01447               if ( !((*f1) == (*f2)) )
01448                   return false;
01449           }
01450       }
01451       return Type::operator==(otype);
01452    } 
01453    catch (...) 
01454    {
01455       return false;
01456    }
01457 }
01458 
01459 std::vector<Field *> * fieldListType::getComponents() const 
01460 {
01461    if (derivedFieldList == NULL)
01462        const_cast<fieldListType *>(this)->fixupComponents();
01463    return derivedFieldList;
01464 }
01465 
01466 std::vector<Field *> *fieldListType::getFields() const 
01467 {
01468    return const_cast<std::vector<Field *> *>(&fieldList);
01469 }
01470 
01471 void fieldListType::fixupComponents() 
01472 {
01473    // bperr "Getting the %d components of '%s' at 0x%x\n", fieldList.size(), getName(), this );
01474    /* Iterate over the field list.  Recursively (replace)
01475       '{superclass}' with the superclass's non-private fields. */
01476    derivedFieldList = new std::vector< Field * >();
01477    for( unsigned int i = 0; i < fieldList.size(); i++ ) {
01478       Field * currentField = fieldList[i];
01479       // bperr( "Considering field '%s'\n", currentField->getName() );
01480       if( currentField->getName() ==  "{superclass}" ) {
01481          /* Note that this is a recursive call.  However, because
01482             the class-graph is acyclic (Stroustrup SpecialEd pg 308),
01483             we're OK. */
01484          // bperr( "Found superclass '%s'...\n", currentField->getType()->getName() );
01485          fieldListInterface *superclass = dynamic_cast<fieldListInterface *>(currentField->getType());
01486          assert (superclass != NULL);
01487          const std::vector<Field *> * superClassFields = superclass->getComponents();
01488          // bperr( "Superclass has %d components.\n", superClassFields->size() );
01489          /* FIXME: do we also need to consider the visibility of the superclass itself? */
01490          /* FIXME: visibility can also be described on a per-name basis in the
01491             subclass.  We have now way to convey this information currently, but I'm not
01492             sure that it matters for our purposes... */
01493          for( unsigned int i = 0; i < superClassFields->size(); i++ ) {
01494             Field * currentSuperField = (*superClassFields)[i];
01495             // bperr( "Considering superfield '%s'\n", currentSuperField->getName() );
01496             
01497             if( currentSuperField->getVisibility() != visPrivate ) {
01498                derivedFieldList->push_back( currentSuperField );
01499             }
01500          } /* end super-class iteration */
01501       } /* end if currentField is a superclass */
01502       else {
01503          derivedFieldList->push_back( currentField );
01504       }
01505    } /* end field iteration */
01506 }
01507 
01508 /*
01509  * void fieldListType::addField
01510  * Creates field object and adds it to the list of fields for this
01511  * type object.
01512  *     STRUCTS OR UNIONS
01513  */
01514 void fieldListType::addField(std::string fieldname, Type *type, int offsetVal, visibility_t vis)
01515 {
01516   Field * newField;
01517   newField = new Field(fieldname, type, offsetVal, vis);
01518 
01519   // Add field to list of struct/union fields
01520   fieldList.push_back(newField);
01521 
01522   // API defined structs/union's size are defined on the fly.
01523   postFieldInsert(type->getSize());
01524 }
01525 
01526 void fieldListType::addField(Field *fld)
01527 {
01528   Field *newField = new Field(*fld);
01529   // Add field to list of struct/union fields
01530   fieldList.push_back(newField);
01531 
01532   // API defined structs/union's size are defined on the fly.
01533   postFieldInsert(newField->getSize());
01534 }
01535 
01536 void fieldListType::addField(unsigned num, std::string fieldname, Type *type, int offsetVal, visibility_t vis)
01537 {
01538   Field * newField;
01539   newField = new Field(fieldname, type, offsetVal, vis);
01540 
01541   if(num >fieldList.size()+1)
01542     num = fieldList.size();
01543   // Add field to list of struct/union fields
01544   fieldList.insert(fieldList.begin()+num, newField);
01545 
01546   // API defined structs/union's size are defined on the fly.
01547   postFieldInsert(type->getSize());
01548 }
01549 
01550 void fieldListType::addField(unsigned num, Field *fld)
01551 {
01552   Field *newField = new Field(*fld);
01553   // Add field to list of struct/union fields
01554   if(num >fieldList.size()+1)
01555     num = fieldList.size();
01556   // Add field to list of struct/union fields
01557   fieldList.insert(fieldList.begin()+num, newField);
01558 
01559   // API defined structs/union's size are defined on the fly.
01560   postFieldInsert(newField->getSize());
01561 }
01562 
01563 //void fieldListType::fixupUnknown(Module *m)
01564 //{
01565 //  type *t = dynamic_cast<Type *>(this);
01566 //  assert(t);
01567 //  t->fixupUnknown(m);
01568   //((Type *)this)->fixupUnknown(m);
01569 //}
01570 
01571 
01572 /*
01573  * DERIVED
01574  */
01575 
01576 derivedType::derivedType(std::string &name, typeId_t id, int size, dataClass typeDes)
01577    :Type(name, id, typeDes)
01578 {
01579     baseType_ = NULL; //Symtab::type_Error;
01580    size_ = size;
01581 }
01582 
01583 derivedType::derivedType(std::string &name, int size, dataClass typeDes)
01584    :Type(name, USER_TYPE_ID--, typeDes)
01585 {
01586     baseType_ = NULL; //Symtab::type_Error;
01587    size_ = size;
01588 }
01589 
01590 Type *derivedType::getConstituentType() const
01591 {
01592    return baseType_;
01593 }
01594 
01595 bool derivedType::operator==(const Type &otype) const {
01596    try {
01597       //const derivedType &oderivedtype = dynamic_cast<const derivedType &>(otype);
01598       return Type::operator==(otype);
01599    } catch (...) {
01600       return false;
01601    }
01602 }
01603 
01604 derivedType::~derivedType()
01605 {
01606    if(baseType_)
01607     baseType_->decrRefCount();
01608 }
01609 
01610 /*
01611  * RANGED
01612  */
01613 
01614 rangedType::rangedType(std::string &name, typeId_t ID, dataClass typeDes, int size, unsigned long low, unsigned long hi) :
01615     Type(name, ID, typeDes), 
01616     low_(low), 
01617     hi_(hi) 
01618 {
01619    size_ = size;
01620 }
01621 
01622 rangedType::rangedType(std::string &name, dataClass typeDes, int size, unsigned long low, unsigned long hi) :
01623     Type(name, USER_TYPE_ID--, typeDes), 
01624     low_(low), 
01625     hi_(hi)
01626 {
01627    size_ = size;
01628 }
01629 
01630 /*
01631 rangedType::rangedType(const char *_name, int _ID, dataClass _class, int _size, const char *_low, const char *_hi) 
01632    : Type(_name, _ID, _class) {
01633 
01634    low = strdup(_low);
01635    hi = strdup(_hi);
01636 
01637    size = _size;
01638 }
01639 */
01640 
01641 rangedType::~rangedType() {
01642 }
01643 
01644 bool rangedType::operator==(const Type &otype) const 
01645 {
01646    try 
01647    {
01648       const rangedType &oRangedtype = dynamic_cast<const rangedType &>(otype);
01649       return (low_ == oRangedtype.low_ && hi_ == oRangedtype.hi_ &&
01650               Type::operator==(otype));
01651    } 
01652    catch (...) 
01653    {
01654       return false;
01655    }
01656 }
01657 
01658 //
01659 // Define the type compatability among the intrensic types of the various
01660 //     languages.  For example int in c is compatiable to integer*4 in Fortran.
01661 //     Each equivelence class is given a unique number.
01662 //
01663 struct intrensicTypes_ {
01664     const char *name;
01665     int tid;
01666 };
01667 
01668 struct intrensicTypes_ intrensicTypes[] = {
01669     { "int",        1 },
01670     { "integer*4",  1 },
01671     { "INTEGER*4",  1 },
01672     { NULL,     0 },
01673 };
01674 
01675 static int findIntrensicType(std::string &name)
01676 {
01677     struct intrensicTypes_ *curr;
01678 
01679     for (curr = intrensicTypes; curr->name; curr++) {
01680     if ((name != "")&& curr->name && !strcmp(name.c_str(), curr->name)) {
01681         return curr->tid;
01682     }
01683     }
01684 
01685     return 0;
01686 }
01687 
01688 
01689 Field::Field() :
01690     FIELD_ANNOTATABLE_CLASS(),
01691     type_(NULL),
01692     vis_(visUnknown),
01693     offset_(-1)
01694 {}
01695 /*
01696  * Field::Field
01697  *
01698  * Constructor for Field.  Creates a Field object for 
01699  * an enumerated type.
01700  * type = offset = size = 0;
01701  */
01702 Field::Field(std::string name, Type *typ, int offsetVal, visibility_t vis) :
01703     FIELD_ANNOTATABLE_CLASS(),
01704    fieldName_(name), 
01705    type_(typ), 
01706    vis_(vis), 
01707    offset_(offsetVal)
01708 {
01709     if (typ)
01710         typ->incrRefCount();
01711 }
01712 
01713 std::string &Field::getName()
01714 {
01715    return fieldName_;
01716 }
01717 
01718 Type *Field::getType()
01719 {
01720    return type_;
01721 }
01722 
01723 visibility_t Field::getVisibility()
01724 {
01725    return vis_;
01726 }
01727 
01728 int Field::getOffset()
01729 {
01730    return offset_;
01731 }
01732 
01733 unsigned int Field::getSize()
01734 {
01735    return type_ ? type_->getSize() : 0;
01736 }
01737 
01738 Field::Field(Field &oField) :
01739     Serializable(),
01740     FIELD_ANNOTATABLE_CLASS()
01741 {
01742    type_ = oField.type_;
01743    offset_ = oField.offset_;
01744    fieldName_ = std::string(oField.fieldName_);
01745    vis_ = oField.vis_;
01746    fprintf(stderr, "%s[%d]:  copy annnotations here??\n", FILE__, __LINE__);
01747 
01748    if (type_ != NULL)
01749       type_->incrRefCount();
01750 }
01751 
01752 Field::~Field() 
01753 {
01754    if (type_ != NULL) 
01755       type_->decrRefCount();
01756 }
01757 
01758 void Field::fixupUnknown(Module *module) 
01759 {
01760    if (type_->getDataClass() == dataUnknownType) 
01761    {
01762       Type *otype = type_;
01763       typeCollection *tc = typeCollection::getModTypeCollection(module);
01764       assert(tc);
01765       type_ = tc->findType(type_->getID());
01766       type_->incrRefCount();
01767       otype->decrRefCount();
01768    }
01769 }
01770 
01771 bool Field::operator==(const Field &f) const
01772 {
01773     if (type_ && !f.type_) return false;
01774     if (!type_ && f.type_) return false;
01775     if (type_)
01776     {
01777         if (type_->getID() != f.type_->getID()) return false;
01778     }
01779     if (fieldName_ != f.fieldName_) return false;
01780     if (vis_ != f.vis_) return false;
01781     if (offset_ != f.offset_) return false;
01782     return true;
01783 }
01784 
01785 /**************************************************************************
01786  * CBlock
01787  *************************************************************************/
01788 
01789 void CBlock::fixupUnknowns(Module *module) 
01790 {
01791     for (unsigned int i = 0; i < fieldList.size(); i++) 
01792     {
01793         fieldList[i]->fixupUnknown(module);
01794     }
01795 }
01796 
01797 std::vector<Field *> *CBlock::getComponents()
01798 {
01799   return &fieldList;
01800 }
01801 
01802 std::vector<Symbol *> *CBlock::getFunctions()
01803 {
01804   return &functions;
01805 }
01806 
01807 Type::Type() : name_(std::string("unnamedType")), size_(0), type_(dataUnknownType) {}
01808 fieldListType::fieldListType() : derivedFieldList(NULL) {}
01809 rangedType::rangedType() {}
01810 derivedType::derivedType() {}
01811 typeEnum::typeEnum() {}
01812 typeFunction::typeFunction() {}
01813 typeScalar::typeScalar() {}
01814 typeCommon::typeCommon() {}
01815 typeStruct::typeStruct() {}
01816 typeUnion::typeUnion() {}
01817 typePointer::typePointer() {}
01818 typeTypedef::typeTypedef() {}
01819 typeRef::typeRef() {}
01820 typeSubrange::typeSubrange() {}
01821 typeArray::typeArray() {}
01822 
01823 #if !defined(SERIALIZATION_DISABLED)
01824 Serializable * Type::serialize_impl(SerializerBase *s, const char *tag) THROW_SPEC (SerializerError)
01825 {
01826     Type *newt = this;
01827     ifxml_start_element(s, tag);
01828     gtranslate(s, (int &) ID_, "typeid");
01829     gtranslate(s, type_, dataClass2Str, "dataClass");
01830     gtranslate(s, name_, "name");
01831     gtranslate(s, size_, "size");
01832 
01833     if (!(name_.length())) 
01834         serialize_printf("%s[%d]:  WARNING:  %sserializing type %s w/out name\n", 
01835                 FILE__, __LINE__, s->isInput() ? "de" : "", dataClass2Str(type_));
01836 
01837     if (s->isInput())
01838     {
01839         newt->incrRefCount();
01840         switch(type_) 
01841         {
01842             case dataEnum:
01843                 newt = new typeEnum(ID_, name_);
01844                 assert(newt);
01845                 break;
01846             case dataPointer:
01847                 newt = new typePointer(ID_, NULL, name_);
01848                 assert(newt);
01849                 break;
01850             case dataFunction:
01851                 newt = new typeFunction(ID_, NULL, name_);
01852                 assert(newt);
01853                 break;
01854             case dataSubrange:
01855                 newt = new typeSubrange(ID_, size_, 0L, 0L, name_);
01856                 assert(newt);
01857                 break;
01858             case dataArray:
01859                 newt = new typeArray(ID_, NULL, 0L, 0L, name_);
01860                 assert(newt);
01861                 break;
01862             case dataStructure:
01863                 newt = new typeStruct(ID_, name_);
01864                 assert(newt);
01865                 break;
01866             case dataUnion:
01867                 newt = new typeUnion(ID_, name_);
01868                 assert(newt);
01869                 break;
01870             case dataCommon:
01871                 newt = new typeCommon(ID_, name_);
01872                 assert(newt);
01873                 break;
01874             case dataScalar:
01875                 newt = new typeScalar(ID_, size_, name_);
01876                 assert(newt);
01877                 break;
01878             case dataTypedef:
01879                 newt = new typeTypedef(ID_, NULL, name_);
01880                 assert(newt);
01881                 break;
01882             case dataReference:
01883                 newt = new typeRef(ID_, NULL, name_);
01884                 assert(newt);
01885                 break;
01886             case dataUnknownType:
01887             case dataNullType:
01888             default:
01889                 serialize_printf("%s[%d]:  WARN:  nonspecific %s type: '%s'\n", 
01890                         FILE__, __LINE__, dataClass2Str(type_), newt->getName().c_str());
01891                 break;
01892         };
01893     }
01894     newt->serialize_specific(s);
01895     ifxml_end_element(s, tag);
01896 
01897     if (s->isInput())
01898     {
01899         updatingSize = false;
01900         refCount = 0;
01901         if ((ID_ < 0) && (Type::USER_TYPE_ID >= ID_))
01902         {
01903             //  USER_TYPE_ID is the next available (increasingly negative)
01904             //  type ID available for user defined types.
01905             Type::USER_TYPE_ID = ID_ -1;
01906         }
01907     }
01908     return newt;
01909 }
01910 
01911 void typeEnum::serialize_specific(SerializerBase *sb) THROW_SPEC(SerializerError)
01912 {
01913     ifxml_start_element(sb, "typeEnum");
01914     gtranslate(sb, consts, "EnumElements", "EnumElement");
01915     ifxml_end_element(sb, "typeEnum");
01916 }
01917 
01918 void typePointer::serialize_specific(SerializerBase *sb) THROW_SPEC(SerializerError)
01919 {
01920     derivedType *dt = this;
01921 
01922     ifxml_start_element(sb, "typePointer");
01923     dt->serialize_derived(sb);
01924     ifxml_end_element(sb, "typePointer");
01925 }
01926 
01927 void typeFunction::serialize_specific(SerializerBase *sb) THROW_SPEC(SerializerError)
01928 {
01929     int t_id = retType_ ? retType_->getID() : 0xdeadbeef;
01930     int t_dc = (int) (retType_ ? retType_->getDataClass() : dataUnknownType);
01931 
01932     std::vector<std::pair<int, int> > ptypes;
01933     for (unsigned int i = 0; i < params_.size(); ++i)
01934         ptypes.push_back(std::pair<int, int>(params_[i]->getID(), params_[i]->getDataClass()));
01935 
01936     ifxml_start_element(sb, "typeFunction");
01937     gtranslate(sb, t_id, "retTypeID");
01938     gtranslate(sb, t_dc, "retTypeDataClass");
01939     gtranslate(sb, ptypes, "ParameterTypes", "ParameterTypeID");
01940     ifxml_end_element(sb, "typeFunction");
01941     if (sb->isInput()) 
01942     {
01943         retType_ = NULL; //Symtab::type_Error;
01944         typeCollection::addDeferredLookup(t_id, (dataClass) t_dc, &retType_);
01945         params_.resize(ptypes.size());
01946         for (unsigned int i = 0; i < ptypes.size(); ++i)
01947         {
01948             params_[i] = NULL; // Symtab::type_Error;
01949             typeCollection::addDeferredLookup(ptypes[i].first, (dataClass) ptypes[i].second, &params_[i]);
01950         }
01951     }
01952 }
01953 
01954 void typeSubrange::serialize_specific(SerializerBase *sb) THROW_SPEC(SerializerError)
01955 {
01956     ifxml_start_element(sb, "typeSubrange");
01957     serialize_ranged(sb);
01958     ifxml_end_element(sb, "typeSubrange");
01959 }
01960 
01961 void typeArray::serialize_specific(SerializerBase *sb) THROW_SPEC(SerializerError)
01962 {
01963     unsigned int t_id = arrayElem ? arrayElem->getID() : 0xdeadbeef;
01964     int t_dc = (int)(arrayElem ? arrayElem->getDataClass() : dataUnknownType);
01965 
01966     ifxml_start_element(sb, "typeArray");
01967     serialize_ranged(sb);
01968     gtranslate(sb, sizeHint_, "sizeHint");
01969     gtranslate(sb, t_id, "elemTypeID");
01970     gtranslate(sb, t_dc, "elemTypeID");
01971     ifxml_end_element(sb, "typeArray");
01972 
01973     if (sb->isInput())
01974     {
01975         //arrayElem = Symtab::type_Error;
01976         arrayElem = NULL;
01977         typeCollection::addDeferredLookup(t_id, (dataClass) t_dc, &arrayElem);
01978     }
01979 }
01980 
01981 void typeStruct::serialize_specific(SerializerBase *sb) THROW_SPEC(SerializerError)
01982 {
01983     ifxml_start_element(sb, "typeStruct");
01984     serialize_fieldlist(sb, "structFieldList");
01985     ifxml_end_element(sb, "typeStruct");
01986 }
01987 
01988 void typeUnion::serialize_specific(SerializerBase *sb) THROW_SPEC(SerializerError)
01989 {
01990     ifxml_start_element(sb, "typeUnion");
01991     serialize_fieldlist(sb, "unionFieldList");
01992     ifxml_end_element(sb, "typeUnion");
01993 }
01994 
01995 void typeScalar::serialize_specific(SerializerBase *sb) THROW_SPEC(SerializerError)
01996 {
01997 
01998     ifxml_start_element(sb, "typeScalar");
01999     gtranslate(sb, isSigned_, "isSigned");
02000     ifxml_end_element(sb, "typeScalar");
02001 }
02002 
02003 void typeCommon::serialize_specific(SerializerBase *sb) THROW_SPEC(SerializerError)
02004 {
02005 
02006     ifxml_start_element(sb, "typeCommon");
02007     serialize_fieldlist(sb, "commonBlockFieldList");
02008     gtranslate(sb, cblocks, "CommonBlocks", "CommonBlock");
02009     ifxml_end_element(sb, "typeCommon");
02010 }
02011 
02012 void typeTypedef::serialize_specific(SerializerBase *sb) THROW_SPEC(SerializerError)
02013 {
02014     derivedType *dt = this;
02015 
02016     ifxml_start_element(sb, "typeTypedef");
02017     dt->serialize_derived(sb);
02018     gtranslate(sb, sizeHint_, "sizeHint");
02019     ifxml_end_element(sb, "typeTypedef");
02020 }
02021 
02022 void typeRef::serialize_specific(SerializerBase *sb) THROW_SPEC(SerializerError)
02023 {
02024     derivedType *dt = this;
02025 
02026     ifxml_start_element(sb, "typeRef");
02027     dt->serialize_derived(sb);
02028     ifxml_end_element(sb, "typeRef");
02029 }
02030 
02031 void fieldListType::serialize_fieldlist(SerializerBase *sb, const char *tag) THROW_SPEC(SerializerError)
02032 {
02033     bool have_derived_field_list = (NULL != derivedFieldList);
02034    ifxml_start_element(sb, tag);
02035    gtranslate(sb, fieldList, "fieldList", "field");
02036    gtranslate(sb, have_derived_field_list, "haveDerivedFieldList");
02037    if (have_derived_field_list)
02038    {
02039        //  TODO:  this dereference should work transparently
02040        // without requiring a manual realloc here
02041        if (sb->isInput())
02042            derivedFieldList = new std::vector<Field *>();
02043        gtranslate(sb, *derivedFieldList, "derivedFieldList");
02044    }
02045    ifxml_end_element(sb, tag);
02046 }
02047 
02048 void derivedType::serialize_derived(SerializerBase *sb, const char *tag) THROW_SPEC (SerializerError)
02049 {
02050     int t_id = baseType_ ? baseType_->getID() : 0xdeadbeef;
02051     int t_dc = (int) (baseType_ ? baseType_->getDataClass() : dataUnknownType);
02052 
02053     ifxml_start_element(sb, tag);
02054     gtranslate(sb, t_id, "baseTypeID");
02055     gtranslate(sb, t_dc, "baseTypeDC");
02056     ifxml_end_element(sb, tag);
02057     if (sb->isInput())
02058     {
02059         //  save the type lookup for later in case the target type has not yet been
02060         //  deserialized
02061         baseType_ = NULL; // Symtab::type_Error;
02062         typeCollection::addDeferredLookup(t_id, (dataClass) t_dc, &baseType_);
02063     }
02064 }
02065 
02066 void rangedType::serialize_ranged(SerializerBase *sb, const char *tag) THROW_SPEC(SerializerError)
02067 {
02068     ifxml_start_element(sb, tag);
02069     gtranslate(sb, low_, "low");
02070     gtranslate(sb, hi_, "high");
02071     ifxml_end_element(sb, tag);
02072 }
02073 
02074 Serializable *Field::serialize_impl(SerializerBase *sb, const char *tag) THROW_SPEC(SerializerError)
02075 {
02076     unsigned int t_id = type_ ? type_->getID() : 0xdeadbeef;
02077     int t_dc = (int) (type_ ? type_->getDataClass() : dataUnknownType);
02078 
02079     ifxml_start_element(sb, tag);
02080     gtranslate(sb, fieldName_, "fieldName");
02081     gtranslate(sb, t_id, "fieldTypeID");
02082     gtranslate(sb, t_dc, "fieldTypeID");
02083     gtranslate(sb, vis_, visibility2Str, "visibility");
02084     gtranslate(sb, offset_, "offset");
02085     ifxml_end_element(sb, tag);
02086 
02087     if (sb->isInput())
02088     {
02089         type_ = NULL; //Symtab::type_Error;
02090         typeCollection::addDeferredLookup(t_id, (dataClass) t_dc, &type_);
02091     }
02092     return NULL;
02093 }
02094 
02095 Serializable * CBlock::serialize_impl(SerializerBase *sb, const char *tag) THROW_SPEC(SerializerError)
02096 {
02097     std::vector<Offset> f_offsets;
02098     for (unsigned int i = 0; i < functions.size(); ++i)
02099         f_offsets.push_back(functions[i]->getOffset());
02100 
02101     ifxml_start_element(sb, tag);
02102     gtranslate(sb, fieldList, "CBLockFieldList", "CBlockField");
02103     gtranslate(sb, f_offsets, "CBLockFunctionOffsets", "CBlockFuncOffset");
02104     ifxml_end_element(sb, tag);
02105 
02106     if (sb->isInput())
02107         fprintf(stderr, "%s[%d]:  TODO:  need to look up %lu symbols here\n", 
02108             FILE__, __LINE__, (unsigned long) f_offsets.size());
02109 
02110     return NULL;
02111 }
02112 
02113 #else
02114 
02115 Serializable * Type::serialize_impl(SerializerBase *, const char *) THROW_SPEC (SerializerError)
02116 {
02117    return NULL;
02118 }
02119 
02120 void typeEnum::serialize_specific(SerializerBase *) THROW_SPEC(SerializerError)
02121 {
02122 }
02123 
02124 void typePointer::serialize_specific(SerializerBase *) THROW_SPEC(SerializerError)
02125 {
02126 }
02127 
02128 void typeFunction::serialize_specific(SerializerBase *) THROW_SPEC(SerializerError)
02129 {
02130 }
02131 
02132 void typeSubrange::serialize_specific(SerializerBase *) THROW_SPEC(SerializerError)
02133 {
02134 }
02135 
02136 void typeArray::serialize_specific(SerializerBase *) THROW_SPEC(SerializerError)
02137 {
02138 }
02139 
02140 void typeStruct::serialize_specific(SerializerBase *) THROW_SPEC(SerializerError)
02141 {
02142 }
02143 
02144 void typeUnion::serialize_specific(SerializerBase *) THROW_SPEC(SerializerError)
02145 {
02146 }
02147 
02148 void typeScalar::serialize_specific(SerializerBase *) THROW_SPEC(SerializerError)
02149 {
02150 }
02151 
02152 void typeCommon::serialize_specific(SerializerBase *) THROW_SPEC(SerializerError)
02153 {
02154 }
02155 
02156 void typeTypedef::serialize_specific(SerializerBase *) THROW_SPEC(SerializerError)
02157 {
02158 }
02159 
02160 void typeRef::serialize_specific(SerializerBase *) THROW_SPEC(SerializerError)
02161 {
02162 }
02163 
02164 void fieldListType::serialize_fieldlist(SerializerBase *, const char *) THROW_SPEC(SerializerError)
02165 {
02166 }
02167 
02168 void derivedType::serialize_derived(SerializerBase *, const char *) THROW_SPEC (SerializerError)
02169 {
02170 }
02171 
02172 void rangedType::serialize_ranged(SerializerBase *, const char *) THROW_SPEC(SerializerError)
02173 {
02174 }
02175 
02176 Serializable *Field::serialize_impl(SerializerBase *, const char *) THROW_SPEC(SerializerError)
02177 {
02178    return NULL;
02179 }
02180 
02181 Serializable * CBlock::serialize_impl(SerializerBase *, const char *) THROW_SPEC(SerializerError)
02182 {
02183    return NULL;
02184 }
02185 
02186 #endif
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1