Make changes needed to handle code which uses ANSI-mangled names (and

new G++ 1.95 dbxout output).
This commit is contained in:
Michael Tiemann 1991-11-18 00:32:34 +00:00
parent a89f7423b4
commit 572acbbedc
4 changed files with 276 additions and 72 deletions

View File

@ -1,3 +1,28 @@
Sun Nov 17 16:20:53 1991 Michael Tiemann (tiemann at rtl.cygnus.com)
* symtab.h (struct type): Moved C++-specific fields into new type
`struct cplus_struct_type'. Now takes 10% less memory. Many
macros changed.
* symtab.c (init_type): Don't set fields belonging to
TYPE_CPLUS_SPECIFIC unless TYPE is TYPE_CODE_STRUCT.
* buildsym.c (read_type): Allocate TYPE_CPLUS_SPECIFIC for
TYPE_CODE_STRUCT.
(read_struct_type): Ditto. Also, add comments about how we can
deduce TYPE_VPTR_FIELDNO from inheritance info and fieldname info.
* coffread.c (decode_base_type): Allocate TYPE_CPLUS_SPECIFIC for
TYPE_CODE_STRUCT.
(read_struct_type): Ditto.
* dwarfread.c (struct_type): Ditto.
* symtab.c (read_range_type): Don't set TYPE_MAIN_VARIANT.
(lookup_pointer_type): Don't use or set TYPE_MAIN_VARIANT.
(lookup_reference_type): Ditto.
* cplus-dem.c: Many changes made to handle decoding of
ANSI-mangled names.
* symtab.c (gdb_mangle_name): Mangle/demangle ANSI-mangled names
as well.
Fri Nov 15 17:57:59 1991 Stu Grossman (grossman at cygnus.com)
* mipsread.c (parse_partial_symbols): patch to keep DEC C

View File

@ -1636,6 +1636,12 @@ read_type (pp)
type = dbx_alloc_type (typenums);
TYPE_CODE (type) = code;
TYPE_NAME (type) = type_name;
if (code == TYPE_CODE_STRUCT)
{
TYPE_CPLUS_SPECIFIC (type)
= (struct cplus_struct_type *) obstack_alloc (symbol_obstack, sizeof (struct cplus_struct_type));
bzero (TYPE_CPLUS_SPECIFIC (type), sizeof (struct cplus_struct_type));
}
TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
@ -1853,11 +1859,12 @@ read_struct_type (pp, type)
int nfn_fields = 0;
if (TYPE_MAIN_VARIANT (type) == 0)
{
TYPE_MAIN_VARIANT (type) = type;
}
TYPE_MAIN_VARIANT (type) = type;
TYPE_CODE (type) = TYPE_CODE_STRUCT;
TYPE_CPLUS_SPECIFIC (type)
= (struct cplus_struct_type *) obstack_alloc (symbol_obstack, sizeof (struct cplus_struct_type));
bzero (TYPE_CPLUS_SPECIFIC (type), sizeof (struct cplus_struct_type));
/* First comes the total size in bytes. */
@ -2393,12 +2400,47 @@ read_struct_type (pp, type)
/* 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. */
int predicted_fieldno = -1;
/* 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);
p = (*pp)++;
while (*p != '\0' && *p != ';')
@ -2421,7 +2463,7 @@ read_struct_type (pp, type)
}
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))
sizeof (vptr_name) -1))
{
TYPE_VPTR_FIELDNO (type) = i;
break;
@ -2432,6 +2474,12 @@ read_struct_type (pp, type)
}
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;
}
}
@ -2796,7 +2844,6 @@ read_range_type (pp, typenums)
sizeof (struct type));
bzero (result_type, sizeof (struct type));
TYPE_LENGTH (result_type) = nbits / TARGET_CHAR_BIT;
TYPE_MAIN_VARIANT (result_type) = result_type;
TYPE_CODE (result_type) = TYPE_CODE_INT;
if (got_unsigned)
TYPE_FLAGS (result_type) |= TYPE_FLAG_UNSIGNED;

View File

@ -2,31 +2,33 @@
Copyright (C) 1989 Free Software Foundation, Inc.
written by James Clark (jjc@jclark.uucp)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* This is for g++ 1.36.1 (November 6 version). It will probably
require changes for any other version.
Modified for g++ 1.36.2 (November 18 version).
Modified for g++ 1.90.06 (December 31 version). */
Modified for g++ 1.90.06 (December 31 version).
Modified for g++ 1.95.03 (November 13 verison). */
/* This file exports one function
char *cplus_demangle (const char *name, int mode)
If NAME is a mangled function name produced by GNU C++, then
a pointer to a malloced string giving a C++ representation
of the name will be returned; otherwise NULL will be returned.
@ -108,44 +110,81 @@ static int typevec_size = 0;
const static struct optable {
const char *in;
const char *out;
int ansi;
} optable[] = {
"nw", " new", /* new (1.92) */
"dl", " delete", /* new (1.92) */
"new", " new", /* old (1.91, and 1.x) */
"delete", " delete", /* old (1.91, and 1.x) */
"ne", "!=",
"eq", "==",
"ge", ">=",
"gt", ">",
"le", "<=",
"lt", "<",
"plus", "+",
"minus", "-",
"mult", "*",
"convert", "+", /* unary + */
"negate", "-", /* unary - */
"trunc_mod", "%",
"trunc_div", "/",
"truth_andif", "&&",
"truth_orif", "||",
"truth_not", "!",
"postincrement", "++",
"postdecrement", "--",
"bit_ior", "|",
"bit_xor", "^",
"bit_and", "&",
"bit_not", "~",
"call", "()",
"cond", "?:",
"alshift", "<<",
"arshift", ">>",
"component", "->",
"indirect", "*",
"method_call", "->()",
"addr", "&", /* unary & */
"array", "[]",
"compound", ",",
"nop", "", /* for operator= */
"nw", " new", 1, /* new (1.92, ansi) */
"dl", " delete", 1, /* new (1.92, ansi) */
"new", " new", 0, /* old (1.91, and 1.x) */
"delete", " delete", 0, /* old (1.91, and 1.x) */
"as", "=", 1, /* ansi */
"ne", "!=", 1, /* old, ansi */
"eq", "==", 1, /* old, ansi */
"ge", ">=", 1, /* old, ansi */
"gt", ">", 1, /* old, ansi */
"le", "<=", 1, /* old, ansi */
"lt", "<", 1, /* old, ansi */
"plus", "+", 0, /* old */
"pl", "+", 1, /* ansi */
"apl", "+=", 1, /* ansi */
"minus", "-", 0, /* old */
"mi", "-", 1, /* ansi */
"ami", "-=", 1, /* ansi */
"mult", "*", 0, /* old */
"ml", "*", 1, /* ansi */
"aml", "*=", 1, /* ansi */
"convert", "+", 0, /* old (unary +) */
"negate", "-", 0, /* old (unary -) */
"trunc_mod", "%", 0, /* old */
"md", "%", 1, /* ansi */
"amd", "%=", 1, /* ansi */
"trunc_div", "/", 0, /* old */
"dv", "/", 1, /* ansi */
"adv", "/=", 1, /* ansi */
"truth_andif", "&&", 0, /* old */
"aa", "&&", 1, /* ansi */
"truth_orif", "||", 0, /* old */
"oo", "||", 1, /* ansi */
"truth_not", "!", 0, /* old */
"nt", "!", 1, /* ansi */
"postincrement", "++", 0, /* old */
"pp", "++", 1, /* ansi */
"postdecrement", "--", 0, /* old */
"mm", "--", 1, /* ansi */
"bit_ior", "|", 0, /* old */
"or", "|", 1, /* ansi */
"aor", "|=", 1, /* ansi */
"bit_xor", "^", 0, /* old */
"er", "^", 1, /* ansi */
"aer", "^=", 1, /* ansi */
"bit_and", "&", 0, /* old */
"ad", "&", 1, /* ansi */
"aad", "&=", 1, /* ansi */
"bit_not", "~", 0, /* old */
"co", "~", 1, /* ansi */
"call", "()", 0, /* old */
"cl", "()", 1, /* ansi */
"alshift", "<<", 0, /* old */
"ls", "<<", 1, /* ansi */
"als", "<<=", 1, /* ansi */
"arshift", ">>", 0, /* old */
"rs", ">>", 1, /* ansi */
"ars", ">>=", 1, /* ansi */
"component", "->", 0, /* old */
"rf", "->", 1, /* ansi */
"indirect", "*", 0, /* old */
"method_call", "->()", 0, /* old */
"addr", "&", 0, /* old (unary &) */
"array", "[]", 0, /* old */
"vc", "[]", 1, /* ansi */
"compound", ",", 0, /* old */
"cm", ",", 1, /* ansi */
"cond", "?:", 0, /* old */
"cn", "?:", 1, /* psuedo-ansi */
"max", ">?", 0, /* old */
"mx", ">?", 1, /* psuedo-ansi */
"min", "<?", 0, /* old */
"mn", "<?", 1, /* psuedo-ansi */
"nop", "", 0, /* old (for operator=) */
};
/* Beware: these aren't '\0' terminated. */
@ -200,16 +239,24 @@ static void remember_type ();
#endif
/* Takes operator name as e.g. "++" and returns mangled
operator name (e.g. "postincrement_expr"), or NULL if not found. */
operator name (e.g. "postincrement_expr"), or NULL if not found.
If ARG_MODE == 1, return the ANSI name;
if ARG_MODE == 0 return the old GNU name. */
char *
cplus_mangle_opname (opname)
cplus_mangle_opname (opname, arg_mode)
char *opname;
int arg_mode;
{
int i, len = strlen (opname);
if (arg_mode != 0 && arg_mode != 1)
error ("invalid arg_mode");
for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
{
if (strlen (optable[i].out) == len
&& arg_mode == optable[i].ansi
&& memcmp (optable[i].out, opname, len) == 0)
return (char *)optable[i].in;
}
@ -251,19 +298,30 @@ cplus_demangle (type, arg_mode)
/* destructor */
if (type[0] == '_' && type[1] == CPLUS_MARKER && type[2] == '_')
{
destructor = 1;
p = type;
int n = (strlen (type) - 3)*2 + 3 + 2 + 1;
char *tem = (char *) xmalloc (n);
strcpy (tem, type + 3);
strcat (tem, "::~");
strcat (tem, type + 3);
if (print_arg_types)
strcat (tem, "()");
return tem;
}
/* static data member */
if (*type != '_' && (strchr (type, CPLUS_MARKER) != NULL))
if (*type != '_' && (p = strchr (type, CPLUS_MARKER)) != NULL)
{
static_type = 1;
p = type;
int n = strlen (type) + 2;
char *tem = (char *) xmalloc (n);
memcpy (tem, type, p - type);
strcpy (tem + (p - type), "::");
strcpy (tem + (p - type) + 2, p + 1);
return tem;
}
/* virtual table "_vt$" */
/* virtual table "_vt$" */
if (type[0] == '_' && type[1] == 'v' && type[2] == 't' && type[3] == CPLUS_MARKER)
{
char *tem = (char *) xmalloc (strlen (type + 4) + 14 + 1);
int n = strlen (type + 4) + 14 + 1;
char *tem = (char *) xmalloc (n);
strcpy (tem, type + 4);
strcat (tem, " virtual table");
return tem;
@ -283,17 +341,32 @@ cplus_demangle (type, arg_mode)
}
else if (p == type)
{
if (!isdigit (p[2]))
if (!isdigit (p[2]) && ('t' != p[2]))
{
string_delete (&decl);
return NULL;
p += 1;
while (*p != '\0' && !(*p == '_' && p[1] == '_'))
p++;
string_appendn (&decl, type, p - type);
*(decl.p) = '\0';
munge_function_name (&decl, 1);
if (decl.b[0] == '_')
{
string_delete (&decl);
return NULL;
}
else
p += 2;
}
else
{
constructor = 1;
p += 2;
}
constructor = 1;
p += 2;
}
else
{
string_appendn (&decl, type, p - type);
*(decl.p) = '\0';
munge_function_name (&decl, arg_mode);
p += 2;
}
@ -1048,7 +1121,10 @@ munge_function_name (name, arg_mode)
string *name;
int arg_mode;
{
if (!string_empty (name) && name->p - name->b >= 3
if (string_empty (name))
return;
if (name->p - name->b >= 3
&& name->b[0] == 'o' && name->b[1] == 'p' && name->b[2] == CPLUS_MARKER)
{
int i;
@ -1087,8 +1163,7 @@ munge_function_name (name, arg_mode)
}
return;
}
else if (!string_empty (name) && name->p - name->b >= 5
&& memcmp (name->b, "type$", 5) == 0)
else if (name->p - name->b >= 5 && memcmp (name->b, "type$", 5) == 0)
{
/* type conversion operator */
string type;
@ -1102,6 +1177,60 @@ munge_function_name (name, arg_mode)
return;
}
}
/* ANSI. */
else if (name->b[2] == 'o' && name->b[3] == 'p')
{
/* type conversion operator. */
string type;
const char *tem = name->b + 4;
if (do_type (&tem, &type))
{
string_clear (name);
string_append (name, "operator ");
string_appends (name, &type);
string_delete (&type);
return;
}
}
else if (name->b[0] == '_' && name->b[1] == '_'
&& name->b[2] >= 'a' && name->b[2] <= 'z'
&& name->b[3] >= 'a' && name->b[3] <= 'z')
{
int i;
if (name->b[4] == '\0')
{
/* Operator. */
for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
{
if (strlen (optable[i].in) == 2
&& memcmp (optable[i].in, name->b + 2, 2) == 0)
{
string_clear (name);
string_append (name, "operator");
string_append (name, optable[i].out);
return;
}
}
}
else
{
if (name->b[2] != 'a' || name->b[5] != '\0')
return;
/* Assignment. */
for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
{
if (strlen (optable[i].in) == 3
&& memcmp (optable[i].in, name->b + 2, 3) == 0)
{
string_clear (name);
string_append (name, "operator");
string_append (name, optable[i].out);
return;
}
}
}
}
}
/* a mini string-handling package */

View File

@ -899,6 +899,9 @@ DEFUN(struct_type, (dip, thisdie, enddie),
{
case TAG_structure_type:
TYPE_CODE (type) = TYPE_CODE_STRUCT;
TYPE_CPLUS_SPECIFIC (type)
= (struct cplus_struct_type *) obstack_alloc (symbol_obstack, sizeof (struct cplus_struct_type));
bzero (TYPE_CPLUS_SPECIFIC (type), sizeof (struct cplus_struct_type));
tpart1 = "struct ";
break;
case TAG_union_type: