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