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