-#define CFRONT_VISIBILITY_PRIVATE '2' /* Stabs character for private field */
-#define CFRONT_VISIBILITY_PUBLIC '1' /* Stabs character for public field */
-
-/* This code added to support parsing of ARM/Cfront stabs strings */
-
-/* Get substring from string up to char c, advance string pointer past
- suibstring. */
-
-static char *
-get_substring (char **p, int c)
-{
- char *str;
- str = *p;
- *p = strchr (*p, c);
- if (*p)
- {
- **p = 0;
- (*p)++;
- }
- else
- str = 0;
- return str;
-}
-
-/* Physname gets strcat'd onto sname in order to recreate the mangled
- name (see funtion gdb_mangle_name in gdbtypes.c). For cfront, make
- the physname look like that of g++ - take out the initial mangling
- eg: for sname="a" and fname="foo__1aFPFs_i" return "FPFs_i" */
-
-static char *
-get_cfront_method_physname (char *fname)
-{
- int len = 0;
- /* FIXME would like to make this generic for g++ too, but
- that is already handled in read_member_funcctions */
- char *p = fname;
-
- /* search ahead to find the start of the mangled suffix */
- if (*p == '_' && *(p + 1) == '_') /* compiler generated; probably a ctor/dtor */
- p += 2;
- while (p && (unsigned) ((p + 1) - fname) < strlen (fname) && *(p + 1) != '_')
- p = strchr (p, '_');
- if (!(p && *p == '_' && *(p + 1) == '_'))
- error ("Invalid mangled function name %s", fname);
- p += 2; /* advance past '__' */
-
- /* struct name length and name of type should come next; advance past it */
- while (isdigit (*p))
- {
- len = len * 10 + (*p - '0');
- p++;
- }
- p += len;
-
- return p;
-}
-
-/* Read base classes within cfront class definition.
- eg: A:ZcA;1@Bpub v2@Bvirpri;__ct__1AFv func__1AFv *sfunc__1AFv ;as__1A ;;
- ^^^^^^^^^^^^^^^^^^
-
- A:ZcA;;foopri__1AFv foopro__1AFv __ct__1AFv __ct__1AFRC1A foopub__1AFv ;;;
- ^
- */
-
-static int
-read_cfront_baseclasses (struct field_info *fip, char **pp, struct type *type,
- struct objfile *objfile)
-{
- static struct complaint msg_unknown =
- {"\
- Unsupported token in stabs string %s.\n",
- 0, 0};
- static struct complaint msg_notfound =
- {"\
- Unable to find base type for %s.\n",
- 0, 0};
- int bnum = 0;
- char *p;
- int i;
- struct nextfield *new;
-
- if (**pp == ';') /* no base classes; return */
- {
- ++(*pp);
- return 1;
- }
-
- /* first count base classes so we can allocate space before parsing */
- for (p = *pp; p && *p && *p != ';'; p++)
- {
- if (*p == ' ')
- bnum++;
- }
- bnum++; /* add one more for last one */
-
- /* now parse the base classes until we get to the start of the methods
- (code extracted and munged from read_baseclasses) */
- ALLOCATE_CPLUS_STRUCT_TYPE (type);
- TYPE_N_BASECLASSES (type) = bnum;
-
- /* allocate space */
- {
- int num_bytes = B_BYTES (TYPE_N_BASECLASSES (type));
- char *pointer;
-
- pointer = (char *) TYPE_ALLOC (type, num_bytes);
- TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *) pointer;
- }
- B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), TYPE_N_BASECLASSES (type));
-
- for (i = 0; i < TYPE_N_BASECLASSES (type); i++)
- {
- new = (struct nextfield *) xmalloc (sizeof (struct nextfield));
- make_cleanup (xfree, new);
- memset (new, 0, sizeof (struct nextfield));
- new->next = fip->list;
- fip->list = new;
- FIELD_BITSIZE (new->field) = 0; /* this should be an unpacked field! */
-
- STABS_CONTINUE (pp, objfile);
-
- /* virtual? eg: v2@Bvir */
- if (**pp == 'v')
- {
- SET_TYPE_FIELD_VIRTUAL (type, i);
- ++(*pp);
- }
-
- /* access? eg: 2@Bvir */
- /* Note: protected inheritance not supported in cfront */
- switch (*(*pp)++)
- {
- case CFRONT_VISIBILITY_PRIVATE:
- new->visibility = VISIBILITY_PRIVATE;
- break;
- case CFRONT_VISIBILITY_PUBLIC:
- new->visibility = VISIBILITY_PUBLIC;
- break;
- default:
- /* Bad visibility format. Complain and treat it as
- public. */
- {
- static struct complaint msg =
- {
- "Unknown visibility `%c' for baseclass", 0, 0};
- complain (&msg, new->visibility);
- new->visibility = VISIBILITY_PUBLIC;
- }
- }
-
- /* "@" comes next - eg: @Bvir */
- if (**pp != '@')
- {
- complain (&msg_unknown, *pp);
- return 1;
- }
- ++(*pp);
-
-
- /* Set the bit offset of the portion of the object corresponding
- to this baseclass. Always zero in the absence of
- multiple inheritance. */
- /* Unable to read bit position from stabs;
- Assuming no multiple inheritance for now FIXME! */
- /* We may have read this in the structure definition;
- now we should fixup the members to be the actual base classes */
- FIELD_BITPOS (new->field) = 0;
-
- /* Get the base class name and type */
- {
- char *bname; /* base class name */
- struct symbol *bsym; /* base class */
- char *p1, *p2;
- p1 = strchr (*pp, ' ');
- p2 = strchr (*pp, ';');
- if (p1 < p2)
- bname = get_substring (pp, ' ');
- else
- bname = get_substring (pp, ';');
- if (!bname || !*bname)
- {
- complain (&msg_unknown, *pp);
- return 1;
- }
- /* FIXME! attach base info to type */
- bsym = lookup_symbol (bname, 0, STRUCT_NAMESPACE, 0, 0); /*demangled_name */
- if (bsym)
- {
- new->field.type = SYMBOL_TYPE (bsym);
- new->field.name = type_name_no_tag (new->field.type);
- }
- else
- {
- complain (&msg_notfound, *pp);
- return 1;
- }
- }
-
- /* If more base classes to parse, loop again.
- We ate the last ' ' or ';' in get_substring,
- so on exit we will have skipped the trailing ';' */
- /* if invalid, return 0; add code to detect - FIXME! */
- }
- return 1;
-}
-
-/* read cfront member functions.
- pp points to string starting with list of functions
- eg: A:ZcA;1@Bpub v2@Bvirpri;__ct__1AFv func__1AFv *sfunc__1AFv ;as__1A ;;
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- A:ZcA;;foopri__1AFv foopro__1AFv __ct__1AFv __ct__1AFRC1A foopub__1AFv ;;;
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- */
-
-static int
-read_cfront_member_functions (struct field_info *fip, char **pp,
- struct type *type, struct objfile *objfile)
-{
- /* This code extracted from read_member_functions
- so as to do the similar thing for our funcs */
-
- int nfn_fields = 0;
- int length = 0;
- /* Total number of member functions defined in this class. If the class
- defines two `f' functions, and one `g' function, then this will have
- the value 3. */
- int total_length = 0;
- int i;
- struct next_fnfield
- {
- struct next_fnfield *next;
- struct fn_field fn_field;
- }
- *sublist;
- struct type *look_ahead_type;
- struct next_fnfieldlist *new_fnlist;
- struct next_fnfield *new_sublist;
- char *main_fn_name;
- char *fname;
- struct symbol *ref_func = 0;
-
- /* Process each list until we find the end of the member functions.
- eg: p = "__ct__1AFv foo__1AFv ;;;" */
-
- STABS_CONTINUE (pp, objfile); /* handle \\ */
-
- while (**pp != ';' && (fname = get_substring (pp, ' '), fname))
- {
- int is_static = 0;
- int sublist_count = 0;
- char *pname;
- if (fname[0] == '*') /* static member */
- {
- is_static = 1;
- sublist_count++;
- fname++;
- }
- ref_func = lookup_symbol (fname, 0, VAR_NAMESPACE, 0, 0); /* demangled name */
- if (!ref_func)
- {
- static struct complaint msg =
- {"\
- Unable to find function symbol for %s\n",
- 0, 0};
- complain (&msg, fname);
- continue;
- }
- sublist = NULL;
- look_ahead_type = NULL;
- length = 0;
-
- new_fnlist = (struct next_fnfieldlist *)
- xmalloc (sizeof (struct next_fnfieldlist));
- make_cleanup (xfree, new_fnlist);
- memset (new_fnlist, 0, sizeof (struct next_fnfieldlist));
-
- /* The following is code to work around cfront generated stabs.
- The stabs contains full mangled name for each field.
- We try to demangle the name and extract the field name out of it. */
- {
- char *dem, *dem_p, *dem_args;
- int dem_len;
- dem = cplus_demangle (fname, DMGL_ANSI | DMGL_PARAMS);
- if (dem != NULL)
- {
- dem_p = strrchr (dem, ':');
- if (dem_p != 0 && *(dem_p - 1) == ':')
- dem_p++;
- /* get rid of args */
- dem_args = strchr (dem_p, '(');
- if (dem_args == NULL)
- dem_len = strlen (dem_p);
- else
- dem_len = dem_args - dem_p;
- main_fn_name =
- obsavestring (dem_p, dem_len, &objfile->type_obstack);
- }
- else
- {
- main_fn_name =
- obsavestring (fname, strlen (fname), &objfile->type_obstack);
- }
- } /* end of code for cfront work around */
-
- new_fnlist->fn_fieldlist.name = main_fn_name;
-
-/*-------------------------------------------------*/
- /* Set up the sublists
- Sublists are stuff like args, static, visibility, etc.
- so in ARM, we have to set that info some other way.
- Multiple sublists happen if overloading
- eg: foo::26=##1;:;2A.;
- In g++, we'd loop here thru all the sublists... */
-
- new_sublist =
- (struct next_fnfield *) xmalloc (sizeof (struct next_fnfield));
- make_cleanup (xfree, new_sublist);
- memset (new_sublist, 0, sizeof (struct next_fnfield));
-
- /* eat 1; from :;2A.; */
- new_sublist->fn_field.type = SYMBOL_TYPE (ref_func); /* normally takes a read_type */
- /* Make this type look like a method stub for gdb */
- TYPE_FLAGS (new_sublist->fn_field.type) |= TYPE_FLAG_STUB;
- TYPE_CODE (new_sublist->fn_field.type) = TYPE_CODE_METHOD;
-
- /* If this is just a stub, then we don't have the real name here. */
- if (TYPE_STUB (new_sublist->fn_field.type))
- {
- if (!TYPE_DOMAIN_TYPE (new_sublist->fn_field.type))
- TYPE_DOMAIN_TYPE (new_sublist->fn_field.type) = type;
- new_sublist->fn_field.is_stub = 1;
- }
-
- /* physname used later in mangling; eg PFs_i,5 for foo__1aFPFs_i
- physname gets strcat'd in order to recreate the onto mangled name */
- pname = get_cfront_method_physname (fname);
- new_sublist->fn_field.physname = savestring (pname, strlen (pname));
-
-
- /* Set this member function's visibility fields.
- Unable to distinguish access from stabs definition!
- Assuming public for now. FIXME!
- (for private, set new_sublist->fn_field.is_private = 1,
- for public, set new_sublist->fn_field.is_protected = 1) */
-
- /* Unable to distinguish const/volatile from stabs definition!
- Assuming normal for now. FIXME! */
-
- new_sublist->fn_field.is_const = 0;
- new_sublist->fn_field.is_volatile = 0; /* volatile not implemented in cfront */
-
- /* Set virtual/static function info
- How to get vtable offsets ?
- Assuming normal for now FIXME!!
- For vtables, figure out from whence this virtual function came.
- It may belong to virtual function table of
- one of its baseclasses.
- set:
- new_sublist -> fn_field.voffset = vtable offset,
- new_sublist -> fn_field.fcontext = look_ahead_type;
- where look_ahead_type is type of baseclass */
- if (is_static)
- new_sublist->fn_field.voffset = VOFFSET_STATIC;
- else /* normal member function. */
- new_sublist->fn_field.voffset = 0;
- new_sublist->fn_field.fcontext = 0;
-
-
- /* Prepare new sublist */
- new_sublist->next = sublist;
- sublist = new_sublist;
- length++;
-
- /* In g++, we loop thu sublists - now we set from functions. */
- new_fnlist->fn_fieldlist.fn_fields = (struct fn_field *)
- obstack_alloc (&objfile->type_obstack,
- sizeof (struct fn_field) * length);
- memset (new_fnlist->fn_fieldlist.fn_fields, 0,
- sizeof (struct fn_field) * length);
- for (i = length; (i--, sublist); sublist = sublist->next)
- {
- new_fnlist->fn_fieldlist.fn_fields[i] = sublist->fn_field;
- }
-
- new_fnlist->fn_fieldlist.length = length;
- new_fnlist->next = fip->fnlist;
- fip->fnlist = new_fnlist;
- nfn_fields++;
- total_length += length;
- STABS_CONTINUE (pp, objfile); /* handle \\ */
- } /* end of loop */
-
- if (nfn_fields)
- {
- /* type should already have space */
- 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;
- }
-
- /* end of scope for reading member func */
-
- /* eg: ";;" */
-
- /* Skip trailing ';' and bump count of number of fields seen */
- if (**pp == ';')
- (*pp)++;
- else
- return 0;
- return 1;
-}
-
-/* This routine fixes up partial cfront types that were created
- while parsing the stabs. The main need for this function is
- to add information such as methods to classes.
- Examples of "p": "sA;;__ct__1AFv foo__1AFv ;;;" */
-int
-resolve_cfront_continuation (struct objfile *objfile, struct symbol *sym,
- char *p)
-{
- struct symbol *ref_sym = 0;
- char *sname;
- /* snarfed from read_struct_type */
- struct field_info fi;
- struct type *type;
- struct cleanup *back_to;
-
- /* Need to make sure that fi isn't gunna conflict with struct
- in case struct already had some fnfs */
- fi.list = NULL;
- fi.fnlist = NULL;
- back_to = make_cleanup (null_cleanup, 0);
-
- /* We only accept structs, classes and unions at the moment.
- Other continuation types include t (typedef), r (long dbl), ...
- We may want to add support for them as well;
- right now they are handled by duplicating the symbol information
- into the type information (see define_symbol) */
- if (*p != 's' /* structs */
- && *p != 'c' /* class */
- && *p != 'u') /* union */
- return 0; /* only handle C++ types */
- p++;
-
- /* Get symbol typs name and validate
- eg: p = "A;;__ct__1AFv foo__1AFv ;;;" */
- sname = get_substring (&p, ';');
- if (!sname || strcmp (sname, SYMBOL_NAME (sym)))
- error ("Internal error: base symbol type name does not match\n");
-
- /* Find symbol's internal gdb reference using demangled_name.
- This is the real sym that we want;
- sym was a temp hack to make debugger happy */
- ref_sym = lookup_symbol (SYMBOL_NAME (sym), 0, STRUCT_NAMESPACE, 0, 0);
- type = SYMBOL_TYPE (ref_sym);
-
-
- /* Now read the baseclasses, if any, read the regular C struct or C++
- class member fields, attach the fields to the type, read the C++
- member functions, attach them to the type, and then read any tilde
- field (baseclass specifier for the class holding the main vtable). */
-
- if (!read_cfront_baseclasses (&fi, &p, type, objfile)
- /* g++ does this next, but cfront already did this:
- || !read_struct_fields (&fi, &p, type, objfile) */
- || !copy_cfront_struct_fields (&fi, type, objfile)
- || !read_cfront_member_functions (&fi, &p, type, objfile)
- || !read_cfront_static_fields (&fi, &p, type, objfile)
- || !attach_fields_to_type (&fi, type, objfile)
- || !attach_fn_fields_to_type (&fi, type)
- /* g++ does this next, but cfront doesn't seem to have this:
- || !read_tilde_fields (&fi, &p, type, objfile) */
- )
- {
- type = error_type (&p, objfile);
- }
-
- do_cleanups (back_to);
- return 0;
-}
-/* End of code added to support parsing of ARM/Cfront stabs strings */
-
-
-/* This routine fixes up symbol references/aliases to point to the original
- symbol definition. Returns 0 on failure, non-zero on success. */
-
-static int
-resolve_symbol_reference (struct objfile *objfile, struct symbol *sym, char *p)
-{
- int refnum;
- struct symbol *ref_sym = 0;
- struct alias_list *alias;
-
- /* If this is not a symbol reference return now. */
- if (*p != '#')
- return 0;
-
- /* Use "#<num>" as the name; we'll fix the name later.
- We stored the original symbol name as "#<id>=<name>"
- so we can now search for "#<id>" to resolving the reference.
- We'll fix the names later by removing the "#<id>" or "#<id>=" */
-
-/*---------------------------------------------------------*/
- /* Get the reference id number, and
- advance p past the names so we can parse the rest.
- eg: id=2 for p : "2=", "2=z:r(0,1)" "2:r(0,1);l(#5,#6),l(#7,#4)" */
-/*---------------------------------------------------------*/
-
- /* This gets reference name from string. sym may not have a name. */
-
- /* Get the reference number associated with the reference id in the
- gdb stab string. From that reference number, get the main/primary
- symbol for this alias. */
- refnum = process_reference (&p);
- ref_sym = ref_search (refnum);
- if (!ref_sym)
- {
- complain (&lrs_general_complaint, "symbol for reference not found");
- return 0;
- }
-
- /* Parse the stab of the referencing symbol
- now that we have the referenced symbol.
- Add it as a new symbol and a link back to the referenced symbol.
- eg: p : "=", "=z:r(0,1)" ":r(0,1);l(#5,#6),l(#7,#4)" */
-
-
- /* If the stab symbol table and string contain:
- RSYM 0 5 00000000 868 #15=z:r(0,1)
- LBRAC 0 0 00000000 899 #5=
- SLINE 0 16 00000003 923 #6=
- Then the same symbols can be later referenced by:
- RSYM 0 5 00000000 927 #15:r(0,1);l(#5,#6)
- This is used in live range splitting to:
- 1) specify that a symbol (#15) is actually just a new storage
- class for a symbol (#15=z) which was previously defined.
- 2) specify that the beginning and ending ranges for a symbol
- (#15) are the values of the beginning (#5) and ending (#6)
- symbols. */
-
- /* Read number as reference id.
- eg: p : "=", "=z:r(0,1)" ":r(0,1);l(#5,#6),l(#7,#4)" */
- /* FIXME! Might I want to use SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
- in case of "l(0,0)"? */
-
-/*--------------------------------------------------*/
- /* Add this symbol to the reference list. */
-/*--------------------------------------------------*/
-
- alias = (struct alias_list *) obstack_alloc (&objfile->type_obstack,
- sizeof (struct alias_list));
- if (!alias)
- {
- complain (&lrs_general_complaint, "Unable to allocate alias list memory");
- return 0;
- }
-
- alias->next = 0;
- alias->sym = sym;
-
- if (!SYMBOL_ALIASES (ref_sym))
- {
- SYMBOL_ALIASES (ref_sym) = alias;
- }
- else
- {
- struct alias_list *temp;
-
- /* Get to the end of the list. */
- for (temp = SYMBOL_ALIASES (ref_sym);
- temp->next;
- temp = temp->next)
- ;
- temp->next = alias;
- }
-
- /* Want to fix up name so that other functions (eg. valops)
- will correctly print the name.
- Don't add_symbol_to_list so that lookup_symbol won't find it.
- nope... needed for fixups. */
- SYMBOL_NAME (sym) = SYMBOL_NAME (ref_sym);
-
- /* Done! */
- return 1;
-}
-