119370Spst/* Support for printing C++ values for GDB, the GNU debugger. 298944Sobrien Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 3130803Smarcel 2000, 2001, 2002, 2003 419370Spst Free Software Foundation, Inc. 519370Spst 698944Sobrien This file is part of GDB. 719370Spst 898944Sobrien This program is free software; you can redistribute it and/or modify 998944Sobrien it under the terms of the GNU General Public License as published by 1098944Sobrien the Free Software Foundation; either version 2 of the License, or 1198944Sobrien (at your option) any later version. 1219370Spst 1398944Sobrien This program is distributed in the hope that it will be useful, 1498944Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1598944Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1698944Sobrien GNU General Public License for more details. 1719370Spst 1898944Sobrien You should have received a copy of the GNU General Public License 1998944Sobrien along with this program; if not, write to the Free Software 2098944Sobrien Foundation, Inc., 59 Temple Place - Suite 330, 2198944Sobrien Boston, MA 02111-1307, USA. */ 2219370Spst 2319370Spst#include "defs.h" 24130803Smarcel#include "gdb_obstack.h" 2519370Spst#include "symtab.h" 2619370Spst#include "gdbtypes.h" 2719370Spst#include "expression.h" 2819370Spst#include "value.h" 2919370Spst#include "command.h" 3019370Spst#include "gdbcmd.h" 3119370Spst#include "demangle.h" 3219370Spst#include "annotate.h" 3319370Spst#include "gdb_string.h" 3419370Spst#include "c-lang.h" 3546283Sdfr#include "target.h" 3698944Sobrien#include "cp-abi.h" 37130803Smarcel#include "valprint.h" 3819370Spst 3998944Sobrien/* Indication of presence of HP-compiled object files */ 4098944Sobrienextern int hp_som_som_object_present; /* defined in symtab.c */ 4146283Sdfr 4246283Sdfr 4319370Spstint vtblprint; /* Controls printing of vtbl's */ 4419370Spstint objectprint; /* Controls looking up an object's derived type 4519370Spst using what we find in its vtables. */ 4698944Sobrienint static_field_print; /* Controls printing of static fields. */ 4719370Spst 4819370Spststatic struct obstack dont_print_vb_obstack; 4919370Spststatic struct obstack dont_print_statmem_obstack; 5019370Spst 5198944Sobrienextern void _initialize_cp_valprint (void); 5219370Spst 5398944Sobrienstatic void cp_print_static_field (struct type *, struct value *, 5498944Sobrien struct ui_file *, int, int, 5598944Sobrien enum val_prettyprint); 5619370Spst 5798944Sobrienstatic void cp_print_value (struct type *, struct type *, char *, int, 5898944Sobrien CORE_ADDR, struct ui_file *, int, int, 5998944Sobrien enum val_prettyprint, struct type **); 6046283Sdfr 6198944Sobrienstatic void cp_print_hpacc_virtual_table_entries (struct type *, int *, 6298944Sobrien struct value *, 6398944Sobrien struct ui_file *, int, 6498944Sobrien int, 6598944Sobrien enum val_prettyprint); 6646283Sdfr 6798944Sobrien 6819370Spstvoid 6998944Sobriencp_print_class_method (char *valaddr, 7098944Sobrien struct type *type, 7198944Sobrien struct ui_file *stream) 7219370Spst{ 7319370Spst struct type *domain; 7419370Spst struct fn_field *f = NULL; 7519370Spst int j = 0; 7619370Spst int len2; 7719370Spst int offset; 7819370Spst char *kind = ""; 7919370Spst CORE_ADDR addr; 8019370Spst struct symbol *sym; 8119370Spst unsigned len; 8219370Spst unsigned int i; 8319370Spst struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type)); 8419370Spst 8519370Spst domain = TYPE_DOMAIN_TYPE (target_type); 8698944Sobrien if (domain == (struct type *) NULL) 8719370Spst { 8819370Spst fprintf_filtered (stream, "<unknown>"); 8919370Spst return; 9019370Spst } 91130803Smarcel addr = unpack_pointer (type, valaddr); 9219370Spst if (METHOD_PTR_IS_VIRTUAL (addr)) 9319370Spst { 9419370Spst offset = METHOD_PTR_TO_VOFFSET (addr); 9519370Spst len = TYPE_NFN_FIELDS (domain); 9619370Spst for (i = 0; i < len; i++) 9719370Spst { 9819370Spst f = TYPE_FN_FIELDLIST1 (domain, i); 9919370Spst len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i); 10098944Sobrien 101130803Smarcel check_stub_method_group (domain, i); 10219370Spst for (j = 0; j < len2; j++) 10319370Spst { 10419370Spst if (TYPE_FN_FIELD_VOFFSET (f, j) == offset) 10519370Spst { 10619370Spst kind = "virtual "; 10719370Spst goto common; 10819370Spst } 10919370Spst } 11019370Spst } 11119370Spst } 11219370Spst else 11319370Spst { 11419370Spst sym = find_pc_function (addr); 11519370Spst if (sym == 0) 11619370Spst { 11798944Sobrien /* 1997-08-01 Currently unsupported with HP aCC */ 11898944Sobrien if (hp_som_som_object_present) 11998944Sobrien { 12098944Sobrien fputs_filtered ("?? <not supported with HP aCC>", stream); 12198944Sobrien return; 12298944Sobrien } 12319370Spst error ("invalid pointer to member function"); 12419370Spst } 12519370Spst len = TYPE_NFN_FIELDS (domain); 12619370Spst for (i = 0; i < len; i++) 12719370Spst { 12819370Spst f = TYPE_FN_FIELDLIST1 (domain, i); 12919370Spst len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i); 13098944Sobrien 131130803Smarcel check_stub_method_group (domain, i); 13219370Spst for (j = 0; j < len2; j++) 13319370Spst { 134130803Smarcel if (strcmp (DEPRECATED_SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)) 135130803Smarcel == 0) 136130803Smarcel goto common; 13719370Spst } 13819370Spst } 13919370Spst } 14098944Sobrien common: 14119370Spst if (i < len) 14219370Spst { 14346283Sdfr char *demangled_name; 14446283Sdfr 14519370Spst fprintf_filtered (stream, "&"); 146130803Smarcel fputs_filtered (kind, stream); 14746283Sdfr demangled_name = cplus_demangle (TYPE_FN_FIELD_PHYSNAME (f, j), 14846283Sdfr DMGL_ANSI | DMGL_PARAMS); 14946283Sdfr if (demangled_name == NULL) 15046283Sdfr fprintf_filtered (stream, "<badly mangled name %s>", 15146283Sdfr TYPE_FN_FIELD_PHYSNAME (f, j)); 15219370Spst else 15319370Spst { 15446283Sdfr fputs_filtered (demangled_name, stream); 15598944Sobrien xfree (demangled_name); 15619370Spst } 15719370Spst } 15819370Spst else 15919370Spst { 16019370Spst fprintf_filtered (stream, "("); 16119370Spst type_print (type, "", stream, -1); 16219370Spst fprintf_filtered (stream, ") %d", (int) addr >> 3); 16319370Spst } 16419370Spst} 16519370Spst 166130803Smarcel/* GCC versions after 2.4.5 use this. */ 16798944Sobrienconst char vtbl_ptr_name[] = "__vtbl_ptr_type"; 16819370Spst 169130803Smarcel/* HP aCC uses different names. */ 17098944Sobrienconst char hpacc_vtbl_ptr_name[] = "__vfp"; 17198944Sobrienconst char hpacc_vtbl_ptr_type_name[] = "__vftyp"; 17246283Sdfr 17319370Spst/* Return truth value for assertion that TYPE is of the type 17419370Spst "pointer to virtual function". */ 17519370Spst 17619370Spstint 17798944Sobriencp_is_vtbl_ptr_type (struct type *type) 17819370Spst{ 17919370Spst char *typename = type_name_no_tag (type); 18019370Spst 181130803Smarcel return (typename != NULL && !strcmp (typename, vtbl_ptr_name)); 18219370Spst} 18319370Spst 18419370Spst/* Return truth value for the assertion that TYPE is of the type 18519370Spst "pointer to virtual function table". */ 18619370Spst 18719370Spstint 18898944Sobriencp_is_vtbl_member (struct type *type) 18919370Spst{ 190130803Smarcel /* With older versions of g++, the vtbl field pointed to an array 191130803Smarcel of structures. Nowadays it points directly to the structure. */ 19219370Spst if (TYPE_CODE (type) == TYPE_CODE_PTR) 19319370Spst { 19419370Spst type = TYPE_TARGET_TYPE (type); 19519370Spst if (TYPE_CODE (type) == TYPE_CODE_ARRAY) 19619370Spst { 19719370Spst type = TYPE_TARGET_TYPE (type); 19898944Sobrien if (TYPE_CODE (type) == TYPE_CODE_STRUCT /* if not using thunks */ 19998944Sobrien || TYPE_CODE (type) == TYPE_CODE_PTR) /* if using thunks */ 20019370Spst { 20119370Spst /* Virtual functions tables are full of pointers 20298944Sobrien to virtual functions. */ 20319370Spst return cp_is_vtbl_ptr_type (type); 20419370Spst } 20519370Spst } 206130803Smarcel else if (TYPE_CODE (type) == TYPE_CODE_STRUCT) /* if not using thunks */ 207130803Smarcel { 208130803Smarcel return cp_is_vtbl_ptr_type (type); 209130803Smarcel } 210130803Smarcel else if (TYPE_CODE (type) == TYPE_CODE_PTR) /* if using thunks */ 211130803Smarcel { 212130803Smarcel /* The type name of the thunk pointer is NULL when using dwarf2. 213130803Smarcel We could test for a pointer to a function, but there is 214130803Smarcel no type info for the virtual table either, so it wont help. */ 215130803Smarcel return cp_is_vtbl_ptr_type (type); 216130803Smarcel } 21719370Spst } 21819370Spst return 0; 21919370Spst} 22019370Spst 22119370Spst/* Mutually recursive subroutines of cp_print_value and c_val_print to 22219370Spst print out a structure's fields: cp_print_value_fields and cp_print_value. 22398944Sobrien 22419370Spst TYPE, VALADDR, ADDRESS, STREAM, RECURSE, and PRETTY have the 22519370Spst same meanings as in cp_print_value and c_val_print. 22619370Spst 22746283Sdfr 2nd argument REAL_TYPE is used to carry over the type of the derived 22846283Sdfr class across the recursion to base classes. 22946283Sdfr 23019370Spst DONT_PRINT is an array of baseclass types that we 23119370Spst should not print, or zero if called from top level. */ 23219370Spst 23319370Spstvoid 23498944Sobriencp_print_value_fields (struct type *type, struct type *real_type, char *valaddr, 23598944Sobrien int offset, CORE_ADDR address, struct ui_file *stream, 23698944Sobrien int format, int recurse, enum val_prettyprint pretty, 23798944Sobrien struct type **dont_print_vb, int dont_print_statmem) 23819370Spst{ 23919370Spst int i, len, n_baseclasses; 24019370Spst struct obstack tmp_obstack; 24119370Spst char *last_dont_print = obstack_next_free (&dont_print_statmem_obstack); 24246283Sdfr int fields_seen = 0; 24319370Spst 24419370Spst CHECK_TYPEDEF (type); 24519370Spst 24619370Spst fprintf_filtered (stream, "{"); 24719370Spst len = TYPE_NFIELDS (type); 24819370Spst n_baseclasses = TYPE_N_BASECLASSES (type); 24919370Spst 25046283Sdfr /* First, print out baseclasses such that we don't print 25119370Spst duplicates of virtual baseclasses. */ 25246283Sdfr 25319370Spst if (n_baseclasses > 0) 25446283Sdfr cp_print_value (type, real_type, valaddr, offset, address, stream, 25598944Sobrien format, recurse + 1, pretty, dont_print_vb); 25619370Spst 25746283Sdfr /* Second, print out data fields */ 25846283Sdfr 25946283Sdfr /* If there are no data fields, or if the only field is the 26098944Sobrien * vtbl pointer, skip this part */ 26198944Sobrien if ((len == n_baseclasses) 26298944Sobrien || ((len - n_baseclasses == 1) 26398944Sobrien && TYPE_HAS_VTABLE (type) 264130803Smarcel && strncmp (TYPE_FIELD_NAME (type, n_baseclasses), 265130803Smarcel hpacc_vtbl_ptr_name, 5) == 0) 26698944Sobrien || !len) 26719370Spst fprintf_filtered (stream, "<No data fields>"); 26819370Spst else 26919370Spst { 27019370Spst if (dont_print_statmem == 0) 27119370Spst { 27219370Spst /* If we're at top level, carve out a completely fresh 27319370Spst chunk of the obstack and use that until this particular 27419370Spst invocation returns. */ 27519370Spst tmp_obstack = dont_print_statmem_obstack; 27619370Spst obstack_finish (&dont_print_statmem_obstack); 27719370Spst } 27819370Spst 27919370Spst for (i = n_baseclasses; i < len; i++) 28019370Spst { 28119370Spst /* If requested, skip printing of static fields. */ 28219370Spst if (!static_field_print && TYPE_FIELD_STATIC (type, i)) 28319370Spst continue; 28446283Sdfr 28598944Sobrien /* If a vtable pointer appears, we'll print it out later */ 28698944Sobrien if (TYPE_HAS_VTABLE (type) 287130803Smarcel && strncmp (TYPE_FIELD_NAME (type, i), hpacc_vtbl_ptr_name, 288130803Smarcel 5) == 0) 28998944Sobrien continue; 29098944Sobrien 29119370Spst if (fields_seen) 29219370Spst fprintf_filtered (stream, ", "); 29319370Spst else if (n_baseclasses > 0) 29419370Spst { 29519370Spst if (pretty) 29619370Spst { 29719370Spst fprintf_filtered (stream, "\n"); 29819370Spst print_spaces_filtered (2 + 2 * recurse, stream); 29919370Spst fputs_filtered ("members of ", stream); 30019370Spst fputs_filtered (type_name_no_tag (type), stream); 30119370Spst fputs_filtered (": ", stream); 30219370Spst } 30319370Spst } 30419370Spst fields_seen = 1; 30519370Spst 30619370Spst if (pretty) 30719370Spst { 30819370Spst fprintf_filtered (stream, "\n"); 30919370Spst print_spaces_filtered (2 + 2 * recurse, stream); 31019370Spst } 31198944Sobrien else 31219370Spst { 31319370Spst wrap_here (n_spaces (2 + 2 * recurse)); 31419370Spst } 31519370Spst if (inspect_it) 31619370Spst { 31719370Spst if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR) 31819370Spst fputs_filtered ("\"( ptr \"", stream); 31919370Spst else 32019370Spst fputs_filtered ("\"( nodef \"", stream); 32119370Spst if (TYPE_FIELD_STATIC (type, i)) 32219370Spst fputs_filtered ("static ", stream); 32319370Spst fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), 32419370Spst language_cplus, 32519370Spst DMGL_PARAMS | DMGL_ANSI); 32619370Spst fputs_filtered ("\" \"", stream); 32719370Spst fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), 32819370Spst language_cplus, 32919370Spst DMGL_PARAMS | DMGL_ANSI); 33019370Spst fputs_filtered ("\") \"", stream); 33119370Spst } 33219370Spst else 33319370Spst { 33419370Spst annotate_field_begin (TYPE_FIELD_TYPE (type, i)); 33519370Spst 33619370Spst if (TYPE_FIELD_STATIC (type, i)) 33719370Spst fputs_filtered ("static ", stream); 33819370Spst fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), 33919370Spst language_cplus, 34019370Spst DMGL_PARAMS | DMGL_ANSI); 34119370Spst annotate_field_name_end (); 34246283Sdfr /* do not print leading '=' in case of anonymous unions */ 34346283Sdfr if (strcmp (TYPE_FIELD_NAME (type, i), "")) 34446283Sdfr fputs_filtered (" = ", stream); 34519370Spst annotate_field_value (); 34619370Spst } 34719370Spst 34819370Spst if (!TYPE_FIELD_STATIC (type, i) && TYPE_FIELD_PACKED (type, i)) 34919370Spst { 35098944Sobrien struct value *v; 35119370Spst 35219370Spst /* Bitfields require special handling, especially due to byte 35398944Sobrien order problems. */ 35419370Spst if (TYPE_FIELD_IGNORE (type, i)) 35519370Spst { 35698944Sobrien fputs_filtered ("<optimized out or zero length>", stream); 35719370Spst } 35819370Spst else 35919370Spst { 36098944Sobrien v = value_from_longest 36198944Sobrien (TYPE_FIELD_TYPE (type, i), 36298944Sobrien unpack_field_as_long (type, valaddr + offset, i)); 36319370Spst 364242936Semaste common_val_print (v, stream, format, 0, recurse + 1, pretty); 36519370Spst } 36619370Spst } 36719370Spst else 36819370Spst { 36919370Spst if (TYPE_FIELD_IGNORE (type, i)) 37019370Spst { 37198944Sobrien fputs_filtered ("<optimized out or zero length>", stream); 37219370Spst } 37319370Spst else if (TYPE_FIELD_STATIC (type, i)) 37419370Spst { 37598944Sobrien struct value *v = value_static_field (type, i); 37646283Sdfr if (v == NULL) 37719370Spst fputs_filtered ("<optimized out>", stream); 37819370Spst else 37946283Sdfr cp_print_static_field (TYPE_FIELD_TYPE (type, i), v, 38046283Sdfr stream, format, recurse + 1, 38146283Sdfr pretty); 38219370Spst } 38319370Spst else 38419370Spst { 38598944Sobrien val_print (TYPE_FIELD_TYPE (type, i), 38698944Sobrien valaddr, offset + TYPE_FIELD_BITPOS (type, i) / 8, 38798944Sobrien address + TYPE_FIELD_BITPOS (type, i) / 8, 38898944Sobrien stream, format, 0, recurse + 1, pretty); 38919370Spst } 39019370Spst } 39119370Spst annotate_field_end (); 39219370Spst } 39319370Spst 39419370Spst if (dont_print_statmem == 0) 39519370Spst { 39619370Spst /* Free the space used to deal with the printing 39719370Spst of the members from top level. */ 39819370Spst obstack_free (&dont_print_statmem_obstack, last_dont_print); 39919370Spst dont_print_statmem_obstack = tmp_obstack; 40019370Spst } 40119370Spst 40219370Spst if (pretty) 40319370Spst { 40419370Spst fprintf_filtered (stream, "\n"); 40519370Spst print_spaces_filtered (2 * recurse, stream); 40619370Spst } 40798944Sobrien } /* if there are data fields */ 40898944Sobrien /* Now print out the virtual table pointer if there is one */ 40998944Sobrien if (TYPE_HAS_VTABLE (type) 410130803Smarcel && strncmp (TYPE_FIELD_NAME (type, n_baseclasses), 411130803Smarcel hpacc_vtbl_ptr_name, 5) == 0) 41246283Sdfr { 41398944Sobrien struct value *v; 41498944Sobrien /* First get the virtual table pointer and print it out */ 41546283Sdfr 41646283Sdfr#if 0 41746283Sdfr fputs_filtered ("__vfp = ", stream); 41846283Sdfr#endif 41946283Sdfr 42046283Sdfr fputs_filtered (", Virtual table at ", stream); 42146283Sdfr 42246283Sdfr /* pai: FIXME 32x64 problem? */ 42346283Sdfr /* Not sure what the best notation is in the case where there is no 42446283Sdfr baseclass name. */ 42598944Sobrien v = value_from_pointer (lookup_pointer_type (builtin_type_unsigned_long), 42698944Sobrien *(unsigned long *) (valaddr + offset)); 42746283Sdfr 428242936Semaste common_val_print (v, stream, format, 0, recurse + 1, pretty); 42946283Sdfr fields_seen = 1; 43046283Sdfr 43146283Sdfr if (vtblprint) 43298944Sobrien { 43398944Sobrien /* Print out function pointers in vtable. */ 43446283Sdfr 43598944Sobrien /* FIXME: then-clause is for non-RRBC layout of virtual 43698944Sobrien * table. The RRBC case in the else-clause is yet to be 43798944Sobrien * implemented. The if (1) below should be changed to a 43898944Sobrien * test for whether the executable we have was compiled 43998944Sobrien * with a version of HP aCC that doesn't have RRBC 44098944Sobrien * support. */ 44146283Sdfr 44298944Sobrien if (1) 44398944Sobrien { 44498944Sobrien /* no RRBC support; function pointers embedded directly 44598944Sobrien in vtable */ 44646283Sdfr 44798944Sobrien int vfuncs = count_virtual_fns (real_type); 44846283Sdfr 44998944Sobrien fputs_filtered (" {", stream); 45046283Sdfr 45198944Sobrien /* FIXME : doesn't work at present */ 45246283Sdfr#if 0 45398944Sobrien fprintf_filtered (stream, "%d entr%s: ", vfuncs, 45498944Sobrien vfuncs == 1 ? "y" : "ies"); 45546283Sdfr#else 45698944Sobrien fputs_filtered ("not implemented", stream); 45746283Sdfr 45846283Sdfr 45946283Sdfr#endif 46046283Sdfr 46198944Sobrien /* recursive function that prints all virtual function entries */ 46246283Sdfr#if 0 46398944Sobrien cp_print_hpacc_virtual_table_entries (real_type, &vfuncs, v, 46498944Sobrien stream, format, recurse, 46598944Sobrien pretty); 46646283Sdfr#endif 46798944Sobrien fputs_filtered ("}", stream); 46898944Sobrien } /* non-RRBC case */ 46998944Sobrien else 47098944Sobrien { 47198944Sobrien /* FIXME -- see comments above */ 47298944Sobrien /* RRBC support present; function pointers are found 47398944Sobrien * by indirection through the class segment entries. */ 47446283Sdfr 47546283Sdfr 47698944Sobrien } /* RRBC case */ 47798944Sobrien } /* if vtblprint */ 47898944Sobrien 47946283Sdfr if (pretty) 48046283Sdfr { 48146283Sdfr fprintf_filtered (stream, "\n"); 48246283Sdfr print_spaces_filtered (2 * recurse, stream); 48346283Sdfr } 48446283Sdfr 48598944Sobrien } /* if vtable exists */ 48698944Sobrien 48719370Spst fprintf_filtered (stream, "}"); 48819370Spst} 48919370Spst 49019370Spst/* Special val_print routine to avoid printing multiple copies of virtual 49119370Spst baseclasses. */ 49219370Spst 49319370Spststatic void 49498944Sobriencp_print_value (struct type *type, struct type *real_type, char *valaddr, 49598944Sobrien int offset, CORE_ADDR address, struct ui_file *stream, 49698944Sobrien int format, int recurse, enum val_prettyprint pretty, 49798944Sobrien struct type **dont_print_vb) 49819370Spst{ 49919370Spst struct obstack tmp_obstack; 50019370Spst struct type **last_dont_print 50198944Sobrien = (struct type **) obstack_next_free (&dont_print_vb_obstack); 50219370Spst int i, n_baseclasses = TYPE_N_BASECLASSES (type); 50398944Sobrien int thisoffset; 50498944Sobrien struct type *thistype; 50519370Spst 50619370Spst if (dont_print_vb == 0) 50719370Spst { 50819370Spst /* If we're at top level, carve out a completely fresh 50998944Sobrien chunk of the obstack and use that until this particular 51098944Sobrien invocation returns. */ 51119370Spst tmp_obstack = dont_print_vb_obstack; 51219370Spst /* Bump up the high-water mark. Now alpha is omega. */ 51319370Spst obstack_finish (&dont_print_vb_obstack); 51419370Spst } 51519370Spst 51619370Spst for (i = 0; i < n_baseclasses; i++) 51719370Spst { 51819370Spst int boffset; 51946283Sdfr int skip; 52019370Spst struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i)); 52119370Spst char *basename = TYPE_NAME (baseclass); 52246283Sdfr char *base_valaddr; 52319370Spst 52419370Spst if (BASETYPE_VIA_VIRTUAL (type, i)) 52519370Spst { 52619370Spst struct type **first_dont_print 52798944Sobrien = (struct type **) obstack_base (&dont_print_vb_obstack); 52819370Spst 52998944Sobrien int j = (struct type **) obstack_next_free (&dont_print_vb_obstack) 53019370Spst - first_dont_print; 53119370Spst 53219370Spst while (--j >= 0) 53319370Spst if (baseclass == first_dont_print[j]) 53419370Spst goto flush_it; 53519370Spst 53619370Spst obstack_ptr_grow (&dont_print_vb_obstack, baseclass); 53719370Spst } 53819370Spst 53998944Sobrien thisoffset = offset; 54098944Sobrien thistype = real_type; 54146283Sdfr if (TYPE_HAS_VTABLE (type) && BASETYPE_VIA_VIRTUAL (type, i)) 54298944Sobrien { 54398944Sobrien /* Assume HP/Taligent runtime convention */ 54498944Sobrien find_rt_vbase_offset (type, TYPE_BASECLASS (type, i), 54598944Sobrien valaddr, offset, &boffset, &skip); 54698944Sobrien if (skip >= 0) 54798944Sobrien error ("Virtual base class offset not found from vtable while" 54898944Sobrien " printing"); 54998944Sobrien base_valaddr = valaddr; 55098944Sobrien } 55146283Sdfr else 55298944Sobrien { 55398944Sobrien boffset = baseclass_offset (type, i, 55498944Sobrien valaddr + offset, 555130803Smarcel address); 55698944Sobrien skip = ((boffset == -1) || (boffset + offset) < 0) ? 1 : -1; 55719370Spst 55898944Sobrien if (BASETYPE_VIA_VIRTUAL (type, i)) 55998944Sobrien { 56098944Sobrien /* The virtual base class pointer might have been 56198944Sobrien clobbered by the user program. Make sure that it 56298944Sobrien still points to a valid memory location. */ 56346283Sdfr 56498944Sobrien if (boffset != -1 56598944Sobrien && ((boffset + offset) < 0 56698944Sobrien || (boffset + offset) >= TYPE_LENGTH (type))) 56798944Sobrien { 56898944Sobrien /* FIXME (alloca): unsafe if baseclass is really really large. */ 56998944Sobrien base_valaddr = (char *) alloca (TYPE_LENGTH (baseclass)); 570130803Smarcel if (target_read_memory (address + boffset, base_valaddr, 57198944Sobrien TYPE_LENGTH (baseclass)) != 0) 57298944Sobrien skip = 1; 573130803Smarcel address = address + boffset; 57498944Sobrien thisoffset = 0; 57598944Sobrien boffset = 0; 57698944Sobrien thistype = baseclass; 57798944Sobrien } 57898944Sobrien else 57998944Sobrien base_valaddr = valaddr; 58098944Sobrien } 58198944Sobrien else 58298944Sobrien base_valaddr = valaddr; 58346283Sdfr } 58446283Sdfr 58546283Sdfr /* now do the printing */ 58619370Spst if (pretty) 58719370Spst { 58819370Spst fprintf_filtered (stream, "\n"); 58919370Spst print_spaces_filtered (2 * recurse, stream); 59019370Spst } 59119370Spst fputs_filtered ("<", stream); 59219370Spst /* Not sure what the best notation is in the case where there is no 59398944Sobrien baseclass name. */ 59419370Spst fputs_filtered (basename ? basename : "", stream); 59519370Spst fputs_filtered ("> = ", stream); 59646283Sdfr 59746283Sdfr 59846283Sdfr if (skip >= 1) 59919370Spst fprintf_filtered (stream, "<invalid address>"); 60019370Spst else 60198944Sobrien cp_print_value_fields (baseclass, thistype, base_valaddr, 602130803Smarcel thisoffset + boffset, address + boffset, 603130803Smarcel stream, format, 60498944Sobrien recurse, pretty, 60598944Sobrien ((struct type **) 60698944Sobrien obstack_base (&dont_print_vb_obstack)), 60719370Spst 0); 60819370Spst fputs_filtered (", ", stream); 60919370Spst 61019370Spst flush_it: 61119370Spst ; 61219370Spst } 61319370Spst 61419370Spst if (dont_print_vb == 0) 61519370Spst { 61619370Spst /* Free the space used to deal with the printing 61798944Sobrien of this type from top level. */ 61819370Spst obstack_free (&dont_print_vb_obstack, last_dont_print); 61919370Spst /* Reset watermark so that we can continue protecting 62098944Sobrien ourselves from whatever we were protecting ourselves. */ 62119370Spst dont_print_vb_obstack = tmp_obstack; 62219370Spst } 62319370Spst} 62419370Spst 62519370Spst/* Print value of a static member. 62619370Spst To avoid infinite recursion when printing a class that contains 62719370Spst a static instance of the class, we keep the addresses of all printed 62819370Spst static member classes in an obstack and refuse to print them more 62919370Spst than once. 63019370Spst 63119370Spst VAL contains the value to print, TYPE, STREAM, RECURSE, and PRETTY 63219370Spst have the same meanings as in c_val_print. */ 63319370Spst 63419370Spststatic void 63598944Sobriencp_print_static_field (struct type *type, 63698944Sobrien struct value *val, 63798944Sobrien struct ui_file *stream, 63898944Sobrien int format, 63998944Sobrien int recurse, 64098944Sobrien enum val_prettyprint pretty) 64119370Spst{ 64219370Spst if (TYPE_CODE (type) == TYPE_CODE_STRUCT) 64319370Spst { 64419370Spst CORE_ADDR *first_dont_print; 64519370Spst int i; 64619370Spst 64719370Spst first_dont_print 64898944Sobrien = (CORE_ADDR *) obstack_base (&dont_print_statmem_obstack); 64998944Sobrien i = (CORE_ADDR *) obstack_next_free (&dont_print_statmem_obstack) 65019370Spst - first_dont_print; 65119370Spst 65219370Spst while (--i >= 0) 65319370Spst { 65419370Spst if (VALUE_ADDRESS (val) == first_dont_print[i]) 65519370Spst { 65698944Sobrien fputs_filtered ("<same as static member of an already" 65798944Sobrien " seen type>", 65819370Spst stream); 65919370Spst return; 66019370Spst } 66119370Spst } 66219370Spst 66319370Spst obstack_grow (&dont_print_statmem_obstack, (char *) &VALUE_ADDRESS (val), 66419370Spst sizeof (CORE_ADDR)); 66519370Spst 66619370Spst CHECK_TYPEDEF (type); 66798944Sobrien cp_print_value_fields (type, type, VALUE_CONTENTS_ALL (val), 66898944Sobrien VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val), 66919370Spst stream, format, recurse, pretty, NULL, 1); 67019370Spst return; 67119370Spst } 67298944Sobrien val_print (type, VALUE_CONTENTS_ALL (val), 67398944Sobrien VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val), 67419370Spst stream, format, 0, recurse, pretty); 67519370Spst} 67619370Spst 67719370Spstvoid 67898944Sobriencp_print_class_member (char *valaddr, struct type *domain, 67998944Sobrien struct ui_file *stream, char *prefix) 68019370Spst{ 68198944Sobrien 68219370Spst /* VAL is a byte offset into the structure type DOMAIN. 68319370Spst Find the name of the field for that offset and 68419370Spst print it. */ 68519370Spst int extra = 0; 68619370Spst int bits = 0; 687130803Smarcel unsigned int i; 68819370Spst unsigned len = TYPE_NFIELDS (domain); 68946283Sdfr 69019370Spst /* @@ Make VAL into bit offset */ 69146283Sdfr 69246283Sdfr /* Note: HP aCC generates offsets that are the real byte offsets added 69346283Sdfr to a constant bias 0x20000000 (1 << 29). This constant bias gets 69446283Sdfr shifted out in the code below -- joyous happenstance! */ 69546283Sdfr 69646283Sdfr /* Note: HP cfront uses a constant bias of 1; if we support this 69798944Sobrien compiler ever, we will have to adjust the computation below */ 69898944Sobrien 69919370Spst LONGEST val = unpack_long (builtin_type_int, valaddr) << 3; 70019370Spst for (i = TYPE_N_BASECLASSES (domain); i < len; i++) 70119370Spst { 70219370Spst int bitpos = TYPE_FIELD_BITPOS (domain, i); 70319370Spst QUIT; 70419370Spst if (val == bitpos) 70519370Spst break; 70619370Spst if (val < bitpos && i != 0) 70719370Spst { 70819370Spst /* Somehow pointing into a field. */ 70919370Spst i -= 1; 71019370Spst extra = (val - TYPE_FIELD_BITPOS (domain, i)); 71119370Spst if (extra & 0x7) 71219370Spst bits = 1; 71319370Spst else 71419370Spst extra >>= 3; 71519370Spst break; 71619370Spst } 71719370Spst } 71819370Spst if (i < len) 71919370Spst { 72019370Spst char *name; 721130803Smarcel fputs_filtered (prefix, stream); 72219370Spst name = type_name_no_tag (domain); 72319370Spst if (name) 72498944Sobrien fputs_filtered (name, stream); 72519370Spst else 72619370Spst c_type_print_base (domain, stream, 0, 0); 72719370Spst fprintf_filtered (stream, "::"); 72819370Spst fputs_filtered (TYPE_FIELD_NAME (domain, i), stream); 72919370Spst if (extra) 73019370Spst fprintf_filtered (stream, " + %d bytes", extra); 73119370Spst if (bits) 73219370Spst fprintf_filtered (stream, " (offset in bits)"); 73319370Spst } 73419370Spst else 73598944Sobrien fprintf_filtered (stream, "%ld", (long) (val >> 3)); 73619370Spst} 73719370Spst 73846283Sdfr 73946283Sdfr/* This function prints out virtual table entries for a class; it 74046283Sdfr * recurses on the base classes to find all virtual functions 74146283Sdfr * available in a class. 74246283Sdfr * 74346283Sdfr * pai/1997-05-21 Note: As the name suggests, it's currently 74446283Sdfr * implemented for HP aCC runtime only. g++ objects are handled 74546283Sdfr * differently and I have made no attempt to fold that logic in 74646283Sdfr * here. The runtime layout is different for the two cases. Also, 74746283Sdfr * this currently has only the code for non-RRBC layouts generated by 74846283Sdfr * the HP aCC compiler; RRBC code is stubbed out and will have to be 74946283Sdfr * added later. */ 75046283Sdfr 75198944Sobrien 75246283Sdfrstatic void 75398944Sobriencp_print_hpacc_virtual_table_entries (struct type *type, int *vfuncs, 75498944Sobrien struct value *v, struct ui_file *stream, 75598944Sobrien int format, int recurse, 75698944Sobrien enum val_prettyprint pretty) 75746283Sdfr{ 75846283Sdfr int fn, oi; 75946283Sdfr 76046283Sdfr /* pai: FIXME this function doesn't work. It should handle a given 76146283Sdfr * virtual function only once (latest redefinition in class hierarchy) 76246283Sdfr */ 76346283Sdfr 76498944Sobrien /* Recursion on other classes that can share the same vtable */ 76598944Sobrien struct type *pbc = primary_base_class (type); 76646283Sdfr if (pbc) 76798944Sobrien cp_print_hpacc_virtual_table_entries (pbc, vfuncs, v, stream, format, 76898944Sobrien recurse, pretty); 76998944Sobrien 77046283Sdfr /* Now deal with vfuncs declared in this class */ 77146283Sdfr for (fn = 0; fn < TYPE_NFN_FIELDS (type); fn++) 77246283Sdfr for (oi = 0; oi < TYPE_FN_FIELDLIST_LENGTH (type, fn); oi++) 77346283Sdfr if (TYPE_FN_FIELD_VIRTUAL_P (TYPE_FN_FIELDLIST1 (type, fn), oi)) 77498944Sobrien { 77598944Sobrien char *vf_name; 77698944Sobrien const char *field_physname; 77746283Sdfr 77898944Sobrien /* virtual function offset */ 77998944Sobrien int vx = (TYPE_FN_FIELD_VOFFSET (TYPE_FN_FIELDLIST1 (type, fn), oi) 78098944Sobrien - 1); 78146283Sdfr 78298944Sobrien /* Get the address of the vfunction entry */ 78398944Sobrien struct value *vf = value_copy (v); 78498944Sobrien if (VALUE_LAZY (vf)) 78598944Sobrien (void) value_fetch_lazy (vf); 78698944Sobrien /* adjust by offset */ 78798944Sobrien vf->aligner.contents[0] += 4 * (HP_ACC_VFUNC_START + vx); 78898944Sobrien vf = value_ind (vf); /* get the entry */ 78998944Sobrien VALUE_TYPE (vf) = VALUE_TYPE (v); /* make it a pointer */ 79046283Sdfr 79198944Sobrien /* print out the entry */ 792242936Semaste common_val_print (vf, stream, format, 0, recurse + 1, pretty); 79398944Sobrien field_physname 79498944Sobrien = TYPE_FN_FIELD_PHYSNAME (TYPE_FN_FIELDLIST1 (type, fn), oi); 79598944Sobrien /* pai: (temp) FIXME Maybe this should be DMGL_ANSI */ 79698944Sobrien vf_name = cplus_demangle (field_physname, DMGL_ARM); 79798944Sobrien fprintf_filtered (stream, " %s", vf_name); 79898944Sobrien if (--(*vfuncs) > 0) 79998944Sobrien fputs_filtered (", ", stream); 80098944Sobrien } 80146283Sdfr} 80246283Sdfr 80346283Sdfr 80446283Sdfr 80519370Spstvoid 80698944Sobrien_initialize_cp_valprint (void) 80719370Spst{ 80819370Spst add_show_from_set 80919370Spst (add_set_cmd ("static-members", class_support, var_boolean, 81098944Sobrien (char *) &static_field_print, 81119370Spst "Set printing of C++ static members.", 81219370Spst &setprintlist), 81319370Spst &showprintlist); 81419370Spst /* Turn on printing of static fields. */ 81519370Spst static_field_print = 1; 81619370Spst 81719370Spst add_show_from_set 81898944Sobrien (add_set_cmd ("vtbl", class_support, var_boolean, (char *) &vtblprint, 81919370Spst "Set printing of C++ virtual function tables.", 82019370Spst &setprintlist), 82119370Spst &showprintlist); 82219370Spst 82319370Spst add_show_from_set 82498944Sobrien (add_set_cmd ("object", class_support, var_boolean, (char *) &objectprint, 82598944Sobrien "Set printing of object's derived type based on vtable info.", 82619370Spst &setprintlist), 82719370Spst &showprintlist); 82819370Spst 82919370Spst /* Give people the defaults which they are used to. */ 83019370Spst objectprint = 0; 83119370Spst vtblprint = 0; 83219370Spst obstack_begin (&dont_print_vb_obstack, 32 * sizeof (struct type *)); 83319370Spst obstack_specify_allocation (&dont_print_statmem_obstack, 83419370Spst 32 * sizeof (CORE_ADDR), sizeof (CORE_ADDR), 83598944Sobrien xmalloc, xfree); 83619370Spst} 837