From 572acbbedcc289fad1de4ef807c4c47634338a0a Mon Sep 17 00:00:00 2001 From: Michael Tiemann Date: Mon, 18 Nov 1991 00:32:34 +0000 Subject: [PATCH] Make changes needed to handle code which uses ANSI-mangled names (and new G++ 1.95 dbxout output). --- gdb/ChangeLog | 25 +++++ gdb/buildsym.c | 57 ++++++++++- gdb/cplus-dem.c | 263 ++++++++++++++++++++++++++++++++++++------------ gdb/dwarfread.c | 3 + 4 files changed, 276 insertions(+), 72 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 84a29f40ce0..a2be86b181f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -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 diff --git a/gdb/buildsym.c b/gdb/buildsym.c index 1c55a68f159..410417d942e 100644 --- a/gdb/buildsym.c +++ b/gdb/buildsym.c @@ -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; diff --git a/gdb/cplus-dem.c b/gdb/cplus-dem.c index e7f9d86686b..2398ffbfb7f 100644 --- a/gdb/cplus-dem.c +++ b/gdb/cplus-dem.c @@ -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", "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 */ diff --git a/gdb/dwarfread.c b/gdb/dwarfread.c index 2d72310b2e4..0f96332fe87 100644 --- a/gdb/dwarfread.c +++ b/gdb/dwarfread.c @@ -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: -- 2.30.2