aboutsummaryrefslogtreecommitdiff
path: root/gdb/c-valprint.c
diff options
context:
space:
mode:
authorFred Fish <fnf@specifix.com>1992-12-18 20:21:32 +0000
committerFred Fish <fnf@specifix.com>1992-12-18 20:21:32 +0000
commita8a69e6332cc7f83a608af394e757e00355f5550 (patch)
tree3cab52bf4425a2e1c821aeaeb9e61bb1db910962 /gdb/c-valprint.c
parent6c1cabd48fce2d5014ec869c477b4a8756332f42 (diff)
downloadgdb-a8a69e6332cc7f83a608af394e757e00355f5550.zip
gdb-a8a69e6332cc7f83a608af394e757e00355f5550.tar.gz
gdb-a8a69e6332cc7f83a608af394e757e00355f5550.tar.bz2
* Makefile.in (VERSION): Bump to 4.7.4.
* Makefile.in (SFILES_MAINDIR): Add typeprint.c, c-typeprint.c, m2-typeprint.c, c-valprint.c cp-valprint.c m2-valprint.c. * Makefile.in (HFILES): Add valprint.h. * Makefile.in (OBS): Add typeprint.o, c-typeprint.o, m2-typeprint.o, c-valprint.o, cp-valprint.o m2-valprint.o. * typeprint.c, typeprint.h: New files for language independent type printing functions. * c-typeprint.c, m2-typeprint.c: New files for language dependent type printing functions and definitions. * valprint.h: New include file for language independent value printing definitions. * c-valprint.c, cp-valprint.c, m2-valprint.c: New files for language dependent value printing functions. * c-exp.y (production ptype): Add range_type variable and use new create_range_type function. * c-exp.y (tokentab2, tokentab3), c-lang.c (c_op_print_tab), infcmd.c (path_var_name), language.c (unk_op_print_tab), m2-lang.c (m2_op_print_tab): Change from ANSI-obsolescent "const static" to ANSI-conformant "static const". * c-exp.y (c_create_fundamental_type): Remove unused nbytes. * c-exp.y (c_language_defn, cplus_language_defn): Add c_print_type, and c_val_print. * c-lang.h (c_print_type, c_val_print): Add prototypes. * coffread.c (decode_type): Add range_type variable and call to new create_range_type function. * complaints.c (complain): Remove unused val variable. * complaints.c (_initialize_complaints): Make it void. * convex-tdep.c (value_of_trapped_internalvar): Add range_type variable and call new create_range_type function. * defs.h (enum val_prettyprint): Move enum from value.h to here so we can avoid having to include value.h just for prototypes that need the enum (thanks ANSI). * dwarfread.c (struct_type): Local anonymous_size variable is only used if !BITS_BIG_ENDIAN. * dwarfread.c (decode_subscript_data_item): Add rangetype variable and call new create_range_type function. * elfread.c (elf_symfile_read): Remove unused dbx and text_sect variables. * eval.c (evaluate_subexp): Remove unused local variable name and the statement with no side effects that initializes it. * expprint.c (print_subexp): Change local_printstr to LA_PRINT_STRING. * gdbtypes.c (create_range_type): New function that creates a range type using code fragments from object file readers as an example of what has to be initialized. * gdbtypes.c (create_array_type): Removed index_type, low_bound, and high_bound parameters, replaced with a single range_type parameter. Change function body to use passed in range_type rather than handcrafting one. * gdbtypes.h (create_range_type): Add prototype. * gdbtypes.h (create_array_type): Change prototype parameters. * infrun.c (normal_stop): Remove unused local variables tem and c. * infrun.c (hook_stop_stub): Return 0 rather than random value. * language.c (unk_lang_print_type, unk_lang_val_print): Add stub functions that call error if called. * language.c (unknown_language_defn, auto_language_defn, local_language_defn): Add initializers unk_lang_print_type and unk_lang_val_print. * language.h (struct language_defn): Reformat for larger comments, add la_print_type and la_val_print members. Add LA_PRINT_TYPE and LA_VAL_PRINT macros. Change local_printchar to LA_PRINT_CHAR and local_printstr to LA_PRINT_STRING. * m2-lang.c (m2_create_fundamental_type): Remove unused local variable nbytes. * m2-lang.c (m2_language_defn): Add initializers m2_print_type and m2_val_print. * m2-lang.h (m2_print_type, m2_val_print): Add prototypes. * main.c (execute_command): Remove unused local variable cmdlines. * main.c (echo_command), stabsread.c (read_type), printcmd.c (clear_displays), symmisc.c (block_depth), values.c (clear_value_history): Make testing of truth value of assignment result explicit. * mipsread.c (upgrade_type): Update FIXME to include future use of create_range_type. * printcmd.c (ptype_command, ptype_eval, whatis_command, whatis_exp, maintenance_print_type): Move prototypes and functions to new typeprint.c. * printcmd.c (_initialize_printcmd): Move add_com calls for ptype_command and whatis_command to new typeprint.c. * ser-bsd.c (serial_open): Remove unused variable sgttyb. * source.c (find_source_lines): Local variable c only used when LSEEK_NOT_LINEAR is defined. * stabsread.c (read_array_type): Use new create_range_type function. * stabsread.c (read_range_type): Add new index_type variable and call new create_range_type function rather than handcrafting range types. * symmisc.c (type_print_1): Change usages to LA_PRINT_TYPE. * symtab.c (typedef_print usages): Use c_typedef_print, renamed. * symtab.c (type_print_base usages): Use c_type_print_base. * symtab.c (type_print_varspec_prefix usages): Use c_type_print_varspec_prefix. * symtab.c (type_print_method_args usages): Use cp_type_print_method_args. * valprint.c: Completely ripped apart and the fragments used to create c-valprint.c, cp-valprint.c, m2-valprint.c, and valprint.h. Remaining stuff is language independent. * value.h (struct fn_field): Forward declare for prototypes. * value.h (type_print_1): Remove prototype. * value.h (enum val_prettyprint): Moved to defs.h. * value.h (typedef_print): Prototype renamed to c_typedef_print. * value.h (baseclass_offset): Add prototype. **** start-sanitize-chill **** * Makefile.in (SFILES_MAINDIR): Add ch-typeprint.c, ch-valprint.c. * Makefile.in (OBS): Add ch-typeprint.o, ch-valprint.o. * ch-typeprint.c: New file for language dependent type printing. * ch-valprint.c: New file for language dependent value printing. * ch-exp.y (parse_number): Remove prototype and stub function. * ch-exp.y (decode_integer_literal): Removed unused digits and temp variables. * ch-exp.y (convert_float): Completely ifdef out for now. * ch-exp.y (tokentab2, tokentab3, tokentab4, tokentab5), ch-lang.c (chill_op_print_tab): Change from ANSI-obsolescent "const static" to ANSI-conformant "static const". * ch-exp.y (yylex): Add unhandled storage class enumeration literals to switch statement for completeness. * ch-lang.c (chill_create_fundamental_types): Remove unused nbytes variable. Change dummy type to 2 bytes to match int. Handle FT_VOID types gratuituously added to chill DWARF by compiler. Change FT_CHAR case to generate an TYPE_CODE_CHAR type rather than a one byte TYPE_CODE_INT type. * ch-lang.c (chill_language_defn): Add chill_print_type and chill_val_print. * ch-lang.h (chill_print_type, chill_val_print): Add prototypes. **** end-sanitize-chill ****
Diffstat (limited to 'gdb/c-valprint.c')
-rw-r--r--gdb/c-valprint.c542
1 files changed, 542 insertions, 0 deletions
diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c
new file mode 100644
index 0000000..91d9a57
--- /dev/null
+++ b/gdb/c-valprint.c
@@ -0,0 +1,542 @@
+/* Support for printing C values for GDB, the GNU debugger.
+ Copyright 1986, 1988, 1989, 1991 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
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "value.h"
+#include "demangle.h"
+#include "valprint.h"
+#include "language.h"
+
+/* BEGIN-FIXME */
+
+extern int vtblprint; /* Controls printing of vtbl's */
+extern int demangle; /* whether to print C++ syms raw or src-form */
+
+extern void
+cp_print_class_member PARAMS ((char *, struct type *, FILE *, char *));
+
+extern int
+cp_is_vtbl_ptr_type PARAMS ((struct type *));
+
+extern void
+cp_print_value_fields PARAMS ((struct type *, char *, FILE *, int, int,
+ enum val_prettyprint, struct type **));
+
+extern int
+cp_is_vtbl_member PARAMS ((struct type *));
+
+/* END-FIXME */
+
+
+/* BEGIN-FIXME: Hooks into c-typeprint.c */
+
+extern void
+c_type_print_varspec_prefix PARAMS ((struct type *, FILE *, int, int));
+
+extern void
+cp_type_print_method_args PARAMS ((struct type **, char *, char *, int,
+ FILE *));
+/* END-FIXME */
+
+
+extern struct obstack dont_print_obstack;
+
+
+/* Print data of type TYPE located at VALADDR (within GDB), which came from
+ the inferior at address ADDRESS, onto stdio stream STREAM according to
+ FORMAT (a letter or 0 for natural format). The data at VALADDR is in
+ target byte order.
+
+ If the data are a string pointer, returns the number of string characters
+ printed.
+
+ If DEREF_REF is nonzero, then dereference references, otherwise just print
+ them like pointers.
+
+ The PRETTY parameter controls prettyprinting. */
+
+int
+c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
+ pretty)
+ struct type *type;
+ char *valaddr;
+ CORE_ADDR address;
+ FILE *stream;
+ int format;
+ int deref_ref;
+ int recurse;
+ enum val_prettyprint pretty;
+{
+ register unsigned int i;
+ unsigned len;
+ struct type *elttype;
+ unsigned eltlen;
+ LONGEST val;
+ unsigned char c;
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_ARRAY:
+ if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
+ {
+ elttype = TYPE_TARGET_TYPE (type);
+ eltlen = TYPE_LENGTH (elttype);
+ len = TYPE_LENGTH (type) / eltlen;
+ if (prettyprint_arrays)
+ {
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ }
+ fprintf_filtered (stream, "{");
+ /* For an array of chars, print with string syntax. */
+ if (eltlen == 1 && TYPE_CODE (elttype) == TYPE_CODE_INT
+ && (format == 0 || format == 's') )
+ {
+ LA_PRINT_STRING (stream, valaddr, len, 0);
+ }
+ else
+ {
+ /* If this is a virtual function table, print the 0th
+ entry specially, and the rest of the members normally. */
+ if (cp_is_vtbl_ptr_type (elttype))
+ {
+ i = 1;
+ fprintf_filtered (stream, "%d vtable entries", len - 1);
+ }
+ else
+ {
+ i = 0;
+ }
+ val_print_array_elements (type, valaddr, address, stream,
+ format, deref_ref, recurse, pretty, i);
+ }
+ fprintf_filtered (stream, "}");
+ break;
+ }
+ /* Array of unspecified length: treat like pointer to first elt. */
+ valaddr = (char *) &address;
+
+ case TYPE_CODE_PTR:
+ if (format && format != 's')
+ {
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ break;
+ }
+ if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD)
+ {
+ struct type *domain = TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type));
+ struct fn_field *f;
+ int j, len2;
+ char *kind = "";
+ CORE_ADDR addr;
+
+ addr = unpack_pointer (lookup_pointer_type (builtin_type_void),
+ valaddr);
+ if (METHOD_PTR_IS_VIRTUAL(addr))
+ {
+ int offset = METHOD_PTR_TO_VOFFSET(addr);
+ len = TYPE_NFN_FIELDS (domain);
+ for (i = 0; i < len; i++)
+ {
+ f = TYPE_FN_FIELDLIST1 (domain, i);
+ len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
+
+ for (j = 0; j < len2; j++)
+ {
+ QUIT;
+ if (TYPE_FN_FIELD_VOFFSET (f, j) == offset)
+ {
+ kind = "virtual ";
+ goto common;
+ }
+ }
+ }
+ }
+ else
+ {
+ struct symbol *sym = find_pc_function (addr);
+ if (sym == 0)
+ {
+ error ("invalid pointer to member function");
+ }
+ len = TYPE_NFN_FIELDS (domain);
+ for (i = 0; i < len; i++)
+ {
+ f = TYPE_FN_FIELDLIST1 (domain, i);
+ len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
+
+ for (j = 0; j < len2; j++)
+ {
+ QUIT;
+ if (!strcmp (SYMBOL_NAME (sym),
+ TYPE_FN_FIELD_PHYSNAME (f, j)))
+ {
+ goto common;
+ }
+ }
+ }
+ }
+ common:
+ if (i < len)
+ {
+ fprintf_filtered (stream, "&");
+ c_type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0);
+ fprintf (stream, kind);
+ if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'
+ && TYPE_FN_FIELD_PHYSNAME (f, j)[1] == CPLUS_MARKER)
+ cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j) + 1, "~",
+ TYPE_FN_FIELDLIST_NAME (domain, i),
+ 0, stream);
+ else
+ cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j), "",
+ TYPE_FN_FIELDLIST_NAME (domain, i),
+ 0, stream);
+ break;
+ }
+ fprintf_filtered (stream, "(");
+ type_print (type, "", stream, -1);
+ fprintf_filtered (stream, ") %d", (int) addr >> 3);
+ }
+ else if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_MEMBER)
+ {
+ cp_print_class_member (valaddr,
+ TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)),
+ stream, "&");
+ }
+ else
+ {
+ CORE_ADDR addr = unpack_pointer (type, valaddr);
+ elttype = TYPE_TARGET_TYPE (type);
+
+ if (TYPE_CODE (elttype) == TYPE_CODE_FUNC)
+ {
+ /* Try to print what function it points to. */
+ print_address_demangle (addr, stream, demangle);
+ /* Return value is irrelevant except for string pointers. */
+ return (0);
+ }
+
+ if (addressprint && format != 's')
+ {
+ fprintf_filtered (stream, "0x%x", addr);
+ }
+
+ /* For a pointer to char or unsigned char, also print the string
+ pointed to, unless pointer is null. */
+ i = 0; /* Number of characters printed. */
+ if (TYPE_LENGTH (elttype) == 1 &&
+ TYPE_CODE (elttype) == TYPE_CODE_INT &&
+ (format == 0 || format == 's') &&
+ addr != 0 &&
+ /* If print_max is UINT_MAX, the alloca below will fail.
+ In that case don't try to print the string. */
+ print_max < UINT_MAX)
+ {
+ int first_addr_err = 0;
+ int errcode = 0;
+
+ /* Get first character. */
+ errcode = target_read_memory (addr, (char *)&c, 1);
+ if (errcode != 0)
+ {
+ /* First address out of bounds. */
+ first_addr_err = 1;
+ }
+ else
+ {
+ /* A real string. */
+ char *string = (char *) alloca (print_max);
+
+ /* If the loop ends by us hitting print_max characters,
+ we need to have elipses at the end. */
+ int force_ellipses = 1;
+
+ /* This loop always fetches print_max characters, even
+ though LA_PRINT_STRING might want to print more or fewer
+ (with repeated characters). This is so that
+ we don't spend forever fetching if we print
+ a long string consisting of the same character
+ repeated. Also so we can do it all in one memory
+ operation, which is faster. However, this will be
+ slower if print_max is set high, e.g. if you set
+ print_max to 1000, not only will it take a long
+ time to fetch short strings, but if you are near
+ the end of the address space, it might not work. */
+ QUIT;
+ errcode = target_read_memory (addr, string, print_max);
+ if (errcode != 0)
+ {
+ /* Try reading just one character. If that succeeds,
+ assume we hit the end of the address space, but
+ the initial part of the string is probably safe. */
+ char x[1];
+ errcode = target_read_memory (addr, x, 1);
+ }
+ if (errcode != 0)
+ force_ellipses = 0;
+ else
+ for (i = 0; i < print_max; i++)
+ if (string[i] == '\0')
+ {
+ force_ellipses = 0;
+ break;
+ }
+ QUIT;
+
+ if (addressprint)
+ {
+ fputs_filtered (" ", stream);
+ }
+ LA_PRINT_STRING (stream, string, i, force_ellipses);
+ }
+
+ if (errcode != 0)
+ {
+ if (errcode == EIO)
+ {
+ fprintf_filtered (stream,
+ (" <Address 0x%x out of bounds>" +
+ first_addr_err),
+ addr + i);
+ }
+ else
+ {
+ error ("Error reading memory address 0x%x: %s.",
+ addr + i, safe_strerror (errcode));
+ }
+ }
+
+ fflush (stream);
+ }
+ else if (cp_is_vtbl_member(type))
+ {
+ /* print vtbl's nicely */
+ CORE_ADDR vt_address = unpack_pointer (type, valaddr);
+
+ struct minimal_symbol *msymbol =
+ lookup_minimal_symbol_by_pc (vt_address);
+ if ((msymbol != NULL) && (vt_address == msymbol -> address))
+ {
+ fputs_filtered (" <", stream);
+ fputs_demangled (msymbol -> name, stream,
+ DMGL_ANSI | DMGL_PARAMS);
+ fputs_filtered (">", stream);
+ }
+ if (vtblprint)
+ {
+ value vt_val;
+
+ vt_val = value_at (TYPE_TARGET_TYPE (type), vt_address);
+ val_print (VALUE_TYPE (vt_val), VALUE_CONTENTS (vt_val),
+ VALUE_ADDRESS (vt_val), stream, format,
+ deref_ref, recurse + 1, pretty);
+ if (pretty)
+ {
+ fprintf_filtered (stream, "\n");
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ }
+ }
+ }
+
+ /* Return number of characters printed, plus one for the
+ terminating null if we have "reached the end". */
+ return (i + (print_max && i != print_max));
+ }
+ break;
+
+ case TYPE_CODE_MEMBER:
+ error ("not implemented: member type in c_val_print");
+ break;
+
+ case TYPE_CODE_REF:
+ if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_MEMBER)
+ {
+ cp_print_class_member (valaddr,
+ TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)),
+ stream, "");
+ break;
+ }
+ if (addressprint)
+ {
+ fprintf_filtered (stream, "@0x%lx",
+ unpack_long (builtin_type_int, valaddr));
+ if (deref_ref)
+ fputs_filtered (": ", stream);
+ }
+ /* De-reference the reference. */
+ if (deref_ref)
+ {
+ if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_UNDEF)
+ {
+ value deref_val =
+ value_at
+ (TYPE_TARGET_TYPE (type),
+ unpack_pointer (lookup_pointer_type (builtin_type_void),
+ valaddr));
+ val_print (VALUE_TYPE (deref_val),
+ VALUE_CONTENTS (deref_val),
+ VALUE_ADDRESS (deref_val), stream, format,
+ deref_ref, recurse + 1, pretty);
+ }
+ else
+ fputs_filtered ("???", stream);
+ }
+ break;
+
+ case TYPE_CODE_UNION:
+ if (recurse && !unionprint)
+ {
+ fprintf_filtered (stream, "{...}");
+ break;
+ }
+ /* Fall through. */
+ case TYPE_CODE_STRUCT:
+ if (vtblprint && cp_is_vtbl_ptr_type(type))
+ {
+ /* Print the unmangled name if desired. */
+ print_address_demangle(*((int *) (valaddr + /* FIXME bytesex */
+ TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8)),
+ stream, demangle);
+ break;
+ }
+ cp_print_value_fields (type, valaddr, stream, format, recurse, pretty,
+ 0);
+ break;
+
+ case TYPE_CODE_ENUM:
+ if (format)
+ {
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ break;
+ }
+ len = TYPE_NFIELDS (type);
+ val = unpack_long (builtin_type_int, valaddr);
+ for (i = 0; i < len; i++)
+ {
+ QUIT;
+ if (val == TYPE_FIELD_BITPOS (type, i))
+ {
+ break;
+ }
+ }
+ if (i < len)
+ {
+ fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
+ }
+ else
+ {
+#ifdef LONG_LONG
+ fprintf_filtered (stream, "%lld", val);
+#else
+ fprintf_filtered (stream, "%ld", val);
+#endif
+ }
+ break;
+
+ case TYPE_CODE_FUNC:
+ if (format)
+ {
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ break;
+ }
+ /* FIXME, we should consider, at least for ANSI C language, eliminating
+ the distinction made between FUNCs and POINTERs to FUNCs. */
+ fprintf_filtered (stream, "{");
+ type_print (type, "", stream, -1);
+ fprintf_filtered (stream, "} ");
+ /* Try to print what function it points to, and its address. */
+ print_address_demangle (address, stream, demangle);
+ break;
+
+ case TYPE_CODE_INT:
+ format = format ? format : output_format;
+ if (format)
+ {
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ }
+ else
+ {
+ val_print_type_code_int (type, valaddr, stream);
+ /* C and C++ has no single byte int type, char is used instead.
+ Since we don't know whether the value is really intended to
+ be used as an integer or a character, print the character
+ equivalent as well. */
+ if (TYPE_LENGTH (type) == 1)
+ {
+ fputs_filtered (" ", stream);
+ LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr),
+ stream);
+ }
+ }
+ break;
+
+ case TYPE_CODE_CHAR:
+ format = format ? format : output_format;
+ if (format)
+ {
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ }
+ else
+ {
+ fprintf_filtered (stream, TYPE_UNSIGNED (type) ? "%u" : "%d",
+ unpack_long (type, valaddr));
+ fputs_filtered (" ", stream);
+ LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr), stream);
+ }
+ break;
+
+ case TYPE_CODE_FLT:
+ if (format)
+ {
+ print_scalar_formatted (valaddr, type, format, 0, stream);
+ }
+ else
+ {
+ print_floating (valaddr, type, stream);
+ }
+ break;
+
+ case TYPE_CODE_VOID:
+ fprintf_filtered (stream, "void");
+ break;
+
+ case TYPE_CODE_ERROR:
+ fprintf_filtered (stream, "<error type>");
+ break;
+
+ case TYPE_CODE_RANGE:
+ /* FIXME, we should not ever have to print one of these yet. */
+ fprintf_filtered (stream, "<range type>");
+ break;
+
+ case TYPE_CODE_UNDEF:
+ /* This happens (without TYPE_FLAG_STUB set) on systems which don't use
+ dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar"
+ and no complete type for struct foo in that file. */
+ fprintf_filtered (stream, "<incomplete type>");
+ break;
+
+ default:
+ error ("Invalid C/C++ type code %d in symbol table.", TYPE_CODE (type));
+ }
+ fflush (stream);
+ return (0);
+}