📄 stabsread.c
字号:
case 'B': /* `const' member functions. */ new_sublist->fn_field.is_const = 1; new_sublist->fn_field.is_volatile = 0; (*pp)++; break; case 'C': /* `volatile' member function. */ new_sublist->fn_field.is_const = 0; new_sublist->fn_field.is_volatile = 1; (*pp)++; break; case 'D': /* `const volatile' member function. */ new_sublist->fn_field.is_const = 1; new_sublist->fn_field.is_volatile = 1; (*pp)++; break; case '*': /* File compiled with g++ version 1 -- no info */ case '?': case '.': break; default: complain (&const_vol_complaint, (char *) (long) **pp); break; } switch (*(*pp)++) { case '*': /* virtual member function, followed by index. */ /* The sign bit is set to distinguish pointers-to-methods from virtual function indicies. Since the array is in words, the quantity must be shifted left by 1 on 16 bit machine, and by 2 on 32 bit machine, forcing the sign bit out, and usable as a valid index into the array. Remove the sign bit here. */ new_sublist->fn_field.voffset = (0x7fffffff & read_number (pp, ';')) + 2; if (**pp == '\\') *pp = next_symbol_text (); if (**pp == ';' || **pp == '\0') /* Must be g++ version 1. */ new_sublist->fn_field.fcontext = 0; else { /* Figure out from whence this virtual function came. It may belong to virtual function table of one of its baseclasses. */ look_ahead_type = read_type (pp, objfile); if (**pp == ':') { /* g++ version 1 overloaded methods. */ } else { new_sublist->fn_field.fcontext = look_ahead_type; if (**pp != ';') return error_type (pp); else ++*pp; look_ahead_type = NULL; } } break; case '?': /* static member function. */ new_sublist->fn_field.voffset = VOFFSET_STATIC; if (strncmp (new_sublist->fn_field.physname, main_fn_name, strlen (main_fn_name))) new_sublist->fn_field.is_stub = 1; break; default: /* error */ complain (&member_fn_complaint, (char *) (long) (*pp)[-1]); /* Fall through into normal member function. */ case '.': /* normal member function. */ new_sublist->fn_field.voffset = 0; new_sublist->fn_field.fcontext = 0; break; } new_sublist->next = sublist; sublist = new_sublist; length++; if (**pp == '\\') *pp = next_symbol_text (); } while (**pp != ';' && **pp != '\0'); *pp += 1; new_mainlist->fn_fieldlist.fn_fields = (struct fn_field *) obstack_alloc (&objfile -> type_obstack, sizeof (struct fn_field) * length); memset (new_mainlist->fn_fieldlist.fn_fields, 0, sizeof (struct fn_field) * length); for (i = length; (i--, sublist); sublist = sublist->next) new_mainlist->fn_fieldlist.fn_fields[i] = sublist->fn_field; new_mainlist->fn_fieldlist.length = length; new_mainlist->next = mainlist; mainlist = new_mainlist; nfn_fields++; total_length += length; if (**pp == '\\') *pp = next_symbol_text (); } while (**pp != ';'); } *pp += 1; if (nfn_fields) { TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *) TYPE_ALLOC (type, sizeof (struct fn_fieldlist) * nfn_fields); memset (TYPE_FN_FIELDLISTS (type), 0, sizeof (struct fn_fieldlist) * nfn_fields); TYPE_NFN_FIELDS (type) = nfn_fields; TYPE_NFN_FIELDS_TOTAL (type) = total_length; } { int i; for (i = 0; i < TYPE_N_BASECLASSES (type); ++i) { if (TYPE_CODE (TYPE_BASECLASS (type, i)) == TYPE_CODE_UNDEF) /* @@ Memory leak on objfile->type_obstack? */ return error_type (pp); TYPE_NFN_FIELDS_TOTAL (type) += TYPE_NFN_FIELDS_TOTAL (TYPE_BASECLASS (type, i)); } } for (n = nfn_fields; mainlist; mainlist = mainlist->next) { --n; /* Circumvent Sun3 compiler bug */ TYPE_FN_FIELDLISTS (type)[n] = mainlist->fn_fieldlist; } if (**pp == '~') { *pp += 1; if (**pp == '=' || **pp == '+' || **pp == '-') { /* Obsolete flags that used to indicate the presence of constructors and/or destructors. */ *pp += 1; } /* Read either a '%' or the final ';'. */ if (*(*pp)++ == '%') { /* We'd like to be able to derive the vtable pointer field from the type information, but when it's inherited, that's hard. A reason it's hard is because we may read in the info about a derived class before we read in info about the base class that provides the vtable pointer field. Once the base info has been read, we could fill in the info for the derived classes, but for the fact that by then, we don't remember who needs what. */#if 0 int predicted_fieldno = -1;#endif /* Now we must record the virtual function table pointer's field information. */ struct type *t; int i;#if 0 { /* In version 2, we derive the vfield ourselves. */ for (n = 0; n < nfields; n++) { if (! strncmp (TYPE_FIELD_NAME (type, n), vptr_name, sizeof (vptr_name) -1)) { predicted_fieldno = n; break; } } if (predicted_fieldno < 0) for (n = 0; n < TYPE_N_BASECLASSES (type); n++) if (! TYPE_FIELD_VIRTUAL (type, n) && TYPE_VPTR_FIELDNO (TYPE_BASECLASS (type, n)) >= 0) { predicted_fieldno = TYPE_VPTR_FIELDNO (TYPE_BASECLASS (type, n)); break; } }#endif t = read_type (pp, objfile); p = (*pp)++; while (*p != '\0' && *p != ';') p++; if (*p == '\0') /* Premature end of symbol. */ return error_type (pp); TYPE_VPTR_BASETYPE (type) = t; if (type == t) { if (TYPE_FIELD_NAME (t, TYPE_N_BASECLASSES (t)) == 0) { /* FIXME-tiemann: what's this? */#if 0 TYPE_VPTR_FIELDNO (type) = i = TYPE_N_BASECLASSES (t);#else error_type (pp);#endif } else for (i = TYPE_NFIELDS (t) - 1; i >= TYPE_N_BASECLASSES (t); --i) if (! strncmp (TYPE_FIELD_NAME (t, i), vptr_name, sizeof (vptr_name) - 1)) { TYPE_VPTR_FIELDNO (type) = i; break; } if (i < 0) /* Virtual function table field not found. */ return error_type (pp); } else TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (t);#if 0 if (TYPE_VPTR_FIELDNO (type) != predicted_fieldno) error ("TYPE_VPTR_FIELDNO miscalculated");#endif *pp = p + 1; } } return type;}/* Read a definition of an array type, and create and return a suitable type object. Also creates a range type which represents the bounds of that array. */static struct type *read_array_type (pp, type, objfile) register char **pp; register struct type *type; struct objfile *objfile;{ struct type *index_type, *element_type, *range_type; int lower, upper; int adjustable = 0; /* Format of an array type: "ar<index type>;lower;upper;<array_contents_type>". Put code in to handle this. Fortran adjustable arrays use Adigits or Tdigits for lower or upper; for these, produce a type like float[][]. */ index_type = read_type (pp, objfile); if (**pp != ';') /* Improper format of array type decl. */ return error_type (pp); ++*pp; if (!(**pp >= '0' && **pp <= '9')) { *pp += 1; adjustable = 1; } lower = read_number (pp, ';'); if (!(**pp >= '0' && **pp <= '9')) { *pp += 1; adjustable = 1; } upper = read_number (pp, ';'); element_type = read_type (pp, objfile); if (adjustable) { lower = 0; upper = -1; } { /* Create range type. */ range_type = alloc_type (objfile); TYPE_CODE (range_type) = TYPE_CODE_RANGE; TYPE_TARGET_TYPE (range_type) = index_type; /* This should never be needed. */ TYPE_LENGTH (range_type) = sizeof (int); TYPE_NFIELDS (range_type) = 2; TYPE_FIELDS (range_type) = (struct field *) TYPE_ALLOC (range_type, 2 * sizeof (struct field)); memset (TYPE_FIELDS (range_type), 0, 2 * sizeof (struct field)); TYPE_FIELD_BITPOS (range_type, 0) = lower; TYPE_FIELD_BITPOS (range_type, 1) = upper; } TYPE_CODE (type) = TYPE_CODE_ARRAY; TYPE_TARGET_TYPE (type) = element_type; TYPE_LENGTH (type) = (upper - lower + 1) * TYPE_LENGTH (element_type); TYPE_NFIELDS (type) = 1; TYPE_FIELDS (type) = (struct field *) TYPE_ALLOC (type, sizeof (struct field)); memset (TYPE_FIELDS (type), 0, sizeof (struct field)); TYPE_FIELD_TYPE (type, 0) = range_type; /* If we have an array whose element type is not yet known, but whose bounds *are* known, record it to be adjusted at the end of the file. */ if (TYPE_LENGTH (element_type) == 0 && !adjustable) add_undefined_type (type); return type;}/* Read a definition of an enumeration type, and create and return a suitable type object. Also defines the symbols that represent the values of the type. */static struct type *read_enum_type (pp, type, objfile) register char **pp; register struct type *type; struct objfile *objfile;{ register char *p; char *name; register long n; register struct symbol *sym; int nsyms = 0; struct pending **symlist; struct pending *osyms, *syms; int o_nsyms;#if 0 /* FIXME! The stabs produced by Sun CC merrily define things that ought to be file-scope, between N_FN entries, using N_LSYM. What's a mother to do? For now, force all enum values to file scope. */ if (within_function) symlist = &local_symbols; else#endif symlist = &file_symbols; osyms = *symlist; o_nsyms = osyms ? osyms->nsyms : 0; /* Read the value-names and their values. The input syntax is NAME:VALUE,NAME:VALUE, and so on. A semicolon or comma instead of a NAME means the end. */ while (**pp && **pp != ';' && **pp != ',') { /* Check for and handle cretinous dbx symbol name continuation! */ if (**pp == '\\') *pp = next_symbol_text (); p = *pp; while (*p != ':') p++; name = obsavestring (*pp, p - *pp, &objfile -> symbol_obstack); *pp = p + 1; n = read_number (pp, ','); sym = (struct symbol *) obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol)); memset (sym, 0, sizeof (struct symbol)); SYMBOL_NAME (sym) = name; SYMBOL_CLASS (sym) = LOC_CONST; SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; SYMBOL_VALUE (sym) = n; add_symbol_to_list (sym, symlist); nsyms++; } if (**pp == ';') (*pp)++; /* Skip the semicolon. */ /* Now fill in the fields of the type-structure. */ TYPE_LENGTH (type) = sizeof (int); TYPE_CODE (type) = TYPE_CODE_ENUM; TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB; TYPE_NFIELDS (type) = nsyms; TYPE_FIELDS (type) = (struct field *) TYPE_ALLOC (type, sizeof (struct field) * nsyms); memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nsyms); /* Find the symbols for the values and put them into the type. The symbols can be found in the symlist that we put them on to cause them to be defined. osyms contains the old value of that symlist; everything up to there was defined by us. */ /* Note that we preserve the order of the enum constants, so that in something like "enum {FOO, LAST_THING=FOO}" we print FOO, not LAST_THING. */ for (syms = *symlist, n = 0; syms; syms = syms->next) { int j = 0; if (syms == osyms) j = o_nsyms; for (; j < syms->nsyms; j++,n++) { struct symbol *xsym = syms->symbol[j]; SYMBOL_TYPE (xsym) = type; TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym); TYPE_FIELD_VALUE (type, n) = 0; TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym); TYPE_FIELD_BITSIZE (type, n) = 0; } if (syms == osyms) break; }#if 0 /* This screws up perfectly good C programs with enums. FIXME. */ /* Is this Modula-2's BOOLEAN type? Flag it as such if so. */ if(TYPE_NFIELDS(type) == 2 && ((!strcmp(TYPE_FIELD_NAME(type,0),"TRUE") && !strcmp(TYPE_FIELD_NAME(type,1),"FALSE")) || (!strcmp(TYPE_FIELD_NAME(type,1),"TRUE") && !strcmp(TYPE_FIELD_NAME(type,0),"FALSE")))) TYPE_CODE(type) = TYPE_CODE_BOOL;#endif return type;}/* Sun's ACC uses a somewhat saner method for specifying the builtin typedefs in every file (for int, long, etc): type = b <signed> <width>; <offset>; <nbits> signed = u or s. Possible c in addition to u or s (for char?). offset = offset from high order bit to start bit of type. width is # bytes in object of this type, nbits is # bits in type. The width/offset stuff appears to be for small objects stored in larger ones (e.g. `shorts' in `int' registers). We i
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -