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