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