Changes to work towards compatability with IBM's version of dyninst.
[dyninst.git] / dyninstAPI / src / parseStab.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 <ctype.h>
43
44 #include "BPatch.h"
45 #include "BPatch_module.h"
46 #include "BPatch_collections.h"
47 #include "showerror.h"
48
49 extern char *current_func_name;
50
51 // Forward references for parsing routines
52 static int parseSymDesc(char *stabstr, int &cnt);
53 static BPatch_type *parseConstantUse(BPatch_module*, char *stabstr, int &cnt);
54 static char *parseTypeDef(BPatch_module*, char *stabstr, char *name, int ID);
55 static int parseTypeUse(BPatch_module*, char *&stabstr, int &cnt, char *name);
56 static inline bool isSymId(char ch);
57 static char *getIdentifier(char *stabstr, int &cnt);
58
59 //
60 // Start of code to parse Stab information.
61 //    The structure of this code is a recursive decent parser that parses
62 //    information in stab records and builds up the corresponding BPatch_types.
63 //    
64 //    Each non-terminal in the grammer has a function of the form parse<NT>.
65 //      
66 //    The grammar for a non-terminal appears in the comments just before
67 //    the non-terminal parsing function
68 //      
69
70 // This function takes the stab stabstring and parses it to create a new 
71 // type or variable object.  This function only defines the type/variable 
72 // name and ID.
73 //
74 // <stabString> = <ident>:<symDesc>                     |
75 //                <ident>:c<constantUse>                |
76 //                <ident>:f<symDesc>                    |
77 //                <ident>:f<syymDesc>,<ident>,<ident>   |
78 //                <ident>:F<typeUse><paramList>         |
79 //                <ident>:G<typeUse>                    |
80 //                <ident>:r<int>                        |
81 //                <ident>:S<typeUse>                    |
82 //                <ident>:[pPr]<typeUse>                |
83 //                <ident>::T<typeUse>                   |
84 //                <ident>:t<typeUse>                    |
85 //                <ident>:T<typeUse>                    |
86 //                <ident>:v<typeUse>                    |
87 //                <ident>:V<symDesc>
88 //
89 // <paramList> = | <typeUse>;<paramList> 
90 //
91 char *parseStabString(BPatch_module *mod, int linenum, char *stabstr, 
92                       int framePtr, BPatch_type *commonBlock = NULL)
93 {
94
95     int cnt;
96     int ID = 0;
97     int symdescID = 0;
98     int funcReturnID = 0;
99     BPatch_function  *fp;
100     BPatch_type * ptrType = NULL;
101     BPatch_type * newType = NULL; // For new types to add to the collection
102     BPatch_localVar *locVar = NULL;
103
104     cnt= 0;
105
106     /* get type or variable name */
107     char *name = getIdentifier(stabstr, cnt);
108
109     if (*name) {
110        // non-null string
111        // AIX puts out some symbols like this eg .bs
112        if (stabstr[cnt] != ':') {
113            return name;
114        }
115     }
116     if (stabstr[cnt] == ':') {
117        // skip to type part
118        cnt++;
119     }
120
121     if (isSymId(stabstr[cnt])) {
122         /* instance of a predefined type */
123
124         ID = parseSymDesc(stabstr, cnt);
125         
126         //printf("Variable: %s  Type ID: %d, file ID %d \n",name, ID, file_ID);
127         if (stabstr[cnt] == '=') {
128           /* More Stuff to parse, call parseTypeDef */
129           stabstr = parseTypeDef(mod, (&stabstr[cnt+1]), name, ID);
130           cnt = 0;
131           ptrType = mod->moduleTypes->findType( ID);
132           if (current_func_name) {
133             // XXX-may want to use N_LBRAC and N_RBRAC to set function scope 
134             // -- jdd 5/13/99
135             // Still need to add to local variable list if in a function
136             fp = mod->findFunction( current_func_name );
137             if (!fp) {
138                 char modName[100];
139                 mod->getName(modName, 99);
140                 printf(" Can't find function %s in module %s\n", current_func_name, modName);
141                 printf("Unable to add %s to local variable list in %s\n",
142                        name,current_func_name);
143             } else {
144                 locVar = new BPatch_localVar(name, ptrType, linenum, framePtr);
145                 fp->localVariables->addLocalVar( locVar);
146             }
147           }
148         } else if (current_func_name) {
149           // Try to find the BPatch_Function
150           ptrType = mod->moduleTypes->findType( ID);
151           fp = mod->findFunction(current_func_name);
152           if (!fp) {
153               char modName[100];
154               mod->getName(modName, 99);
155               printf(" Can't find function in BPatch_function vector: %s in module %s\n",
156                    current_func_name, modName);
157           } else {
158               locVar = new BPatch_localVar(name, ptrType, linenum, framePtr);
159               fp->localVariables->addLocalVar( locVar);
160           }
161         }
162     } else if (stabstr[cnt]) {
163         switch (stabstr[cnt]) {
164             case 'f': /*Local Function*/ {
165               char *scopeName=NULL;
166               char *lfuncName=NULL;
167               cnt++;
168               current_func_name = name;
169               // funcReturnID = parseSymDesc(stabstr, cnt);
170               funcReturnID = parseTypeUse(mod, stabstr, cnt, name);
171       
172               if (stabstr[cnt]==',') {
173                   cnt++;        /*skip the comma*/
174
175                   /* Local Function Name */
176                   lfuncName = getIdentifier(stabstr, cnt);
177
178                   assert(stabstr[cnt] == ',');
179                   cnt++;        /*skip the comma*/
180
181                   /* Scope Name of Local Function */
182                   scopeName = getIdentifier(stabstr, cnt);
183
184                   if (stabstr[cnt]) {
185                       fprintf(stderr, "Extra: %s\n", &stabstr[cnt]);
186                   }
187               }
188
189               if (!scopeName) { // Not an embeded function
190                   ptrType = mod->moduleTypes->findType(funcReturnID);
191                   if( !ptrType) ptrType = BPatch::bpatch->type_Untyped;
192
193                   fp = mod->findFunction( name );
194                   if (!fp) {
195                       showInfoCallback(string("missing local function ") +
196                           string(name));
197                   } else {
198                       // set return type.
199                       fp->setReturnType(ptrType);
200                   }
201               } else {
202                   printf("%s is an embedded function in %s\n",name, scopeName);
203               }
204               break;
205           }  
206
207           case 'F':/* Global Function */
208               cnt++; /*skipping 'F' */
209
210               funcReturnID = parseTypeUse(mod, stabstr, cnt, name);
211               current_func_name = name;
212
213               //
214               // For SunPro compilers there may be a parameter list after 
215               //   the return
216               //
217               while (stabstr[cnt] == ';') {
218                   cnt++;        // skip ';'
219                   (void) parseTypeUse(mod, stabstr, cnt, "");
220               }
221
222               ptrType = mod->moduleTypes->findType(funcReturnID);
223               if (!ptrType) ptrType = BPatch::bpatch->type_Untyped;
224
225               fp = mod->findFunction( name );
226               if (!fp) {
227                   // for FORTRAN look with trailing _
228                   char tempName[strlen(name)+2];
229                   sprintf(tempName, "%s_", name);
230
231                   // this leaks tempName XXXX 
232                   current_func_name = strdup(tempName);
233
234                   fp = mod->findFunction(tempName);
235                   if (!fp) {
236                       showInfoCallback(string("missing local function ") + 
237                           string(name));
238                   }
239               }
240
241               if (fp) {
242                   // set return type.
243                   fp->setReturnType(ptrType);
244               }
245               break;
246
247           case 'G':/* Global Varaible */
248               cnt++; /* skip the 'G' */
249
250               /* Get variable type number */
251               symdescID = parseTypeUse(mod, stabstr, cnt, name);
252               if (stabstr[cnt]) 
253                   fprintf(stderr, "\tMore to parse %s\n", &stabstr[cnt]);
254
255               // lookup symbol and set type
256               BPatch_type *BPtype;
257       
258               BPtype = mod->moduleTypes->findType(symdescID);
259               if (!BPtype) {
260                   fprintf(stderr, 
261                       "ERROR: unable to find type #%d for variable %s\n", 
262                        symdescID, name);
263               } else {
264                   /** XXXX - should add local too here **/
265                   mod->moduleTypes->addGlobalVariable(name, BPtype);
266               }
267               break;
268
269           case 'R':     // function parameter passed in a register (AIX style)
270           case 'P':     // function parameter passed in a register (GNU/Solaris)
271           case 'v':     // Fortran Local Variable
272           case 'p': {   // Function Parameter
273               cnt++; /* skip the 'p' */
274
275               /* Get variable type number */
276               symdescID = parseTypeUse(mod, stabstr, cnt, name);
277
278               if (stabstr[cnt] == ';') {
279                   // parameter type information, not used for now
280                   cnt = strlen(stabstr);
281               } else if (stabstr[cnt]) {
282                   fprintf(stderr, "\tMore to parse %s\n", &stabstr[cnt]);
283               }
284
285               ptrType = mod->moduleTypes->findType(symdescID);
286               if (!ptrType) ptrType = BPatch::bpatch->type_Untyped;
287
288               BPatch_localVar *param;
289               param = new BPatch_localVar(name, ptrType, linenum, framePtr);
290       
291               if (current_func_name) {
292                   fp = mod->findFunction( current_func_name );
293                   if (!fp) {
294                       showInfoCallback(string("missing local function ") + 
295                          string(current_func_name));
296                   } else { // found function, add parameter
297                       fp->funcParameters->addLocalVar(param);
298                       fp->addParam(name, ptrType, linenum, framePtr);
299                   }
300               } else {
301                   showInfoCallback(string("parameter without local function ") 
302                        + string(stabstr));
303               }
304               break;
305           }
306
307           case 'c': /* constant */
308               cnt++; /*move past the 'c' */
309
310               ptrType = parseConstantUse(mod, stabstr, cnt);
311               if (stabstr[cnt])
312                 printf("Parsing Error More constant info to Parse!!: %s\n",
313                     &(stabstr[cnt]));
314
315               if (!ptrType) ptrType = BPatch::bpatch->type_Untyped;
316
317               BPatch_localVar *var;
318               var = new BPatch_localVar(name, ptrType, linenum, 0);
319       
320               if (current_func_name) {
321                   fp = mod->findFunction( current_func_name );
322                   if (!fp) {
323                       showInfoCallback(string("missing local function ") + 
324                          string(current_func_name));
325                   } else { // found function, add parameter
326                       fp->funcParameters->addLocalVar(var);
327                       fp->addParam(name, ptrType, linenum, 0);
328                   }
329               } else {
330                   showInfoCallback(string("parameter without local function ") 
331                        + string(stabstr));
332               }
333               break;
334
335           case 'r':/* Register Variable */
336               cnt++; /*move past the 'r'*/
337               /* get type reference */
338
339               symdescID = parseSymDesc(stabstr, cnt);
340
341 #ifdef notdef
342               /* often have rNN=*yy - what is this ? jkh 11/30/00 */
343               if (stabstr[cnt])
344                 printf("Parsing Error More register info to Parse!!: %s\n",
345                     &(stabstr[cnt]));
346 #endif
347               break;
348
349           case 'S':/* Global Static Variable */ {
350               cnt++; /*move past the 'S'*/
351
352               /* get type reference */
353               symdescID = parseTypeUse(mod, stabstr, cnt, name);
354
355               // lookup symbol and set type
356               BPatch_type *BPtype;
357       
358               BPtype = mod->moduleTypes->findType(symdescID);
359               if (!BPtype) {
360                   fprintf(stderr, 
361                       "ERROR: unable to find type #%d for variable %s\n", 
362                        symdescID, name);
363               } else {
364                   BPatch_image *img = (BPatch_image *) mod->getObjParent();
365                   if (img->findVariable(name,false)) {
366                       mod->moduleTypes->addGlobalVariable(name, BPtype);
367                   }
368               }
369
370               if (stabstr[cnt])
371                 printf("Parsing Error More Global Static info to Parse!!: %s\n",
372                        &(stabstr[cnt]));
373               break;
374           }
375
376           case 't':     // Type Name 
377               cnt++; /*move past the 't'*/
378
379               /* get type reference */
380               symdescID = parseSymDesc(stabstr, cnt);
381
382               //Create BPatch_type.
383               if (stabstr[cnt] == '=') {
384                 /* More Stuff to parse, call parseTypeDef */
385                 stabstr = parseTypeDef(mod, (&stabstr[cnt+1]), name, symdescID);
386                 cnt = 0;
387                 // AIX seems to append an semi at the end of these
388                 if (stabstr[0] && strcmp(stabstr, ";")) {
389                     fprintf(stderr, "\tMore to parse %s\n", stabstr);
390                 }
391               } else {
392                 //Create BPatch_type defined as a pre-exisitng type.
393                 ptrType = mod->moduleTypes->findType(symdescID);
394                 if (!ptrType)
395                   ptrType = BPatch::bpatch->type_Untyped;
396                 newType = new BPatch_type(name, symdescID, ptrType);
397                 if (newType) {
398                     mod->moduleTypes->addType(newType);
399                 }
400               }
401               break;
402     
403           case ':':     // :T... - skip ":" and parse 'T'
404               if ((stabstr[cnt+1] == 't') || (stabstr[cnt+1] == 'T')) {
405                   // parse as a normal typedef
406                   parseStabString(mod, linenum, &stabstr[cnt+1], framePtr);
407               } else {
408                   fprintf(stderr, "Unknown type seen %s\n", stabstr);
409               }
410               break;
411
412           case 'T':/* Aggregate type tag -struct, union, enum */
413               cnt++; /*move past the 'T'*/
414
415               if (stabstr[cnt] == 't') {
416                   //C++ struct  tag "T" and type def "t"
417                   //printf("SKipping C++ Identifier t of Tt\n");
418                   cnt++;  //skip it
419               }
420
421               /* get type reference */
422               symdescID = parseSymDesc(stabstr, cnt);
423     
424               //Create BPatch_type.
425               if (stabstr[cnt] == '=') {
426                   /* More Stuff to parse, call parseTypeDef */
427                   stabstr = parseTypeDef(mod,(&stabstr[cnt+1]),name,symdescID);
428                   cnt = 0;
429                   if (stabstr[0]) {
430                       fprintf(stderr, "\tMore to parse %s\n", (&stabstr[cnt]));
431                   }
432               } else {
433                   //Create BPatch_type defined as a pre-exisitng type.
434                   newType = new BPatch_type(name, symdescID);
435                   if (newType) mod->moduleTypes->addType(newType);
436               }
437
438               break;
439
440           case 'V':/* Local Static Variable (common block vars too) */
441               cnt++; /*move past the 'V'*/
442
443               // printf("parsing 'v' type of %s\n", stabstr);
444               /* Get variable type number */
445               symdescID = parseTypeUse(mod, stabstr, cnt, name);
446               if (stabstr[cnt]) 
447                   fprintf(stderr, "\tMore to parse %s\n", &stabstr[cnt]);
448
449               // lookup symbol and set type
450               BPtype = mod->moduleTypes->findType(symdescID);
451               if (!BPtype) {
452                   fprintf(stderr, 
453                       "ERROR: unable to find type #%d for variable %s\n", 
454                        symdescID, name);
455                   break;
456               }
457               if (commonBlock) {
458                   /* This variable is in a common block */
459                   /* add it only if not already there, common block
460                      are re-defined for each subroutine but subroutines
461                      define only the member they care about
462                   */
463                   bool found = false;
464                   BPatch_Vector<BPatch_field *> *fields;
465
466                   fields = commonBlock->getComponents();
467                   if (fields) {
468                       for (int i=0; i < fields->size(); i++) {
469                           if (!strcmp((*fields)[i]->getName(), name)) {
470                               found = true;
471                               break;
472                           }
473                           int start1, start2, end1, end2;
474                           start1 = (*fields)[i]->getOffset();
475                           end1 = start1 + (*fields)[i]->getSize();
476                           start2 = framePtr;
477                           end2 = framePtr + BPtype->getSize();
478                           if (((start2 >= start1) && (start2 < end1)) ||
479                               ((start1 >= start2) && (start1 < end2))) {
480                               /* common block aliasing detected */
481                               printf("WARN: EQUIVALENCE used in %s: %s and %s\n",
482                                   current_func_name, name, (*fields)[i]->getName());
483                               found = true;
484                               break;
485                           }
486                       }
487                   }
488                   if (!found) {
489                       commonBlock->addField(name, BPatch_dataScalar, BPtype,
490                           framePtr, BPtype->getSize());
491                   }
492               } else {
493                   // put it into the local variable scope
494                   fp = mod->findFunction( current_func_name );
495                   if (!fp) {
496                       char modName[100];
497                       mod->getName(modName, 99);
498                       printf(" Can't find function %s in module %s\n", 
499                           current_func_name, modName);
500                       printf("Unable to add %s to local variable list in %s\n",
501                           name,current_func_name);
502                   } else {
503                       printf("adding local variable %s at %x\n",
504                         name, framePtr);
505                       locVar = new BPatch_localVar(name, BPtype, linenum, 
506                           framePtr, 5, false);
507                       fp->localVariables->addLocalVar( locVar);
508                   }
509               }
510               break;
511           default:
512               fprintf(stderr, "Unknown symbol descriptor: %c\n", stabstr[cnt]);
513       }   
514     }
515     return(&stabstr[cnt]);
516 } /* end of parseStabString */
517
518
519 //
520 // Is the current character a valid prefix for a symDesc non-terminal?
521 //
522 inline bool isSymId(char ch)
523 {
524     return ((ch == '(') || isdigit(ch) || (ch == '-'));
525 }
526
527 //
528 // parse a Symbol Descriptor ID
529 //      symDesc = <int> | (<int>,<int>)
530 //
531 int parseSymDesc(char *stabstr, int &cnt)
532 {
533     int id;
534     int lid;
535     int hid;
536     int sign = 1;
537     bool newForm = false;
538
539     // printf("\n    parseSymDesc call on %s\n", &stabstr[cnt+i]);
540
541     hid = 0; //file-number
542     // parse both an int and (int,int) format (file-number, type ID)
543     if (stabstr[cnt] == '(') {
544         cnt++;
545         while (isdigit(stabstr[cnt])) {
546             hid = hid * 10 + stabstr[cnt] - '0';
547             cnt++;
548         }
549
550         // skip ","
551         if (stabstr[cnt] == ',') cnt++;
552         newForm = true;
553     }
554        
555     if (stabstr[cnt] == '-') {
556         sign = -1;
557         cnt++;
558     }
559
560     lid = 0; //type ID
561     while (isdigit(stabstr[cnt])) {
562         lid = lid * 10 + stabstr[cnt] - '0';
563         cnt++;
564     }
565     if( hid != 0 )
566       assert(lid < 65536);
567     
568     // skip closing ')'
569     if (newForm) cnt++;
570
571     id = hid * 65536 + lid;
572     id = id * sign;
573     return id;
574 }
575
576 //
577 // parse an identifier up to a ":" or "," or ";"
578 //
579 char *getIdentifier(char *stabstr, int &cnt)
580 {
581     int i = 0;
582     char *ret;
583     int brCnt = 0;
584     bool idChar = true;
585
586     while(idChar) {
587         switch(stabstr[cnt+i]) {
588         case '<':
589         case '(':
590                 brCnt++;
591                 i++;
592                 break;
593
594         case '>':
595         case ')':
596                 brCnt--;
597                 i++;
598                 break;
599
600         case '\0':
601         case ':':
602         case ',':
603         case ';':
604                 if (brCnt)
605                         i++;
606                 else
607                         idChar = false;
608                 break;
609         default:
610                 i++;
611                 break;
612         }
613     }
614
615     ret = (char *) malloc(i+1);
616     assert(ret);
617
618     strncpy(ret, &stabstr[cnt], i);
619     ret[i] = '\0';
620     cnt += i;
621
622     return ret;
623 }
624
625 //
626 // Parse a use of a type.  
627 //
628 //      <typeUse> = <symDesc> | <symDesc>=<typeDef>
629 //
630 static int parseTypeUse(BPatch_module *mod,char *&stabstr, int &cnt, char *name)
631 {
632     int ret = parseSymDesc(stabstr, cnt);
633
634     if (stabstr[cnt] == '=') {
635         /* More Stuff to parse, call parseTypeDef */
636         stabstr = parseTypeDef(mod, (&stabstr[cnt+1]), name, ret);
637         cnt = 0;
638     }
639     return ret;
640 }
641
642 //
643 // parseCrossRef - internal struct/union pointer
644 //
645 //      <crossRef>      = [s|u|e]<ident>
646 //
647 static char *parseCrossRef(BPatch_typeCollection *moduleTypes, char *name,
648                     int ID, char *stabstr, int &cnt)
649 {
650     char *temp;
651     BPatch_type *newType;
652     BPatch_dataClass typdescr = BPatch_dataPointer;
653     cnt++; /* skip 'x'*/
654
655     if ((stabstr[cnt] == 's') ||        // struct 
656         (stabstr[cnt] == 'u') ||        // union
657         (stabstr[cnt] == 'e')) {        // enum
658       cnt++;
659
660       temp = getIdentifier(stabstr, cnt);
661       cnt++; /*skip ':' */
662
663       // Find type that this one points to.
664       BPatch_type *ptrType = moduleTypes->findType(temp);
665       if (ptrType) {
666         //Create a new B_type that points to a structure
667         newType = new BPatch_type(name, ID, typdescr, ptrType);
668         // Add to typeCollection
669         if(newType)
670           moduleTypes->addType(newType);
671         if(!newType) {
672           printf(" Can't Allocate new type ");
673           exit(-1);
674         }
675       }
676     } else {
677       /* don't know what it is?? */
678       
679       temp = getIdentifier(stabstr, cnt);
680       cnt++; /*skip ':' */
681     }
682
683     return( &(stabstr[cnt]));
684 }
685             
686 //
687 // parse the definition of an array.
688 //      arrayDef = ar<symDesc>;<symDesc>;<symDesc>;<symDesc> |
689 //                 ar<symDesc>;<symDesc>;<symDesc>;<arrayDef>
690 //
691 static BPatch_type *parseArrayDef(BPatch_module *mod, char *name,
692                      int ID, char *stabstr, int &cnt)
693 {
694     char *symdesc;
695     int symdescID;
696     int elementType;
697     BPatch_type *newType;
698     BPatch_type *ptrType;
699     int lowbound, hibound;
700
701     // format is ar<indexType>;<lowBound>;<highBound>;<elementType>
702
703     assert(stabstr[cnt] == 'a');
704
705     cnt ++;
706     if (stabstr[cnt] != 'r') {
707         printf("unknown array definition seen %s\n", &stabstr[cnt]);
708         return(NULL);
709     }
710
711     /* array with range */
712     symdesc = &(stabstr[cnt]);
713
714     cnt++;      /* skip 'r' */
715     symdescID = parseSymDesc(stabstr, cnt);
716  
717     cnt++; /* skip semicolon */
718     lowbound = parseSymDesc(stabstr, cnt);
719
720     cnt++; /* skip semicolon */
721     if (stabstr[cnt] == 'J') {
722         /* Fortran unbounded array */
723         hibound = 0;
724         cnt++;
725     } else if (stabstr[cnt] == 'T') {
726         /* Fortran runtime bound array - T0 is the form */
727         hibound = 0;
728         cnt += 2;
729     } else {
730         hibound = parseSymDesc(stabstr, cnt);
731     }
732
733     cnt++; /* skip semicolon */
734     elementType = parseSymDesc(stabstr, cnt);
735
736     if (stabstr[cnt] == 'a') {
737         /* multi dimensional array - Fortran style */
738         /* it has no valid id, so we give it a known duplicate */
739         ptrType = parseArrayDef(mod, name, 0, stabstr, cnt);
740     } else { 
741         if (stabstr[cnt] == '=') {
742             /* multi dimensional array */
743             char *temp;
744             temp = parseTypeDef(mod, &(stabstr[cnt+1]), NULL, elementType);
745             /* parseTypeDef uses old style of returning updated stabstr,
746                but parseArrayDef function needs to return an updated cnt.  
747                This simple hack updates cnt based on how far parseTypDef 
748                advances it.  jkh 12/4/00 */
749             cnt = temp-stabstr;
750             if (stabstr[cnt] == ':') {
751                 //C++ stuff
752                 //printf("Skipping C++ rest of array def:  %s\n",name );
753                 while (stabstr[cnt] != ';') cnt++;
754             }
755         }
756         ptrType = mod->moduleTypes->findType(elementType);
757     }
758
759     // fprintf(stderr, "Symbol Desriptor: %s Descriptor ID: %d Type: %d, Low Bound: %d, Hi Bound: %d,\n", symdesc, symdescID, elementType, lowbound, hibound);
760
761
762     if (ptrType) {
763         // Create new type - field in a struct or union
764         newType = new BPatch_type(name, ID, BPatch_dataArray, ptrType,
765                                  lowbound, hibound);
766         if (newType) {
767             // Add to Collection
768             mod->moduleTypes->addType(newType);
769         } else {
770             fprintf(stderr, " Could not create newType Array\n");
771             exit(-1);
772         }
773     }
774             
775     // fprintf(stderr, "parsed array def to %d, remaining %s\n", cnt, &stabstr[cnt]);
776     return (newType);
777 }
778
779 #if defined(i386_unknown_linux2_0)
780 //
781 // parse range type of the form:        
782 //
783 //      <rangeType> = r<typeNum>;<low>;<high>;
784 //
785 static char *parseRangeType(BPatch_module *mod,char *name,int ID, char *stabstr)
786 {
787     int cnt, i;
788     int sign = 1;
789
790     cnt = i = 0;
791
792     assert(stabstr[0] == 'r');
793     cnt++;
794
795     BPatch_dataClass typdescr = BPatchSymTypeRange;
796
797     // range index type - not used
798     (void) parseSymDesc(stabstr, cnt);
799
800     // printf("\tSymbol Descriptor: %c and Value: %d\n",tmpchar, symdescID);
801
802     cnt++; /* Discarding the ';' */
803     if (stabstr[cnt] == '-' ) cnt++;
804
805     /* Getting type range or size */
806     i=0;
807     while (isdigit(stabstr[cnt+i])) i++;
808
809     char *low = (char *)malloc(sizeof(char)*(i+1));
810     if(!strncpy(low, &(stabstr[cnt]), i))
811       /* Error copying size/range*/
812       exit(1);
813     low[i] = '\0';
814
815     cnt = cnt + i + 1; /* Discard other Semicolon */
816     i = 0;
817     if((stabstr[cnt]) == '-') {
818         i++; /* discard '-' for (long) unsigned int */
819     }
820     //Find high bound
821     while (isdigit(stabstr[cnt+i])) i++;
822     char *hi = (char *)malloc(sizeof(char)*(i+1));
823     if(!strncpy(hi, &(stabstr[cnt]), i))
824         /* Error copying upper range */
825         exit(1);
826     hi[i] = '\0';
827
828     int j = atol(hi);
829     
830     if (j == 0) {
831     //Size
832         int size = atol(low);
833
834         //Create new type
835         BPatch_type *newType = new BPatch_type( name, ID, typdescr, size);
836         //Add to Collection
837         mod->moduleTypes->addType(newType);
838     }
839     else {
840         //Range
841         //Create new type
842         BPatch_type *newType = new BPatch_type( name, ID, typdescr, low, hi);
843         //Add to Collection
844         mod->moduleTypes->addType(newType);
845     }
846
847     free(low);
848     free(hi);
849     hi=low=NULL;
850
851     cnt = cnt + i;
852     if( stabstr[cnt] == ';')
853       cnt++;
854     if( stabstr[cnt] ) {
855       fprintf(stderr, "ERROR: More to parse in type-r- %s\n", &(stabstr[cnt]));
856     }
857     
858     return(&(stabstr[cnt]));
859 }
860
861 #else
862 //
863 // parse range type of the form:        
864 //
865 //      <rangeType> = r<typeNum>;<low>;<high>;
866 //
867 static char *parseRangeType(BPatch_module *mod,char *name,int ID, char *stabstr)
868 {
869     int cnt, i;
870
871     cnt = i = 0;
872
873     assert(stabstr[0] == 'r');
874     cnt++;
875
876     BPatch_dataClass typdescr = BPatchSymTypeRange;
877
878     // range index type - not used
879     (void) parseSymDesc(stabstr, cnt);
880
881     // printf("\tSymbol Descriptor: %c and Value: %d\n",tmpchar, symdescID);
882
883     cnt++; /* Discarding the ';' */
884     if (stabstr[cnt] == '-' ) cnt++;
885
886     /* Getting type range or size */
887     i=0;
888     while (isdigit(stabstr[cnt+i])) i++;
889
890     char *temp = (char *)malloc(sizeof(char)*(i+1));
891     if(!strncpy(temp, &(stabstr[cnt]), i))
892       /* Error copying size/range*/
893       exit(1);
894     temp[i] = '\0';
895     int j = atol(temp);
896     
897     if( j <= 0 ){
898       /* range */
899       char *low = temp;
900       temp = NULL;
901       
902       cnt = cnt + i + 1; /* Discard other Semicolon */
903       i = 0;
904       if((stabstr[cnt]) == '-')
905         i++; /* discard '-' for (long) unsigned int */
906       
907       while(isdigit(stabstr[cnt+i])){
908         i++;
909       }
910       char *hi = (char *)malloc(sizeof(char)*(i+1));
911       if(!strncpy(hi, &(stabstr[cnt]), i))
912         /* Error copying upper range */
913         exit(1);
914       hi[i] = '\0';
915       // printf("\tLower limit: %s and Upper limit: %s\n", low, hi);
916       //Create new type
917       BPatch_type *newType = new BPatch_type( name, ID, typdescr, low, hi);
918       //Add to Collection
919       mod->moduleTypes->addType(newType);
920
921       free(low);
922       free(hi);
923       hi=low=NULL;
924       
925     } else if( j > 0){
926       /*size */
927       int size = (int)j;
928       
929       cnt = cnt + i + 1; /* Discard other Semicolon */
930       i = 0;
931       while(isdigit(stabstr[cnt+i])){
932         i++;
933       }
934       temp = (char *)malloc(sizeof(char)*(i+1));
935       if(!strncpy(temp, &(stabstr[cnt]), i))
936         /* Error copying Zero  */
937         exit(1);
938       temp[i] = '\0';
939       
940       j = atol(temp);
941       free(temp);
942       if(j == 0){
943         // printf("\tSize of Type : %d bytes\n",size);
944         //Create new type
945         BPatch_type *newType = new BPatch_type( name, ID, typdescr, size);
946         //Add to Collection
947         mod->moduleTypes->addType(newType);
948       } else {
949         // printf("Type RANGE: ERROR!!\n");
950       } 
951     }
952     cnt = cnt + i;
953     if( stabstr[cnt] == ';')
954       cnt++;
955     if( stabstr[cnt] ) {
956       fprintf(stderr, "ERROR: More to parse in type-r- %s\n", &(stabstr[cnt]));
957     }
958     
959     return(&(stabstr[cnt]));
960 }
961
962 #endif
963
964 //
965 //  <attrType> = @s<int>;<int>
966 //
967 static void parseAttrType(BPatch_module *mod, char *name,
968                          int ID, char *stabstr, int &cnt)
969 {
970     // format @s(size in bits); negative type number;
971     BPatch_dataClass typdescr = BPatch_dataTypeAttrib;
972
973     assert(stabstr[cnt] == '@');
974     cnt++; /* skip the @ */
975
976     if (stabstr[cnt] == 's') {
977       cnt++;
978       
979       int size = parseSymDesc(stabstr, cnt);
980       cnt++;  // skip ';'
981
982       int type = parseSymDesc(stabstr, cnt);
983       // skip ';' end of stab record ??? (at least for bool)
984       cnt++;
985
986       // Create a new B_type that points to a builtInTypes
987       BPatch_type *ptrType =BPatch::bpatch->builtInTypes->findBuiltInType(type);
988       
989       if (!ptrType) ptrType = BPatch::bpatch->type_Untyped;
990       
991       BPatch_type *newType = new BPatch_type(name, ID, typdescr, size/8, ptrType);
992       
993       // Add type to collection
994       if(newType) mod->moduleTypes->addType(newType);
995       if(!newType) {
996             printf(" Can't Allocate new type ");
997             exit(-1);
998       }
999       
1000       if (stabstr[cnt]) {
1001           printf("More Type Attribute to Parse: %s ID %d : %s\n", name,
1002                ID, &(stabstr[cnt]));
1003       }
1004     } else {
1005         //printf(" Unable to parse Type Attribute: %s ID %d : %s\n", 
1006         // name,ID, &(stabstr[cnt]));
1007     }
1008 }
1009
1010 //
1011 //  <refType> = &<typeUse>
1012 //
1013 static char *parseRefType(BPatch_module *mod, char *name,
1014                    int ID, char *stabstr, int &cnt)
1015 {
1016     /* reference to another type */
1017     assert(stabstr[cnt] == '&');
1018     cnt++;
1019     
1020     int refID = parseTypeUse(mod, stabstr, cnt, name);
1021     
1022     // Create a new B_type that points to a structure
1023     BPatch_type *ptrType = mod->moduleTypes->findType(refID);
1024     if (!ptrType) ptrType = BPatch::bpatch->type_Untyped;
1025     
1026     BPatch_type *newType = new BPatch_type(name, ID, BPatch_dataPointer, ptrType);
1027     // Add to typeCollection
1028     if(newType) {
1029         mod->moduleTypes->addType(newType);
1030     } else {
1031         printf(" Can't Allocate new type ");
1032         exit(-1);
1033     }
1034     
1035     return(&(stabstr[cnt]));
1036 }
1037
1038 //
1039 // parse a list of fields.
1040 //    Format is <fieldName>:<type-desc>;offset;size;
1041 //
1042 static char *parseFieldList(BPatch_module *mod, BPatch_type *newType, 
1043                             char *stabstr)
1044 {
1045     int cnt = 0;
1046     int size = 0;
1047     char *compname;
1048     int comptype= 0;
1049     int beg_offset=0;
1050     BPatch_visibility _vis = BPatch_visUnknown;
1051     BPatch_dataClass typedescr;
1052
1053     if (stabstr[cnt] == '!') {
1054         //Inheritance definition, Add base class field list to the current one
1055         //according to visibility rules.
1056
1057         cnt++; //Skip '!'
1058
1059         //Get # of base classes
1060         int baseClNum = atoi(getIdentifier(stabstr, cnt));
1061         cnt++; //Skip ','
1062
1063         //Skip information for each base class
1064         for(int i=0; i<baseClNum; ++i) {
1065                 //Skip virtual inheritance flag, base visibility flag and base offset
1066                 getIdentifier(stabstr, cnt);
1067                 cnt++; //Skip ','
1068
1069                 //Find base class type identifier
1070                 int baseID = parseSymDesc(stabstr, cnt);
1071
1072                 cnt++; //Skip ';'
1073
1074                 //Find base class
1075                 BPatch_type *baseCl = mod->moduleTypes->findType(baseID);
1076                 if (!baseCl || (baseCl->getDataClass() != BPatch_dataStructure) ) 
1077                         continue;
1078
1079                 //Get field descriptions of the base type
1080                 BPatch_Vector<BPatch_field *> *baseClFields = baseCl->getComponents();
1081                 for(int fieldNum=0; fieldNum < baseClFields->size(); fieldNum++) {
1082                         BPatch_field *field = (*baseClFields)[fieldNum];
1083
1084                         if (field->getVisibility() == BPatch_private)
1085                                 continue; //Can not add this member
1086
1087                         newType->addField(field->getName(), 
1088                                           field->getTypeDesc(),
1089                                           field->getType(),
1090                                           field->getOffset(),
1091                                           field->getVisibility());
1092                 }
1093         }
1094      }
1095
1096      while (stabstr[cnt] && (stabstr[cnt] != ';')) {
1097         typedescr = BPatch_dataScalar;
1098
1099         if (stabstr[cnt] == '~') {
1100                 //End of virtual class
1101                 while(stabstr[cnt] != ';') cnt++;
1102                 break; //End of class is reached
1103         }
1104
1105         compname = getIdentifier(stabstr, cnt);
1106 /*
1107         if (strlen(compname) == 0) {
1108                 //Something wrong! Most probably unhandled C++ type
1109                 //Skip the rest of the structure
1110                 while(stabstr[cnt]) cnt++;
1111                 return(&stabstr[cnt]);
1112         }
1113 */
1114         cnt++;  // Skip ":"
1115
1116         if ((stabstr[cnt]) == ':') {
1117           //Method definition
1118           typedescr = BPatch_dataMethod;
1119           cnt++;
1120         }
1121
1122         if ((stabstr[cnt]) == '/') { // visibility C++
1123           cnt++; /* get '/' */
1124           switch (stabstr[cnt]) {
1125           case '0':
1126             _vis = BPatch_private;
1127             break;
1128           case '1':
1129             _vis = BPatch_protected;
1130             break;
1131           case '2':
1132             _vis = BPatch_public;
1133             break;
1134           case '9':
1135             _vis = BPatch_optimized;
1136             break;
1137           default:
1138             _vis = BPatch_visUnknown;
1139           }
1140           cnt++; // get visibility value
1141         }
1142
1143         // should be a typeDescriptor
1144         comptype = parseTypeUse(mod, stabstr, cnt, "");
1145
1146         if (stabstr[cnt] == ':') {
1147                 cnt++; //Discard ':'
1148
1149                 beg_offset = 0;
1150                 size = 0;
1151                 if (typedescr == BPatch_dataMethod) {
1152                         while(1) {
1153                                 //Mangling of arguments
1154                                 while(stabstr[cnt] != ';') cnt++;
1155
1156                                 cnt++; //Skip ';'
1157                                 cnt++; //Skip visibility
1158                                 cnt++; //Skip method modifier
1159                                 if (stabstr[cnt] == '*') {
1160                                         //Virtual fcn definition
1161                                         cnt++;
1162                                         while(stabstr[cnt] != ';') cnt++; //Skip vtable index
1163                                         cnt++; //Skip ';'
1164                                         while(stabstr[cnt] != ';') cnt++; //Skip type number to 
1165                                                                           //the base class
1166                                         while(stabstr[cnt] == ';') cnt++; //Skip all ';'
1167                                 }
1168                                 else if ( (stabstr[cnt] == '.') ||
1169                                           (stabstr[cnt] == '?') )
1170                                         cnt++; //Skip '.' or '?'
1171
1172                                 if (isSymId(stabstr[cnt])) {
1173                                         //Still more to process, but what is this?
1174                                         //It seems, it is another fcn definition
1175                                         parseTypeUse(mod, stabstr, cnt, "");
1176                                         if (stabstr[cnt] == ':') 
1177                                                 cnt++; //Discard ':'
1178                                 }
1179                                 else {
1180                                         if (stabstr[cnt] == '~')
1181                                                 cnt--; //Get back to ';'
1182                                         else if (stabstr[cnt] == ';') {
1183                                                 //Skip all ';' except last one or two
1184                                                 while(stabstr[cnt] == ';') cnt++;
1185                                                 if (!stabstr[cnt] || (stabstr[cnt] == ',') )
1186                                                         cnt--; //There must be two ';'
1187                                                 cnt--;
1188                                         }
1189                                         else {
1190                                                 //Something wrong! Skip entire stab record and exit
1191                                                 while(stabstr[cnt]) cnt++;
1192                                                 return (&stabstr[cnt]);
1193                                         }
1194
1195                                         break;
1196                                 }
1197                         } //While 1
1198                 }
1199                 else {
1200                         //Static member var
1201                         char *varName = getIdentifier(stabstr, cnt);
1202                         free(varName);
1203                         //Don't know what to do!
1204                 }
1205         }
1206         else if (stabstr[cnt] == ',') {
1207                 assert(stabstr[cnt] == ',');
1208                 cnt++;  // skip ','
1209                 beg_offset = parseSymDesc(stabstr, cnt);
1210
1211                 if (stabstr[cnt] == ',') {
1212                         cnt++;  // skip ','
1213                         size = parseSymDesc(stabstr, cnt);
1214                 }
1215                 else
1216                         size = 0;
1217         }
1218
1219         assert(stabstr[cnt] == ';');
1220         cnt++;  // skip ';' at end of field
1221
1222         // printf("\tType: %d, Starting Offset: %d (bits), Size: %d (bits)\n", comptype, beg_offset, size);
1223         // Add struct field to type
1224         BPatch_type *fieldType = mod->moduleTypes->findType(comptype);
1225         if (fieldType == NULL) {
1226                 //C++ compilers may add extra fields whose types might not available.
1227                 //Assign void type to these kind of fields. --Mehmet
1228                 fieldType = mod->moduleTypes->findType("void");
1229         }
1230         if (_vis == BPatch_visUnknown) {
1231             newType->addField(compname, typedescr, fieldType,
1232                             beg_offset, size);
1233         } else {
1234             newType->addField(compname, typedescr, fieldType,
1235                             beg_offset, size, _vis);
1236             //printf("Adding Component with VISIBILITY STRUCT\n");
1237         }
1238     }
1239
1240     // should end with a ';'
1241     if (stabstr[cnt] == ';') {
1242         return &stabstr[cnt+1];
1243     } else if (stabstr[cnt] == '\0') {
1244         return &stabstr[cnt];
1245     } else {
1246         printf("invalid stab record: %s\n", &stabstr[cnt]);
1247         abort();
1248     }
1249 }
1250
1251 //
1252 // This function takes a <typeDef> and parses it 
1253 //
1254 //      <typeDef> = <symDesc>   |
1255 //              <crossRef>      |       
1256 //              *<typeUse>      |       Pointer to a type
1257 //              <arrayDef>      |
1258 //              f<typeUse>      |       function type
1259 //              R<int>,<int>    |       Real type 
1260 //              b[u|s][c|]<int>;<int>;<int>     |       Builtin
1261 //              <rangeType>     |
1262 //              e<enumType>     |
1263 //              <attrType>      |
1264 //              <refType>       |
1265 //              k<typeDef>      |       SunPro constant
1266 //              B<typeDef>      |       SunPro volatile
1267 //              M<symDesc>;<int>|       Fortran CHARACTER array
1268 //              s<int><fields>  |       Structure <int> is size
1269 //              u<int><fields>  |       Union <int> is size
1270 //              V<typeUse>
1271 //
1272 //      <enumType> = <ident>:<int> | <ident>:<int>,<enumType>
1273 //
1274 // It adds the typeDef to the type definition with the name name, and id ID.
1275 //
1276 static char *parseTypeDef(BPatch_module *mod, char *stabstr, char *name, int ID)
1277 {
1278
1279     BPatch_type * newType = NULL;
1280     BPatch_type * ptrType = NULL;
1281   
1282     char * temp=NULL;
1283     char * compsymdesc=NULL;
1284   
1285     BPatch_dataClass typdescr;
1286     int ptrID=0;
1287     
1288     int value;
1289     int cnt,i,j,k;
1290     int structsize;
1291     int type;
1292     cnt = i = j = k = 0;
1293   
1294     assert (stabstr[0] != '=');
1295
1296     // fprintf(stderr, "parsing %s\n", stabstr);
1297     if (isSymId(stabstr[0])) {
1298         typdescr = BPatch_dataScalar;
1299         type = parseSymDesc(stabstr, cnt);
1300                     
1301         if (ID == type) {
1302             newType = new BPatch_type( name, ID, typdescr, type);
1303             if (newType) mod->moduleTypes->addType(newType);
1304             if(!newType) {
1305               printf(" Can't Allocate newType ");
1306               exit(-1);
1307             }
1308         } else if (stabstr[cnt] == '=') {
1309             // XXX - in the new type t(0,1)=(0,2)=s... is possible
1310             //       skip the second id for now -- jkh 3/21/99
1311             stabstr = parseTypeDef(mod, &(stabstr[cnt+i+1]), name, type);
1312             cnt = 0;
1313             BPatch_type *oldType;
1314             
1315             oldType = mod->moduleTypes->findType(type);
1316             if(!oldType) oldType = BPatch::bpatch->type_Untyped;
1317             newType = new BPatch_type( name, ID, typdescr, oldType);
1318             if (newType) mod->moduleTypes->addType(newType);
1319         } else {
1320             BPatch_type *oldType;
1321             
1322             oldType = mod->moduleTypes->findType(type);
1323             newType = new BPatch_type( name, ID, typdescr, oldType);
1324             if(newType) mod->moduleTypes->addType(newType);
1325             if(!newType) {
1326                 printf(" Can't Allocate newType ");
1327                 exit(-1);
1328             }
1329         }
1330     } else {
1331       switch (stabstr[0]) {
1332           case 'x':  //cross reference 
1333             parseCrossRef(mod->moduleTypes, name, ID, stabstr, cnt);
1334             break;
1335              
1336           case '*':
1337             typdescr = BPatch_dataPointer;
1338             /* pointer to another type */
1339             cnt++;
1340             ptrID = parseTypeUse(mod, stabstr, cnt, NULL);
1341
1342             // Create a new B_type that points to a structure
1343             ptrType = mod->moduleTypes->findType(ptrID);
1344             if (!ptrType) ptrType = BPatch::bpatch->type_Untyped;
1345
1346             newType = new BPatch_type(NULL, ID, BPatch_dataPointer, ptrType);
1347             // Add to typeCollection
1348             if(newType) mod->moduleTypes->addType(newType);
1349             if(!newType) {
1350                 printf(" Can't Allocate new type ");
1351                 exit(-1);
1352             }
1353
1354             return(&(stabstr[cnt]));
1355             break;
1356
1357           case 'a':
1358               (void) parseArrayDef(mod, name, ID, stabstr, cnt);
1359               return (&stabstr[cnt]);
1360               break;
1361
1362           case 'f':
1363                 /* function type */
1364                 typdescr = BPatch_dataFunction;
1365
1366                 cnt++; /* skip the f */
1367                 type = parseTypeUse(mod, stabstr, cnt, name);
1368
1369                 break;
1370
1371          case 'M': {
1372                 /* CHARACTER ??? */
1373                 cnt++; // skip  'M'
1374
1375                 int baseType = parseSymDesc(stabstr, cnt);
1376                 if (baseType != -2 || (stabstr[cnt] != ';')) {
1377                     printf("unexpected non character array %s\n", stabstr);
1378                 } else {
1379                     cnt++; // skip ';'
1380                     int size = parseSymDesc(stabstr, cnt);
1381
1382                     ptrType = mod->moduleTypes->findType(baseType);
1383                     newType = new BPatch_type(name, ID, BPatch_dataArray, ptrType,
1384                         1, size);
1385                     mod->moduleTypes->addType(newType);
1386                 }
1387                 break;
1388
1389          }
1390          case 'R': {
1391                 // Define a floating point type - R fp-type; bytes;
1392                 cnt++;
1393                 (void) parseSymDesc(stabstr, cnt);
1394                 cnt ++;
1395
1396                 int bytes = parseSymDesc(stabstr, cnt);
1397
1398                 newType = new BPatch_type(name, ID, BPatch_dataBuilt_inType, bytes);
1399                 mod->moduleTypes->addType(newType);
1400
1401                 if (stabstr[cnt] == ';') cnt++; // skip the final ';'
1402
1403                 break;
1404           }
1405
1406           case 'b': {
1407                 // builtin type b  - signed char-flag width; offset; nbits
1408                 typdescr = BPatch_dataBuilt_inType;
1409                 int limit = strlen(&stabstr[cnt]);
1410
1411                 // skip to width
1412                 while (stabstr[cnt+i] != ';' && (i < limit)) i++;       
1413                 if (i >= limit) return(&(stabstr[cnt]));
1414
1415                 i++;    // skip the ';'
1416
1417                 // skip to offset
1418                 while (stabstr[cnt+i] != ';' && (i < limit)) i++;       
1419                 if (i >= limit) return(&(stabstr[cnt]));
1420                 i++;
1421
1422                 cnt += i;
1423                 int nbits = parseSymDesc(stabstr, cnt);
1424                 
1425                 if (stabstr[cnt]) cnt++;        // skip the final ';'
1426
1427                 newType = new BPatch_type(name, ID, BPatch_dataBuilt_inType, 
1428                     nbits/8);
1429                 //Add to Collection
1430                 mod->moduleTypes->addType(newType);
1431
1432                 return &stabstr[cnt];
1433                 break;
1434             }
1435
1436         case 'r':               // range type
1437             return parseRangeType(mod, name, ID, stabstr);
1438             break;
1439
1440         case 'e':               // Enumerated type
1441             typdescr = BPatch_dataEnumerated;
1442             cnt++;      /* skip the 'e' */
1443
1444             // Create new Enum type
1445             newType = new BPatch_type(name, ID, typdescr);
1446             // Add type to collection
1447             mod->moduleTypes->addType(newType);
1448                 
1449             while (stabstr[cnt]) {
1450                 /* Get enum component value */
1451                 compsymdesc = getIdentifier(stabstr, cnt);
1452                 cnt++; /* skip colon */
1453                   
1454                 value = parseSymDesc(stabstr, cnt);
1455
1456                 // add enum field to type
1457                 newType->addField(compsymdesc, BPatch_dataScalar, value);
1458                   
1459                 free(temp);
1460                 free(compsymdesc);
1461                 temp = compsymdesc = NULL;
1462
1463                 cnt++; /* skip trailing comma */
1464                 if ((stabstr[cnt]) == ';') cnt++; /* End of enum stab record */
1465             }
1466             break;
1467             
1468         case '@':  // type attribute, defines size and type (negative num)
1469             parseAttrType(mod, name, ID, stabstr, cnt);
1470             break;
1471
1472         case '&': //XXX- Need to complete, may be more to parse jdd 4/22/99
1473             return parseRefType(mod, name, ID, stabstr, cnt);
1474             break;
1475
1476         case 'k':       // Sun constant type s<typeDef> - parse as <typeDef>
1477             return parseTypeDef(mod, &stabstr[cnt+1], name, ID);
1478             break;
1479
1480         case 'V':       // AIX colatile ? type V<typeDef> - parse as <typeDef>
1481         case 'B':       // Sun volatile type B<typeDef> - parse as <typeDef>
1482             return parseTypeDef(mod, &stabstr[cnt+1], name, ID);
1483             break;
1484
1485         case 's':       // struct
1486         case 'u':       // union
1487             /* Type descriptor */
1488             if (stabstr[cnt] == 's') {
1489                 typdescr = BPatch_dataStructure;
1490             } else {
1491                 typdescr = BPatch_dataUnion;
1492             }
1493
1494             cnt++;              // skip to size
1495             structsize = parseSymDesc(stabstr, cnt);
1496             
1497             //Create new type
1498             newType = new BPatch_type(name, ID, typdescr, structsize);
1499             //add to type collection
1500             mod->moduleTypes->addType(newType);
1501               
1502             return parseFieldList(mod, newType, &stabstr[cnt]);
1503
1504             break;
1505
1506         case 'Z':  // What is this ??? - jkh 10/14/99 (xlc compiler uses it)
1507             return (&stabstr[1]);
1508             break;
1509
1510         case '#':
1511             //Class method definition
1512             cnt++; //Skip '#'
1513             if (stabstr[cnt] == '#') {
1514                 //Get return type
1515                 cnt++; //Skip '#'
1516                 parseTypeUse(mod, stabstr, cnt, name);
1517             }
1518             else {
1519                 while(1) {
1520                         //Skip class type, return typ and arg types
1521                         parseTypeUse(mod, stabstr, cnt, name);
1522                         if (stabstr[cnt] == ',')
1523                                 cnt++;
1524                         else if (stabstr[cnt] == ';')
1525                                 break;
1526                 }
1527             }
1528
1529             cnt++; //Skip ';'
1530             return(&(stabstr[cnt]));
1531             break;
1532
1533         default:
1534             fprintf(stderr, "ERROR: Unrecognized str = %s\n", &stabstr[cnt]);
1535             return "";
1536             break;
1537       }
1538     }
1539
1540     return(&(stabstr[cnt]));
1541 } /* end of parseTypeDef*/
1542
1543 //
1544 // parseConstantUse - parse a constant (used by Fortran PARAMETERS)
1545 //
1546 // <constantUse> = =i<int> |
1547 //                 =r <float>
1548 //
1549 //
1550 static BPatch_type *parseConstantUse(BPatch_module *mod, char *stabstr, int &cnt)
1551 {
1552     // skip =
1553     cnt++;
1554
1555     BPatch_type *ret;
1556
1557     if (stabstr[cnt] == 'i') {
1558         ret = mod->moduleTypes->findType("integer*4");
1559     } else if (stabstr[cnt] == 'r') {
1560         ret = mod->moduleTypes->findType("double");
1561     } else {
1562         printf("unknown constant type %s\n", &stabstr[cnt]);
1563         ret = NULL;
1564     }
1565
1566     cnt = strlen(stabstr);
1567
1568     return ret;
1569 }