Fix warnings from compiling with gcc 4.3.0
[dyninst.git] / symtabAPI / src / Type.C
1 /*
2  * Copyright (c) 1996-2007 Barton P. Miller
3  *
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  *
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  *
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  *
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  *
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
30  */
31                              
32 #include <stdio.h>
33
34 #include "symutil.h"
35 #include "Type.h"
36 #include "Symtab.h"
37 #include "Module.h"
38 #include "Collections.h"
39
40 #include <string.h>
41
42 using namespace Dyninst;
43 using namespace Dyninst::SymtabAPI;
44
45 //#include "collections.h"
46 //#include "debug.h" TODO: We want such behaviour. LATER!
47
48 #if defined(_MSC_VER)
49 #define snprintf _snprintf
50 #endif
51
52 static int findIntrensicType(std::string &name);
53
54 // This is the ID that is decremented for each type a user defines. It is
55 // Global so that every type that the user defines has a unique ID.
56 typeId_t Type::USER_TYPE_ID = -1000;
57
58
59 /* These are the wrappers for constructing a type.  Since we can create
60    types six ways to Sunday, let's do them all in one centralized place. */
61
62
63 Type *Type::createFake(std::string name) {
64    // Creating a fake type without a name is just silly
65    assert(name != "");
66
67    Type *t = new Type(name);
68    t->type_ = dataNullType;
69
70    return t;
71 }
72
73 Type *Type::createPlaceholder(typeId_t ID, std::string name)
74 {
75     return new Type(name ,ID, dataUnknownType);
76 }
77
78 /*
79  * Type::Type
80  *
81  * EMPTY Constructor for type.  
82  * 
83  */
84 Type::Type(std::string name, typeId_t ID, dataClass dataTyp)
85    :ID_(ID), name_(name), size_(sizeof(/*long*/ int)), type_(dataTyp), updatingSize(false), refCount(1), upPtr_(NULL)
86 {
87 }
88
89 Type::Type(std::string name, dataClass dataTyp)
90    :ID_(USER_TYPE_ID--), name_(name), size_(sizeof(/*long*/ int)), type_(dataTyp), updatingSize(false), refCount(1), upPtr_(NULL)
91 {
92 }
93
94 /* type destructor
95  * Basic destructor for proper memory management.
96  */
97 Type::~Type()
98 {
99 }
100
101 const char *Dyninst::SymtabAPI::dataClass2Str(dataClass dc)
102 {
103    switch(dc) {
104       CASE_RETURN_STR(dataEnum);
105       CASE_RETURN_STR(dataPointer);
106       CASE_RETURN_STR(dataFunction);
107       CASE_RETURN_STR(dataSubrange);
108       CASE_RETURN_STR(dataArray);
109       CASE_RETURN_STR(dataStructure);
110       CASE_RETURN_STR(dataUnion);
111       CASE_RETURN_STR(dataCommon);
112       CASE_RETURN_STR(dataScalar);
113       CASE_RETURN_STR(dataTypedef);
114       CASE_RETURN_STR(dataReference);
115       CASE_RETURN_STR(dataUnknownType);
116       CASE_RETURN_STR(dataNullType);
117       CASE_RETURN_STR(dataTypeClass);
118    };
119    return "bad_data_class";
120 }
121
122 const char *visibility2Str(visibility_t v) 
123 {
124    switch(v) {
125       CASE_RETURN_STR(visPrivate);
126       CASE_RETURN_STR(visProtected);
127       CASE_RETURN_STR(visPublic);
128       CASE_RETURN_STR(visUnknown);
129    };
130    return "bad_visibility";
131 }
132 const char *storageClass2Str(storageClass sc) 
133 {
134    switch(sc) {
135       CASE_RETURN_STR(storageAddr);
136       CASE_RETURN_STR(storageReg);
137       CASE_RETURN_STR(storageRegOffset);
138    };
139    return "bad_storage_class";
140 }
141
142 void Type::serialize(SerializerBase *s, const char *)
143 {
144    //  this should no be called directly, but by serialization functions at leaf nodes
145    //  of the c++hierarchy (objects that descent from Type)
146    //ifxml_start_element(s, tag);
147    gtranslate(s, (int &) ID_, "typeid");
148    gtranslate(s, type_, dataClass2Str, "dataClass");
149    gtranslate(s, name_, "name");
150    gtranslate(s, size_, "size");
151    //ifxml_end_element(s, tag);
152 }
153
154 bool Type::operator==(const Type &otype) const 
155 {
156    return (ID_ == otype.ID_ && name_ == otype.name_ && size_== otype.size_ && type_ == otype.type_);
157 }
158
159 unsigned int Type::getSize()
160 {
161    if (!size_) 
162       const_cast<Type *>(this)->updateSize(); 
163    return size_;
164 }
165
166 bool Type::setSize(unsigned int size)
167 {
168    size_ = size;
169    return true;
170 }
171
172 bool Type::setUpPtr(void *upPtr){
173    upPtr_ = upPtr;
174    return true;
175 }
176
177 void *Type::getUpPtr() const{
178    return upPtr_;
179 }
180
181
182 void Type::incrRefCount() {
183    ++refCount;
184 }
185
186
187 void Type::decrRefCount() {
188     assert(refCount > 0);
189     if (!--refCount)
190         delete this;
191 }
192
193 std::string &Type::getName(){
194     return name_;
195 }
196
197 bool Type::setName(std::string name){
198     name_ = std::string(name);
199     return true;
200 }
201
202 typeId_t Type::getID() const
203 {
204     return ID_;
205 }
206
207 dataClass Type::getDataClass() const
208 {
209     return type_;
210 }
211
212 void Type::fixupUnknowns(Module *){
213 }
214
215 typeEnum *Type::getEnumType(){
216     return dynamic_cast<typeEnum *>(this);
217 }
218
219 typePointer *Type::getPointerType(){
220     return dynamic_cast<typePointer *>(this);
221 }
222  
223 typeFunction *Type::getFunctionType(){
224     return dynamic_cast<typeFunction *>(this);
225 }
226  
227 typeSubrange *Type::getSubrangeType(){
228     return dynamic_cast<typeSubrange *>(this);
229 }
230            
231 typeArray *Type::getArrayType(){
232     return dynamic_cast<typeArray *>(this);
233 }
234
235 typeStruct *Type::getStructType(){
236     return dynamic_cast<typeStruct *>(this);
237 }
238
239 typeUnion *Type::getUnionType(){
240     return dynamic_cast<typeUnion *>(this);
241 }
242
243 typeScalar *Type::getScalarType(){
244     return dynamic_cast<typeScalar *>(this);
245 }
246
247 typeCommon *Type::getCommonType(){
248     return dynamic_cast<typeCommon *>(this);
249 }
250
251 typeTypedef *Type::getTypedefType(){
252     return dynamic_cast<typeTypedef *>(this);
253 }
254         
255 typeRef *Type::getRefType(){
256     return dynamic_cast<typeRef *>(this);
257 }
258
259 bool Type::isCompatible(Type * /*oType*/){
260    return true;
261 }
262
263 /*
264  * ENUM
265  */
266 typeEnum::typeEnum(int ID, std::string name)
267     : Type(name, ID, dataEnum)
268 {
269    size_ = sizeof(int);
270 }
271
272 typeEnum::typeEnum(std::string name)
273    : Type(name, USER_TYPE_ID--, dataEnum)
274 {
275    size_ = sizeof(int);
276 }
277
278 typeEnum *typeEnum::create(std::string &name, std::vector< std::pair<std::string, int> *> &constants, Symtab *obj)
279 {
280    typeEnum *typ = new typeEnum(name);
281    for(unsigned i=0; i<constants.size();i++)
282         typ->addConstant(constants[i]->first, constants[i]->second);
283     
284     if(obj)
285        obj->addType(typ);
286     //obj->addType(typ); TODO: declare a static container if obj is NULL and add to it.
287     //Symtab::noObjTypes->push_back(typ); ??
288     return typ; 
289 }
290
291 typeEnum *typeEnum::create(std::string &name, std::vector<std::string> &constNames, Symtab *obj)
292 {
293    typeEnum *typ = new typeEnum(name);
294    for(unsigned i=0; i<constNames.size();i++)
295         typ->addConstant(constNames[i], i);
296     if(obj)
297        obj->addType(typ);
298     //obj->addType(typ); TODO: declare a static container if obj is NULL and add to it.
299     //Symtab::noObjTypes->push_back(typ); ??
300     return typ; 
301 }       
302
303 std::vector<std::pair<std::string, int> *> &typeEnum::getConstants()
304 {
305    return consts;
306 }
307
308 bool typeEnum::addConstant(const std::string &constName, int value){
309    consts.push_back(new std::pair<std::string, int>(constName, value));
310    return true;
311 }
312
313 bool typeEnum::isCompatible(Type *otype) {
314    if((otype->getDataClass() == dataUnknownType) || (otype->getDataClass() == dataNullType))
315        return true;
316    typeTypedef *otypedef = dynamic_cast<typeTypedef *>(otype);
317    if (otypedef != NULL) return isCompatible(otypedef->getConstituentType());
318
319    typeEnum *oEnumtype = dynamic_cast<typeEnum *>(otype);
320
321    if (oEnumtype == NULL)
322       return false;
323       
324    if( (name_ != "") &&( oEnumtype->name_ != "") && (name_ == oEnumtype->name_) && (ID_ == oEnumtype->ID_))
325       return true;
326    
327    const std::vector< std::pair<std::string, int> *> fields1 = this->getConstants();
328    const std::vector< std::pair<std::string, int> *> fields2 = oEnumtype->getConstants();
329    
330    if( fields1.size() != fields2.size()) {
331       //reportError(BPatchWarning, 112, "enumerated type mismatch ");
332       return false;
333    }
334    
335    //need to compare componment by component to verify compatibility
336    for(unsigned int i=0;i<fields1.size();i++){
337       std::pair<std::string, int> *field1 = fields1[i];
338       std::pair<std::string, int> *field2 = fields2[i];
339       if( (field1->second != field2->second) ||
340           (field1->first != field2->first))
341       {
342          // reportError(BPatchWarning, 112, "enum element mismatch ");
343          return false;
344       } 
345    }
346    // Everything matched so they are the same
347    return true;
348 }
349
350 /* 
351  * POINTER
352  */
353
354 typePointer::typePointer(int ID, Type *ptr, std::string name) 
355    : derivedType(name, ID, 0, dataPointer) {
356    size_ = sizeof(void *);
357    if (ptr)
358      setPtr(ptr);
359 }
360
361 typePointer::typePointer(Type *ptr, std::string name) 
362    : derivedType(name, USER_TYPE_ID--, 0, dataPointer) {
363    size_ = sizeof(void *);
364    if (ptr)
365      setPtr(ptr);
366 }
367
368 typePointer *typePointer::create(std::string &name, Type *ptr, Symtab *obj)
369 {
370    if(!ptr)
371         return NULL;
372    typePointer *typ = new typePointer(ptr, name);
373
374    if(obj)
375         obj->addType(typ);
376    //obj->addType(typ); TODO: declare a static container if obj is NULL and add to it.
377    //Symtab::noObjTypes->push_back(typ); ??
378                                    
379    return typ;  
380 }
381
382 typePointer *typePointer::create(std::string &name, Type *ptr, int size, Symtab *obj)
383 {
384    if(!ptr)
385         return NULL;
386    typePointer *typ = new typePointer(ptr, name);
387    typ->setSize(size);
388
389    if(obj)
390         obj->addType(typ);
391    //obj->addType(typ); TODO: declare a static container if obj is NULL and add to it.
392    //Symtab::noObjTypes->push_back(typ); ??
393                                    
394    return typ;  
395 }
396
397 bool typePointer::setPtr(Type *ptr) { 
398   assert(ptr);
399   baseType_ = ptr; 
400   baseType_->incrRefCount(); 
401
402   if (name_ == "" && ptr->getName() != "") {
403      name_ = std::string(ptr->getName())+" *";
404   }
405   return true;
406 }
407
408 bool typePointer::isCompatible(Type *otype) {
409    if((otype->getDataClass() == dataUnknownType) || (otype->getDataClass() == dataNullType))
410        return true;
411    typeTypedef *otypedef = dynamic_cast<typeTypedef *>(otype);
412    if (otypedef != NULL) return isCompatible(otypedef->getConstituentType());
413
414    typePointer *oPointertype = dynamic_cast<typePointer *>(otype);
415
416    if (oPointertype == NULL) {
417       //reportError(BPatchWarning, 112, 
418       //                   "Pointer and non-Pointer are not type compatible");
419       return false;
420    }
421    // verify type that each one points to is compatible
422    return baseType_->isCompatible(oPointertype->baseType_);
423 }
424
425 void typePointer::fixupUnknowns(Module *module) {
426    if (baseType_->getDataClass() == dataUnknownType) {
427       Type *optr = baseType_;
428       baseType_ = module->getModuleTypes()->findType(baseType_->getID());
429       baseType_->incrRefCount();
430       optr->decrRefCount();
431    }
432 }
433
434 /*
435  * FUNCTION
436  */
437
438 typeFunction::typeFunction(typeId_t ID, Type *retType, std::string name)
439    : Type(name, ID, dataFunction), retType_(retType) {
440    size_ = sizeof(void *);
441    if (retType)
442      retType->incrRefCount();
443 }
444
445 typeFunction::typeFunction(Type *retType, std::string name)
446    : Type(name, USER_TYPE_ID--, dataFunction), retType_(retType) {
447    size_ = sizeof(void *);
448    if (retType)
449      retType->incrRefCount();
450 }
451
452 typeFunction *typeFunction::create(std::string &name, Type *retType, std::vector<Type *> &paramTypes, Symtab *obj)
453 {
454     typeFunction *type = new typeFunction(retType, name);
455     for(unsigned i=0;i<paramTypes.size();i++)
456         type->addParam(paramTypes[i]);
457     if(obj)
458         obj->addType(type);
459     //obj->addType(type); TODO: declare a static container if obj is NULL and add to it.
460     //Symtab::noObjTypes->push_back(type); ??
461     return type;
462 }
463
464 Type *typeFunction::getReturnType() const{
465     return retType_;
466 }
467
468 bool typeFunction::setRetType(Type *rtype) {
469         if(retType_)
470                 retType_->decrRefCount();
471     retType_ = rtype;
472     retType_->incrRefCount();
473     return true;
474 }
475
476 bool typeFunction::addParam(Type *paramType){
477     paramType->incrRefCount();
478     params_.push_back(paramType);
479     return true;
480 }
481
482 std::vector<Type *> &typeFunction::getParams(){
483     return params_;
484 }
485
486 bool typeFunction::isCompatible(Type *otype) {
487    if((otype->getDataClass() == dataUnknownType) || (otype->getDataClass() == dataNullType))
488        return true;
489    typeTypedef *otypedef = dynamic_cast<typeTypedef *>(otype);
490    if (otypedef != NULL) return isCompatible(otypedef->getConstituentType());
491
492    typeFunction *oFunctiontype = dynamic_cast<typeFunction *>(otype);
493
494    if (oFunctiontype == NULL)
495       return false;
496
497    if (retType_ != oFunctiontype->retType_)
498       return false;
499
500    std::vector<Type *> fields1 = this->getParams();
501    std::vector<Type *> fields2 = oFunctiontype->getParams();
502    //const std::vector<Field *> * fields2 = (std::vector<Field *> *) &(otype->fieldList);
503    
504    if (fields1.size() != fields2.size()) {
505       //reportError(BPatchWarning, 112, 
506       //                   "function number of params mismatch ");
507       return false;
508    }
509     
510    //need to compare componment by component to verify compatibility
511    for (unsigned int i=0;i<fields1.size();i++) {
512       Type * ftype1 = fields1[i];
513       Type * ftype2 = fields2[i];
514       
515       if(!(ftype1->isCompatible(ftype2))) {
516          //reportError(BPatchWarning, 112, 
517          //                   "function param type mismatch ");
518          return false;
519       }
520    }
521    return true;
522 }   
523
524 void typeFunction::fixupUnknowns(Module *module) {
525    if (retType_->getDataClass() == dataUnknownType) {
526       Type *otype = retType_;
527       retType_ = module->getModuleTypes()->findType(retType_->getID());
528       retType_->incrRefCount();
529       otype->decrRefCount();
530    }
531    for (unsigned int i = 0; i < params_.size(); i++)
532    {
533       Type *otype = params_[i];
534       params_[i] = module->getModuleTypes()->findType(params_[i]->getID());
535       params_[i]->incrRefCount();
536       otype->decrRefCount();
537    }     
538 }
539
540 typeFunction::~typeFunction()
541
542         retType_->decrRefCount(); 
543 }
544
545 /*
546  * RANGE
547  */
548
549 //typeSubRange::typeSubRange(int ID, int size, const char *_low, const char *_hi, const char *_name)
550 //   : rangedType(_name, _ID, BPatchSymTypeRange, _size, _low, _hi) 
551 //{
552 //}
553
554 typeSubrange::typeSubrange(typeId_t ID, int size, int low, int hi, std::string name)
555   : rangedType(name, ID, dataSubrange, size, low, hi)
556 {
557 }
558
559 typeSubrange::typeSubrange(int size, int low, int hi, std::string name)
560   : rangedType(name, USER_TYPE_ID--, dataSubrange, size, low, hi)
561 {
562 }
563
564 typeSubrange *typeSubrange::create(std::string &name, int size, int low, int hi, Symtab *obj)
565 {
566    typeSubrange *typ = new typeSubrange(size, low, hi, name);
567
568    if(obj)
569        obj->addType(typ);
570    return typ;
571 }
572
573 bool typeSubrange::isCompatible(Type *otype) {
574    if((otype->getDataClass() == dataUnknownType) || (otype->getDataClass() == dataNullType))
575        return true;
576    typeTypedef *otypedef = dynamic_cast<typeTypedef *>(otype);
577    if (otypedef != NULL) return isCompatible(otypedef->getConstituentType());
578
579    typeSubrange *oRangetype = dynamic_cast<typeSubrange *>(otype);
580
581    if (oRangetype == NULL)
582       return false;
583
584    return getSize() == oRangetype->getSize();
585 }
586
587 /*
588  * ARRAY
589  */
590
591 typeArray::typeArray(typeId_t ID,
592                                    Type *base,
593                                    int low,
594                                    int hi,
595                                    std::string name,
596                                    unsigned int sizeHint)
597    : rangedType(name, ID, dataArray, 0, low, hi), arrayElem(base), sizeHint_(sizeHint) {
598    assert(base != NULL);
599    arrayElem->incrRefCount();
600 }
601
602 typeArray::typeArray(Type *base,
603                                    int low,
604                                    int hi,
605                                    std::string name,
606                                    unsigned int sizeHint)
607    : rangedType(name, USER_TYPE_ID--, dataArray, 0, low, hi), arrayElem(base), sizeHint_(sizeHint) {
608    assert(base != NULL);
609    arrayElem->incrRefCount();
610 }
611
612 typeArray *typeArray::create(std::string &name, Type *type, int low, int hi, Symtab *obj){
613    typeArray *typ = new typeArray(type, low, hi, name);
614    
615    if(obj)
616         obj->addType(typ);
617                                    
618    return typ;  
619 }
620
621 bool typeArray::operator==(const Type &otype) const {
622    try {
623       const typeArray &oArraytype = dynamic_cast<const typeArray &>(otype);
624       return (rangedType::operator==(otype) && 
625               (*arrayElem)==*oArraytype.arrayElem);
626    } catch (...) {
627       return false;
628    }
629 }
630
631 void typeArray::merge(Type *other) {
632    // There are wierd cases where we may define an array with an element
633    // that is a forward reference
634    
635            typeArray *otherarray = dynamic_cast<typeArray *>(other);
636
637    if ( otherarray == NULL || this->ID_ != otherarray->ID_ || 
638         this->arrayElem->getDataClass() != dataUnknownType) {
639       //bperr( "Ignoring attempt to merge dissimilar types.\n" );
640       return;
641    }
642
643    arrayElem->decrRefCount();
644    otherarray->arrayElem->incrRefCount();
645    arrayElem = otherarray->arrayElem;
646 }
647
648 Type *typeArray::getBaseType() const{
649     return arrayElem;
650 }
651
652 void typeArray::updateSize()
653 {    
654    if (updatingSize) {
655       size_ = 0;
656       return;
657    }
658    updatingSize = true;
659     // Is our array element's Type still a placeholder?
660     if(arrayElem->getDataClass() == dataUnknownType)
661         size_ = 0;
662     
663     // Otherwise we can now calculate the array type's size
664     else {
665
666         // Calculate the size of a single element
667         unsigned int elemSize = sizeHint_ ? sizeHint_ : arrayElem->getSize();
668         
669         // Calculate the size of the whole array
670         size_ = elemSize * (hi_ ? hi_ - low_ + 1 : 1);
671         
672     }
673    updatingSize = false;
674 }
675
676 bool typeArray::isCompatible(Type *otype) {
677    if((otype->getDataClass() == dataUnknownType) || (otype->getDataClass() == dataNullType))
678        return true;
679    typeTypedef *otypedef = dynamic_cast<typeTypedef *>(otype);
680    if (otypedef != NULL) return isCompatible(otypedef->getConstituentType());
681
682    typeArray *oArraytype = dynamic_cast<typeArray *>(otype);
683
684    if (oArraytype == NULL) {
685       //reportError(BPatchWarning, 112, 
686       //                   "Array and non-array are not type compatible");
687       return false;      
688    }
689    unsigned int ec1, ec2;
690
691    ec1 = hi_ - low_ + 1;
692    ec2 = oArraytype->hi_ - oArraytype->low_ + 1;
693    if (ec1 != ec2) {
694       char message[80];
695       sprintf(message, "Incompatible number of elements [%d..%d] vs. [%d..%d]",
696               this->low_, this->hi_, oArraytype->low_, oArraytype->hi_);
697       //reportError(BPatchWarning, 112, message);
698       return false;
699    }
700    return arrayElem->isCompatible(oArraytype->arrayElem);
701 }
702
703 void typeArray::fixupUnknowns(Module *module) {
704    if (arrayElem->getDataClass() == dataUnknownType) {
705       Type *otype = arrayElem;
706       arrayElem = module->getModuleTypes()->findType(arrayElem->getID());
707       arrayElem->incrRefCount();
708       otype->decrRefCount();
709    }
710 }
711
712 /*
713  * STRUCT
714  */
715
716 typeStruct::typeStruct(typeId_t ID, std::string name) 
717    : fieldListType(name, ID, dataStructure) 
718
719 }
720
721 typeStruct::typeStruct(std::string name) 
722    : fieldListType(name, USER_TYPE_ID--, dataStructure) 
723 {
724 }
725
726 typeStruct *typeStruct::create(std::string &name, std::vector< std::pair<std::string, Type *> *> &flds,
727                                                                 Symtab *obj)
728 {
729    int offset = 0;
730    typeStruct *typ = new typeStruct(name);
731    for(unsigned i=0;i<flds.size();i++)
732    {
733            typ->addField(flds[i]->first, flds[i]->second, offset);
734        // Calculate next offset (in bits) into the struct
735        offset += (flds[i]->second->getSize() * 8);
736    }
737    if(obj)
738         obj->addType(typ);
739    //obj->addType(typ); TODO: declare a static container if obj is NULL and add to it.
740    //Symtab::noObjTypes->push_back(typ); ??
741                                    
742    return typ;  
743 }
744
745 typeStruct *typeStruct::create(std::string &name, std::vector<Field *> &flds, Symtab *obj)
746 {
747    typeStruct *typ = new typeStruct(name);
748    for(unsigned i=0;i<flds.size();i++)
749         typ->addField(flds[i]);
750    if(obj)
751         obj->addType(typ);
752    //obj->addType(typ); TODO: declare a static container if obj is NULL and add to it.
753    //Symtab::noObjTypes->push_back(typ); ??
754                                    
755    return typ;  
756 }
757
758 void typeStruct::merge(Type *other) {
759    // Merging is only for forward references
760 //   assert(!fieldList.size());
761
762    typeStruct *otherstruct = dynamic_cast<typeStruct *>(other);
763
764    if( otherstruct == NULL || this->ID_ != otherstruct->ID_) {
765       //bperr( "Ignoring attempt to merge dissimilar types.\n" );
766       return;
767    }
768
769    if (otherstruct->name_ != "")
770       name_ = std::string(otherstruct->name_);
771    size_ = otherstruct->size_;
772
773    fieldList = otherstruct->fieldList;
774
775    if (otherstruct->derivedFieldList) {
776       derivedFieldList = new std::vector<Field *>;
777       *derivedFieldList = *otherstruct->derivedFieldList;
778    }
779 }
780
781 void typeStruct::updateSize()
782 {
783    if (updatingSize) {
784       size_ = 0;
785       return;
786    }
787    updatingSize = true;
788
789     // Calculate the size of the entire structure
790     size_ = 0;
791     for(unsigned int i = 0; i < fieldList.size(); ++i) {
792         size_ += fieldList[i]->getSize();
793
794         // Is the type of this field still a placeholder?
795         if(fieldList[i]->getType()->getDataClass() == dataUnknownType) {
796             size_ = 0;
797          break;
798         }
799     }
800    updatingSize = false;
801 }
802
803 void typeStruct::postFieldInsert(int nsize) { 
804         size_ += nsize; 
805 }
806
807 bool typeStruct::isCompatible(Type *otype) 
808 {
809    if((otype->getDataClass() == dataUnknownType) || (otype->getDataClass() == dataNullType))
810        return true;
811    typeTypedef *otypedef = dynamic_cast<typeTypedef *>(otype);
812    if (otypedef != NULL) return isCompatible(otypedef->getConstituentType());
813
814    typeStruct *oStructtype = dynamic_cast<typeStruct *>(otype);
815
816    if (oStructtype == NULL)
817       return false;
818
819    const std::vector<Field *> * fields1 = this->getComponents();
820    const std::vector<Field *> * fields2 = oStructtype->getComponents();
821    //const std::vector<Field *> * fields2 = (std::vector<Field *> *) &(otype->fieldList);
822    
823    if (fields1->size() != fields2->size()) {
824       //reportError(BPatchWarning, 112, 
825       //                   "struct/union numer of elements mismatch ");
826       return false;
827    }
828     
829    //need to compare componment by component to verify compatibility
830    for (unsigned int i=0;i<fields1->size();i++) {
831       Field * field1 = (*fields1)[i];
832       Field * field2 = (*fields2)[i];
833       
834       Type * ftype1 = (Type *)field1->getType();
835       Type * ftype2 = (Type *)field2->getType();
836       
837       if(!(ftype1->isCompatible(ftype2))) {
838          //reportError(BPatchWarning, 112, 
839          //                   "struct/union field type mismatch ");
840          return false;
841       }
842    }
843    return true;
844 }
845
846 void typeStruct::fixupUnknowns(Module *module) {
847    for (unsigned int i = 0; i < fieldList.size(); i++)
848       fieldList[i]->fixupUnknown(module);
849 }
850
851 /*
852  * UNION
853  */
854
855 typeUnion::typeUnion(typeId_t ID, std::string name) 
856    : fieldListType(name, ID, dataUnion) 
857
858 }
859
860 typeUnion::typeUnion(std::string name) 
861    : fieldListType(name, USER_TYPE_ID--, dataUnion) 
862 {
863 }
864
865 typeUnion *typeUnion::create(std::string &name, std::vector< std::pair<std::string, Type *> *> &flds,
866                                                                 Symtab *obj)
867 {
868    typeUnion *typ = new typeUnion(name);
869    for(unsigned i=0;i<flds.size();i++)
870         typ->addField(flds[i]->first, flds[i]->second, 0);
871    if(obj)
872         obj->addType(typ);
873    //obj->addType(typ); TODO: declare a static container if obj is NULL and add to it.
874    //Symtab::noObjTypes->push_back(typ); ??
875                                    
876    return typ;  
877 }
878
879 typeUnion *typeUnion::create(std::string &name, std::vector<Field *> &flds, Symtab *obj)
880 {
881    typeUnion *typ = new typeUnion(name);
882    for(unsigned i=0;i<flds.size();i++)
883         typ->addField(flds[i]);
884    if(obj)
885         obj->addType(typ);
886    //obj->addType(typ); TODO: declare a static container if obj is NULL and add to it.
887    //Symtab::noObjTypes->push_back(typ); ??
888                                    
889    return typ;  
890 }
891
892 void typeUnion::merge(Type *other) {
893    // Merging is only for forward references
894    assert(!fieldList.size());
895
896    typeUnion *otherunion = dynamic_cast<typeUnion *>(other);
897
898    if( otherunion == NULL || this->ID_ != otherunion->ID_) {
899       //bperr( "Ignoring attempt to merge dissimilar types.\n" );
900       return;
901    }
902
903    if (otherunion->name_ != "")
904       name_ = std::string(otherunion->name_);
905    size_ = otherunion->size_;
906
907    fieldList = otherunion->fieldList;
908
909    if (otherunion->derivedFieldList) {
910       derivedFieldList = new std::vector<Field *>;
911       *derivedFieldList = *otherunion->derivedFieldList;
912    }
913 }
914
915 void typeUnion::updateSize()
916 {
917    if (updatingSize) {
918       size_ = 0;
919       return;
920    }
921    updatingSize = true;
922
923     // Calculate the size of the union
924     size_ = 0;
925     for(unsigned int i = 0; i < fieldList.size(); ++i) {
926         if(fieldList[i]->getSize() > size_)
927             size_ = fieldList[i]->getSize();
928
929         // Is the type of this field still a placeholder?
930         if(fieldList[i]->getType()->getDataClass() == dataUnknownType) {
931             size_ = 0;
932          break;
933         }
934     }
935    updatingSize = false;
936 }
937
938 void typeUnion::postFieldInsert(int nsize) {
939         if ((unsigned int) nsize > size_) size_ = nsize; 
940 }
941
942 bool typeUnion::isCompatible(Type *otype) {
943    if((otype->getDataClass() == dataUnknownType) || (otype->getDataClass() == dataNullType))
944        return true;
945    typeTypedef *otypedef = dynamic_cast<typeTypedef *>(otype);
946    if (otypedef != NULL) return isCompatible(otypedef->getConstituentType());
947
948    typeUnion *oUniontype = dynamic_cast<typeUnion *>(otype);
949
950    if (oUniontype == NULL)
951       return false;
952
953    const std::vector<Field *> * fields1 = this->getComponents();
954    const std::vector<Field *> * fields2 = oUniontype->getComponents();
955    //const std::vector<Field *> * fields2 = (std::vector<Field *> *) &(otype->fieldList);
956    
957    if (fields1->size() != fields2->size()) {
958       //reportError(BPatchWarning, 112, 
959       //                   "struct/union numer of elements mismatch ");
960       return false;
961    }
962     
963    //need to compare componment by component to verify compatibility
964    for (unsigned int i=0;i<fields1->size();i++) {
965       Field * field1 = (*fields1)[i];
966       Field * field2 = (*fields2)[i];
967       
968       Type * ftype1 = (Type *)field1->getType();
969       Type * ftype2 = (Type *)field2->getType();
970       
971       if(!(ftype1->isCompatible(ftype2))) {
972          //reportError(BPatchWarning, 112, 
973          //                   "struct/union field type mismatch ");
974          return false;
975       }
976    }
977    return true;
978 }
979
980 void typeUnion::fixupUnknowns(Module *module) {
981    for (unsigned int i = 0; i < fieldList.size(); i++)
982       fieldList[i]->fixupUnknown(module);
983 }
984
985 /*
986  * SCALAR
987  */
988
989    
990 typeScalar::typeScalar(typeId_t ID, unsigned int size, std::string name, bool isSigned)
991    : Type(name, ID, dataScalar), isSigned_(isSigned) {
992    size_ = size;
993 }
994
995 typeScalar::typeScalar(unsigned int size, std::string name, bool isSigned)
996    : Type(name, USER_TYPE_ID--, dataScalar), isSigned_(isSigned) {
997    size_ = size;
998 }
999
1000 typeScalar *typeScalar::create(std::string &name, int size, Symtab *obj){
1001    typeScalar *typ = new typeScalar(size, name);
1002    
1003    if(obj)
1004         obj->addType(typ);
1005    //obj->addType(typ); TODO: declare a static container if obj is NULL and add to it.
1006    //Symtab::noObjTypes->push_back(typ); ??
1007                                    
1008    return typ;  
1009 }
1010
1011 bool typeScalar::isSigned(){
1012     return isSigned_;
1013 }
1014
1015 bool typeScalar::isCompatible(Type *otype) {
1016    if((otype->getDataClass() == dataUnknownType) || (otype->getDataClass() == dataNullType))
1017        return true;
1018    bool ret = false;
1019    const typeTypedef *otypedef = dynamic_cast<const typeTypedef *>(otype);
1020    if (otypedef != NULL)  {
1021       ret =  isCompatible(otypedef->getConstituentType());
1022       return ret;
1023    }
1024
1025    typeScalar *oScalartype = dynamic_cast<typeScalar *>(otype);
1026    if (oScalartype == NULL) {
1027       //  Check to see if we have a range type, which can be compatible.
1028       typeSubrange *oSubrangeType = dynamic_cast<typeSubrange *>(otype);
1029       if (oSubrangeType != NULL) {
1030         if ( name_ == "" || oSubrangeType->getName() == "")
1031            return size_ == oSubrangeType->getSize();
1032         else if (name_ == oSubrangeType->getName())
1033            return size_ == oSubrangeType->getSize();
1034         else if (size_ == oSubrangeType->getSize()) {
1035           int t1 = findIntrensicType(name_);
1036           int t2 = findIntrensicType(oSubrangeType->getName());
1037           if (t1 & t2 & (t1 == t2)) {
1038             return true;
1039           }
1040         }
1041       }
1042       return false;
1043    }
1044
1045    if ( name_ == "" || oScalartype->name_ == "")
1046       return size_ == oScalartype->size_;
1047    else if (name_ == oScalartype->name_)
1048       return size_ == oScalartype->size_;
1049    else if (size_ == oScalartype->size_) {
1050       int t1 = findIntrensicType(name_);
1051       int t2 = findIntrensicType(oScalartype->name_);
1052       if (t1 & t2 & (t1 == t2)) {
1053          return true;
1054       }
1055    }
1056    return false;
1057 }
1058
1059 /* 
1060  * COMMON BLOCK
1061  */
1062
1063 typeCommon::typeCommon(int ID, std::string name) 
1064    : fieldListType(name, ID, dataCommon) {}
1065
1066 typeCommon::typeCommon(std::string name) 
1067    : fieldListType(name, USER_TYPE_ID--, dataCommon) {}
1068
1069 void typeCommon::beginCommonBlock() {
1070     std::vector<Field*> emptyList;
1071
1072     // null out field list
1073     fieldList = emptyList;
1074 }
1075
1076 void typeCommon::endCommonBlock(Symbol *func, void *baseAddr) {
1077     unsigned int i, j;
1078
1079     // create local variables in func's scope for each field of common block
1080     for (j=0; j < fieldList.size(); j++) {
1081
1082             localVar *locVar;
1083         locVar = new localVar(fieldList[j]->getName(), 
1084                                              fieldList[j]->getType(), "", 0);
1085         loc_t *loc = (loc_t *)malloc(sizeof(loc_t));
1086         loc->stClass = storageAddr;
1087         loc->refClass = storageNoRef;
1088         loc->reg = -1;    
1089         loc->frameOffset = fieldList[j]->getOffset()+(Offset) baseAddr;
1090         locVar->addLocation(loc);
1091
1092         // localVar->addField() TODO????
1093         //fieldList[j]->getOffset()+(Offset) baseAddr, -1, storageAddr);
1094         
1095         if (!func->addLocalVar(locVar) )
1096         {
1097            fprintf(stderr, "%s[%d]:  FIXME\n", FILE__, __LINE__);
1098         }
1099     }
1100
1101     // look to see if the field list matches an existing block
1102     for (i=0; i < cblocks.size(); i++) {
1103         CBlock *curr = cblocks[i];
1104         for (j=0; j < fieldList.size(); j++) {
1105             if ((fieldList[j]->getName() == curr->fieldList[j]->getName()) ||
1106                 (fieldList[j]->getOffset() !=curr->fieldList[j]->getOffset()) ||
1107                 (fieldList[j]->getSize() != curr->fieldList[j]->getSize())) {
1108                 break; // no match
1109             }
1110         }
1111         if (j == fieldList.size() && (j == curr->fieldList.size())) {
1112             // match
1113             curr->functions.push_back(func);
1114             return;
1115         }
1116     }
1117
1118     // this one is unique
1119     CBlock *newBlock = new CBlock();
1120     newBlock->fieldList = fieldList;
1121     newBlock->functions.push_back(func);
1122     cblocks.push_back(newBlock);
1123 }
1124
1125 void typeCommon::fixupUnknowns(Module *module) {
1126    for (unsigned int i = 0; i < cblocks.size(); i++)
1127       cblocks[i]->fixupUnknowns(module);   
1128 }
1129
1130 std::vector<CBlock *> *typeCommon::getCblocks() const { 
1131         return const_cast<std::vector<CBlock*>*>(&cblocks); 
1132 }
1133
1134 /*
1135  * TYPEDEF
1136  */
1137
1138 typeTypedef::typeTypedef(typeId_t ID, Type *base, std::string name, unsigned int sizeHint) 
1139    : derivedType(name, ID, 0, dataTypedef) {
1140    assert(base != NULL);
1141    baseType_ = base;
1142    sizeHint_ = sizeHint / 8;
1143    baseType_->incrRefCount();
1144 }
1145
1146 typeTypedef::typeTypedef(Type *base, std::string name, unsigned int sizeHint) 
1147    : derivedType(name, USER_TYPE_ID--, 0, dataTypedef) {
1148    assert(base != NULL);
1149    baseType_ = base;
1150    sizeHint_ = sizeHint / 8;
1151    baseType_->incrRefCount();
1152 }
1153
1154 typeTypedef *typeTypedef::create(std::string &name, Type *baseType, Symtab *obj)
1155 {
1156    if(!baseType)
1157         return NULL;
1158    typeTypedef *typ = new typeTypedef(baseType, name);
1159
1160    if(obj)
1161         obj->addType(typ);
1162    //obj->addType(typ); TODO: declare a static container if obj is NULL and add to it.
1163    //Symtab::noObjTypes->push_back(typ); ??
1164                                    
1165    return typ;  
1166 }
1167
1168 bool typeTypedef::operator==(const Type &otype) const {
1169    try {
1170       const typeTypedef &oDeftype = dynamic_cast<const typeTypedef &>(otype);
1171       return baseType_==oDeftype.baseType_;
1172    } catch (...) {
1173       return false;
1174    }
1175 }
1176
1177 bool typeTypedef::isCompatible(Type *otype){
1178     return baseType_->isCompatible(otype);
1179 }
1180
1181 void typeTypedef::updateSize()
1182 {
1183    if (updatingSize) {
1184       size_ = 0;
1185       return;
1186    }
1187    updatingSize = true;
1188
1189     // Is our base type still a placeholder?
1190     if(baseType_->getDataClass() == dataUnknownType)
1191         size_ = 0;
1192
1193     // Otherwise we can now calculate the type definition's size
1194     else {
1195         // Calculate the size of the type definition
1196         size_ = sizeHint_ ? sizeHint_ : baseType_->getSize();
1197     }
1198    updatingSize = false;
1199 }
1200
1201 void typeTypedef::fixupUnknowns(Module *module) {
1202    if (baseType_->getDataClass() == dataUnknownType) {
1203       Type *otype = baseType_;
1204       baseType_ = module->getModuleTypes()->findType(baseType_->getID());
1205       baseType_->incrRefCount();
1206       otype->decrRefCount();
1207    }
1208 }
1209
1210 /*
1211  * REFERENCE
1212  */
1213
1214 typeRef::typeRef(int ID, Type *refType, std::string name)
1215    : derivedType(name, ID, 0, dataReference) {
1216    baseType_ = refType;
1217    if(refType)
1218         refType->incrRefCount();
1219 }
1220
1221 typeRef::typeRef(Type *refType, std::string name)
1222    : derivedType(name, USER_TYPE_ID--, 0, dataReference) {
1223    baseType_ = refType;
1224    if(refType)
1225         refType->incrRefCount();
1226 }
1227
1228 typeRef *typeRef::create(std::string &name, Type *ref, Symtab *obj)
1229 {
1230    typeRef *typ = new typeRef(ref, name);
1231
1232    if(obj)
1233         obj->addType(typ);
1234    //obj->addType(typ); TODO: declare a static container if obj is NULL and add to it.
1235    //Symtab::noObjTypes->push_back(typ); ??
1236                                    
1237    return typ;  
1238 }
1239
1240 bool typeRef::operator==(const Type &otype) const {
1241    try {
1242       const typeRef &oReftype = dynamic_cast<const typeRef &>(otype);
1243       return baseType_== oReftype.baseType_;
1244    } catch (...) {
1245       return false;
1246    }
1247 }
1248
1249 bool typeRef::isCompatible(Type *otype) {
1250    if((otype->getDataClass() == dataUnknownType) || (otype->getDataClass() == dataNullType))
1251        return true;
1252    typeTypedef *otypedef = dynamic_cast<typeTypedef *>(otype);
1253    if (otypedef != NULL) return isCompatible(otypedef->getConstituentType());
1254
1255    typeRef *oReftype = dynamic_cast< typeRef *>(otype);
1256    if (oReftype == NULL) {
1257       return false;
1258    }
1259    return baseType_->isCompatible(const_cast<Type *>(oReftype->getConstituentType()));
1260 }   
1261
1262 void typeRef::fixupUnknowns(Module *module) {
1263    if (baseType_->getDataClass() == dataUnknownType) {
1264       Type *otype = baseType_;
1265       baseType_ = module->getModuleTypes()->findType(baseType_->getID());
1266       baseType_->incrRefCount();
1267       otype->decrRefCount();
1268    }
1269 }
1270                       
1271 /* 
1272  * Subclasses of class Type, with interfaces
1273  */
1274
1275 /*
1276  * FIELD LIST Type
1277  */
1278
1279 fieldListType::fieldListType(std::string &name, typeId_t ID, dataClass typeDes)
1280    : Type(name, ID, typeDes), derivedFieldList(NULL)
1281 {   
1282    size_ = 0;
1283 }
1284
1285 fieldListType::~fieldListType() {
1286    if (derivedFieldList != NULL)
1287       delete derivedFieldList;
1288    fieldList.clear();
1289 }
1290
1291 bool fieldListType::operator==(const Type &otype) const {
1292    try {
1293       const fieldListType &oFieldtype = dynamic_cast<const fieldListType &>(otype);
1294       if (fieldList.size() != oFieldtype.fieldList.size())
1295          return false;
1296       for (unsigned int i = 0; i < fieldList.size(); i++) {
1297          if (fieldList[i] != oFieldtype.fieldList[i])
1298             return false;
1299       }
1300       return Type::operator==(otype);
1301    } catch (...) {
1302       return false;
1303    }
1304 }
1305
1306 std::vector<Field *> * fieldListType::getComponents() const 
1307 {
1308    if (derivedFieldList == NULL)
1309        const_cast<fieldListType *>(this)->fixupComponents();
1310    return derivedFieldList;
1311 }
1312
1313 std::vector<Field *> *fieldListType::getFields() const 
1314 {
1315    return const_cast<std::vector<Field *> *>(&fieldList);
1316 }
1317
1318 void fieldListType::fixupComponents() 
1319 {
1320    // bperr "Getting the %d components of '%s' at 0x%x\n", fieldList.size(), getName(), this );
1321    /* Iterate over the field list.  Recursively (replace)
1322       '{superclass}' with the superclass's non-private fields. */
1323    derivedFieldList = new std::vector< Field * >();
1324    for( unsigned int i = 0; i < fieldList.size(); i++ ) {
1325       Field * currentField = fieldList[i];
1326       // bperr( "Considering field '%s'\n", currentField->getName() );
1327       if( currentField->getName() ==  "{superclass}" ) {
1328          /* Note that this is a recursive call.  However, because
1329             the class-graph is acyclic (Stroustrup SpecialEd pg 308),
1330             we're OK. */
1331          // bperr( "Found superclass '%s'...\n", currentField->getType()->getName() );
1332          fieldListInterface *superclass = dynamic_cast<fieldListInterface *>(currentField->getType());
1333          assert (superclass != NULL);
1334          const std::vector<Field *> * superClassFields = superclass->getComponents();
1335          // bperr( "Superclass has %d components.\n", superClassFields->size() );
1336          /* FIXME: do we also need to consider the visibility of the superclass itself? */
1337          /* FIXME: visibility can also be described on a per-name basis in the
1338             subclass.  We have now way to convey this information currently, but I'm not
1339             sure that it matters for our purposes... */
1340          for( unsigned int i = 0; i < superClassFields->size(); i++ ) {
1341             Field * currentSuperField = (*superClassFields)[i];
1342             // bperr( "Considering superfield '%s'\n", currentSuperField->getName() );
1343             if( currentSuperField->getVisibility() != visPrivate ) {
1344                derivedFieldList->push_back( currentSuperField );
1345             }
1346          } /* end super-class iteration */
1347       } /* end if currentField is a superclass */
1348       else {
1349          derivedFieldList->push_back( currentField );
1350       }
1351    } /* end field iteration */
1352 }
1353
1354 /*
1355  * void fieldListType::addField
1356  * Creates field object and adds it to the list of fields for this
1357  * type object.
1358  *     STRUCTS OR UNIONS
1359  */
1360 void fieldListType::addField(std::string fieldname, Type *type, int offsetVal, visibility_t vis)
1361 {
1362   Field * newField;
1363   newField = new Field(fieldname, type, offsetVal, vis);
1364
1365   // Add field to list of struct/union fields
1366   fieldList.push_back(newField);
1367
1368   // API defined structs/union's size are defined on the fly.
1369   postFieldInsert(type->getSize());
1370 }
1371
1372 void fieldListType::addField(Field *fld)
1373 {
1374   Field *newField = new Field(*fld);
1375   // Add field to list of struct/union fields
1376   fieldList.push_back(newField);
1377
1378   // API defined structs/union's size are defined on the fly.
1379   postFieldInsert(newField->getSize());
1380 }
1381
1382 void fieldListType::addField(unsigned num, std::string fieldname, Type *type, int offsetVal, visibility_t vis)
1383 {
1384   Field * newField;
1385   newField = new Field(fieldname, type, offsetVal, vis);
1386
1387   if(num >fieldList.size()+1)
1388         num = fieldList.size();
1389   // Add field to list of struct/union fields
1390   fieldList.insert(fieldList.begin()+num, newField);
1391
1392   // API defined structs/union's size are defined on the fly.
1393   postFieldInsert(type->getSize());
1394 }
1395
1396 void fieldListType::addField(unsigned num, Field *fld)
1397 {
1398   Field *newField = new Field(*fld);
1399   // Add field to list of struct/union fields
1400   if(num >fieldList.size()+1)
1401         num = fieldList.size();
1402   // Add field to list of struct/union fields
1403   fieldList.insert(fieldList.begin()+num, newField);
1404
1405   // API defined structs/union's size are defined on the fly.
1406   postFieldInsert(newField->getSize());
1407 }
1408
1409 //void fieldListType::fixupUnknown(Module *m)
1410 //{
1411 //  type *t = dynamic_cast<Type *>(this);
1412 //  assert(t);
1413 //  t->fixupUnknown(m);
1414   //((Type *)this)->fixupUnknown(m);
1415 //}
1416 /*
1417  * DERIVED
1418  */
1419
1420 derivedType::derivedType(std::string &name, typeId_t id, int size, dataClass typeDes)
1421    :Type(name, id, typeDes)
1422 {
1423    size_ = size;
1424 }
1425
1426 derivedType::derivedType(std::string &name, int size, dataClass typeDes)
1427    :Type(name, USER_TYPE_ID--, typeDes)
1428 {
1429    size_ = size;
1430 }
1431
1432 Type *derivedType::getConstituentType() const
1433 {
1434    return baseType_;
1435 }
1436
1437 bool derivedType::operator==(const Type &otype) const {
1438    try {
1439       //const derivedType &oderivedtype = dynamic_cast<const derivedType &>(otype);
1440       return Type::operator==(otype);
1441    } catch (...) {
1442       return false;
1443    }
1444 }
1445
1446 derivedType::~derivedType()
1447 {
1448    if(baseType_)
1449         baseType_->decrRefCount();
1450 }
1451
1452 /*
1453  * RANGED
1454  */
1455
1456 rangedType::rangedType(std::string &name, typeId_t ID, dataClass typeDes, int size, int low, int hi) 
1457    : Type(name, ID, typeDes), low_(low), hi_(hi) {
1458    size_ = size;
1459 }
1460
1461 rangedType::rangedType(std::string &name, dataClass typeDes, int size, int low, int hi) 
1462    : Type(name, USER_TYPE_ID--, typeDes), low_(low), hi_(hi){
1463    size_ = size;
1464 }
1465
1466 /*
1467 rangedType::rangedType(const char *_name, int _ID, dataClass _class, int _size, const char *_low, const char *_hi) 
1468    : Type(_name, _ID, _class) {
1469
1470    low = strdup(_low);
1471    hi = strdup(_hi);
1472
1473    size = _size;
1474 }
1475 */
1476
1477 rangedType::~rangedType() {
1478 }
1479
1480 bool rangedType::operator==(const Type &otype) const {
1481    try {
1482       const rangedType &oRangedtype = dynamic_cast<const rangedType &>(otype);
1483       return (low_ == oRangedtype.low_ && hi_ == oRangedtype.hi_ &&
1484               Type::operator==(otype));
1485    } catch (...) {
1486       return false;
1487    }
1488 }
1489
1490 //
1491 // Define the type compatability among the intrensic types of the various
1492 //     languages.  For example int in c is compatiable to integer*4 in Fortran.
1493 //     Each equivelence class is given a unique number.
1494 //
1495 struct intrensicTypes_ {
1496     const char *name;
1497     int tid;
1498 };
1499
1500 struct intrensicTypes_ intrensicTypes[] = {
1501     { "int",            1 },
1502     { "integer*4",      1 },
1503     { "INTEGER*4",      1 },
1504     { NULL,             0 },
1505 };
1506
1507 static int findIntrensicType(std::string &name)
1508 {
1509     struct intrensicTypes_ *curr;
1510
1511     for (curr = intrensicTypes; curr->name; curr++) {
1512         if ((name != "")&& curr->name && !strcmp(name.c_str(), curr->name)) {
1513             return curr->tid;
1514         }
1515     }
1516
1517     return 0;
1518 }
1519
1520
1521 /*
1522  * Field::Field
1523  *
1524  * Constructor for Field.  Creates a Field object for 
1525  * an enumerated type.
1526  * type = offset = size = 0;
1527  */
1528 Field::Field(std::string name, Type *typ, int offsetVal, visibility_t vis)
1529    :fieldName_(name), type_(typ), vis_(vis), offset_(offsetVal), upPtr_(NULL)
1530 {
1531     if(typ)
1532         typ->incrRefCount();
1533 }
1534
1535 std::string &Field::getName(){
1536    return fieldName_;
1537 }
1538
1539 Type *Field::getType(){
1540    return type_;
1541 }
1542
1543 visibility_t Field::getVisibility(){
1544    return vis_;
1545 }
1546
1547 int Field::getOffset(){
1548    return offset_;
1549 }
1550
1551 unsigned int Field::getSize(){
1552    return type_->getSize();
1553 }
1554
1555 void *Field::getUpPtr() const{
1556     return upPtr_;
1557 }
1558
1559 bool Field::setUpPtr(void *upPtr) {
1560     upPtr_ = upPtr;
1561     return true;
1562 }
1563
1564 Field::Field(Field &oField) 
1565 {
1566    type_ = oField.type_;
1567    offset_ = oField.offset_;
1568    fieldName_ = std::string(oField.fieldName_);
1569    vis_ = oField.vis_;
1570    upPtr_ = oField.upPtr_;
1571
1572    if (type_ != NULL)
1573       type_->incrRefCount();
1574 }
1575
1576 Field::~Field() 
1577 {
1578    if (type_ != NULL) 
1579       type_->decrRefCount();
1580 }
1581
1582 void Field::fixupUnknown(Module *module) {
1583    if (type_->getDataClass() == dataUnknownType) {
1584       Type *otype = type_;
1585       type_ = module->getModuleTypes()->findType(type_->getID());
1586       type_->incrRefCount();
1587       otype->decrRefCount();
1588    }
1589 }
1590
1591 /**************************************************************************
1592  * localVar
1593  *************************************************************************/
1594 /*
1595  * localVar Constructor
1596  *
1597  */
1598 localVar::localVar(std::string name,  Type *typ, std::string fileName, int lineNum, std::vector<loc_t *>* locs)
1599  :name_(name), type_(typ), fileName_(fileName), lineNum_(lineNum), locs_(locs), upPtr_(NULL)
1600 {
1601     type_->incrRefCount();
1602 }
1603
1604 localVar::localVar(localVar &lvar) 
1605 {
1606    name_ = lvar.name_;
1607    type_ = lvar.type_;
1608    fileName_ = lvar.fileName_;
1609    lineNum_ = lvar.lineNum_;
1610    if(!lvar.locs_)
1611        locs_ = NULL;
1612    else {
1613        locs_ = new vector<loc_t *>;
1614        for(unsigned i=0;i<lvar.locs_->size();i++){
1615            loc_t *loc = (loc_t *)malloc(sizeof(loc_t));
1616            loc->stClass = (*(lvar.locs_))[i]->stClass;
1617            loc->refClass = (*(lvar.locs_))[i]->refClass;
1618            loc->reg = (*(lvar.locs_))[i]->reg;
1619            loc->frameOffset = (*(lvar.locs_))[i]->frameOffset;
1620            loc->lowPC = (*(lvar.locs_))[i]->lowPC;
1621            loc->hiPC = (*(lvar.locs_))[i]->hiPC;
1622            locs_->push_back(loc);
1623        }
1624    }    
1625    upPtr_ = lvar.upPtr_;
1626    if (type_ != NULL)
1627       type_->incrRefCount();
1628 }
1629
1630 bool localVar::addLocation(loc_t *location)
1631 {
1632     if(!locs_)
1633         locs_ = new std::vector<loc_t *>;
1634     locs_->push_back(location);
1635     return true;
1636 }
1637
1638 bool localVar::setLocation(vector<loc_t *> *locs) {
1639     if(locs_)
1640         return false;
1641     locs_ = locs;
1642     return true;
1643 }
1644
1645 /*
1646  * localVar destructor
1647  *
1648  */
1649 localVar::~localVar()
1650 {
1651     //XXX jdd 5/25/99 More to do later
1652     type_->decrRefCount();
1653     for(unsigned i=0;i<locs_->size();i++)
1654         delete (*locs_)[i];
1655     delete locs_;
1656 }
1657
1658 void localVar::fixupUnknown(Module *module) {
1659    if (type_->getDataClass() == dataUnknownType) {
1660       Type *otype = type_;
1661       type_ = module->getModuleTypes()->findType(type_->getID());
1662       if(type_){
1663           type_->incrRefCount();
1664            otype->decrRefCount();
1665       }
1666       else
1667           type_ = otype;
1668    }
1669 }
1670
1671 std::string &localVar::getName() {
1672         return name_; 
1673 }
1674
1675 Type *localVar::getType() { 
1676         return type_; 
1677 }
1678
1679 bool localVar::setType(Type *newType) {
1680         type_ = newType;
1681         return true;
1682 }
1683
1684 int localVar::getLineNum() { 
1685         return lineNum_; 
1686 }
1687
1688 std::string &localVar::getFileName() { 
1689         return fileName_; 
1690 }
1691
1692 std::vector<Dyninst::SymtabAPI::loc_t *> *localVar::getLocationLists() { 
1693         return locs_; 
1694 }
1695
1696 void *localVar::getUpPtr() const{
1697     return upPtr_;
1698 }
1699
1700 bool localVar::setUpPtr(void *upPtr) {
1701     upPtr_ = upPtr;
1702     return true;
1703 }
1704
1705 /**************************************************************************
1706  * CBlock
1707  *************************************************************************/
1708
1709 void CBlock::fixupUnknowns(Module *module) {
1710    for (unsigned int i = 0; i < fieldList.size(); i++) {
1711       fieldList[i]->fixupUnknown(module);
1712    }
1713 }
1714
1715 std::vector<Field *> *CBlock::getComponents()
1716 {
1717   return &fieldList;
1718 }
1719 std::vector<Symbol *> *CBlock::getFunctions()
1720 {
1721   return &functions;
1722 }
1723
1724 void *CBlock::getUpPtr() const{
1725     return upPtr_;
1726 }
1727
1728 bool CBlock::setUpPtr(void *upPtr) {
1729     upPtr_ = upPtr;
1730     return true;
1731 }
1732