From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21156 invoked by alias); 25 Jan 2012 11:18:33 -0000 Received: (qmail 21140 invoked by uid 22791); 25 Jan 2012 11:18:28 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,TW_CP,TW_VP X-Spam-Check-By: sourceware.org Received: from smtp2-v.fe.bosch.de (HELO smtp2-v.fe.bosch.de) (139.15.237.6) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 25 Jan 2012 11:17:56 +0000 Received: from vsmta13.fe.internet.bosch.com (unknown [10.4.98.30]) by imta24.fe.bosch.de (Postfix) with ESMTP id 76AD3B3B880F for ; Wed, 25 Jan 2012 12:17:30 +0100 (CET) Received: from localhost (vsgw1.fe.internet.bosch.com [10.4.98.15]) by vsmta13.fe.internet.bosch.com (Postfix) with SMTP id F37E15CA04E1 for ; Wed, 25 Jan 2012 12:17:53 +0100 (CET) Received: from SI-MBX09.de.bosch.com ([10.3.153.45]) by fe-hub02.de.bosch.com ([10.3.144.91]) with mapi; Wed, 25 Jan 2012 12:17:50 +0100 From: "Leutwein Tobias (BEG-PT/ESB1)" To: "gdb-patches@sourceware.org" Date: Wed, 25 Jan 2012 11:22:00 -0000 Subject: [RFC, patch] ptype bitfields show bitpos and bitsize Message-ID: <1606F039DD6642449BF6D1519D43AF6216198E7EA6@SI-MBX09.de.bosch.com> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-01/txt/msg00862.txt.bz2 Hello, I have made some changes to the GDB sources to get more information's about= bitfield variables through the ptype command. Example (at gdb sources root directory): gcc -g ./gdb/testsuite/gdb.base/bitfields.c -o ./zzz gdb/gdb zzz (gdb) ptype flags type =3D struct fields { unsigned char uc; int s1 : 1; unsigned int u1 : 1; int s2 : 2; unsigned int u2 : 2; int s3 : 3; unsigned int u3 : 3; int s9 : 9; unsigned int u9 : 9; signed char sc; } (gdb) ptype flags.s9 type =3D int, bitpos =3D 20, bitsize =3D 9 (gdb) ptype flags.u9 type =3D unsigned int, bitsize =3D 9 (gdb) ptype flags.uc type =3D unsigned char At the code I have added a new object la_print_type_through_value to the s= truct language_defn at file language.h. Maybe it would also be possible to = change la_print_type, so that it's doing the same. Because this is my first request of change, I don't know if I do it the rig= ht way. If the changes are ok, is it possible that someone checks it in? Regards Tobias diff -ur 7.4_orig/gdb/ada-lang.c 7.4_ptype/gdb/ada-lang.c --- 7.4_orig/gdb/ada-lang.c 2012-01-06 04:34:45.000000000 +0100 +++ 7.4_ptype/gdb/ada-lang.c 2012-01-24 17:26:54.080750700 +0100 @@ -12337,6 +12337,7 @@ ada_printstr, /* Function to print string constant */ emit_char, /* Function to print single char (not used= ) */ ada_print_type, /* Print a type using appropriate syntax */ + ada_print_type_through_value, /* Print a type using appropriate syntax */ ada_print_typedef, /* Print a typedef using appropriate synta= x */ ada_val_print, /* Print a value using appropriate syntax = */ ada_value_print, /* Print a top-level value */ diff -ur 7.4_orig/gdb/ada-lang.h 7.4_ptype/gdb/ada-lang.h --- 7.4_orig/gdb/ada-lang.h 2012-01-04 09:16:55.000000000 +0100 +++ 7.4_ptype/gdb/ada-lang.h 2012-01-25 07:55:58.546684800 +0100 @@ -160,6 +160,8 @@ /* Defined in ada-typeprint.c */ extern void ada_print_type (struct type *, const char *, struct ui_file *,= int, int); +extern void ada_print_type_through_value (struct value *, const char *, st= ruct ui_file *, int, + int); extern void ada_print_typedef (struct type *type, struct symbol *new_symbo= l, struct ui_file *stream); diff -ur 7.4_orig/gdb/ada-typeprint.c 7.4_ptype/gdb/ada-typeprint.c --- 7.4_orig/gdb/ada-typeprint.c 2012-01-04 09:16:55.000000000 +0100 +++ 7.4_ptype/gdb/ada-typeprint.c 2012-01-25 07:56:28.999809800 +0100 @@ -871,3 +871,25 @@ ada_print_type (type, "", stream, 0, 0); fprintf_filtered (stream, "\n"); } + + +/* Print a description of a value value_p. + Output goes to STREAM (via stdio). + If VARSTRING is a non-empty string, print as an Ada variable/field + declaration. + SHOW+1 is the maximum number of levels of internal type structure + to show (this applies to record types, enumerated types, and + array types). + SHOW is the number of levels of internal type structure to show + when there is a type name for the SHOWth deepest level (0th is + outer level). + When SHOW<0, no inner structure is shown. + LEVEL indicates level of recursion (for nested definitions). */ + +void +ada_print_type_through_value (struct value *value_p, const char *varstring= , struct ui_file *stream, + int show, int level) +{ + struct type *type_p =3D value_type(value_p); + ada_print_type(type_p, varstring, stream, show, level); +} diff -ur 7.4_orig/gdb/c-lang.c 7.4_ptype/gdb/c-lang.c --- 7.4_orig/gdb/c-lang.c 2012-01-04 09:16:59.000000000 +0100 +++ 7.4_ptype/gdb/c-lang.c 2012-01-25 07:51:37.249809800 +0100 @@ -844,6 +844,7 @@ c_printstr, /* Function to print string constant */ c_emit_char, /* Print a single char */ c_print_type, /* Print a type using appropriate s= yntax */ + c_print_type_through_value, /* Print a type using appro= priate syntax */ c_print_typedef, /* Print a typedef using appropriate syntax= */ c_val_print, /* Print a value using appropriate syntax */ c_value_print, /* Print a top-level value */ @@ -967,6 +968,7 @@ c_printstr, /* Function to print string constant */ c_emit_char, /* Print a single char */ c_print_type, /* Print a type using appropriate s= yntax */ + c_print_type_through_value, /* Print a type using appro= priate syntax */ c_print_typedef, /* Print a typedef using appropriate syntax= */ c_val_print, /* Print a value using appropriate syntax */ c_value_print, /* Print a top-level value */ @@ -1008,6 +1010,7 @@ c_printstr, /* Function to print string constant */ c_emit_char, /* Print a single char */ c_print_type, /* Print a type using appropriate s= yntax */ + c_print_type_through_value, /* Print a type using appro= priate syntax */ c_print_typedef, /* Print a typedef using appropriate syntax= */ c_val_print, /* Print a value using appropriate syntax */ c_value_print, /* Print a top-level value */ @@ -1054,6 +1057,7 @@ c_printstr, /* Function to print string constant */ c_emit_char, /* Print a single char */ c_print_type, /* Print a type using appropriate s= yntax */ + c_print_type_through_value, /* Print a type using appro= priate syntax */ c_print_typedef, /* Print a typedef using appropriate syntax= */ c_val_print, /* Print a value using appropriate syntax */ c_value_print, /* Print a top-level value */ diff -ur 7.4_orig/gdb/c-lang.h 7.4_ptype/gdb/c-lang.h --- 7.4_orig/gdb/c-lang.h 2012-01-04 09:17:00.000000000 +0100 +++ 7.4_ptype/gdb/c-lang.h 2012-01-25 07:42:25.687309800 +0100 @@ -66,6 +66,8 @@ /* Defined in c-typeprint.c */ extern void c_print_type (struct type *, const char *, struct ui_file *, int, int); +extern void c_print_type_through_value (struct value *, + const char *, struct ui_file *, int, int); extern void c_print_typedef (struct type *, struct symbol *, @@ -111,6 +113,8 @@ extern void c_type_print_base (struct type *, struct ui_file *, int, int); +extern void c_type_print_base_through_value (struct value *, + struct ui_file *, int, int); /* These are in cp-valprint.c */ diff -ur 7.4_orig/gdb/c-typeprint.c 7.4_ptype/gdb/c-typeprint.c --- 7.4_orig/gdb/c-typeprint.c 2012-01-04 09:17:00.000000000 +0100 +++ 7.4_ptype/gdb/c-typeprint.c 2012-01-25 09:44:15.140434800 +0100 @@ -88,6 +88,56 @@ } } + +/* Same as function as above, the only difference is, that "struct value" + instead of "struct type" is used. Through this change it is possible to= show + the position and size of bitfield variables. + + \param[in] level The depth to indent lines by. +*/ +void +c_print_type_through_value (struct value *value, const char *varstring, st= ruct ui_file *stream, + int show, int level) +{ + enum type_code code; + int demangled_args; + int need_post_space; + + struct type *type =3D value_type (value); + + if (show > 0) + CHECK_TYPEDEF (type); + + c_type_print_base_through_value (value, stream, show, level); + code =3D TYPE_CODE (type); + if ((varstring !=3D NULL && *varstring !=3D '\0') + /* Need a space if going to print stars or brackets; + but not if we will print just a type name. */ + || ((show > 0 || TYPE_NAME (type) =3D=3D 0) + && (code =3D=3D TYPE_CODE_PTR || code =3D=3D TYPE_CODE_FUNC + || code =3D=3D TYPE_CODE_METHOD + || code =3D=3D TYPE_CODE_ARRAY + || code =3D=3D TYPE_CODE_MEMBERPTR + || code =3D=3D TYPE_CODE_METHODPTR + || code =3D=3D TYPE_CODE_REF))) + fputs_filtered (" ", stream); + need_post_space =3D (varstring !=3D NULL && strcmp (varstring, "") !=3D = 0); + c_type_print_varspec_prefix (type, stream, show, 0, need_post_space); + + if (varstring !=3D NULL) + { + fputs_filtered (varstring, stream); + + /* For demangled function names, we have the arglist as part of + the name, so don't print an additional pair of ()'s. */ + + demangled_args =3D strchr (varstring, '(') !=3D NULL; + c_type_print_varspec_suffix (type, stream, show, + 0, demangled_args); + } +} + + /* Print a typedef using C syntax. TYPE is the underlying type. NEW_SYMBOL is the symbol naming the type. STREAM is the stream on which to print. */ @@ -1258,3 +1308,593 @@ break; } } + + +/* Print the name of the type (or the ultimate pointer target, + function value or array element), or the description of a + structure or union. + + SHOW positive means print details about the type (e.g. enum values), + and print structure elements passing SHOW - 1 for show. + SHOW negative means just print the type name or struct tag if there is = one. + If there is no name, print something sensible but concise like + "struct {...}". + SHOW zero means just print the type name or struct tag if there is one. + If there is no name, print something sensible but not as concise like + "struct {int x; int y;}". + + LEVEL is the number of spaces to indent by. + We increase it for some recursive calls. + + \remarks Like c_type_print_base but if it is a bitfield variable, the + position and size will be shown if is not equal to 0. +*/ +void +c_type_print_base_through_value (struct value *value, struct ui_file *stre= am, int show, + int level) +{ + int i; + int len, real_len; + int lastval; + char *mangled_name; + char *demangled_name; + char *demangled_no_static; + enum + { + s_none, s_public, s_private, s_protected + } + section_type; + int need_access_label =3D 0; + int j, len2; + + struct type *type =3D value_type (value); + + QUIT; + + wrap_here (" "); + if (type =3D=3D NULL) + { + fputs_filtered (_(""), stream); + return; + } + + /* When SHOW is zero or less, and there is a valid type name, then + always just print the type name directly from the type. */ + /* If we have "typedef struct foo {. . .} bar;" do we want to print + it as "struct foo" or as "bar"? Pick the latter, because C++ + folk tend to expect things like "class5 *foo" rather than "struct + class5 *foo". */ + + if (show <=3D 0 + && TYPE_NAME (type) !=3D NULL) + { + c_type_print_modifier (type, stream, 0, 1); +//fprintf_filtered (stream, "Lw %s,%i 0x%x ", __FILE__, __LINE__, type); + fputs_filtered (TYPE_NAME (type), stream); + return; + } + + CHECK_TYPEDEF (type); + + switch (TYPE_CODE (type)) + { + case TYPE_CODE_TYPEDEF: + /* If we get here, the typedef doesn't have a name, and we + couldn't resolve TYPE_TARGET_TYPE. Not much we can do. */ + gdb_assert (TYPE_NAME (type) =3D=3D NULL); + gdb_assert (TYPE_TARGET_TYPE (type) =3D=3D NULL); + fprintf_filtered (stream, _("")); + break; + + case TYPE_CODE_ARRAY: + case TYPE_CODE_PTR: + case TYPE_CODE_MEMBERPTR: + case TYPE_CODE_REF: + case TYPE_CODE_FUNC: + case TYPE_CODE_METHOD: + case TYPE_CODE_METHODPTR: + c_type_print_base (TYPE_TARGET_TYPE (type), + stream, show, level); + break; + + case TYPE_CODE_STRUCT: + c_type_print_modifier (type, stream, 0, 1); + if (TYPE_DECLARED_CLASS (type)) + fprintf_filtered (stream, "class "); + else + fprintf_filtered (stream, "struct "); + goto struct_union; + + case TYPE_CODE_UNION: + c_type_print_modifier (type, stream, 0, 1); + fprintf_filtered (stream, "union "); + + struct_union: + + /* Print the tag if it exists. The HP aCC compiler emits a + spurious "{unnamed struct}"/"{unnamed union}"/"{unnamed + enum}" tag for unnamed struct/union/enum's, which we don't + want to print. */ + if (TYPE_TAG_NAME (type) !=3D NULL + && strncmp (TYPE_TAG_NAME (type), "{unnamed", 8)) + { + fputs_filtered (TYPE_TAG_NAME (type), stream); + if (show > 0) + fputs_filtered (" ", stream); + } + wrap_here (" "); + if (show < 0) + { + /* If we just printed a tag name, no need to print anything + else. */ + if (TYPE_TAG_NAME (type) =3D=3D NULL) + fprintf_filtered (stream, "{...}"); + } + else if (show > 0 || TYPE_TAG_NAME (type) =3D=3D NULL) + { + struct type *basetype; + int vptr_fieldno; + + cp_type_print_derivation_info (stream, type); + + fprintf_filtered (stream, "{\n"); + if (TYPE_NFIELDS (type) =3D=3D 0 && TYPE_NFN_FIELDS (type) =3D=3D= 0 + && TYPE_TYPEDEF_FIELD_COUNT (type) =3D=3D 0) + { + if (TYPE_STUB (type)) + fprintfi_filtered (level + 4, stream, + _("\n")); + else + fprintfi_filtered (level + 4, stream, + _("\n")); + } + + /* Start off with no specific section type, so we can print + one for the first field we find, and use that section type + thereafter until we find another type. */ + + section_type =3D s_none; + + /* For a class, if all members are private, there's no need + for a "private:" label; similarly, for a struct or union + masquerading as a class, if all members are public, there's + no need for a "public:" label. */ + + if (TYPE_DECLARED_CLASS (type)) + { + QUIT; + len =3D TYPE_NFIELDS (type); + for (i =3D TYPE_N_BASECLASSES (type); i < len; i++) + if (!TYPE_FIELD_PRIVATE (type, i)) + { + need_access_label =3D 1; + break; + } + QUIT; + if (!need_access_label) + { + len2 =3D TYPE_NFN_FIELDS (type); + for (j =3D 0; j < len2; j++) + { + len =3D TYPE_FN_FIELDLIST_LENGTH (type, j); + for (i =3D 0; i < len; i++) + if (!TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (typ= e, + j),= i)) + { + need_access_label =3D 1; + break; + } + if (need_access_label) + break; + } + } + } + else + { + QUIT; + len =3D TYPE_NFIELDS (type); + for (i =3D TYPE_N_BASECLASSES (type); i < len; i++) + if (TYPE_FIELD_PRIVATE (type, i) + || TYPE_FIELD_PROTECTED (type, i)) + { + need_access_label =3D 1; + break; + } + QUIT; + if (!need_access_label) + { + len2 =3D TYPE_NFN_FIELDS (type); + for (j =3D 0; j < len2; j++) + { + QUIT; + len =3D TYPE_FN_FIELDLIST_LENGTH (type, j); + for (i =3D 0; i < len; i++) + if (TYPE_FN_FIELD_PROTECTED (TYPE_FN_FIELDLIST1 (ty= pe, + j)= , i) + || TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (t= ype, + j= ), + i)) + { + need_access_label =3D 1; + break; + } + if (need_access_label) + break; + } + } + } + + /* If there is a base class for this type, + do not print the field that it occupies. */ + + len =3D TYPE_NFIELDS (type); + vptr_fieldno =3D get_vptr_fieldno (type, &basetype); + for (i =3D TYPE_N_BASECLASSES (type); i < len; i++) + { + QUIT; + + /* If we have a virtual table pointer, omit it. Even if + virtual table pointers are not specifically marked in + the debug info, they should be artificial. */ + if ((i =3D=3D vptr_fieldno && type =3D=3D basetype) + || TYPE_FIELD_ARTIFICIAL (type, i)) + continue; + + if (need_access_label) + { + if (TYPE_FIELD_PROTECTED (type, i)) + { + if (section_type !=3D s_protected) + { + section_type =3D s_protected; + fprintfi_filtered (level + 2, stream, + "protected:\n"); + } + } + else if (TYPE_FIELD_PRIVATE (type, i)) + { + if (section_type !=3D s_private) + { + section_type =3D s_private; + fprintfi_filtered (level + 2, stream, + "private:\n"); + } + } + else + { + if (section_type !=3D s_public) + { + section_type =3D s_public; + fprintfi_filtered (level + 2, stream, + "public:\n"); + } + } + } + + print_spaces_filtered (level + 4, stream); + if (field_is_static (&TYPE_FIELD (type, i))) + fprintf_filtered (stream, "static "); + c_print_type (TYPE_FIELD_TYPE (type, i), + TYPE_FIELD_NAME (type, i), + stream, show - 1, level + 4); + if (!field_is_static (&TYPE_FIELD (type, i)) + && TYPE_FIELD_PACKED (type, i)) + { + /* It is a bitfield. This code does not attempt + to look at the bitpos and reconstruct filler, + unnamed fields. This would lead to misleading + results if the compiler does not put out fields + for such things (I don't know what it does). */ + fprintf_filtered (stream, " : %d", + TYPE_FIELD_BITSIZE (type, i)); + } + fprintf_filtered (stream, ";\n"); + } + + /* If there are both fields and methods, put a blank line + between them. Make sure to count only method that we + will display; artificial methods will be hidden. */ + len =3D TYPE_NFN_FIELDS (type); + real_len =3D 0; + for (i =3D 0; i < len; i++) + { + struct fn_field *f =3D TYPE_FN_FIELDLIST1 (type, i); + int len2 =3D TYPE_FN_FIELDLIST_LENGTH (type, i); + int j; + + for (j =3D 0; j < len2; j++) + if (!TYPE_FN_FIELD_ARTIFICIAL (f, j)) + real_len++; + } + if (real_len > 0 && section_type !=3D s_none) + fprintf_filtered (stream, "\n"); + + /* C++: print out the methods. */ + for (i =3D 0; i < len; i++) + { + struct fn_field *f =3D TYPE_FN_FIELDLIST1 (type, i); + int j, len2 =3D TYPE_FN_FIELDLIST_LENGTH (type, i); + char *method_name =3D TYPE_FN_FIELDLIST_NAME (type, i); + char *name =3D type_name_no_tag (type); + int is_constructor =3D name && strcmp (method_name, + name) =3D=3D 0; + + for (j =3D 0; j < len2; j++) + { + const char *mangled_name; + char *demangled_name; + struct cleanup *inner_cleanup; + const char *physname =3D TYPE_FN_FIELD_PHYSNAME (f, j); + int is_full_physname_constructor =3D + is_constructor_name (physname) + || is_destructor_name (physname) + || method_name[0] =3D=3D '~'; + + /* Do not print out artificial methods. */ + if (TYPE_FN_FIELD_ARTIFICIAL (f, j)) + continue; + + inner_cleanup =3D make_cleanup (null_cleanup, NULL); + + QUIT; + if (TYPE_FN_FIELD_PROTECTED (f, j)) + { + if (section_type !=3D s_protected) + { + section_type =3D s_protected; + fprintfi_filtered (level + 2, stream, + "protected:\n"); + } + } + else if (TYPE_FN_FIELD_PRIVATE (f, j)) + { + if (section_type !=3D s_private) + { + section_type =3D s_private; + fprintfi_filtered (level + 2, stream, + "private:\n"); + } + } + else + { + if (section_type !=3D s_public) + { + section_type =3D s_public; + fprintfi_filtered (level + 2, stream, + "public:\n"); + } + } + + print_spaces_filtered (level + 4, stream); + if (TYPE_FN_FIELD_VIRTUAL_P (f, j)) + fprintf_filtered (stream, "virtual "); + else if (TYPE_FN_FIELD_STATIC_P (f, j)) + fprintf_filtered (stream, "static "); + if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) =3D=3D 0) + { + /* Keep GDB from crashing here. */ + fprintf_filtered (stream, + _(" %s;\n"), + TYPE_FN_FIELD_PHYSNAME (f, j)); + break; + } + else if (!is_constructor /* Constructors don't + have declared + types. */ + && !is_full_physname_constructor /* " " */ + && !is_type_conversion_operator (type, i, j)) + { + type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, = j)), + "", stream, -1); + fputs_filtered (" ", stream); + } + if (TYPE_FN_FIELD_STUB (f, j)) + { + char *tem; + + /* Build something we can demangle. */ + tem =3D gdb_mangle_name (type, i, j); + make_cleanup (xfree, tem); + mangled_name =3D tem; + } + else + mangled_name =3D TYPE_FN_FIELD_PHYSNAME (f, j); + + demangled_name =3D + cplus_demangle (mangled_name, + DMGL_ANSI | DMGL_PARAMS); + if (demangled_name =3D=3D NULL) + { + /* In some cases (for instance with the HP + demangling), if a function has more than 10 + arguments, the demangling will fail. + Let's try to reconstruct the function + signature from the symbol information. */ + if (!TYPE_FN_FIELD_STUB (f, j)) + { + int staticp =3D TYPE_FN_FIELD_STATIC_P (f, j); + struct type *mtype =3D TYPE_FN_FIELD_TYPE (f, j); + + cp_type_print_method_args (mtype, + "", + method_name, + staticp, + stream); + } + else + fprintf_filtered (stream, + _(""), + mangled_name); + } + else + { + char *p; + char *demangled_no_class + =3D remove_qualifiers (demangled_name); + + /* Get rid of the `static' appended by the + demangler. */ + p =3D strstr (demangled_no_class, " static"); + if (p !=3D NULL) + { + int length =3D p - demangled_no_class; + char *demangled_no_static; + + demangled_no_static + =3D (char *) xmalloc (length + 1); + strncpy (demangled_no_static, + demangled_no_class, length); + *(demangled_no_static + length) =3D '\0'; + fputs_filtered (demangled_no_static, stream); + xfree (demangled_no_static); + } + else + fputs_filtered (demangled_no_class, stream); + xfree (demangled_name); + } + + do_cleanups (inner_cleanup); + + fprintf_filtered (stream, ";\n"); + } + } + + /* Print typedefs defined in this class. */ + + if (TYPE_TYPEDEF_FIELD_COUNT (type) !=3D 0) + { + if (TYPE_NFIELDS (type) !=3D 0 || TYPE_NFN_FIELDS (type) !=3D= 0) + fprintf_filtered (stream, "\n"); + + for (i =3D 0; i < TYPE_TYPEDEF_FIELD_COUNT (type); i++) + { + struct type *target =3D TYPE_TYPEDEF_FIELD_TYPE (type, i); + + /* Dereference the typedef declaration itself. */ + gdb_assert (TYPE_CODE (target) =3D=3D TYPE_CODE_TYPEDEF); + target =3D TYPE_TARGET_TYPE (target); + + print_spaces_filtered (level + 4, stream); + fprintf_filtered (stream, "typedef "); + c_print_type (target, TYPE_TYPEDEF_FIELD_NAME (type, i), + stream, show - 1, level + 4); + fprintf_filtered (stream, ";\n"); + } + } + + fprintfi_filtered (level, stream, "}"); + + if (TYPE_LOCALTYPE_PTR (type) && show >=3D 0) + fprintfi_filtered (level, stream, _(" (Local at %s:%d)\n"), + TYPE_LOCALTYPE_FILE (type), + TYPE_LOCALTYPE_LINE (type)); + } + break; + + case TYPE_CODE_ENUM: + c_type_print_modifier (type, stream, 0, 1); + fprintf_filtered (stream, "enum "); + /* Print the tag name if it exists. + The aCC compiler emits a spurious + "{unnamed struct}"/"{unnamed union}"/"{unnamed enum}" + tag for unnamed struct/union/enum's, which we don't + want to print. */ + if (TYPE_TAG_NAME (type) !=3D NULL + && strncmp (TYPE_TAG_NAME (type), "{unnamed", 8)) + { + fputs_filtered (TYPE_TAG_NAME (type), stream); + if (show > 0) + fputs_filtered (" ", stream); + } + + wrap_here (" "); + if (show < 0) + { + /* If we just printed a tag name, no need to print anything + else. */ + if (TYPE_TAG_NAME (type) =3D=3D NULL) + fprintf_filtered (stream, "{...}"); + } + else if (show > 0 || TYPE_TAG_NAME (type) =3D=3D NULL) + { + fprintf_filtered (stream, "{"); + len =3D TYPE_NFIELDS (type); + lastval =3D 0; + for (i =3D 0; i < len; i++) + { + QUIT; + if (i) + fprintf_filtered (stream, ", "); + wrap_here (" "); + fputs_filtered (TYPE_FIELD_NAME (type, i), stream); + if (lastval !=3D TYPE_FIELD_BITPOS (type, i)) + { + fprintf_filtered (stream, " =3D %d", + TYPE_FIELD_BITPOS (type, i)); + lastval =3D TYPE_FIELD_BITPOS (type, i); + } + lastval++; + } + fprintf_filtered (stream, "}"); + } + break; + + case TYPE_CODE_VOID: + fprintf_filtered (stream, "void"); + break; + + case TYPE_CODE_UNDEF: + fprintf_filtered (stream, _("struct ")); + break; + + case TYPE_CODE_ERROR: + fprintf_filtered (stream, "%s", TYPE_ERROR_NAME (type)); + break; + + case TYPE_CODE_RANGE: + /* This should not occur */ + fprintf_filtered (stream, _("")); + break; + + case TYPE_CODE_NAMESPACE: + fputs_filtered ("namespace ", stream); + fputs_filtered (TYPE_TAG_NAME (type), stream); + break; + + default: + /* Handle types not explicitly handled by the other cases, such + as fundamental types. For these, just print whatever the + type name is, as recorded in the type itself. If there is no + type name, then complain. */ + if (TYPE_NAME (type) !=3D NULL) + { + c_type_print_modifier (type, stream, 0, 1); + fputs_filtered (TYPE_NAME (type), stream); + /* show the bit position of this value, if it is not equal to 0 */ + { + int bitpos_i =3D value_bitpos(value); + if (bitpos_i !=3D 0) + { + fprintf_filtered (stream, ", bitpos =3D %d", bitpos_i); + } + } + /* show the bit size of this value, if it is not equal to 0 */ + { + int bitsize_i =3D value_bitsize(value); + if (bitsize_i !=3D 0) + { + fprintf_filtered (stream, ", bitsize =3D %d", bitsize_i); + } + } + } + else + { + /* At least for dump_symtab, it is important that this not + be an error (). */ + fprintf_filtered (stream, _(""), + TYPE_CODE (type)); + } + break; + } +} + diff -ur 7.4_orig/gdb/d-lang.c 7.4_ptype/gdb/d-lang.c --- 7.4_orig/gdb/d-lang.c 2012-01-04 09:17:00.000000000 +0100 +++ 7.4_ptype/gdb/d-lang.c 2012-01-24 17:36:13.158875700 +0100 @@ -252,8 +252,8 @@ c_printstr, /* Function to print string constant. */ c_emit_char, /* Print a single char. */ c_print_type, /* Print a type using appropriate s= yntax. */ - c_print_typedef, /* Print a typedef using appropriate - syntax. */ + c_print_type_through_value, /* Print a type using appro= priate syntax */ + c_print_typedef, /* Print a typedef using appropriate syntax= . */ d_val_print, /* Print a value using appropriate syntax. = */ c_value_print, /* Print a top-level value. */ NULL, /* Language specific skip_trampolin= e. */ diff -ur 7.4_orig/gdb/eval.c 7.4_ptype/gdb/eval.c --- 7.4_orig/gdb/eval.c 2012-01-09 21:27:48.000000000 +0100 +++ 7.4_ptype/gdb/eval.c 2012-01-24 17:26:54.127625700 +0100 @@ -155,8 +155,9 @@ evaluate_type (struct expression *exp) { int pc =3D 0; - - return evaluate_subexp (NULL_TYPE, exp, &pc, EVAL_AVOID_SIDE_EFFECTS); + /* the parameter noside changed from EVAL_AVOID_SIDE_EFFECTS to EVAL_NOR= MAL + to get bitpos an bitsize of bitfield variables */ + return evaluate_subexp (NULL_TYPE, exp, &pc, EVAL_NORMAL); } /* Evaluate a subexpression, avoiding all memory references and diff -ur 7.4_orig/gdb/f-lang.c 7.4_ptype/gdb/f-lang.c --- 7.4_orig/gdb/f-lang.c 2012-01-04 09:17:02.000000000 +0100 +++ 7.4_ptype/gdb/f-lang.c 2012-01-24 17:26:54.127625700 +0100 @@ -290,6 +290,7 @@ f_printstr, /* function to print string constant */ f_emit_char, /* Function to print a single character */ f_print_type, /* Print a type using appropriate s= yntax */ + f_print_type_through_value, /* Print a type using appropriate syntax */ default_print_typedef, /* Print a typedef using appropriate syntax= */ f_val_print, /* Print a value using appropriate syntax */ c_value_print, /* FIXME */ diff -ur 7.4_orig/gdb/f-lang.h 7.4_ptype/gdb/f-lang.h --- 7.4_orig/gdb/f-lang.h 2012-01-04 09:17:02.000000000 +0100 +++ 7.4_ptype/gdb/f-lang.h 2012-01-25 07:56:50.906059800 +0100 @@ -27,6 +27,8 @@ extern void f_print_type (struct type *, const char *, struct ui_file *, i= nt, int); +extern void f_print_type_through_value (struct value *, const char *, stru= ct ui_file *, int, + int); extern int f_val_print (struct type *, const gdb_byte *, int, CORE_ADDR, struct ui_file *, int, diff -ur 7.4_orig/gdb/f-typeprint.c 7.4_ptype/gdb/f-typeprint.c --- 7.4_orig/gdb/f-typeprint.c 2012-01-04 09:17:02.000000000 +0100 +++ 7.4_ptype/gdb/f-typeprint.c 2012-01-25 09:45:59.671684800 +0100 @@ -82,6 +82,18 @@ } } + +/* LEVEL is the depth to indent lines by. */ + +void +f_print_type_through_value (struct value *value_p, const char *varstring, = struct ui_file *stream, + int show, int level) +{ + struct type *type_p =3D value_type(value_p); + f_print_type (type_p, varstring, stream, show, level); +} + + /* Print any asterisks or open-parentheses needed before the variable name (to describe its type). diff -ur 7.4_orig/gdb/jv-lang.c 7.4_ptype/gdb/jv-lang.c --- 7.4_orig/gdb/jv-lang.c 2012-01-08 22:02:45.000000000 +0100 +++ 7.4_ptype/gdb/jv-lang.c 2012-01-24 17:26:54.143250700 +0100 @@ -1178,6 +1178,7 @@ java_printstr, /* Function to print string constant */ java_emit_char, /* Function to print a single character */ java_print_type, /* Print a type using appropriate syntax */ + java_print_type_through_value, /* Print a type using appropriate s= yntax */ default_print_typedef, /* Print a typedef using appropriate syntax= */ java_val_print, /* Print a value using appropriate syntax */ java_value_print, /* Print a top-level value */ diff -ur 7.4_orig/gdb/jv-lang.h 7.4_ptype/gdb/jv-lang.h --- 7.4_orig/gdb/jv-lang.h 2012-01-04 09:17:05.000000000 +0100 +++ 7.4_ptype/gdb/jv-lang.h 2012-01-25 07:57:42.843559800 +0100 @@ -71,6 +71,8 @@ /* Defined in jv-typeprint.c */ extern void java_print_type (struct type *, const char *, struct ui_file *, int, int); +extern void java_print_type_through_value (struct value *, const char *, + struct ui_file *, int, int); extern char *java_demangle_type_signature (char *); diff -ur 7.4_orig/gdb/jv-typeprint.c 7.4_ptype/gdb/jv-typeprint.c --- 7.4_orig/gdb/jv-typeprint.c 2012-01-04 09:17:05.000000000 +0100 +++ 7.4_ptype/gdb/jv-typeprint.c 2012-01-25 07:58:44.296684800 +0100 @@ -352,3 +352,12 @@ demangled_args =3D varstring !=3D NULL && strchr (varstring, '(') !=3D N= ULL; c_type_print_varspec_suffix (type, stream, show, 0, demangled_args); } + + +void +java_print_type_through_value (struct value *value_p, const char *varstrin= g, struct ui_file *stream, + int show, int level) +{ + struct type *type_p =3D value_type(value_p); + java_print_type (type_p, varstring, stream, show, level); +} diff -ur 7.4_orig/gdb/language.c 7.4_ptype/gdb/language.c --- 7.4_orig/gdb/language.c 2012-01-04 19:57:01.000000000 +0100 +++ 7.4_ptype/gdb/language.c 2012-01-25 07:43:58.093559800 +0100 @@ -847,6 +847,13 @@ "function unk_lang_print_type called.")); } +static void +unk_lang_print_type_through_value (struct value *value, const char *varstr= ing, struct ui_file *stream, + int show, int level) +{ + error (_("internal error - unimplemented function unk_lang_print_type_th= rough_value called.")); +} + static int unk_lang_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, @@ -914,6 +921,7 @@ unk_lang_printstr, unk_lang_emit_char, unk_lang_print_type, /* Print a type using appropriate syntax */ + unk_lang_print_type_through_value, /* Print a type using appro= priate syntax */ default_print_typedef, /* Print a typedef using appropriate syntax= */ unk_lang_val_print, /* Print a value using appropriate syntax */ unk_lang_value_print, /* Print a top-level value */ @@ -957,6 +965,7 @@ unk_lang_printstr, unk_lang_emit_char, unk_lang_print_type, /* Print a type using appropriate syntax */ + unk_lang_print_type_through_value, /* Print a type using appro= priate syntax */ default_print_typedef, /* Print a typedef using appropriate syntax= */ unk_lang_val_print, /* Print a value using appropriate syntax */ unk_lang_value_print, /* Print a top-level value */ @@ -998,6 +1007,7 @@ unk_lang_printstr, unk_lang_emit_char, unk_lang_print_type, /* Print a type using appropriate syntax */ + unk_lang_print_type_through_value, /* Print a type using appro= priate syntax */ default_print_typedef, /* Print a typedef using appropriate syntax= */ unk_lang_val_print, /* Print a value using appropriate syntax */ unk_lang_value_print, /* Print a top-level value */ diff -ur 7.4_orig/gdb/language.h 7.4_ptype/gdb/language.h --- 7.4_orig/gdb/language.h 2012-01-04 19:57:01.000000000 +0100 +++ 7.4_ptype/gdb/language.h 2012-01-25 07:54:04.187309800 +0100 @@ -202,6 +202,12 @@ void (*la_print_type) (struct type *, const char *, struct ui_file *, = int, int); + /* Print a type (through value structure) using syntax appropriate for + this language. */ + + void (*la_print_type_through_value) (struct value *, const char *, str= uct ui_file *, int, + int); + /* Print a typedef using syntax appropriate for this language. TYPE is the underlying type. NEW_SYMBOL is the symbol naming the type. STREAM is the output stream on which to print. */ @@ -433,6 +439,8 @@ #define LA_PRINT_TYPE(type,varstring,stream,show,level) \ (current_language->la_print_type(type,varstring,stream,show,level)) +#define LA_PRINT_TYPE_THROUGH_VALUE(value,varstring,stream,show,level) \ + (current_language->la_print_type_through_value(value,varstring,stream,sh= ow,level)) #define LA_PRINT_TYPEDEF(type,new_symbol,stream) \ (current_language->la_print_typedef(type,new_symbol,stream)) diff -ur 7.4_orig/gdb/m2-lang.c 7.4_ptype/gdb/m2-lang.c --- 7.4_orig/gdb/m2-lang.c 2012-01-04 09:17:05.000000000 +0100 +++ 7.4_ptype/gdb/m2-lang.c 2012-01-24 17:26:54.158875700 +0100 @@ -382,6 +382,7 @@ m2_printstr, /* function to print string constant */ m2_emit_char, /* Function to print a single chara= cter */ m2_print_type, /* Print a type using appropriate syntax */ + m2_print_type_through_value, /* Print a type using appropriate syntax */ m2_print_typedef, /* Print a typedef using appropriate syntax= */ m2_val_print, /* Print a value using appropriate = syntax */ c_value_print, /* Print a top-level value */ diff -ur 7.4_orig/gdb/m2-lang.h 7.4_ptype/gdb/m2-lang.h --- 7.4_orig/gdb/m2-lang.h 2012-01-04 09:17:05.000000000 +0100 +++ 7.4_ptype/gdb/m2-lang.h 2012-01-25 07:59:26.234184800 +0100 @@ -25,6 +25,8 @@ /* Defined in m2-typeprint.c */ extern void m2_print_type (struct type *, const char *, struct ui_file *, = int, int); +extern void m2_print_type_through_value (struct value *, const char *, str= uct ui_file *, int, + int); extern void m2_print_typedef (struct type *, struct symbol *, struct ui_file *); diff -ur 7.4_orig/gdb/m2-typeprint.c 7.4_ptype/gdb/m2-typeprint.c --- 7.4_orig/gdb/m2-typeprint.c 2012-01-04 09:17:05.000000000 +0100 +++ 7.4_ptype/gdb/m2-typeprint.c 2012-01-25 07:59:46.406059800 +0100 @@ -151,6 +151,16 @@ } } + +void +m2_print_type_through_value (struct value *value_p, const char *varstring,= struct ui_file *stream, + int show, int level) +{ + struct type *type_p =3D value_type(value_p); + m2_print_type (type_p, varstring, stream, show, level); +} + + /* Print a typedef using M2 syntax. TYPE is the underlying type. NEW_SYMBOL is the symbol naming the type. STREAM is the stream on which to print. */ diff -ur 7.4_orig/gdb/objc-lang.c 7.4_ptype/gdb/objc-lang.c --- 7.4_orig/gdb/objc-lang.c 2012-01-04 09:17:08.000000000 +0100 +++ 7.4_ptype/gdb/objc-lang.c 2012-01-24 17:26:54.174500700 +0100 @@ -521,6 +521,7 @@ objc_printstr, /* Function to print string constant */ objc_emit_char, c_print_type, /* Print a type using appropriate s= yntax */ + c_print_type_through_value, /* Print a type using appropriate syntax */ c_print_typedef, /* Print a typedef using appropriate syntax= */ c_val_print, /* Print a value using appropriate syntax */ c_value_print, /* Print a top-level value */ diff -ur 7.4_orig/gdb/opencl-lang.c 7.4_ptype/gdb/opencl-lang.c --- 7.4_orig/gdb/opencl-lang.c 2012-01-04 09:17:09.000000000 +0100 +++ 7.4_ptype/gdb/opencl-lang.c 2012-01-25 08:27:31.734184800 +0100 @@ -1005,6 +1005,7 @@ c_printstr, /* Function to print string constant */ c_emit_char, /* Print a single char */ c_print_type, /* Print a type using appropriate s= yntax */ + c_print_type_through_value, /* Print a type using appropriate syntax */ c_print_typedef, /* Print a typedef using appropriate syntax= */ c_val_print, /* Print a value using appropriate syntax */ c_value_print, /* Print a top-level value */ diff -ur 7.4_orig/gdb/p-lang.c 7.4_ptype/gdb/p-lang.c --- 7.4_orig/gdb/p-lang.c 2012-01-04 09:17:09.000000000 +0100 +++ 7.4_ptype/gdb/p-lang.c 2012-01-24 17:26:54.174500700 +0100 @@ -441,6 +441,7 @@ pascal_printstr, /* Function to print string constant */ pascal_emit_char, /* Print a single char */ pascal_print_type, /* Print a type using appropriate syntax */ + pascal_print_type_through_value, /* Print a type using appropriate s= yntax */ pascal_print_typedef, /* Print a typedef using appropriat= e syntax */ pascal_val_print, /* Print a value using appropriate syntax */ pascal_value_print, /* Print a top-level value */ diff -ur 7.4_orig/gdb/p-lang.h 7.4_ptype/gdb/p-lang.h --- 7.4_orig/gdb/p-lang.h 2012-01-04 09:17:09.000000000 +0100 +++ 7.4_ptype/gdb/p-lang.h 2012-01-25 07:45:15.077934800 +0100 @@ -32,6 +32,9 @@ extern void pascal_print_type (struct type *, const char *, struct ui_file= *, int, int); +extern void pascal_print_type_through_value (struct value *, const char *, + struct ui_file *, int, int); + extern void pascal_print_typedef (struct type *, struct symbol *, struct ui_file *); diff -ur 7.4_orig/gdb/p-typeprint.c 7.4_ptype/gdb/p-typeprint.c --- 7.4_orig/gdb/p-typeprint.c 2012-01-04 09:17:09.000000000 +0100 +++ 7.4_ptype/gdb/p-typeprint.c 2012-01-25 07:47:32.593559800 +0100 @@ -89,6 +89,18 @@ } + +/* LEVEL is the depth to indent lines by. */ + +void +pascal_print_type_through_value (struct value *value_p, const char *varstr= ing, struct ui_file *stream, + int show, int level) +{ + struct type *type_p =3D value_type(value_p); + pascal_print_type (type_p, varstring, stream, show, level); +} + + /* Print a typedef using Pascal syntax. TYPE is the underlying type. NEW_SYMBOL is the symbol naming the type. STREAM is the stream on which to print. */ diff -ur 7.4_orig/gdb/typeprint.c 7.4_ptype/gdb/typeprint.c --- 7.4_orig/gdb/typeprint.c 2012-01-04 09:27:57.000000000 +0100 +++ 7.4_ptype/gdb/typeprint.c 2012-01-24 17:29:30.315125700 +0100 @@ -79,6 +79,20 @@ LA_PRINT_TYPE (type, varstring, stream, show, 0); } +/* Print a description of a type TYPE in the form of a declaration of a + variable named VARSTRING. (VARSTRING is demangled if necessary.) + Output goes to STREAM (via stdio). + If SHOW is positive, we show the contents of the outermost level + of structure even if there is a type name that could be used instead. + If SHOW is negative, we never show the details of elements' types. */ + +void +type_print_through_value (struct value *value, char *varstring, struct ui_= file *stream, + int show) +{ + LA_PRINT_TYPE_THROUGH_VALUE (value, varstring, stream, show, 0); +} + /* Print TYPE to a string, returning it. The caller is responsible for freeing the string. */ @@ -164,7 +178,10 @@ printf_filtered (" */\n"); } - type_print (type, "", gdb_stdout, show); + /* To see the positon and size of bitfields changed from + type_print (type, "", gdb_stdout, show); + to: */ + type_print_through_value (val, "", gdb_stdout, show); printf_filtered ("\n"); if (exp) diff -ur 7.4_orig/gdb/value.h 7.4_ptype/gdb/value.h --- 7.4_orig/gdb/value.h 2012-01-04 09:27:58.000000000 +0100 +++ 7.4_ptype/gdb/value.h 2012-01-24 17:29:30.330750700 +0100 @@ -779,6 +779,8 @@ extern void type_print (struct type *type, char *varstring, struct ui_file *stream, int show); +extern void type_print_through_value (struct value *value, char *varstring, + struct ui_file *stream, int show); extern char *type_to_string (struct type *type);