X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fc-typeprint.c;h=cb75a4e276480281bc452d8f9ea2a0f2404e2b99;hb=45a466b578083a05f1138eff9232254b1a30f683;hp=bdc5a689ee1dc8ffed41c421399d839102dad529;hpb=2adab5d0b27b20bd56853e9b0c9c6a8763699ae2;p=deliverable%2Fbinutils-gdb.git
diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
index bdc5a689ee..cb75a4e276 100644
--- a/gdb/c-typeprint.c
+++ b/gdb/c-typeprint.c
@@ -1,13 +1,11 @@
/* Support for printing C and C++ types for GDB, the GNU debugger.
- Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1998,
- 1999, 2000
- Free Software Foundation, Inc.
+ Copyright (C) 1986-2013 Free Software Foundation, Inc.
This file is part of GDB.
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
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@@ -16,92 +14,152 @@
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., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ along with this program. If not, see . */
#include "defs.h"
-#include "obstack.h"
-#include "bfd.h" /* Binary File Description */
+#include "gdb_obstack.h"
+#include "bfd.h" /* Binary File Description. */
#include "symtab.h"
#include "gdbtypes.h"
#include "expression.h"
#include "value.h"
#include "gdbcore.h"
#include "target.h"
-#include "command.h"
-#include "gdbcmd.h"
#include "language.h"
#include "demangle.h"
#include "c-lang.h"
#include "typeprint.h"
-
+#include "cp-abi.h"
+#include "jv-lang.h"
#include "gdb_string.h"
#include
+#include "cp-support.h"
-/* Flag indicating target was compiled by HP compiler */
-extern int hp_som_som_object_present;
+static void c_type_print_varspec_prefix (struct type *,
+ struct ui_file *,
+ int, int, int,
+ const struct type_print_options *);
-static void cp_type_print_method_args (struct type ** args, char *prefix,
- char *varstring, int staticp,
- struct ui_file *stream);
+/* Print "const", "volatile", or address space modifiers. */
+static void c_type_print_modifier (struct type *,
+ struct ui_file *,
+ int, int);
+
-static void c_type_print_args (struct type *, struct ui_file *);
+/* A callback function for cp_canonicalize_string_full that uses
+ find_typedef_in_hash. */
-static void cp_type_print_derivation_info (struct ui_file *, struct type *);
+static const char *
+find_typedef_for_canonicalize (struct type *t, void *data)
+{
+ return find_typedef_in_hash (data, t);
+}
-void c_type_print_varspec_prefix (struct type *, struct ui_file *, int,
- int);
+/* Print NAME on STREAM. If the 'raw' field of FLAGS is not set,
+ canonicalize NAME using the local typedefs first. */
-static void c_type_print_cv_qualifier (struct type *, struct ui_file *,
- int, int);
-
+static void
+print_name_maybe_canonical (const char *name,
+ const struct type_print_options *flags,
+ struct ui_file *stream)
+{
+ char *s = NULL;
+ if (!flags->raw)
+ s = cp_canonicalize_string_full (name,
+ find_typedef_for_canonicalize,
+ (void *) flags);
+ fputs_filtered (s ? s : name, stream);
+ xfree (s);
+}
+
+
/* LEVEL is the depth to indent lines by. */
void
-c_print_type (struct type *type, char *varstring, struct ui_file *stream,
- int show, int level)
+c_print_type (struct type *type,
+ const char *varstring,
+ struct ui_file *stream,
+ int show, int level,
+ const struct type_print_options *flags)
{
- register enum type_code code;
+ enum type_code code;
int demangled_args;
+ int need_post_space;
+ const char *local_name;
if (show > 0)
CHECK_TYPEDEF (type);
- c_type_print_base (type, stream, show, level);
- code = TYPE_CODE (type);
- if ((varstring != NULL && *varstring != '\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) == 0)
- &&
- (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC
- || code == TYPE_CODE_METHOD
- || code == TYPE_CODE_ARRAY
- || code == TYPE_CODE_MEMBER
- || code == TYPE_CODE_REF)))
- fputs_filtered (" ", stream);
- c_type_print_varspec_prefix (type, stream, show, 0);
+ local_name = find_typedef_in_hash (flags, type);
+ if (local_name != NULL)
+ {
+ fputs_filtered (local_name, stream);
+ if (varstring != NULL && *varstring != '\0')
+ fputs_filtered (" ", stream);
+ }
+ else
+ {
+ c_type_print_base (type, stream, show, level, flags);
+ code = TYPE_CODE (type);
+ if ((varstring != NULL && *varstring != '\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) == 0)
+ && (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC
+ || code == TYPE_CODE_METHOD
+ || (code == TYPE_CODE_ARRAY
+ && !TYPE_VECTOR (type))
+ || code == TYPE_CODE_MEMBERPTR
+ || code == TYPE_CODE_METHODPTR
+ || code == TYPE_CODE_REF)))
+ fputs_filtered (" ", stream);
+ need_post_space = (varstring != NULL && strcmp (varstring, "") != 0);
+ c_type_print_varspec_prefix (type, stream, show, 0, need_post_space,
+ flags);
+ }
if (varstring != 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 = strchr (varstring, '(') != NULL;
- c_type_print_varspec_suffix (type, stream, show, 0, demangled_args);
+ /* For demangled function names, we have the arglist as part of
+ the name, so don't print an additional pair of ()'s. */
+ if (local_name == NULL)
+ {
+ demangled_args = strchr (varstring, '(') != NULL;
+ c_type_print_varspec_suffix (type, stream, show,
+ 0, demangled_args,
+ flags);
+ }
}
}
+/* 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. */
+
+void
+c_print_typedef (struct type *type,
+ struct symbol *new_symbol,
+ struct ui_file *stream)
+{
+ CHECK_TYPEDEF (type);
+ fprintf_filtered (stream, "typedef ");
+ type_print (type, "", stream, 0);
+ if (TYPE_NAME ((SYMBOL_TYPE (new_symbol))) == 0
+ || strcmp (TYPE_NAME ((SYMBOL_TYPE (new_symbol))),
+ SYMBOL_LINKAGE_NAME (new_symbol)) != 0
+ || TYPE_CODE (SYMBOL_TYPE (new_symbol)) == TYPE_CODE_TYPEDEF)
+ fprintf_filtered (stream, " %s", SYMBOL_PRINT_NAME (new_symbol));
+ fprintf_filtered (stream, ";\n");
+}
+
/* If TYPE is a derived type, then print out derivation information.
- Print only the actual base classes of this type, not the base classes
- of the base classes. I.E. for the derivation hierarchy:
+ Print only the actual base classes of this type, not the base
+ classes of the base classes. I.e. for the derivation hierarchy:
class A { int a; };
class B : public A {int b; };
@@ -113,76 +171,105 @@ c_print_type (struct type *type, char *varstring, struct ui_file *stream,
int c;
}
- Not as the following (like gdb used to), which is not legal C++ syntax for
- derived types and may be confused with the multiple inheritance form:
+ Not as the following (like gdb used to), which is not legal C++
+ syntax for derived types and may be confused with the multiple
+ inheritance form:
class C : public B : public A {
int c;
}
- In general, gdb should try to print the types as closely as possible to
- the form that they appear in the source code.
- Note that in case of protected derivation gcc will not say 'protected'
- but 'private'. The HP's aCC compiler emits specific information for
- derivation via protected inheritance, so gdb can print it out */
+ In general, gdb should try to print the types as closely as
+ possible to the form that they appear in the source code. */
static void
-cp_type_print_derivation_info (struct ui_file *stream, struct type *type)
+cp_type_print_derivation_info (struct ui_file *stream,
+ struct type *type,
+ const struct type_print_options *flags)
{
- char *name;
+ const char *name;
int i;
for (i = 0; i < TYPE_N_BASECLASSES (type); i++)
{
+ wrap_here (" ");
fputs_filtered (i == 0 ? ": " : ", ", stream);
fprintf_filtered (stream, "%s%s ",
- BASETYPE_VIA_PUBLIC (type, i) ? "public"
- : (TYPE_FIELD_PROTECTED (type, i) ? "protected" : "private"),
+ BASETYPE_VIA_PUBLIC (type, i)
+ ? "public" : (TYPE_FIELD_PROTECTED (type, i)
+ ? "protected" : "private"),
BASETYPE_VIA_VIRTUAL (type, i) ? " virtual" : "");
name = type_name_no_tag (TYPE_BASECLASS (type, i));
- fprintf_filtered (stream, "%s", name ? name : "(null)");
+ if (name)
+ print_name_maybe_canonical (name, flags, stream);
+ else
+ fprintf_filtered (stream, "(null)");
}
if (i > 0)
{
fputs_filtered (" ", stream);
}
}
+
/* Print the C++ method arguments ARGS to the file STREAM. */
static void
-cp_type_print_method_args (struct type **args, char *prefix, char *varstring,
- int staticp, struct ui_file *stream)
+cp_type_print_method_args (struct type *mtype, const char *prefix,
+ const char *varstring, int staticp,
+ struct ui_file *stream,
+ const struct type_print_options *flags)
{
+ struct field *args = TYPE_FIELDS (mtype);
+ int nargs = TYPE_NFIELDS (mtype);
+ int varargs = TYPE_VARARGS (mtype);
int i;
- fprintf_symbol_filtered (stream, prefix, language_cplus, DMGL_ANSI);
- fprintf_symbol_filtered (stream, varstring, language_cplus, DMGL_ANSI);
+ fprintf_symbol_filtered (stream, prefix,
+ language_cplus, DMGL_ANSI);
+ fprintf_symbol_filtered (stream, varstring,
+ language_cplus, DMGL_ANSI);
fputs_filtered ("(", stream);
- if (args && args[!staticp] && args[!staticp]->code != TYPE_CODE_VOID)
+
+ /* Skip the class variable. */
+ i = staticp ? 0 : 1;
+ if (nargs > i)
{
- i = !staticp; /* skip the class variable */
- while (1)
+ while (i < nargs)
{
- type_print (args[i++], "", stream, 0);
- if (!args[i])
- {
- fprintf_filtered (stream, " ...");
- break;
- }
- else if (args[i]->code != TYPE_CODE_VOID)
+ c_print_type (args[i++].type, "", stream, 0, 0, flags);
+
+ if (i == nargs && varargs)
+ fprintf_filtered (stream, ", ...");
+ else if (i < nargs)
{
fprintf_filtered (stream, ", ");
+ wrap_here (" ");
}
- else
- break;
}
}
+ else if (varargs)
+ fprintf_filtered (stream, "...");
else if (current_language->la_language == language_cplus)
- {
- fprintf_filtered (stream, "void");
- }
+ fprintf_filtered (stream, "void");
fprintf_filtered (stream, ")");
+
+ /* For non-static methods, read qualifiers from the type of
+ THIS. */
+ if (!staticp)
+ {
+ struct type *domain;
+
+ gdb_assert (nargs > 0);
+ gdb_assert (TYPE_CODE (args[0].type) == TYPE_CODE_PTR);
+ domain = TYPE_TARGET_TYPE (args[0].type);
+
+ if (TYPE_CONST (domain))
+ fprintf_filtered (stream, " const");
+
+ if (TYPE_VOLATILE (domain))
+ fprintf_filtered (stream, " volatile");
+ }
}
@@ -192,13 +279,21 @@ cp_type_print_method_args (struct type **args, char *prefix, char *varstring,
On outermost call, pass 0 for PASSED_A_PTR.
On outermost call, SHOW > 0 means should ignore
any typename for TYPE and show its details.
- SHOW is always zero on recursive calls. */
+ SHOW is always zero on recursive calls.
+
+ NEED_POST_SPACE is non-zero when a space will be be needed
+ between a trailing qualifier and a field, variable, or function
+ name. */
-void
-c_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
- int show, int passed_a_ptr)
+static void
+c_type_print_varspec_prefix (struct type *type,
+ struct ui_file *stream,
+ int show, int passed_a_ptr,
+ int need_post_space,
+ const struct type_print_options *flags)
{
- char *name;
+ const char *name;
+
if (type == 0)
return;
@@ -210,54 +305,64 @@ c_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
switch (TYPE_CODE (type))
{
case TYPE_CODE_PTR:
- c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1);
+ c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
+ stream, show, 1, 1, flags);
fprintf_filtered (stream, "*");
- c_type_print_cv_qualifier (type, stream, 1, 0);
+ c_type_print_modifier (type, stream, 1, need_post_space);
break;
- case TYPE_CODE_MEMBER:
- if (passed_a_ptr)
- fprintf_filtered (stream, "(");
- c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0);
- fprintf_filtered (stream, " ");
+ case TYPE_CODE_MEMBERPTR:
+ c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
+ stream, show, 0, 0, flags);
name = type_name_no_tag (TYPE_DOMAIN_TYPE (type));
if (name)
- fputs_filtered (name, stream);
+ print_name_maybe_canonical (name, flags, stream);
else
- c_type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0, passed_a_ptr);
- fprintf_filtered (stream, "::");
+ c_type_print_base (TYPE_DOMAIN_TYPE (type),
+ stream, -1, passed_a_ptr, flags);
+ fprintf_filtered (stream, "::*");
break;
- case TYPE_CODE_METHOD:
- if (passed_a_ptr)
- fprintf_filtered (stream, "(");
- c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0);
- if (passed_a_ptr)
- {
- fprintf_filtered (stream, " ");
- c_type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0, passed_a_ptr);
- fprintf_filtered (stream, "::");
- }
+ case TYPE_CODE_METHODPTR:
+ c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
+ stream, show, 0, 0, flags);
+ fprintf_filtered (stream, "(");
+ name = type_name_no_tag (TYPE_DOMAIN_TYPE (type));
+ if (name)
+ print_name_maybe_canonical (name, flags, stream);
+ else
+ c_type_print_base (TYPE_DOMAIN_TYPE (type),
+ stream, -1, passed_a_ptr, flags);
+ fprintf_filtered (stream, "::*");
break;
case TYPE_CODE_REF:
- c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1);
+ c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
+ stream, show, 1, 0, flags);
fprintf_filtered (stream, "&");
- c_type_print_cv_qualifier (type, stream, 1, 0);
+ c_type_print_modifier (type, stream, 1, need_post_space);
break;
+ case TYPE_CODE_METHOD:
case TYPE_CODE_FUNC:
- c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0);
+ c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
+ stream, show, 0, 0, flags);
if (passed_a_ptr)
fprintf_filtered (stream, "(");
break;
case TYPE_CODE_ARRAY:
- c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0);
+ c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
+ stream, show, 0, 0, flags);
if (passed_a_ptr)
fprintf_filtered (stream, "(");
break;
+ case TYPE_CODE_TYPEDEF:
+ c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
+ stream, show, passed_a_ptr, 0, flags);
+ break;
+
case TYPE_CODE_UNDEF:
case TYPE_CODE_STRUCT:
case TYPE_CODE_UNION:
@@ -271,104 +376,148 @@ c_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
case TYPE_CODE_SET:
case TYPE_CODE_RANGE:
case TYPE_CODE_STRING:
- case TYPE_CODE_BITSTRING:
case TYPE_CODE_COMPLEX:
- case TYPE_CODE_TYPEDEF:
- case TYPE_CODE_TEMPLATE:
+ case TYPE_CODE_NAMESPACE:
+ case TYPE_CODE_DECFLOAT:
/* These types need no prefix. They are listed here so that
gcc -Wall will reveal any types that haven't been handled. */
break;
default:
- error ("type not handled in c_type_print_varspec_prefix()");
+ error (_("type not handled in c_type_print_varspec_prefix()"));
break;
}
}
-/* Print out "const" and "volatile" attributes.
+/* Print out "const" and "volatile" attributes,
+ and address space id if present.
TYPE is a pointer to the type being printed out.
STREAM is the output destination.
- NEED_SPACE = 1 indicates an initial white space is needed */
+ NEED_PRE_SPACE = 1 indicates an initial white space is needed.
+ NEED_POST_SPACE = 1 indicates a final white space is needed. */
static void
-c_type_print_cv_qualifier (struct type *type, struct ui_file *stream,
- int need_pre_space, int need_post_space)
+c_type_print_modifier (struct type *type, struct ui_file *stream,
+ int need_pre_space, int need_post_space)
{
- int flag = 0;
-
- if (TYPE_CONST (type))
+ int did_print_modifier = 0;
+ const char *address_space_id;
+
+ /* We don't print `const' qualifiers for references --- since all
+ operators affect the thing referenced, not the reference itself,
+ every reference is `const'. */
+ if (TYPE_CONST (type)
+ && TYPE_CODE (type) != TYPE_CODE_REF)
{
if (need_pre_space)
fprintf_filtered (stream, " ");
fprintf_filtered (stream, "const");
- flag = 1;
+ did_print_modifier = 1;
}
if (TYPE_VOLATILE (type))
{
- if (flag || need_pre_space)
+ if (did_print_modifier || need_pre_space)
fprintf_filtered (stream, " ");
fprintf_filtered (stream, "volatile");
- flag = 1;
+ did_print_modifier = 1;
+ }
+
+ address_space_id = address_space_int_to_name (get_type_arch (type),
+ TYPE_INSTANCE_FLAGS (type));
+ if (address_space_id)
+ {
+ if (did_print_modifier || need_pre_space)
+ fprintf_filtered (stream, " ");
+ fprintf_filtered (stream, "@%s", address_space_id);
+ did_print_modifier = 1;
}
- if (flag && need_post_space)
+ if (did_print_modifier && need_post_space)
fprintf_filtered (stream, " ");
}
+/* Print out the arguments of TYPE, which should have TYPE_CODE_METHOD
+ or TYPE_CODE_FUNC, to STREAM. Artificial arguments, such as "this"
+ in non-static methods, are displayed if LINKAGE_NAME is zero. If
+ LINKAGE_NAME is non-zero and LANGUAGE is language_cplus the topmost
+ parameter types get removed their possible const and volatile qualifiers to
+ match demangled linkage name parameters part of such function type.
+ LANGUAGE is the language in which TYPE was defined. This is a necessary
+ evil since this code is used by the C, C++, and Java backends. */
-
-static void
-c_type_print_args (struct type *type, struct ui_file *stream)
+void
+c_type_print_args (struct type *type, struct ui_file *stream,
+ int linkage_name, enum language language,
+ const struct type_print_options *flags)
{
- int i;
- struct type **args;
+ int i, len;
+ struct field *args;
+ int printed_any = 0;
fprintf_filtered (stream, "(");
- args = TYPE_ARG_TYPES (type);
- if (args != NULL)
+ args = TYPE_FIELDS (type);
+ len = TYPE_NFIELDS (type);
+
+ for (i = 0; i < TYPE_NFIELDS (type); i++)
{
- if (args[1] == NULL)
+ struct type *param_type;
+
+ if (TYPE_FIELD_ARTIFICIAL (type, i) && linkage_name)
+ continue;
+
+ if (printed_any)
{
- fprintf_filtered (stream, "...");
+ fprintf_filtered (stream, ", ");
+ wrap_here (" ");
}
- else if ((args[1]->code == TYPE_CODE_VOID) &&
- (current_language->la_language == language_cplus))
+
+ param_type = TYPE_FIELD_TYPE (type, i);
+
+ if (language == language_cplus && linkage_name)
{
- fprintf_filtered (stream, "void");
+ /* C++ standard, 13.1 Overloadable declarations, point 3, item:
+ - Parameter declarations that differ only in the presence or
+ absence of const and/or volatile are equivalent.
+
+ And the const/volatile qualifiers are not present in the mangled
+ names as produced by GCC. */
+
+ param_type = make_cv_type (0, 0, param_type, NULL);
}
+
+ if (language == language_java)
+ java_print_type (param_type, "", stream, -1, 0, flags);
else
- {
- for (i = 1;
- args[i] != NULL && args[i]->code != TYPE_CODE_VOID;
- i++)
- {
- c_print_type (args[i], "", stream, -1, 0);
- if (args[i + 1] == NULL)
- {
- fprintf_filtered (stream, "...");
- }
- else if (args[i + 1]->code != TYPE_CODE_VOID)
- {
- fprintf_filtered (stream, ",");
- wrap_here (" ");
- }
- }
- }
+ c_print_type (param_type, "", stream, -1, 0, flags);
+ printed_any = 1;
}
- else if (current_language->la_language == language_cplus)
+
+ if (printed_any && TYPE_VARARGS (type))
{
- fprintf_filtered (stream, "void");
+ /* Print out a trailing ellipsis for varargs functions. Ignore
+ TYPE_VARARGS if the function has no named arguments; that
+ represents unprototyped (K&R style) C functions. */
+ if (printed_any && TYPE_VARARGS (type))
+ {
+ fprintf_filtered (stream, ", ");
+ wrap_here (" ");
+ fprintf_filtered (stream, "...");
+ }
}
+ else if (!printed_any
+ && ((TYPE_PROTOTYPED (type) && language != language_java)
+ || language == language_cplus))
+ fprintf_filtered (stream, "void");
fprintf_filtered (stream, ")");
}
-
/* Return true iff the j'th overloading of the i'th method of TYPE
is a type conversion operator, like `operator int () { ... }'.
When listing a class's methods, we don't print the return type of
such operators. */
+
static int
is_type_conversion_operator (struct type *type, int i, int j)
{
@@ -376,7 +525,7 @@ is_type_conversion_operator (struct type *type, int i, int j)
by their name is pretty terrible. But I don't think our present
data structure gives us any other way to tell. If you know of
some other way, feel free to rewrite this function. */
- char *name = TYPE_FN_FIELDLIST_NAME (type, i);
+ const char *name = TYPE_FN_FIELDLIST_NAME (type, i);
if (strncmp (name, "operator", 8) != 0)
return 0;
@@ -388,12 +537,20 @@ is_type_conversion_operator (struct type *type, int i, int j)
while (strchr (" \t\f\n\r", *name))
name++;
- if (strncmp (name, "new", 3) == 0)
+ if (!('a' <= *name && *name <= 'z')
+ && !('A' <= *name && *name <= 'Z')
+ && *name != '_')
+ /* If this doesn't look like the start of an identifier, then it
+ isn't a type conversion operator. */
+ return 0;
+ else if (strncmp (name, "new", 3) == 0)
name += 3;
else if (strncmp (name, "delete", 6) == 0)
name += 6;
else
- return 0;
+ /* If it doesn't look like new or delete, it's a type conversion
+ operator. */
+ return 1;
/* Is that really the end of the name? */
if (('a' <= *name && *name <= 'z')
@@ -405,11 +562,11 @@ is_type_conversion_operator (struct type *type, int i, int j)
return 1;
/* That was indeed the end of the name, so it was `operator new' or
- `operator delete', neither of which are type conversion operators. */
+ `operator delete', neither of which are type conversion
+ operators. */
return 0;
}
-
/* Given a C++ qualified identifier QID, strip off the qualifiers,
yielding the unqualified name. The return value is a pointer into
the original string.
@@ -417,17 +574,18 @@ is_type_conversion_operator (struct type *type, int i, int j)
It's a pity we don't have this information in some more structured
form. Even the author of this function feels that writing little
parsers like this everywhere is stupid. */
+
static char *
remove_qualifiers (char *qid)
{
- int quoted = 0; /* zero if we're not in quotes;
- '"' if we're in a double-quoted string;
- '\'' if we're in a single-quoted string. */
- int depth = 0; /* number of unclosed parens we've seen */
+ int quoted = 0; /* Zero if we're not in quotes;
+ '"' if we're in a double-quoted string;
+ '\'' if we're in a single-quoted string. */
+ int depth = 0; /* Number of unclosed parens we've seen. */
char *parenstack = (char *) alloca (strlen (qid));
char *scan;
- char *last = 0; /* The character after the rightmost
- `::' token we've seen so far. */
+ char *last = 0; /* The character after the rightmost
+ `::' token we've seen so far. */
for (scan = qid; *scan; scan++)
{
@@ -443,8 +601,8 @@ remove_qualifiers (char *qid)
/* If we're inside parenthesis (i.e., an argument list) or
angle brackets (i.e., a list of template arguments), then
we don't record the position of this :: token, since it's
- not relevant to the top-level structure we're trying
- to operate on. */
+ not relevant to the top-level structure we're trying to
+ operate on. */
if (depth == 0)
{
last = scan + 2;
@@ -468,10 +626,10 @@ remove_qualifiers (char *qid)
depth--;
else
{
- /* We're going to do a little error recovery here. If we
- don't find a match for *scan on the paren stack, but
- there is something lower on the stack that does match, we
- pop the stack to that point. */
+ /* We're going to do a little error recovery here. If
+ we don't find a match for *scan on the paren stack,
+ but there is something lower on the stack that does
+ match, we pop the stack to that point. */
int i;
for (i = depth - 1; i >= 0; i--)
@@ -492,14 +650,16 @@ remove_qualifiers (char *qid)
return qid;
}
-
/* Print any array sizes, function arguments or close parentheses
needed after the variable name (to describe its type).
Args work like c_type_print_varspec_prefix. */
void
-c_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
- int show, int passed_a_ptr, int demangled_args)
+c_type_print_varspec_suffix (struct type *type,
+ struct ui_file *stream,
+ int show, int passed_a_ptr,
+ int demangled_args,
+ const struct type_print_options *flags)
{
if (type == 0)
return;
@@ -512,66 +672,56 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
switch (TYPE_CODE (type))
{
case TYPE_CODE_ARRAY:
- if (passed_a_ptr)
- fprintf_filtered (stream, ")");
+ {
+ LONGEST low_bound, high_bound;
+ int is_vector = TYPE_VECTOR (type);
- fprintf_filtered (stream, "[");
- if (TYPE_LENGTH (type) >= 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0
- && TYPE_ARRAY_UPPER_BOUND_TYPE (type) != BOUND_CANNOT_BE_DETERMINED)
- fprintf_filtered (stream, "%d",
- (TYPE_LENGTH (type)
- / TYPE_LENGTH (TYPE_TARGET_TYPE (type))));
- fprintf_filtered (stream, "]");
+ if (passed_a_ptr)
+ fprintf_filtered (stream, ")");
- c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0);
+ fprintf_filtered (stream, (is_vector ?
+ " __attribute__ ((vector_size(" : "["));
+ if (get_array_bounds (type, &low_bound, &high_bound))
+ fprintf_filtered (stream, "%s",
+ plongest (high_bound - low_bound + 1));
+ fprintf_filtered (stream, (is_vector ? ")))" : "]"));
+
+ c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
+ show, 0, 0, flags);
+ }
break;
- case TYPE_CODE_MEMBER:
- if (passed_a_ptr)
- fprintf_filtered (stream, ")");
- c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0);
+ case TYPE_CODE_MEMBERPTR:
+ c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
+ show, 0, 0, flags);
break;
- case TYPE_CODE_METHOD:
- if (passed_a_ptr)
- fprintf_filtered (stream, ")");
- c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0);
- if (passed_a_ptr)
- {
- c_type_print_args (type, stream);
- }
+ case TYPE_CODE_METHODPTR:
+ fprintf_filtered (stream, ")");
+ c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
+ show, 0, 0, flags);
break;
case TYPE_CODE_PTR:
case TYPE_CODE_REF:
- c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 1, 0);
+ c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
+ show, 1, 0, flags);
break;
+ case TYPE_CODE_METHOD:
case TYPE_CODE_FUNC:
if (passed_a_ptr)
fprintf_filtered (stream, ")");
if (!demangled_args)
- {
- int i, len = TYPE_NFIELDS (type);
- fprintf_filtered (stream, "(");
- if ((len == 0) && (current_language->la_language == language_cplus))
- {
- fprintf_filtered (stream, "void");
- }
- else
- for (i = 0; i < len; i++)
- {
- if (i > 0)
- {
- fputs_filtered (", ", stream);
- wrap_here (" ");
- }
- c_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0);
- }
- fprintf_filtered (stream, ")");
- }
- c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0,
- passed_a_ptr, 0);
+ c_type_print_args (type, stream, 0, current_language->la_language,
+ flags);
+ c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
+ show, passed_a_ptr, 0, flags);
+ break;
+
+ case TYPE_CODE_TYPEDEF:
+ c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
+ show, passed_a_ptr, 0, flags);
break;
case TYPE_CODE_UNDEF:
@@ -587,45 +737,93 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
case TYPE_CODE_SET:
case TYPE_CODE_RANGE:
case TYPE_CODE_STRING:
- case TYPE_CODE_BITSTRING:
case TYPE_CODE_COMPLEX:
- case TYPE_CODE_TYPEDEF:
- case TYPE_CODE_TEMPLATE:
+ case TYPE_CODE_NAMESPACE:
+ case TYPE_CODE_DECFLOAT:
/* These types do not need a suffix. They are listed so that
- gcc -Wall will report types that may not have been considered. */
+ gcc -Wall will report types that may not have been
+ considered. */
break;
default:
- error ("type not handled in c_type_print_varspec_suffix()");
+ error (_("type not handled in c_type_print_varspec_suffix()"));
break;
}
}
+/* A helper for c_type_print_base that displays template
+ parameters and their bindings, if needed.
+
+ TABLE is the local bindings table to use. If NULL, no printing is
+ done. Note that, at this point, TABLE won't have any useful
+ information in it -- but it is also used as a flag to
+ print_name_maybe_canonical to activate searching the global typedef
+ table.
+
+ TYPE is the type whose template arguments are being displayed.
+
+ STREAM is the stream on which to print. */
+
+static void
+c_type_print_template_args (const struct type_print_options *flags,
+ struct type *type, struct ui_file *stream)
+{
+ int first = 1, i;
+
+ if (flags->raw)
+ return;
+
+ for (i = 0; i < TYPE_N_TEMPLATE_ARGUMENTS (type); ++i)
+ {
+ struct symbol *sym = TYPE_TEMPLATE_ARGUMENT (type, i);
+
+ if (SYMBOL_CLASS (sym) != LOC_TYPEDEF)
+ continue;
+
+ if (first)
+ {
+ wrap_here (" ");
+ fprintf_filtered (stream, _("[with %s = "),
+ SYMBOL_LINKAGE_NAME (sym));
+ first = 0;
+ }
+ else
+ {
+ fputs_filtered (", ", stream);
+ wrap_here (" ");
+ fprintf_filtered (stream, "%s = ", SYMBOL_LINKAGE_NAME (sym));
+ }
+
+ c_print_type (SYMBOL_TYPE (sym), "", stream, -1, 0, flags);
+ }
+
+ if (!first)
+ fputs_filtered (_("] "), stream);
+}
+
/* 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;}".
+ 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. */
void
-c_type_print_base (struct type *type, struct ui_file *stream, int show,
- int level)
+c_type_print_base (struct type *type, struct ui_file *stream,
+ int show, int level, const struct type_print_options *flags)
{
- register int i;
- register int len;
- register int lastval;
- char *mangled_name;
- char *demangled_name;
- char *demangled_no_static;
+ int i;
+ int len, real_len;
enum
{
s_none, s_public, s_private, s_protected
@@ -636,24 +834,24 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
QUIT;
- wrap_here (" ");
if (type == NULL)
{
- fputs_filtered ("", stream);
+ 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". */
+ /* 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 <= 0
&& TYPE_NAME (type) != NULL)
{
- c_type_print_cv_qualifier (type, stream, 0, 1);
- fputs_filtered (TYPE_NAME (type), stream);
+ c_type_print_modifier (type, stream, 0, 1);
+ print_name_maybe_canonical (TYPE_NAME (type), flags, stream);
return;
}
@@ -662,251 +860,298 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
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) == NULL);
+ gdb_assert (TYPE_TARGET_TYPE (type) == NULL);
+ fprintf_filtered (stream, _(""));
+ break;
+
case TYPE_CODE_ARRAY:
case TYPE_CODE_PTR:
- case TYPE_CODE_MEMBER:
+ case TYPE_CODE_MEMBERPTR:
case TYPE_CODE_REF:
case TYPE_CODE_FUNC:
case TYPE_CODE_METHOD:
- c_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
+ case TYPE_CODE_METHODPTR:
+ c_type_print_base (TYPE_TARGET_TYPE (type),
+ stream, show, level, flags);
break;
case TYPE_CODE_STRUCT:
- c_type_print_cv_qualifier (type, stream, 0, 1);
- /* Note TYPE_CODE_STRUCT and TYPE_CODE_CLASS have the same value,
- * so we use another means for distinguishing them.
- */
- if (HAVE_CPLUS_STRUCT (type))
- {
- switch (TYPE_DECLARED_TYPE (type))
- {
- case DECLARED_TYPE_CLASS:
- fprintf_filtered (stream, "class ");
- break;
- case DECLARED_TYPE_UNION:
- fprintf_filtered (stream, "union ");
- break;
- case DECLARED_TYPE_STRUCT:
- fprintf_filtered (stream, "struct ");
- break;
- default:
- /* If there is a CPLUS_STRUCT, assume class if not
- * otherwise specified in the declared_type field.
- */
- fprintf_filtered (stream, "class ");
- break;
- } /* switch */
- }
- else
- {
- /* If not CPLUS_STRUCT, then assume it's a C struct */
+ case TYPE_CODE_UNION:
+ {
+ struct type_print_options local_flags = *flags;
+ struct type_print_options semi_local_flags = *flags;
+ struct cleanup *local_cleanups = make_cleanup (null_cleanup, NULL);
+
+ local_flags.local_typedefs = NULL;
+ semi_local_flags.local_typedefs = NULL;
+
+ if (!flags->raw)
+ {
+ if (flags->local_typedefs)
+ local_flags.local_typedefs
+ = copy_typedef_hash (flags->local_typedefs);
+ else
+ local_flags.local_typedefs = create_typedef_hash ();
+
+ make_cleanup_free_typedef_hash (local_flags.local_typedefs);
+ }
+
+ c_type_print_modifier (type, stream, 0, 1);
+ if (TYPE_CODE (type) == TYPE_CODE_UNION)
+ fprintf_filtered (stream, "union ");
+ else if (TYPE_DECLARED_CLASS (type))
+ fprintf_filtered (stream, "class ");
+ else
fprintf_filtered (stream, "struct ");
- }
- goto struct_union;
- case TYPE_CODE_UNION:
- c_type_print_cv_qualifier (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) != 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) == NULL)
- fprintf_filtered (stream, "{...}");
- }
- else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
- {
- cp_type_print_derivation_info (stream, type);
+ /* 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) != NULL
+ && strncmp (TYPE_TAG_NAME (type), "{unnamed", 8))
+ {
+ /* When printing the tag name, we are still effectively
+ printing in the outer context, hence the use of FLAGS
+ here. */
+ print_name_maybe_canonical (TYPE_TAG_NAME (type), flags, stream);
+ if (show > 0)
+ fputs_filtered (" ", stream);
+ }
- fprintf_filtered (stream, "{\n");
- if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0))
- {
- if (TYPE_FLAGS (type) & TYPE_FLAG_STUB)
- fprintfi_filtered (level + 4, stream, "\n");
- else
- fprintfi_filtered (level + 4, stream, "\n");
- }
+ if (show < 0)
+ {
+ /* If we just printed a tag name, no need to print anything
+ else. */
+ if (TYPE_TAG_NAME (type) == NULL)
+ fprintf_filtered (stream, "{...}");
+ }
+ else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
+ {
+ struct type *basetype;
+ int vptr_fieldno;
- /* 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. */
+ c_type_print_template_args (&local_flags, type, stream);
- section_type = s_none;
+ /* Add in template parameters when printing derivation info. */
+ add_template_parameters (local_flags.local_typedefs, type);
+ cp_type_print_derivation_info (stream, type, &local_flags);
- /* 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. */
+ /* This holds just the global typedefs and the template
+ parameters. */
+ semi_local_flags.local_typedefs
+ = copy_typedef_hash (local_flags.local_typedefs);
+ if (semi_local_flags.local_typedefs)
+ make_cleanup_free_typedef_hash (semi_local_flags.local_typedefs);
- if ((TYPE_DECLARED_TYPE (type) == DECLARED_TYPE_CLASS) ||
- (TYPE_DECLARED_TYPE (type) == DECLARED_TYPE_TEMPLATE))
- {
- QUIT;
- len = TYPE_NFIELDS (type);
- for (i = TYPE_N_BASECLASSES (type); i < len; i++)
- if (!TYPE_FIELD_PRIVATE (type, i))
+ /* Now add in the local typedefs. */
+ recursively_update_typedef_hash (local_flags.local_typedefs, type);
+
+ fprintf_filtered (stream, "{\n");
+ if (TYPE_NFIELDS (type) == 0 && TYPE_NFN_FIELDS (type) == 0
+ && TYPE_TYPEDEF_FIELD_COUNT (type) == 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 = 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 = TYPE_NFIELDS (type);
+ for (i = TYPE_N_BASECLASSES (type); i < len; i++)
+ if (!TYPE_FIELD_PRIVATE (type, i))
+ {
+ need_access_label = 1;
+ break;
+ }
+ QUIT;
+ if (!need_access_label)
{
- need_access_label = 1;
- break;
+ len2 = TYPE_NFN_FIELDS (type);
+ for (j = 0; j < len2; j++)
+ {
+ len = TYPE_FN_FIELDLIST_LENGTH (type, j);
+ for (i = 0; i < len; i++)
+ if (!TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type,
+ j), i))
+ {
+ need_access_label = 1;
+ break;
+ }
+ if (need_access_label)
+ break;
+ }
}
- QUIT;
- if (!need_access_label)
- {
- len2 = TYPE_NFN_FIELDS (type);
- for (j = 0; j < len2; j++)
+ }
+ else
+ {
+ QUIT;
+ len = TYPE_NFIELDS (type);
+ for (i = TYPE_N_BASECLASSES (type); i < len; i++)
+ if (TYPE_FIELD_PRIVATE (type, i)
+ || TYPE_FIELD_PROTECTED (type, i))
{
- len = TYPE_FN_FIELDLIST_LENGTH (type, j);
- for (i = 0; i < len; i++)
- if (!TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type, j), i))
- {
- need_access_label = 1;
- break;
- }
- if (need_access_label)
- break;
+ need_access_label = 1;
+ break;
}
- }
- }
- else if ((TYPE_DECLARED_TYPE (type) == DECLARED_TYPE_STRUCT) ||
- (TYPE_DECLARED_TYPE (type) == DECLARED_TYPE_UNION))
- {
- QUIT;
- len = TYPE_NFIELDS (type);
- for (i = TYPE_N_BASECLASSES (type); i < len; i++)
- if (TYPE_FIELD_PRIVATE (type, i) || TYPE_FIELD_PROTECTED (type, i))
+ QUIT;
+ if (!need_access_label)
{
- need_access_label = 1;
- break;
+ len2 = TYPE_NFN_FIELDS (type);
+ for (j = 0; j < len2; j++)
+ {
+ QUIT;
+ len = TYPE_FN_FIELDLIST_LENGTH (type, j);
+ for (i = 0; i < len; i++)
+ if (TYPE_FN_FIELD_PROTECTED (TYPE_FN_FIELDLIST1 (type,
+ j), i)
+ || TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type,
+ j),
+ i))
+ {
+ need_access_label = 1;
+ break;
+ }
+ if (need_access_label)
+ break;
+ }
}
- QUIT;
- if (!need_access_label)
- {
- len2 = TYPE_NFN_FIELDS (type);
- for (j = 0; j < len2; j++)
- {
- QUIT;
- len = TYPE_FN_FIELDLIST_LENGTH (type, j);
- for (i = 0; i < len; i++)
- if (TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type, j), i) ||
- TYPE_FN_FIELD_PROTECTED (TYPE_FN_FIELDLIST1 (type, j), i))
+ }
+
+ /* If there is a base class for this type,
+ do not print the field that it occupies. */
+
+ len = TYPE_NFIELDS (type);
+ vptr_fieldno = get_vptr_fieldno (type, &basetype);
+ for (i = 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 == vptr_fieldno && type == basetype)
+ || TYPE_FIELD_ARTIFICIAL (type, i))
+ continue;
+
+ if (need_access_label)
+ {
+ if (TYPE_FIELD_PROTECTED (type, i))
+ {
+ if (section_type != s_protected)
{
- need_access_label = 1;
- break;
+ section_type = s_protected;
+ fprintfi_filtered (level + 2, stream,
+ "protected:\n");
}
- if (need_access_label)
- break;
- }
- }
- }
+ }
+ else if (TYPE_FIELD_PRIVATE (type, i))
+ {
+ if (section_type != s_private)
+ {
+ section_type = s_private;
+ fprintfi_filtered (level + 2, stream,
+ "private:\n");
+ }
+ }
+ else
+ {
+ if (section_type != s_public)
+ {
+ section_type = s_public;
+ fprintfi_filtered (level + 2, stream,
+ "public:\n");
+ }
+ }
+ }
- /* If there is a base class for this type,
- do not print the field that it occupies. */
+ 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,
+ &local_flags);
+ 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");
+ }
- len = TYPE_NFIELDS (type);
- for (i = TYPE_N_BASECLASSES (type); i < len; i++)
+ /* 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 = TYPE_NFN_FIELDS (type);
+ if (!flags->print_methods)
+ len = 0;
+ real_len = 0;
+ for (i = 0; i < len; i++)
{
- QUIT;
- /* Don't print out virtual function table. */
- /* HP ANSI C++ case */
- if (TYPE_HAS_VTABLE (type) && (STREQN (TYPE_FIELD_NAME (type, i), "__vfp", 5)))
- continue;
- /* Other compilers */
- if (STREQN (TYPE_FIELD_NAME (type, i), "_vptr", 5)
- && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5]))
- continue;
-
- /* If this is a C++ class we can print the various C++ section
- labels. */
-
- if (HAVE_CPLUS_STRUCT (type) && need_access_label)
- {
- if (TYPE_FIELD_PROTECTED (type, i))
- {
- if (section_type != s_protected)
- {
- section_type = s_protected;
- fprintfi_filtered (level + 2, stream,
- "protected:\n");
- }
- }
- else if (TYPE_FIELD_PRIVATE (type, i))
- {
- if (section_type != s_private)
- {
- section_type = s_private;
- fprintfi_filtered (level + 2, stream, "private:\n");
- }
- }
- else
- {
- if (section_type != s_public)
- {
- section_type = s_public;
- fprintfi_filtered (level + 2, stream, "public:\n");
- }
- }
- }
+ struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
+ int len2 = TYPE_FN_FIELDLIST_LENGTH (type, i);
+ int j;
- print_spaces_filtered (level + 4, stream);
- if (TYPE_FIELD_STATIC (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 (!TYPE_FIELD_STATIC (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");
+ for (j = 0; j < len2; j++)
+ if (!TYPE_FN_FIELD_ARTIFICIAL (f, j))
+ real_len++;
}
-
- /* If there are both fields and methods, put a space between. */
- len = TYPE_NFN_FIELDS (type);
- if (len && section_type != s_none)
+ if (real_len > 0 && section_type != s_none)
fprintf_filtered (stream, "\n");
- /* C++: print out the methods */
+ /* C++: print out the methods. */
for (i = 0; i < len; i++)
{
struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
int j, len2 = TYPE_FN_FIELDLIST_LENGTH (type, i);
- char *method_name = TYPE_FN_FIELDLIST_NAME (type, i);
- char *name = type_name_no_tag (type);
- int is_constructor = name && STREQ (method_name, name);
+ const char *method_name = TYPE_FN_FIELDLIST_NAME (type, i);
+ const char *name = type_name_no_tag (type);
+ int is_constructor = name && strcmp (method_name,
+ name) == 0;
+
for (j = 0; j < len2; j++)
{
- char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
+ const char *mangled_name;
+ char *demangled_name;
+ struct cleanup *inner_cleanup;
+ const char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
int is_full_physname_constructor =
- ((physname[0] == '_' && physname[1] == '_'
- && strchr ("0123456789Qt", physname[2]))
- || STREQN (physname, "__ct__", 6)
- || DESTRUCTOR_PREFIX_P (physname)
- || STREQN (physname, "__dt__", 6));
+ TYPE_FN_FIELD_CONSTRUCTOR (f, j)
+ || is_constructor_name (physname)
+ || is_destructor_name (physname)
+ || method_name[0] == '~';
+
+ /* Do not print out artificial methods. */
+ if (TYPE_FN_FIELD_ARTIFICIAL (f, j))
+ continue;
+
+ inner_cleanup = make_cleanup (null_cleanup, NULL);
QUIT;
if (TYPE_FN_FIELD_PROTECTED (f, j))
@@ -923,7 +1168,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
if (section_type != s_private)
{
section_type = s_private;
- fprintfi_filtered (level + 2, stream, "private:\n");
+ fprintfi_filtered (level + 2, stream,
+ "private:\n");
}
}
else
@@ -931,7 +1177,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
if (section_type != s_public)
{
section_type = s_public;
- fprintfi_filtered (level + 2, stream, "public:\n");
+ fprintfi_filtered (level + 2, stream,
+ "public:\n");
}
}
@@ -943,21 +1190,31 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0)
{
/* Keep GDB from crashing here. */
- fprintf_filtered (stream, " %s;\n",
+ 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))
+ 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);
+ c_print_type (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
+ "", stream, -1, 0,
+ &local_flags);
fputs_filtered (" ", stream);
}
if (TYPE_FN_FIELD_STUB (f, j))
- /* Build something we can demangle. */
- mangled_name = gdb_mangle_name (type, i, j);
+ {
+ char *tem;
+
+ /* Build something we can demangle. */
+ tem = gdb_mangle_name (type, i, j);
+ make_cleanup (xfree, tem);
+ mangled_name = tem;
+ }
else
mangled_name = TYPE_FN_FIELD_PHYSNAME (f, j);
@@ -966,18 +1223,25 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
DMGL_ANSI | DMGL_PARAMS);
if (demangled_name == 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 */
+ /* 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))
- cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j), "",
- method_name,
- TYPE_FN_FIELD_STATIC_P (f, j),
- stream);
+ {
+ int staticp = TYPE_FN_FIELD_STATIC_P (f, j);
+ struct type *mtype = TYPE_FN_FIELD_TYPE (f, j);
+
+ cp_type_print_method_args (mtype,
+ "",
+ method_name,
+ staticp,
+ stream, &local_flags);
+ }
else
- fprintf_filtered (stream, "",
+ fprintf_filtered (stream,
+ _(""),
mangled_name);
}
else
@@ -986,13 +1250,18 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
char *demangled_no_class
= remove_qualifiers (demangled_name);
- /* get rid of the `static' appended by the demangler */
+ /* Get rid of the `static' appended by the
+ demangler. */
p = strstr (demangled_no_class, " static");
if (p != NULL)
{
int length = p - demangled_no_class;
- demangled_no_static = (char *) xmalloc (length + 1);
- strncpy (demangled_no_static, demangled_no_class, length);
+ char *demangled_no_static;
+
+ demangled_no_static
+ = (char *) xmalloc (length + 1);
+ strncpy (demangled_no_static,
+ demangled_no_class, length);
*(demangled_no_static + length) = '\0';
fputs_filtered (demangled_no_static, stream);
xfree (demangled_no_static);
@@ -1002,49 +1271,61 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
xfree (demangled_name);
}
- if (TYPE_FN_FIELD_STUB (f, j))
- xfree (mangled_name);
+ do_cleanups (inner_cleanup);
fprintf_filtered (stream, ";\n");
}
}
- fprintfi_filtered (level, stream, "}");
+ /* Print typedefs defined in this class. */
- if (TYPE_LOCALTYPE_PTR (type) && show >= 0)
- fprintfi_filtered (level, stream, " (Local at %s:%d)\n",
- TYPE_LOCALTYPE_FILE (type),
- TYPE_LOCALTYPE_LINE (type));
- }
- if (TYPE_CODE (type) == TYPE_CODE_TEMPLATE)
- goto go_back;
+ if (TYPE_TYPEDEF_FIELD_COUNT (type) != 0 && flags->print_typedefs)
+ {
+ if (TYPE_NFIELDS (type) != 0 || TYPE_NFN_FIELDS (type) != 0)
+ fprintf_filtered (stream, "\n");
+
+ for (i = 0; i < TYPE_TYPEDEF_FIELD_COUNT (type); i++)
+ {
+ struct type *target = TYPE_TYPEDEF_FIELD_TYPE (type, i);
+ struct typedef_hash_table *table2;
+
+ /* Dereference the typedef declaration itself. */
+ gdb_assert (TYPE_CODE (target) == TYPE_CODE_TYPEDEF);
+ target = TYPE_TARGET_TYPE (target);
+
+ print_spaces_filtered (level + 4, stream);
+ fprintf_filtered (stream, "typedef ");
+
+ /* We want to print typedefs with substitutions
+ from the template parameters or globally-known
+ typedefs but not local typedefs. */
+ c_print_type (target,
+ TYPE_TYPEDEF_FIELD_NAME (type, i),
+ stream, show - 1, level + 4,
+ &semi_local_flags);
+ fprintf_filtered (stream, ";\n");
+ }
+ }
+
+ fprintfi_filtered (level, stream, "}");
+ }
+
+ do_cleanups (local_cleanups);
+ }
break;
case TYPE_CODE_ENUM:
- c_type_print_cv_qualifier (type, stream, 0, 1);
- /* HP C supports sized enums */
- if (hp_som_som_object_present)
- switch (TYPE_LENGTH (type))
- {
- case 1:
- fputs_filtered ("char ", stream);
- break;
- case 2:
- fputs_filtered ("short ", stream);
- break;
- default:
- break;
- }
+ 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) != NULL &&
- strncmp (TYPE_TAG_NAME (type), "{unnamed", 8))
+ want to print. */
+ if (TYPE_TAG_NAME (type) != NULL
+ && strncmp (TYPE_TAG_NAME (type), "{unnamed", 8))
{
- fputs_filtered (TYPE_TAG_NAME (type), stream);
+ print_name_maybe_canonical (TYPE_TAG_NAME (type), flags, stream);
if (show > 0)
fputs_filtered (" ", stream);
}
@@ -1052,15 +1333,17 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
wrap_here (" ");
if (show < 0)
{
- /* If we just printed a tag name, no need to print anything else. */
+ /* If we just printed a tag name, no need to print anything
+ else. */
if (TYPE_TAG_NAME (type) == NULL)
fprintf_filtered (stream, "{...}");
}
else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
{
+ LONGEST lastval = 0;
+
fprintf_filtered (stream, "{");
len = TYPE_NFIELDS (type);
- lastval = 0;
for (i = 0; i < len; i++)
{
QUIT;
@@ -1068,10 +1351,11 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
fprintf_filtered (stream, ", ");
wrap_here (" ");
fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
- if (lastval != TYPE_FIELD_BITPOS (type, i))
+ if (lastval != TYPE_FIELD_ENUMVAL (type, i))
{
- fprintf_filtered (stream, " = %d", TYPE_FIELD_BITPOS (type, i));
- lastval = TYPE_FIELD_BITPOS (type, i);
+ fprintf_filtered (stream, " = %s",
+ plongest (TYPE_FIELD_ENUMVAL (type, i)));
+ lastval = TYPE_FIELD_ENUMVAL (type, i);
}
lastval++;
}
@@ -1084,67 +1368,38 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
break;
case TYPE_CODE_UNDEF:
- fprintf_filtered (stream, "struct ");
+ fprintf_filtered (stream, _("struct "));
break;
case TYPE_CODE_ERROR:
- fprintf_filtered (stream, "");
+ fprintf_filtered (stream, "%s", TYPE_ERROR_NAME (type));
break;
case TYPE_CODE_RANGE:
- /* This should not occur */
- fprintf_filtered (stream, "");
+ /* This should not occur. */
+ fprintf_filtered (stream, _(""));
break;
- case TYPE_CODE_TEMPLATE:
- /* Called on "ptype t" where "t" is a template.
- Prints the template header (with args), e.g.:
- template class "
- and then merges with the struct/union/class code to
- print the rest of the definition. */
- c_type_print_cv_qualifier (type, stream, 0, 1);
- fprintf_filtered (stream, "template <");
- for (i = 0; i < TYPE_NTEMPLATE_ARGS (type); i++)
- {
- struct template_arg templ_arg;
- templ_arg = TYPE_TEMPLATE_ARG (type, i);
- fprintf_filtered (stream, "class %s", templ_arg.name);
- if (i < TYPE_NTEMPLATE_ARGS (type) - 1)
- fprintf_filtered (stream, ", ");
- }
- fprintf_filtered (stream, "> class ");
- /* Yuck, factor this out to a subroutine so we can call
- it and return to the point marked with the "goback:" label... - RT */
- goto struct_union;
- go_back:
- if (TYPE_NINSTANTIATIONS (type) > 0)
- {
- fprintf_filtered (stream, "\ntemplate instantiations:\n");
- for (i = 0; i < TYPE_NINSTANTIATIONS (type); i++)
- {
- fprintf_filtered (stream, " ");
- c_type_print_base (TYPE_INSTANTIATION (type, i), stream, 0, level);
- if (i < TYPE_NINSTANTIATIONS (type) - 1)
- fprintf_filtered (stream, "\n");
- }
- }
+ 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. */
+ /* 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) != NULL)
{
- c_type_print_cv_qualifier (type, stream, 0, 1);
- fputs_filtered (TYPE_NAME (type), stream);
+ c_type_print_modifier (type, stream, 0, 1);
+ print_name_maybe_canonical (TYPE_NAME (type), flags, stream);
}
else
{
- /* At least for dump_symtab, it is important that this not be
- an error (). */
- fprintf_filtered (stream, "",
+ /* At least for dump_symtab, it is important that this not
+ be an error (). */
+ fprintf_filtered (stream, _(""),
TYPE_CODE (type));
}
break;