2 * Copyright (c) 1996 Barton P. Miller
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.
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.
18 * (for other uses, please contact us at paradyn@cs.wisc.edu)
20 * All warranties, including without limitation, any warranty of
21 * merchantability or fitness for a particular purpose, are hereby
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.
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.
45 #include "BPatch_module.h"
46 #include "BPatch_collections.h"
47 #include "showerror.h"
49 extern char *current_func_name;
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);
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.
64 // Each non-terminal in the grammer has a function of the form parse<NT>.
66 // The grammar for a non-terminal appears in the comments just before
67 // the non-terminal parsing function
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
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> |
81 // <ident>:S<typeUse> |
82 // <ident>:[pPr]<typeUse> |
83 // <ident>::T<typeUse> |
84 // <ident>:t<typeUse> |
85 // <ident>:T<typeUse> |
86 // <ident>:v<typeUse> |
89 // <paramList> = | <typeUse>;<paramList>
91 char *parseStabString(BPatch_module *mod, int linenum, char *stabstr,
92 int framePtr, BPatch_type *commonBlock = NULL)
100 BPatch_type * ptrType = NULL;
101 BPatch_type * newType = NULL; // For new types to add to the collection
102 BPatch_localVar *locVar = NULL;
106 /* get type or variable name */
107 char *name = getIdentifier(stabstr, cnt);
111 // AIX puts out some symbols like this eg .bs
112 if (stabstr[cnt] != ':') {
116 if (stabstr[cnt] == ':') {
121 if (isSymId(stabstr[cnt])) {
122 /* instance of a predefined type */
124 ID = parseSymDesc(stabstr, cnt);
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);
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
135 // Still need to add to local variable list if in a function
136 fp = mod->findFunction( current_func_name );
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);
144 locVar = new BPatch_localVar(name, ptrType, linenum, framePtr);
145 fp->localVariables->addLocalVar( locVar);
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);
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);
158 locVar = new BPatch_localVar(name, ptrType, linenum, framePtr);
159 fp->localVariables->addLocalVar( locVar);
162 } else if (stabstr[cnt]) {
163 switch (stabstr[cnt]) {
164 case 'f': /*Local Function*/ {
165 char *scopeName=NULL;
166 char *lfuncName=NULL;
168 current_func_name = name;
169 // funcReturnID = parseSymDesc(stabstr, cnt);
170 funcReturnID = parseTypeUse(mod, stabstr, cnt, name);
172 if (stabstr[cnt]==',') {
173 cnt++; /*skip the comma*/
175 /* Local Function Name */
176 lfuncName = getIdentifier(stabstr, cnt);
178 assert(stabstr[cnt] == ',');
179 cnt++; /*skip the comma*/
181 /* Scope Name of Local Function */
182 scopeName = getIdentifier(stabstr, cnt);
185 fprintf(stderr, "Extra: %s\n", &stabstr[cnt]);
189 if (!scopeName) { // Not an embeded function
190 ptrType = mod->moduleTypes->findType(funcReturnID);
191 if( !ptrType) ptrType = BPatch::bpatch->type_Untyped;
193 fp = mod->findFunction( name );
195 showInfoCallback(string("missing local function ") +
199 fp->setReturnType(ptrType);
202 printf("%s is an embedded function in %s\n",name, scopeName);
207 case 'F':/* Global Function */
208 cnt++; /*skipping 'F' */
210 funcReturnID = parseTypeUse(mod, stabstr, cnt, name);
211 current_func_name = name;
214 // For SunPro compilers there may be a parameter list after
217 while (stabstr[cnt] == ';') {
219 (void) parseTypeUse(mod, stabstr, cnt, "");
222 ptrType = mod->moduleTypes->findType(funcReturnID);
223 if (!ptrType) ptrType = BPatch::bpatch->type_Untyped;
225 fp = mod->findFunction( name );
227 // for FORTRAN look with trailing _
228 char tempName[strlen(name)+2];
229 sprintf(tempName, "%s_", name);
231 // this leaks tempName XXXX
232 current_func_name = strdup(tempName);
234 fp = mod->findFunction(tempName);
236 showInfoCallback(string("missing local function ") +
243 fp->setReturnType(ptrType);
247 case 'G':/* Global Varaible */
248 cnt++; /* skip the 'G' */
250 /* Get variable type number */
251 symdescID = parseTypeUse(mod, stabstr, cnt, name);
253 fprintf(stderr, "\tMore to parse %s\n", &stabstr[cnt]);
255 // lookup symbol and set type
258 BPtype = mod->moduleTypes->findType(symdescID);
261 "ERROR: unable to find type #%d for variable %s\n",
264 /** XXXX - should add local too here **/
265 mod->moduleTypes->addGlobalVariable(name, BPtype);
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' */
275 /* Get variable type number */
276 symdescID = parseTypeUse(mod, stabstr, cnt, name);
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]);
285 ptrType = mod->moduleTypes->findType(symdescID);
286 if (!ptrType) ptrType = BPatch::bpatch->type_Untyped;
288 BPatch_localVar *param;
289 param = new BPatch_localVar(name, ptrType, linenum, framePtr);
291 if (current_func_name) {
292 fp = mod->findFunction( current_func_name );
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);
301 showInfoCallback(string("parameter without local function ")
307 case 'c': /* constant */
308 cnt++; /*move past the 'c' */
310 ptrType = parseConstantUse(mod, stabstr, cnt);
312 printf("Parsing Error More constant info to Parse!!: %s\n",
315 if (!ptrType) ptrType = BPatch::bpatch->type_Untyped;
317 BPatch_localVar *var;
318 var = new BPatch_localVar(name, ptrType, linenum, 0);
320 if (current_func_name) {
321 fp = mod->findFunction( current_func_name );
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);
330 showInfoCallback(string("parameter without local function ")
335 case 'r':/* Register Variable */
336 cnt++; /*move past the 'r'*/
337 /* get type reference */
339 symdescID = parseSymDesc(stabstr, cnt);
342 /* often have rNN=*yy - what is this ? jkh 11/30/00 */
344 printf("Parsing Error More register info to Parse!!: %s\n",
349 case 'S':/* Global Static Variable */ {
350 cnt++; /*move past the 'S'*/
352 /* get type reference */
353 symdescID = parseTypeUse(mod, stabstr, cnt, name);
355 // lookup symbol and set type
358 BPtype = mod->moduleTypes->findType(symdescID);
361 "ERROR: unable to find type #%d for variable %s\n",
364 BPatch_image *img = (BPatch_image *) mod->getObjParent();
365 if (img->findVariable(name,false)) {
366 mod->moduleTypes->addGlobalVariable(name, BPtype);
371 printf("Parsing Error More Global Static info to Parse!!: %s\n",
376 case 't': // Type Name
377 cnt++; /*move past the 't'*/
379 /* get type reference */
380 symdescID = parseSymDesc(stabstr, cnt);
382 //Create BPatch_type.
383 if (stabstr[cnt] == '=') {
384 /* More Stuff to parse, call parseTypeDef */
385 stabstr = parseTypeDef(mod, (&stabstr[cnt+1]), name, symdescID);
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);
392 //Create BPatch_type defined as a pre-exisitng type.
393 ptrType = mod->moduleTypes->findType(symdescID);
395 ptrType = BPatch::bpatch->type_Untyped;
396 newType = new BPatch_type(name, symdescID, ptrType);
398 mod->moduleTypes->addType(newType);
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);
408 fprintf(stderr, "Unknown type seen %s\n", stabstr);
412 case 'T':/* Aggregate type tag -struct, union, enum */
413 cnt++; /*move past the 'T'*/
415 if (stabstr[cnt] == 't') {
416 //C++ struct tag "T" and type def "t"
417 //printf("SKipping C++ Identifier t of Tt\n");
421 /* get type reference */
422 symdescID = parseSymDesc(stabstr, cnt);
424 //Create BPatch_type.
425 if (stabstr[cnt] == '=') {
426 /* More Stuff to parse, call parseTypeDef */
427 stabstr = parseTypeDef(mod,(&stabstr[cnt+1]),name,symdescID);
430 fprintf(stderr, "\tMore to parse %s\n", (&stabstr[cnt]));
433 //Create BPatch_type defined as a pre-exisitng type.
434 newType = new BPatch_type(name, symdescID);
435 if (newType) mod->moduleTypes->addType(newType);
440 case 'V':/* Local Static Variable (common block vars too) */
441 cnt++; /*move past the 'V'*/
443 // printf("parsing 'v' type of %s\n", stabstr);
444 /* Get variable type number */
445 symdescID = parseTypeUse(mod, stabstr, cnt, name);
447 fprintf(stderr, "\tMore to parse %s\n", &stabstr[cnt]);
449 // lookup symbol and set type
450 BPtype = mod->moduleTypes->findType(symdescID);
453 "ERROR: unable to find type #%d for variable %s\n",
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
464 BPatch_Vector<BPatch_field *> *fields;
466 fields = commonBlock->getComponents();
468 for (int i=0; i < fields->size(); i++) {
469 if (!strcmp((*fields)[i]->getName(), name)) {
473 int start1, start2, end1, end2;
474 start1 = (*fields)[i]->getOffset();
475 end1 = start1 + (*fields)[i]->getSize();
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());
489 commonBlock->addField(name, BPatch_dataScalar, BPtype,
490 framePtr, BPtype->getSize());
493 // put it into the local variable scope
494 fp = mod->findFunction( current_func_name );
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);
503 printf("adding local variable %s at %x\n",
505 locVar = new BPatch_localVar(name, BPtype, linenum,
507 fp->localVariables->addLocalVar( locVar);
512 fprintf(stderr, "Unknown symbol descriptor: %c\n", stabstr[cnt]);
515 return(&stabstr[cnt]);
516 } /* end of parseStabString */
520 // Is the current character a valid prefix for a symDesc non-terminal?
522 inline bool isSymId(char ch)
524 return ((ch == '(') || isdigit(ch) || (ch == '-'));
528 // parse a Symbol Descriptor ID
529 // symDesc = <int> | (<int>,<int>)
531 int parseSymDesc(char *stabstr, int &cnt)
537 bool newForm = false;
539 // printf("\n parseSymDesc call on %s\n", &stabstr[cnt+i]);
541 hid = 0; //file-number
542 // parse both an int and (int,int) format (file-number, type ID)
543 if (stabstr[cnt] == '(') {
545 while (isdigit(stabstr[cnt])) {
546 hid = hid * 10 + stabstr[cnt] - '0';
551 if (stabstr[cnt] == ',') cnt++;
555 if (stabstr[cnt] == '-') {
561 while (isdigit(stabstr[cnt])) {
562 lid = lid * 10 + stabstr[cnt] - '0';
571 id = hid * 65536 + lid;
577 // parse an identifier up to a ":" or "," or ";"
579 char *getIdentifier(char *stabstr, int &cnt)
587 switch(stabstr[cnt+i]) {
615 ret = (char *) malloc(i+1);
618 strncpy(ret, &stabstr[cnt], i);
626 // Parse a use of a type.
628 // <typeUse> = <symDesc> | <symDesc>=<typeDef>
630 static int parseTypeUse(BPatch_module *mod,char *&stabstr, int &cnt, char *name)
632 int ret = parseSymDesc(stabstr, cnt);
634 if (stabstr[cnt] == '=') {
635 /* More Stuff to parse, call parseTypeDef */
636 stabstr = parseTypeDef(mod, (&stabstr[cnt+1]), name, ret);
643 // parseCrossRef - internal struct/union pointer
645 // <crossRef> = [s|u|e]<ident>
647 static char *parseCrossRef(BPatch_typeCollection *moduleTypes, char *name,
648 int ID, char *stabstr, int &cnt)
651 BPatch_type *newType;
652 BPatch_dataClass typdescr = BPatch_dataPointer;
655 if ((stabstr[cnt] == 's') || // struct
656 (stabstr[cnt] == 'u') || // union
657 (stabstr[cnt] == 'e')) { // enum
660 temp = getIdentifier(stabstr, cnt);
663 // Find type that this one points to.
664 BPatch_type *ptrType = moduleTypes->findType(temp);
666 //Create a new B_type that points to a structure
667 newType = new BPatch_type(name, ID, typdescr, ptrType);
668 // Add to typeCollection
670 moduleTypes->addType(newType);
672 printf(" Can't Allocate new type ");
677 /* don't know what it is?? */
679 temp = getIdentifier(stabstr, cnt);
683 return( &(stabstr[cnt]));
687 // parse the definition of an array.
688 // arrayDef = ar<symDesc>;<symDesc>;<symDesc>;<symDesc> |
689 // ar<symDesc>;<symDesc>;<symDesc>;<arrayDef>
691 static BPatch_type *parseArrayDef(BPatch_module *mod, char *name,
692 int ID, char *stabstr, int &cnt)
697 BPatch_type *newType;
698 BPatch_type *ptrType;
699 int lowbound, hibound;
701 // format is ar<indexType>;<lowBound>;<highBound>;<elementType>
703 assert(stabstr[cnt] == 'a');
706 if (stabstr[cnt] != 'r') {
707 printf("unknown array definition seen %s\n", &stabstr[cnt]);
711 /* array with range */
712 symdesc = &(stabstr[cnt]);
714 cnt++; /* skip 'r' */
715 symdescID = parseSymDesc(stabstr, cnt);
717 cnt++; /* skip semicolon */
718 lowbound = parseSymDesc(stabstr, cnt);
720 cnt++; /* skip semicolon */
721 if (stabstr[cnt] == 'J') {
722 /* Fortran unbounded array */
725 } else if (stabstr[cnt] == 'T') {
726 /* Fortran runtime bound array - T0 is the form */
730 hibound = parseSymDesc(stabstr, cnt);
733 cnt++; /* skip semicolon */
734 elementType = parseSymDesc(stabstr, cnt);
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);
741 if (stabstr[cnt] == '=') {
742 /* multi dimensional array */
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 */
750 if (stabstr[cnt] == ':') {
752 //printf("Skipping C++ rest of array def: %s\n",name );
753 while (stabstr[cnt] != ';') cnt++;
756 ptrType = mod->moduleTypes->findType(elementType);
759 // fprintf(stderr, "Symbol Desriptor: %s Descriptor ID: %d Type: %d, Low Bound: %d, Hi Bound: %d,\n", symdesc, symdescID, elementType, lowbound, hibound);
763 // Create new type - field in a struct or union
764 newType = new BPatch_type(name, ID, BPatch_dataArray, ptrType,
768 mod->moduleTypes->addType(newType);
770 fprintf(stderr, " Could not create newType Array\n");
775 // fprintf(stderr, "parsed array def to %d, remaining %s\n", cnt, &stabstr[cnt]);
779 #if defined(i386_unknown_linux2_0)
781 // parse range type of the form:
783 // <rangeType> = r<typeNum>;<low>;<high>;
785 static char *parseRangeType(BPatch_module *mod,char *name,int ID, char *stabstr)
792 assert(stabstr[0] == 'r');
795 BPatch_dataClass typdescr = BPatchSymTypeRange;
797 // range index type - not used
798 (void) parseSymDesc(stabstr, cnt);
800 // printf("\tSymbol Descriptor: %c and Value: %d\n",tmpchar, symdescID);
802 cnt++; /* Discarding the ';' */
803 if (stabstr[cnt] == '-' ) cnt++;
805 /* Getting type range or size */
807 while (isdigit(stabstr[cnt+i])) i++;
809 char *low = (char *)malloc(sizeof(char)*(i+1));
810 if(!strncpy(low, &(stabstr[cnt]), i))
811 /* Error copying size/range*/
815 cnt = cnt + i + 1; /* Discard other Semicolon */
817 if((stabstr[cnt]) == '-') {
818 i++; /* discard '-' for (long) unsigned int */
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 */
832 int size = atol(low);
835 BPatch_type *newType = new BPatch_type( name, ID, typdescr, size);
837 mod->moduleTypes->addType(newType);
842 BPatch_type *newType = new BPatch_type( name, ID, typdescr, low, hi);
844 mod->moduleTypes->addType(newType);
852 if( stabstr[cnt] == ';')
855 fprintf(stderr, "ERROR: More to parse in type-r- %s\n", &(stabstr[cnt]));
858 return(&(stabstr[cnt]));
863 // parse range type of the form:
865 // <rangeType> = r<typeNum>;<low>;<high>;
867 static char *parseRangeType(BPatch_module *mod,char *name,int ID, char *stabstr)
873 assert(stabstr[0] == 'r');
876 BPatch_dataClass typdescr = BPatchSymTypeRange;
878 // range index type - not used
879 (void) parseSymDesc(stabstr, cnt);
881 // printf("\tSymbol Descriptor: %c and Value: %d\n",tmpchar, symdescID);
883 cnt++; /* Discarding the ';' */
884 if (stabstr[cnt] == '-' ) cnt++;
886 /* Getting type range or size */
888 while (isdigit(stabstr[cnt+i])) i++;
890 char *temp = (char *)malloc(sizeof(char)*(i+1));
891 if(!strncpy(temp, &(stabstr[cnt]), i))
892 /* Error copying size/range*/
902 cnt = cnt + i + 1; /* Discard other Semicolon */
904 if((stabstr[cnt]) == '-')
905 i++; /* discard '-' for (long) unsigned int */
907 while(isdigit(stabstr[cnt+i])){
910 char *hi = (char *)malloc(sizeof(char)*(i+1));
911 if(!strncpy(hi, &(stabstr[cnt]), i))
912 /* Error copying upper range */
915 // printf("\tLower limit: %s and Upper limit: %s\n", low, hi);
917 BPatch_type *newType = new BPatch_type( name, ID, typdescr, low, hi);
919 mod->moduleTypes->addType(newType);
929 cnt = cnt + i + 1; /* Discard other Semicolon */
931 while(isdigit(stabstr[cnt+i])){
934 temp = (char *)malloc(sizeof(char)*(i+1));
935 if(!strncpy(temp, &(stabstr[cnt]), i))
936 /* Error copying Zero */
943 // printf("\tSize of Type : %d bytes\n",size);
945 BPatch_type *newType = new BPatch_type( name, ID, typdescr, size);
947 mod->moduleTypes->addType(newType);
949 // printf("Type RANGE: ERROR!!\n");
953 if( stabstr[cnt] == ';')
956 fprintf(stderr, "ERROR: More to parse in type-r- %s\n", &(stabstr[cnt]));
959 return(&(stabstr[cnt]));
965 // <attrType> = @s<int>;<int>
967 static void parseAttrType(BPatch_module *mod, char *name,
968 int ID, char *stabstr, int &cnt)
970 // format @s(size in bits); negative type number;
971 BPatch_dataClass typdescr = BPatch_dataTypeAttrib;
973 assert(stabstr[cnt] == '@');
974 cnt++; /* skip the @ */
976 if (stabstr[cnt] == 's') {
979 int size = parseSymDesc(stabstr, cnt);
982 int type = parseSymDesc(stabstr, cnt);
983 // skip ';' end of stab record ??? (at least for bool)
986 // Create a new B_type that points to a builtInTypes
987 BPatch_type *ptrType =BPatch::bpatch->builtInTypes->findBuiltInType(type);
989 if (!ptrType) ptrType = BPatch::bpatch->type_Untyped;
991 BPatch_type *newType = new BPatch_type(name, ID, typdescr, size/8, ptrType);
993 // Add type to collection
994 if(newType) mod->moduleTypes->addType(newType);
996 printf(" Can't Allocate new type ");
1001 printf("More Type Attribute to Parse: %s ID %d : %s\n", name,
1002 ID, &(stabstr[cnt]));
1005 //printf(" Unable to parse Type Attribute: %s ID %d : %s\n",
1006 // name,ID, &(stabstr[cnt]));
1011 // <refType> = &<typeUse>
1013 static char *parseRefType(BPatch_module *mod, char *name,
1014 int ID, char *stabstr, int &cnt)
1016 /* reference to another type */
1017 assert(stabstr[cnt] == '&');
1020 int refID = parseTypeUse(mod, stabstr, cnt, name);
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;
1026 BPatch_type *newType = new BPatch_type(name, ID, BPatch_dataPointer, ptrType);
1027 // Add to typeCollection
1029 mod->moduleTypes->addType(newType);
1031 printf(" Can't Allocate new type ");
1035 return(&(stabstr[cnt]));
1039 // parse a list of fields.
1040 // Format is <fieldName>:<type-desc>;offset;size;
1042 static char *parseFieldList(BPatch_module *mod, BPatch_type *newType,
1050 BPatch_visibility _vis = BPatch_visUnknown;
1051 BPatch_dataClass typedescr;
1053 if (stabstr[cnt] == '!') {
1054 //Inheritance definition, Add base class field list to the current one
1055 //according to visibility rules.
1059 //Get # of base classes
1060 int baseClNum = atoi(getIdentifier(stabstr, cnt));
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);
1069 //Find base class type identifier
1070 int baseID = parseSymDesc(stabstr, cnt);
1075 BPatch_type *baseCl = mod->moduleTypes->findType(baseID);
1076 if (!baseCl || (baseCl->getDataClass() != BPatch_dataStructure) )
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];
1084 if (field->getVisibility() == BPatch_private)
1085 continue; //Can not add this member
1087 newType->addField(field->getName(),
1088 field->getTypeDesc(),
1091 field->getVisibility());
1096 while (stabstr[cnt] && (stabstr[cnt] != ';')) {
1097 typedescr = BPatch_dataScalar;
1099 if (stabstr[cnt] == '~') {
1100 //End of virtual class
1101 while(stabstr[cnt] != ';') cnt++;
1102 break; //End of class is reached
1105 compname = getIdentifier(stabstr, cnt);
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]);
1116 if ((stabstr[cnt]) == ':') {
1118 typedescr = BPatch_dataMethod;
1122 if ((stabstr[cnt]) == '/') { // visibility C++
1123 cnt++; /* get '/' */
1124 switch (stabstr[cnt]) {
1126 _vis = BPatch_private;
1129 _vis = BPatch_protected;
1132 _vis = BPatch_public;
1135 _vis = BPatch_optimized;
1138 _vis = BPatch_visUnknown;
1140 cnt++; // get visibility value
1143 // should be a typeDescriptor
1144 comptype = parseTypeUse(mod, stabstr, cnt, "");
1146 if (stabstr[cnt] == ':') {
1147 cnt++; //Discard ':'
1151 if (typedescr == BPatch_dataMethod) {
1153 //Mangling of arguments
1154 while(stabstr[cnt] != ';') cnt++;
1157 cnt++; //Skip visibility
1158 cnt++; //Skip method modifier
1159 if (stabstr[cnt] == '*') {
1160 //Virtual fcn definition
1162 while(stabstr[cnt] != ';') cnt++; //Skip vtable index
1164 while(stabstr[cnt] != ';') cnt++; //Skip type number to
1166 while(stabstr[cnt] == ';') cnt++; //Skip all ';'
1168 else if ( (stabstr[cnt] == '.') ||
1169 (stabstr[cnt] == '?') )
1170 cnt++; //Skip '.' or '?'
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 ':'
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 ';'
1190 //Something wrong! Skip entire stab record and exit
1191 while(stabstr[cnt]) cnt++;
1192 return (&stabstr[cnt]);
1201 char *varName = getIdentifier(stabstr, cnt);
1203 //Don't know what to do!
1206 else if (stabstr[cnt] == ',') {
1207 assert(stabstr[cnt] == ',');
1209 beg_offset = parseSymDesc(stabstr, cnt);
1211 if (stabstr[cnt] == ',') {
1213 size = parseSymDesc(stabstr, cnt);
1219 assert(stabstr[cnt] == ';');
1220 cnt++; // skip ';' at end of field
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");
1230 if (_vis == BPatch_visUnknown) {
1231 newType->addField(compname, typedescr, fieldType,
1234 newType->addField(compname, typedescr, fieldType,
1235 beg_offset, size, _vis);
1236 //printf("Adding Component with VISIBILITY STRUCT\n");
1240 // should end with a ';'
1241 if (stabstr[cnt] == ';') {
1242 return &stabstr[cnt+1];
1243 } else if (stabstr[cnt] == '\0') {
1244 return &stabstr[cnt];
1246 printf("invalid stab record: %s\n", &stabstr[cnt]);
1252 // This function takes a <typeDef> and parses it
1254 // <typeDef> = <symDesc> |
1256 // *<typeUse> | Pointer to a type
1258 // f<typeUse> | function type
1259 // R<int>,<int> | Real type
1260 // b[u|s][c|]<int>;<int>;<int> | Builtin
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
1272 // <enumType> = <ident>:<int> | <ident>:<int>,<enumType>
1274 // It adds the typeDef to the type definition with the name name, and id ID.
1276 static char *parseTypeDef(BPatch_module *mod, char *stabstr, char *name, int ID)
1279 BPatch_type * newType = NULL;
1280 BPatch_type * ptrType = NULL;
1283 char * compsymdesc=NULL;
1285 BPatch_dataClass typdescr;
1292 cnt = i = j = k = 0;
1294 assert (stabstr[0] != '=');
1296 // fprintf(stderr, "parsing %s\n", stabstr);
1297 if (isSymId(stabstr[0])) {
1298 typdescr = BPatch_dataScalar;
1299 type = parseSymDesc(stabstr, cnt);
1302 newType = new BPatch_type( name, ID, typdescr, type);
1303 if (newType) mod->moduleTypes->addType(newType);
1305 printf(" Can't Allocate newType ");
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);
1313 BPatch_type *oldType;
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);
1320 BPatch_type *oldType;
1322 oldType = mod->moduleTypes->findType(type);
1323 newType = new BPatch_type( name, ID, typdescr, oldType);
1324 if(newType) mod->moduleTypes->addType(newType);
1326 printf(" Can't Allocate newType ");
1331 switch (stabstr[0]) {
1332 case 'x': //cross reference
1333 parseCrossRef(mod->moduleTypes, name, ID, stabstr, cnt);
1337 typdescr = BPatch_dataPointer;
1338 /* pointer to another type */
1340 ptrID = parseTypeUse(mod, stabstr, cnt, NULL);
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;
1346 newType = new BPatch_type(NULL, ID, BPatch_dataPointer, ptrType);
1347 // Add to typeCollection
1348 if(newType) mod->moduleTypes->addType(newType);
1350 printf(" Can't Allocate new type ");
1354 return(&(stabstr[cnt]));
1358 (void) parseArrayDef(mod, name, ID, stabstr, cnt);
1359 return (&stabstr[cnt]);
1364 typdescr = BPatch_dataFunction;
1366 cnt++; /* skip the f */
1367 type = parseTypeUse(mod, stabstr, cnt, name);
1375 int baseType = parseSymDesc(stabstr, cnt);
1376 if (baseType != -2 || (stabstr[cnt] != ';')) {
1377 printf("unexpected non character array %s\n", stabstr);
1380 int size = parseSymDesc(stabstr, cnt);
1382 ptrType = mod->moduleTypes->findType(baseType);
1383 newType = new BPatch_type(name, ID, BPatch_dataArray, ptrType,
1385 mod->moduleTypes->addType(newType);
1391 // Define a floating point type - R fp-type; bytes;
1393 (void) parseSymDesc(stabstr, cnt);
1396 int bytes = parseSymDesc(stabstr, cnt);
1398 newType = new BPatch_type(name, ID, BPatch_dataBuilt_inType, bytes);
1399 mod->moduleTypes->addType(newType);
1401 if (stabstr[cnt] == ';') cnt++; // skip the final ';'
1407 // builtin type b - signed char-flag width; offset; nbits
1408 typdescr = BPatch_dataBuilt_inType;
1409 int limit = strlen(&stabstr[cnt]);
1412 while (stabstr[cnt+i] != ';' && (i < limit)) i++;
1413 if (i >= limit) return(&(stabstr[cnt]));
1415 i++; // skip the ';'
1418 while (stabstr[cnt+i] != ';' && (i < limit)) i++;
1419 if (i >= limit) return(&(stabstr[cnt]));
1423 int nbits = parseSymDesc(stabstr, cnt);
1425 if (stabstr[cnt]) cnt++; // skip the final ';'
1427 newType = new BPatch_type(name, ID, BPatch_dataBuilt_inType,
1430 mod->moduleTypes->addType(newType);
1432 return &stabstr[cnt];
1436 case 'r': // range type
1437 return parseRangeType(mod, name, ID, stabstr);
1440 case 'e': // Enumerated type
1441 typdescr = BPatch_dataEnumerated;
1442 cnt++; /* skip the 'e' */
1444 // Create new Enum type
1445 newType = new BPatch_type(name, ID, typdescr);
1446 // Add type to collection
1447 mod->moduleTypes->addType(newType);
1449 while (stabstr[cnt]) {
1450 /* Get enum component value */
1451 compsymdesc = getIdentifier(stabstr, cnt);
1452 cnt++; /* skip colon */
1454 value = parseSymDesc(stabstr, cnt);
1456 // add enum field to type
1457 newType->addField(compsymdesc, BPatch_dataScalar, value);
1461 temp = compsymdesc = NULL;
1463 cnt++; /* skip trailing comma */
1464 if ((stabstr[cnt]) == ';') cnt++; /* End of enum stab record */
1468 case '@': // type attribute, defines size and type (negative num)
1469 parseAttrType(mod, name, ID, stabstr, cnt);
1472 case '&': //XXX- Need to complete, may be more to parse jdd 4/22/99
1473 return parseRefType(mod, name, ID, stabstr, cnt);
1476 case 'k': // Sun constant type s<typeDef> - parse as <typeDef>
1477 return parseTypeDef(mod, &stabstr[cnt+1], name, ID);
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);
1487 /* Type descriptor */
1488 if (stabstr[cnt] == 's') {
1489 typdescr = BPatch_dataStructure;
1491 typdescr = BPatch_dataUnion;
1494 cnt++; // skip to size
1495 structsize = parseSymDesc(stabstr, cnt);
1498 newType = new BPatch_type(name, ID, typdescr, structsize);
1499 //add to type collection
1500 mod->moduleTypes->addType(newType);
1502 return parseFieldList(mod, newType, &stabstr[cnt]);
1506 case 'Z': // What is this ??? - jkh 10/14/99 (xlc compiler uses it)
1507 return (&stabstr[1]);
1511 //Class method definition
1513 if (stabstr[cnt] == '#') {
1516 parseTypeUse(mod, stabstr, cnt, name);
1520 //Skip class type, return typ and arg types
1521 parseTypeUse(mod, stabstr, cnt, name);
1522 if (stabstr[cnt] == ',')
1524 else if (stabstr[cnt] == ';')
1530 return(&(stabstr[cnt]));
1534 fprintf(stderr, "ERROR: Unrecognized str = %s\n", &stabstr[cnt]);
1540 return(&(stabstr[cnt]));
1541 } /* end of parseTypeDef*/
1544 // parseConstantUse - parse a constant (used by Fortran PARAMETERS)
1546 // <constantUse> = =i<int> |
1550 static BPatch_type *parseConstantUse(BPatch_module *mod, char *stabstr, int &cnt)
1557 if (stabstr[cnt] == 'i') {
1558 ret = mod->moduleTypes->findType("integer*4");
1559 } else if (stabstr[cnt] == 'r') {
1560 ret = mod->moduleTypes->findType("double");
1562 printf("unknown constant type %s\n", &stabstr[cnt]);
1566 cnt = strlen(stabstr);