Changes to work towards compatability with IBM's version of dyninst.
[dyninst.git] / dyninstAPI / src / BPatch_type.C
1 /*
2  * Copyright (c) 1996 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  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 #include <stdio.h>
43
44 #define BPATCH_FILE
45
46
47 #include "util.h"
48 #include "BPatch_Vector.h"
49 #include "BPatch_type.h"
50 #include "BPatch_collections.h"
51 #include "showerror.h"
52 #include "BPatch.h"
53
54 // This is the ID that is decremented for each type a user defines. It is
55 // Global so that every type that the user defines has a unique ID.
56 // jdd 7/29/99
57 static int USER_BPATCH_TYPE_ID = -1000;
58
59 /*
60  * BPatch_type::BPatch_type
61  *
62  * EMPTY Constructor for BPatch_type.  
63  * 
64  */
65 BPatch_type::BPatch_type() :
66     nullType(true), cblocks(NULL)
67 {
68   name = NULL;
69   ID = 0;
70   size = sizeof(int);
71   low = NULL;
72   hi = NULL;
73   ptr = NULL;
74 }
75
76 /*
77  * BPatch_type::BPatch_type
78  *
79  * Constructor for BPatch_type.  Creates a type object representing a type
80  * with the features given in the parameters.
81  */
82 BPatch_type::BPatch_type(const char *_name, bool _nullType) :
83   nullType(_nullType), cblocks(NULL)
84 {
85     /* XXX More later. */
86   if( _name)
87     name = strdup(_name);
88   else
89     name = NULL;
90
91   size = sizeof(int);
92   low = NULL;
93   hi = NULL;
94   ptr = NULL;
95
96 }
97
98 /*
99  * BPatch_type::BPatch_type
100  *
101  * Constructor for BPatch_type ENUM.  Creates a type object representing a type
102  * with the features given in the parameters.
103  */
104 BPatch_type::BPatch_type(const char *_name, int _ID, BPatch_dataClass _type):
105 nullType(false), cblocks(NULL)
106 {
107   ID = _ID;
108   type_ = _type;
109   // This is just for now XXX 
110   size = sizeof(int);
111   low = NULL;
112   hi= NULL;
113   ptr = NULL;
114   if( _name)
115     name = strdup(_name);
116   else
117     name = NULL;
118 }
119
120 /*
121  * BPatch_type::BPatch_type
122  *
123  * Constructor for BPatch_type Structs, Unions, range(size),
124  * and reference(void) and built-in type. These are the negative type
125  * numbers defined in the gdb doc.  The type ID neg. type num.
126  * Creates a type object representing a type
127  * with the features given in the parameters.
128  * A collection of the built-in types is created in for the image and
129  * is gloabally accessible to all modules. This way it is only created once..
130  */
131 BPatch_type::BPatch_type(const char *_name, int _ID, BPatch_dataClass _type,
132                          int _size):
133 nullType(false), cblocks(NULL)
134 {
135   ID = _ID;
136   type_ = _type;
137
138   if( _name)
139     name = strdup(_name);
140   else
141     name = NULL;
142   
143   low = NULL;
144   hi = NULL;
145   ptr = NULL;
146   type_ = _type;
147   //typeCol = NULL;
148   size = _size;
149
150   if( _type == BPatch_dataScalar) {
151     // Check that void type == void type
152     if( _ID == _size ){
153
154       low = NULL;
155       hi = NULL;
156       type_ = _type;
157       ptr = NULL;
158       //typeCol = NULL;
159       size = 0;
160     }
161     else{
162     size = _size;
163     low = NULL;
164     hi = NULL;
165     type_ = _type;
166     ptr = NULL;
167     //typeCol = NULL;
168     }
169   }
170   else{
171     size = _size;
172     low = NULL;
173     hi = NULL;
174     type_ = _type;
175     ptr = NULL;
176     //typeCol = NULL;
177   }
178 }
179
180 /*
181  * BPatch_type::BPatch_type
182  *
183  * Constructor for BPatch_type Pointers (and Internal).
184  * Creates a type object representing a type
185  * with the features given in the parameters.
186  */
187 BPatch_type::BPatch_type(const char *_name, int _ID, BPatch_dataClass _type,
188                          BPatch_type * _ptr):
189 nullType(false), cblocks(NULL)
190 {
191     
192   ID = _ID;
193   if(_type == BPatch_dataScalar){  // could be a typedef for something
194     if( _name)
195       name = strdup(_name);
196     else
197       name = NULL;
198     if(_ptr ){
199       if(_ptr->ptr) // point to whatever it points to
200         ptr = _ptr->ptr;
201       else  // or just point to the oldType
202         ptr = _ptr;
203       type_ = _ptr->type_;
204       size = _ptr->size;
205       fieldList = _ptr->fieldList;
206     } else{
207       ptr = _ptr;
208       size = sizeof(int);
209       type_ = _type;
210     }
211         
212     low = NULL;
213     hi = NULL;
214   } else{
215     type_=_type;
216     ptr = _ptr;
217     if( _name)
218       name = strdup(_name);
219     else
220       name = NULL;
221
222     size = sizeof(void *);
223     low = NULL;
224     hi = NULL;
225   }
226 }
227
228 /*
229  * BPatch_type::BPatch_type
230  *
231  * Constructor for BPatch_type Range with lower and upper bound.
232  * Creates a type object representing a type
233  * with the features given in the parameters.
234  */
235 BPatch_type::BPatch_type(const char *_name, int _ID, BPatch_dataClass _type,
236                          const char * _low, const char * _hi):
237 nullType(false), cblocks(NULL)
238 {
239   ID = _ID;
240   type_ = _type;
241
242   if( _name)
243     name = strdup(_name);
244   else
245     name = NULL;
246   
247   name = strdup(_name);
248   low = strdup(_low);
249   hi = strdup(_hi);
250   /* need to change for smaller types, maybe case statement
251      needs to be arch. independent and there may be a lot of cases*/
252   size = sizeof(int);
253   ptr = NULL;
254 }
255
256 /*
257  * BPatch_type::BPatch_type
258  *
259  * Constructor for BPatch_type Array.
260  * Creates a type object representing a type
261  * with the features given in the parameters.
262  */
263 BPatch_type::BPatch_type(const char *_name, int _ID, BPatch_dataClass _type,
264                          BPatch_type * _ptr, int _low, int _hi):
265   nullType(false), cblocks(NULL)
266 {
267   
268   char temp[255];
269
270   ID = _ID;
271   type_ = _type;
272   ptr = _ptr;
273
274   if( _name)
275     name = strdup(_name);
276   else
277     name = NULL;
278
279
280   sprintf(temp, "%d", _low);
281   low = strdup(temp);
282
283   sprintf(temp, "%d", _hi);
284   hi = strdup(temp);
285
286   /* size = sizeof(artype)*(_hi+1)
287      need to find out how big that size is first */
288   size = ((ptr->getSize())*(_hi-_low+1));
289 }
290
291 /*
292  * BPatch_type::BPatch_type
293  *
294  * Constructor for BPatch_type typedef--pre-existing type.
295  * Creates a type object representing a type
296  * with the features given in the parameters.
297  */
298 BPatch_type::BPatch_type(const char * _name, int _ID, BPatch_type *  _ptr):
299 nullType(false), cblocks(NULL)
300 {
301   if(_ptr){
302     ID = _ID;
303     size = _ptr->size;
304
305     if( _name)
306       name = strdup(_name);
307     else
308       name = NULL;
309
310     if(_ptr->low)
311       low = strdup(_ptr->low);
312     else
313       low = NULL;
314     if(_ptr->hi)
315       hi = strdup(_ptr->hi);
316     else
317       hi = NULL;
318     type_ = _ptr->type_;
319     if(_ptr->ptr)
320       ptr = _ptr->ptr;
321     else
322       ptr = _ptr;
323   }
324   else{
325     ID = _ID;
326     size = sizeof(int);
327     if( _name)
328       name = strdup(_name);
329     else
330       name = NULL;
331     hi = NULL;
332     low = NULL;
333     type_ = BPatch_dataScalar;
334     ptr = _ptr;
335   }
336 }
337
338 /*
339  * BPatch_type::BPatch_type
340  *
341  * Constructor for BPatch_type Type Attributes.  These are types defined
342  * by the built-in types and use the '@' as the type identifier.
343  * Creates a type object representing a type
344  * with the features given in the parameters.
345  */
346 BPatch_type::BPatch_type(const char * _name, int _ID, BPatch_dataClass _type,
347                          int _size, BPatch_type * _ptr):
348 nullType(false), cblocks(NULL)
349 {
350   int b_size;
351
352   b_size = _ptr->getSize();
353   
354   ID = _ID;
355
356   if( b_size != _size) {
357     sprintf(errorLine, "Built-in Type size %d and Stabs record size %d differ"
358         " for [%d]%s: Overriding built-in type size!!",
359         b_size, _size, _ID, _name);
360     BPatch_reportError(BPatchWarning, 112, errorLine);
361   }
362   
363   size = _size;
364
365   if( _name)
366     name = strdup(_name);
367   else
368     name = NULL;
369
370   low = NULL;
371   hi = NULL;
372   type_ = _type;
373   ptr = _ptr;
374 }
375
376 //---------------------------------------------------------------------
377 //  User defined BPatch_Type Constructors
378 //
379 //  These functions allow the user to create their own types and manipulate
380 //  these types.  The user defined types are stored with the other system
381 //  types.  They can be differentiated from system types by their type ID.  It
382 //  is less than -1000.  jdd 7/29/99
383
384
385 /* USER_DEFINED BPATCH_TYPE
386  *  
387  * BPatch_type::BPatch_type
388  *
389  * Constructor for BPatch_type ENUM.  Creates a type object representing a type
390  * with the features given in the parameters.
391  */
392 BPatch_type::BPatch_type(const char *_name, BPatch_dataClass _type):
393 nullType(false), cblocks(NULL)
394 {
395   ID = USER_BPATCH_TYPE_ID;
396   USER_BPATCH_TYPE_ID--;
397   
398   type_ = _type;
399   // This is just for now XXX jdd 8/5/99, may need to be changed later
400   size = sizeof(int);
401   low = NULL;
402   hi= NULL;
403   ptr = NULL;
404   if( _name)
405     name = strdup(_name);
406   else
407     name = NULL;
408 }
409
410 /* USER_DEFINED BPATCH_TYPE
411  * 
412  * BPatch_type::BPatch_type
413  *
414  * Constructor for BPatch_type Structs, Unions, range(size),
415  * and reference(void) and built-in type. These are the negative type
416  * numbers defined in the gdb doc.  The type ID neg. type num.
417  * Creates a type object representing a type
418  * with the features given in the parameters.
419  * A collection of the built-in types is created in for the image and
420  * is gloabally accessible to all modules. This way it is only created once..
421  */
422 BPatch_type::BPatch_type(const char *_name, BPatch_dataClass _type,
423                          int _size):
424 nullType(false), cblocks(NULL)
425 {
426   ID =USER_BPATCH_TYPE_ID;
427   USER_BPATCH_TYPE_ID--;
428   
429   type_ = _type;
430
431   if( _name)
432     name = strdup(_name);
433   else
434     name = NULL;
435   
436   size = _size;
437   low = NULL;
438   hi = NULL;
439   type_ = _type;
440   if(_size == -1){
441      ptr = (BPatch_type *)_size; // check this field before adding new struct, union component
442                   // to see if the size needs to be computed.
443   }
444   else
445     ptr = NULL;
446 }
447
448 /* USER_DEFINED BPATCH_TYPE
449  * 
450  * BPatch_type::BPatch_type
451  *
452  * Constructor for BPatch_type Pointers (and Internal).
453  * Creates a type object representing a type
454  * with the features given in the parameters.
455  */
456 BPatch_type::BPatch_type(const char *_name, BPatch_type * _ptr, int size_):
457 nullType(false), cblocks(NULL)
458 {
459   ID = USER_BPATCH_TYPE_ID;
460   USER_BPATCH_TYPE_ID--;
461
462   type_ = BPatch_dataPointer;
463   size = size_;
464   
465   if( _name)
466     name = strdup(_name);
467   else
468     name = NULL;
469
470   if(_ptr ){
471     if(_ptr->ptr) // point to whatever it points to
472       ptr = _ptr->ptr;
473     else  // or just point to the oldType
474       ptr = _ptr;
475     fieldList = _ptr->fieldList;
476   }
477   else{
478     ptr = _ptr;
479   }
480         
481   low = NULL;
482   hi = NULL;
483 }
484
485 /* USER_DEFINED BPATCH_TYPE
486  * 
487  * BPatch_type::BPatch_type
488  *
489  * Constructor for BPatch_type Range with lower and upper bound.
490  * Creates a type object representing a type
491  * with the features given in the parameters.
492  */
493 BPatch_type::BPatch_type(const char *_name, BPatch_dataClass _type,
494                          const char * _low, const char * _hi):
495 nullType(false), cblocks(NULL)
496 {
497   ID = USER_BPATCH_TYPE_ID;
498   USER_BPATCH_TYPE_ID--;
499
500   type_ = _type;
501
502   if( _name)
503     name = strdup(_name);
504   else
505     name = NULL;
506   
507   name = strdup(_name);
508   low = strdup(_low);
509   hi = strdup(_hi);
510   /* need to change for smaller types, maybe case statement
511      needs to be arch. independent and there may be a lot of cases*/
512   size = sizeof(int);
513   ptr = NULL;
514 }
515
516 /* USER_DEFINED BPATCH_TYPE
517  * 
518  * BPatch_type::BPatch_type
519  *
520  * Constructor for BPatch_type Array.
521  * Creates a type object representing a type
522  * with the features given in the parameters.
523  */
524 BPatch_type::BPatch_type(const char *_name, BPatch_dataClass _type,
525                          BPatch_type * _ptr, int _low, int _hi):
526   nullType(false),
527   cblocks(NULL)
528 {
529   ID = USER_BPATCH_TYPE_ID;
530   USER_BPATCH_TYPE_ID--;
531   
532   char temp[255];
533
534   type_ = _type;
535   ptr = _ptr;
536
537   if( _name)
538     name = strdup(_name);
539   else
540     name = NULL;
541
542
543   sprintf(temp, "%d", _low);
544   low = strdup(temp);
545
546   sprintf(temp, "%d", _hi);
547   hi = strdup(temp);
548
549   /* size = sizeof(artype)*(_hi+1)
550      need to find out how big that size is first */
551   size = ((ptr->getSize())*(_hi+1));
552 }
553
554 /* USER_DEFINED BPATCH_TYPE
555  * 
556  * BPatch_type::BPatch_type
557  *
558  * Constructor for BPatch_type typedef--pre-existing type.
559  * Creates a type object representing a type
560  * with the features given in the parameters.
561  */
562 BPatch_type::BPatch_type(const char * _name, BPatch_type *  _ptr):
563 nullType(false)
564 {
565   if(_ptr){
566     ID = USER_BPATCH_TYPE_ID;
567     USER_BPATCH_TYPE_ID--;
568  
569     size = _ptr->size;
570
571     if( _name)
572       name = strdup(_name);
573     else
574       name = NULL;
575
576     if(_ptr->low)
577       low = strdup(_ptr->low);
578     else
579       low = NULL;
580     if(_ptr->hi)
581       hi = strdup(_ptr->hi);
582     else
583       hi = NULL;
584     type_ = _ptr->type_;
585     if(_ptr->ptr)
586       ptr = _ptr->ptr;
587     else
588       ptr = _ptr;
589   }
590   else{
591     ID = USER_BPATCH_TYPE_ID;
592     USER_BPATCH_TYPE_ID--;
593  
594     size = sizeof(int);
595     if( _name)
596       name = strdup(_name);
597     else
598       name = NULL;
599     hi = NULL;
600     low = NULL;
601     type_ = BPatch_dataScalar;
602     ptr = _ptr;
603   }
604 }
605
606 /* USER_DEFINED BPATCH_TYPE
607  * 
608  * BPatch_type::BPatch_type
609  *
610  * Constructor for BPatch_type Type Attributes.  These are types defined
611  * by the built-in types and use the '@' as the type identifier.
612  * Creates a type object representing a type
613  * with the features given in the parameters.
614  */
615 BPatch_type::BPatch_type(const char * _name, BPatch_dataClass _type,
616                          int _size, BPatch_type * _ptr):
617 nullType(false)  
618 {
619   int b_size;
620
621   b_size = _ptr->getSize();
622   ID = USER_BPATCH_TYPE_ID;
623   USER_BPATCH_TYPE_ID--;
624
625   if( b_size != _size) {
626     sprintf(errorLine, "Built-in Type size %d and Stabs record size %d differ"
627         " for [%d]%s: Overriding built-in type size!!",
628         b_size, _size, ID, _name);
629     BPatch_reportError(BPatchWarning, 112, errorLine);
630   }
631   
632   size = _size;
633
634   if( _name)
635     name = strdup(_name);
636   else
637     name = NULL;
638
639   low = NULL;
640   hi = NULL;
641   type_ = _type;
642   ptr = _ptr;
643 }
644
645 void BPatch_type::beginCommonBlock()
646 {
647     BPatch_Vector<BPatch_field*> emptyList;
648
649     if (!cblocks) cblocks = new BPatch_Vector<BPatch_cblock *>;
650
651     // null out field list
652     fieldList = emptyList;
653 }
654
655 void BPatch_type::endCommonBlock(BPatch_function *func, void *baseAddr)
656 {
657     int i, j;
658
659     // create local variables in func's scope for each field of common block
660     for (j=0; j < fieldList.size(); j++) {
661         BPatch_localVar *locVar;
662         locVar = new BPatch_localVar((char *) fieldList[j]->getName(), 
663             fieldList[j]->getType(), 0, 
664             fieldList[j]->getOffset()+(Address) baseAddr, 5, 
665                 false);
666         func->localVariables->addLocalVar( locVar);
667     }
668
669     // look to see if the field list matches an existing block
670     for (i=0; i < cblocks->size(); i++) {
671         BPatch_cblock *curr = (*cblocks)[i];
672         for (j=0; j < fieldList.size(); j++) {
673             if (strcmp(fieldList[j]->getName(),curr->fieldList[j]->getName()) ||
674                 (fieldList[j]->getOffset() !=curr->fieldList[j]->getOffset()) ||
675                 (fieldList[j]->getSize() != curr->fieldList[j]->getSize())) {
676                 break; // no match
677             }
678         }
679         if (j == fieldList.size() && (j == curr->fieldList.size())) {
680             // match
681             curr->functions.push_back(func);
682             return;
683         }
684     }
685
686     // this one is unique
687     BPatch_cblock *newBlock = new BPatch_cblock();
688     newBlock->fieldList = fieldList;
689     newBlock->functions.push_back(func);
690     cblocks->push_back(newBlock);
691
692     // create local variables in func's scope for each field of common block
693     for (j=0; j < fieldList.size(); j++) {
694         BPatch_localVar *locVar;
695         locVar = new BPatch_localVar((char *) fieldList[j]->getName(), 
696             fieldList[j]->getType(), 0, 
697             fieldList[j]->getOffset()+(Address) baseAddr, 5, 
698                 false);
699         func->localVariables->addLocalVar( locVar);
700     }
701
702     return;
703 }
704
705
706 /*
707  * BPatch_type::isCompatible
708  *
709  * Returns true of the type is compatible with the other specified type, false
710  * if it is not (if it breaks out of the case).
711  *
712  * oType        The other type to check for compatibility.
713  */
714 bool BPatch_type::isCompatible(BPatch_type *otype)
715 {
716   // simple compare.
717   if (nullType || otype->nullType)
718         return true;
719   
720   // name, ID and type are the same them it has to be the same BPatch_type
721   if ((ID == otype->ID) && (type_ == otype->type_)) {
722       if (name && otype->name && !strcmp(name,otype->name)) {
723           return true;
724       }
725   }
726
727   if ((type_ == BPatch_dataUnknownType) || (otype->type_ == BPatch_dataUnknownType)) {
728       BPatch_reportError(BPatchWarning, 112,
729                        "One or more unknown BPatch_types");
730       return true;
731   }
732
733   switch(type_){
734   case BPatch_dataScalar:
735       if (!strcmp(name,otype->name) && (size == otype->size)) {
736           return true;
737       } else {
738           BPatch_reportError(BPatchWarning, 112, "scalar's not compatible");
739           return false;
740       }
741       break;
742
743   case BPatchSymTypeRange:
744       if (!(strcmp(name,otype->name))&& (ID == otype->ID)&&(size == otype->size))
745           return true;
746       if (!(strcmp(name,otype->name))&&(size == otype->size))
747           return true;
748       break;
749
750   case BPatch_dataReference:
751       if (!(strcmp(name,otype->name)) && (size == otype->size))
752           return true;
753       break;
754
755   case BPatch_dataBuilt_inType:
756       if (!(strcmp(name,otype->name))&&(size == otype->size))
757           return true;
758       break;
759
760   case BPatch_dataUnknownType:
761       // should be caught above
762       assert(0);
763       break;
764
765   case BPatch_dataTypeAttrib:
766     if (!(strcmp(name,otype->name))&&(size == otype->size))
767         return true;
768     break;
769
770   case BPatch_dataPointer:
771     {
772       BPatch_type *pType1, *pType2;
773
774       if (otype->type_ != BPatch_dataPointer) {
775           BPatch_reportError(BPatchWarning, 112, 
776               "Pointer and non-Pointer are not type compatible");
777           return false;
778       } else {
779           // verify type that each one points to is compatible
780           pType1 = this->ptr;
781           pType2 = otype->ptr;
782           if (!pType1 || !pType2 || !pType1->isCompatible(pType2)) {
783               return false;
784           } else {
785               return true;
786           }
787       }
788     }
789     break;
790
791   case BPatch_dataFunction:
792     if (!(strcmp(name,otype->name))&&(ID == otype->ID)) {
793           return true;
794     } else {
795           BPatch_reportError(BPatchWarning, 112, 
796               "function call not compatible");
797           return false;
798     }
799     break;
800
801   case BPatch_dataArray:
802     {
803       BPatch_type * arType1, * arType2;
804       
805       if (otype->type_ != BPatch_dataArray) {
806           BPatch_reportError(BPatchWarning, 112, 
807               "Array and non-array are not type compatible");
808           return false;
809       }
810
811       // verify that the number of elements is the same
812       if ((atoi(this->hi) - atoi(this->low)) != (atoi(otype->hi) - atoi(otype->low))) {
813           char message[80];
814           sprintf(message, "Incompatible number of elements [%s..%s] vs. [%s..%s]",
815               this->low, this->hi, otype->low, otype->hi);
816           BPatch_reportError(BPatchWarning, 112, message);
817           return false;
818       }
819
820       // verify that elements of the array are compatible
821       arType1 = this->ptr;
822       arType2 = otype->ptr;
823       if (!arType1 || !arType2 || !arType1->isCompatible(arType2)) {
824           // no need to report error, recursive call will
825           return false;
826       } else {
827           return true;
828       }
829     }
830     break;
831
832   case BPatch_dataEnumerated:
833     {
834       if( !strcmp( name, otype->name) && (ID == otype->ID))
835         return true;
836       BPatch_Vector<BPatch_field *> * fields1 = this->getComponents();
837       // BPatch_Vector<BPatch_field *> * fields2 = ((BPatch_type)otype).getComponents();
838       BPatch_Vector<BPatch_field *> * fields2 = (BPatch_Vector<BPatch_field *> *) &(otype->fieldList);
839       
840       if( fields1->size() != fields2->size()) {
841         BPatch_reportError(BPatchWarning, 112, "enumerated type mismatch ");
842         return false;
843       }
844       
845       //need to compare componment by component to verify compatibility
846       for(int i=0;i<fields1->size();i++){
847         BPatch_field * field1 = (*fields1)[i];
848         BPatch_field * field2 = (*fields2)[i];
849         if( (field1->getValue() != field2->getValue()) ||
850             (strcmp(field1->getName(), field2->getName())))
851           BPatch_reportError(BPatchWarning, 112, "enum element mismatch ");
852           return false;
853       }
854       // Everything matched so they are the same
855       return true;
856     }
857     break;
858
859   case BPatch_dataStructure:
860   case BPatch_dataUnion:
861     {
862       if (!strcmp( name, otype->name) && (ID == otype->ID))
863           return true;
864       BPatch_Vector<BPatch_field *> * fields1 = this->getComponents();
865       // The line below does not work in linux.
866       // BPatch_Vector<BPatch_field *> * fields2 = ((BPatch_type)otype).getComponents();
867       BPatch_Vector<BPatch_field *> * fields2 = (BPatch_Vector<BPatch_field *> *) &(otype->fieldList);
868
869       if (fields1->size() != fields2->size()) {
870           BPatch_reportError(BPatchWarning, 112, 
871               "struct/union numer of elements mismatch ");
872           return false;
873       }
874     
875       //need to compare componment by component to verify compatibility
876       for (int i=0;i<fields1->size();i++) {
877         BPatch_field * field1 = (*fields1)[i];
878         BPatch_field * field2 = (*fields2)[i];
879         
880         BPatch_type * ftype1 = (BPatch_type *)field1->getType();
881         BPatch_type * ftype2 = (BPatch_type *)field2->getType();
882         
883         if(!(ftype1->isCompatible(ftype2))) {
884              BPatch_reportError(BPatchWarning, 112, 
885                   "struct/union field type mismatch ");
886              return false;
887         }
888       }
889       return true;
890     }
891     break;
892
893   default:
894     cerr<<"UNKNOWN TYPE, UNABLE TO COMPARE!!"<<endl;
895   }
896
897   char message[256];
898   if (name && otype->name) {
899       sprintf(message, "%s is not compatible with %s ", name, otype->name);
900   } else {
901       sprintf(message, "unknown type mismatch ");
902   }
903   BPatch_reportError(BPatchWarning, 112, message);
904   return( false );
905 }
906
907
908 /*
909  * void BPatch_type::addField
910  * Creates field object and adds it to the list of fields for this
911  * BPatch_type object.
912  *     ENUMS
913  */
914 void BPatch_type::addField(const char * _fieldname, BPatch_dataClass _typeDes,
915                            int value)
916 {
917   BPatch_field * newField;
918
919   newField = new BPatch_field(_fieldname, _typeDes, value);
920
921   // Add field to list of enum fields
922   fieldList.push_back(newField);
923 }
924
925 /*
926  * void BPatch_type::addField
927  * Creates field object and adds it to the list of fields for this
928  * BPatch_type object.
929  *     ENUMS C++ - have visibility
930  */
931 void BPatch_type::addField(const char * _fieldname, BPatch_dataClass _typeDes,
932                            int value, BPatch_visibility _vis)
933 {
934   BPatch_field * newField;
935
936   newField = new BPatch_field(_fieldname, _typeDes, value, _vis);
937
938   // Add field to list of enum fields
939   fieldList.push_back(newField);
940 }
941
942 /*
943  * void BPatch_type::addField
944  * Creates field object and adds it to the list of fields for this
945  * BPatch_type object.
946  *     STRUCTS OR UNIONS
947  */
948 void BPatch_type::addField(const char * _fieldname, BPatch_dataClass _typeDes,
949                            BPatch_type *_type, int _offset, int _nsize)
950 {
951   BPatch_field * newField;
952
953   // API defined structs/union's size are defined on the fly.
954   if (this->type_ == BPatch_dataStructure)
955       this->size += _nsize;
956   else if ( this->type_ == BPatch_dataUnion) {
957       if( _nsize > size) size = _nsize;
958   } else if (type_ == BPatch_dataCommon) {
959       if (size < _offset + _nsize) size = _offset + _nsize; 
960   } assert ( this->size > 0 );
961
962   // Create Field for struct or union
963   newField = new BPatch_field(_fieldname, _typeDes, _type, _offset, _nsize);
964
965   // Add field to list of struct/union fields
966   fieldList.push_back(newField);
967
968 }
969
970 /*
971  * void BPatch_type::addField
972  * Creates field object and adds it to the list of fields for this
973  * BPatch_type object.
974  *     STRUCTS OR UNIONS C++ have visibility
975  */
976 void BPatch_type::addField(const char * _fieldname, BPatch_dataClass _typeDes,
977                            BPatch_type *_type, int _offset, int _size,
978                            BPatch_visibility _vis)
979 {
980   BPatch_field * newField;
981
982   // Create Field for struct or union
983   newField = new BPatch_field(_fieldname, _typeDes, _type, _offset, _size,
984                               _vis);
985
986   // Add field to list of struct/union fields
987   fieldList.push_back(newField);
988
989 }
990
991 /*
992  * BPatch_field::BPatch_field
993  *
994  * Constructor for BPatch_field.  Creates a field object for 
995  * an enumerated type.
996  * type = offset = size = 0;
997  */
998 BPatch_field::BPatch_field(const char * fName, BPatch_dataClass _typeDes,
999                            int evalue)
1000 {
1001   typeDes = _typeDes;
1002   value = evalue;
1003   fieldname = strdup(fName);
1004
1005   _type = NULL;
1006   offset = size = 0;
1007   vis = BPatch_visUnknown;
1008   // printf("adding field %s\n", fName);
1009
1010 }
1011
1012 /*
1013  * BPatch_field::BPatch_field
1014  *
1015  * Constructor for BPatch_field.  Creates a field object for 
1016  * an enumerated type with a C++ visibility value
1017  * type = offset = size = 0;
1018  */
1019 BPatch_field::BPatch_field(const char * fName, BPatch_dataClass _typeDes,
1020                            int evalue, BPatch_visibility _vis)
1021 {
1022   typeDes = _typeDes;
1023   value = evalue;
1024   fieldname = strdup(fName);
1025
1026   _type = NULL;
1027   offset = size = 0;
1028   vis = _vis;
1029   // printf("adding field %s\n", fName);
1030
1031 }
1032
1033 /*
1034  * BPatch_field::BPatch_field
1035  *
1036  * Constructor for BPatch_field.  Creates a field object for 
1037  * an struct and union types.
1038  * value= 0;
1039  */
1040 BPatch_field::BPatch_field(const char * fName, BPatch_dataClass _typeDes,
1041                            BPatch_type *suType, int suOffset, int suSize)
1042 {
1043   
1044   typeDes = _typeDes;
1045   _type = suType;
1046   offset = suOffset;
1047   fieldname = strdup(fName);
1048   size = suSize;
1049   
1050   value = 0;
1051   vis = BPatch_visUnknown;
1052 }
1053
1054 /*
1055  * BPatch_field::BPatch_field
1056  *
1057  * Constructor for BPatch_field.  Creates a field object for 
1058  * a struct and union types for C++ fields that have visibility.
1059  * value= 0;
1060  */
1061 BPatch_field::BPatch_field(const char * fName, BPatch_dataClass _typeDes,
1062                            BPatch_type *suType, int suOffset, int suSize,
1063                            BPatch_visibility _vis)
1064 {
1065   
1066   typeDes = _typeDes;
1067   _type = suType;
1068   offset = suOffset;
1069   fieldname = strdup(fName);
1070   size = suSize;
1071   
1072   value = 0;
1073   vis = _vis;
1074 }
1075
1076
1077 /**************************************************************************
1078  * BPatch_localVar
1079  *************************************************************************/
1080 /*
1081  * BPatch_localVar Constructor
1082  *
1083  */
1084 BPatch_localVar::BPatch_localVar(char * _name,  BPatch_type * _type,
1085                              int _lineNum,int _frameOffset, int _sc, bool fr)
1086 {
1087   if( _name)
1088     name = strdup(_name);
1089   else
1090     name = NULL;
1091   type = _type;
1092   lineNum = _lineNum;
1093   frameOffset = _frameOffset;
1094   frameRelative = fr;
1095   storageClass = _sc; //Only for COFF format. Default value is scAbs
1096 }
1097
1098
1099 /*
1100  * BPatch_localVar destructor
1101  *
1102  */
1103 BPatch_localVar::~BPatch_localVar()
1104 {
1105
1106   //XXX jdd 5/25/99 More to do later
1107
1108 }
1109