- 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 (addr < 128) /* FIXME! What is this 128? */
- {
- 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) == addr)
- {
- 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, "&");
- 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)
- type_print_method_args
- (TYPE_FN_FIELD_ARGS (f, j) + 1, "~",
- TYPE_FN_FIELDLIST_NAME (domain, i), 0, stream);
- else
- 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)
- {
- 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 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);
- 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
- {
- if (errcode >= sys_nerr || errcode < 0)
- error ("Error reading memory address 0x%x: unknown error (%d).",
- addr + i, errcode);
- else
- error ("Error reading memory address 0x%x: %s.",
- addr + i, sys_errlist[errcode]);
- }
- }
-
- fflush (stream);
- }
- else /* print vtbl's nicely */
- if (is_vtbl_member(type))
- {
- 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, 1);
- 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 val_print");
- break;
-
- case TYPE_CODE_REF:
- if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_MEMBER)
- {
- 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 && 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;
- }
- val_print_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:
- if (format || output_format)
- {
- print_scalar_formatted (valaddr, type,
- format? format: output_format,
- 0, stream);
- break;
- }
- if (TYPE_LENGTH (type) > sizeof (LONGEST))
- {
- if (TYPE_UNSIGNED (type))
- {
- /* First figure out whether the number in fact has zeros
- in all its bytes more significant than least significant
- sizeof (LONGEST) ones. */
- char *p;
- /* Pointer to first (i.e. lowest address) nonzero character. */
- char *first_addr;
- len = TYPE_LENGTH (type);
-
-#if TARGET_BYTE_ORDER == BIG_ENDIAN
- for (p = valaddr;
- len > sizeof (LONGEST)
- && p < valaddr + TYPE_LENGTH (type);
- p++)
-#else /* Little endian. */
- first_addr = valaddr;
- for (p = valaddr + TYPE_LENGTH (type);
- len > sizeof (LONGEST) && p >= valaddr;
- p--)
-#endif /* Little endian. */
- {
- if (*p == 0)
- len--;
- else
- break;
- }
-#if TARGET_BYTE_ORDER == BIG_ENDIAN
- first_addr = p;
-#endif
-
- if (len <= sizeof (LONGEST))
- {
- /* We can print it in decimal. */
- fprintf_filtered
- (stream,
-#if defined (LONG_LONG)
- "%llu",
-#else
- "%lu",
-#endif
- unpack_long (BUILTIN_TYPE_LONGEST, first_addr));
- }
- else
- {
- /* It is big, so print it in hex. */
- print_hex_chars (stream, (unsigned char *)first_addr, len);
- }
- }
- else
- {
- /* Signed. One could assume two's complement (a reasonable
- assumption, I think) and do better than this. */
- print_hex_chars (stream, (unsigned char *)valaddr,
- TYPE_LENGTH (type));
- }
- break;
- }
-#ifdef PRINT_TYPELESS_INTEGER
- PRINT_TYPELESS_INTEGER (stream, type, unpack_long (type, valaddr));
-#else
-#ifndef LONG_LONG
- fprintf_filtered (stream,
- TYPE_UNSIGNED (type) ? "%u" : "%d",
- unpack_long (type, valaddr));
-#else
- fprintf_filtered (stream,
- TYPE_UNSIGNED (type) ? "%llu" : "%lld",
- unpack_long (type, valaddr));
-#endif
-#endif
-
- if (TYPE_LENGTH (type) == 1)
- {
- fprintf_filtered (stream, " '");
- printchar ((unsigned char) unpack_long (type, valaddr),
- stream, '\'');
- fprintf_filtered (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_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, "<unknown struct>");
- break;
-
- case TYPE_CODE_ERROR:
- fprintf_filtered (stream, "?");
- break;
-
- case TYPE_CODE_RANGE:
- /* FIXME, we should not ever have to print one of these yet. */
- fprintf_filtered (stream, "<range type>");
- break;
-
- default:
- error ("Invalid type code in symbol table.");
- }
- fflush (stream);
- return 0;
-}
-\f
-/* Print a description of a type in the format of a
- typedef for the current language.
- NEW is the new name for a type TYPE. */
-void
-typedef_print (type, new, stream)
- struct type *type;
- struct symbol *new;
- FILE *stream;
-{
- switch (current_language->la_language)
- {
-#ifdef _LANG_c
- case language_c:
- case language_cplus:
- fprintf_filtered(stream, "typedef ");
- type_print(type,"",stream,0);
- if(TYPE_NAME ((SYMBOL_TYPE (new))) == 0
- || 0 != strcmp (TYPE_NAME ((SYMBOL_TYPE (new))),
- SYMBOL_NAME (new)))
- fprintf_filtered(stream, " %s", SYMBOL_NAME(new));
- break;
-#endif
-#ifdef _LANG_m2
- case language_m2:
- fprintf_filtered(stream, "TYPE ");
- if(!TYPE_NAME(SYMBOL_TYPE(new)) ||
- strcmp (TYPE_NAME(SYMBOL_TYPE(new)),
- SYMBOL_NAME(new)))
- fprintf_filtered(stream, "%s = ", SYMBOL_NAME(new));
- else
- fprintf_filtered(stream, "<builtin> = ");
- type_print(type,"",stream,0);
- break;
-#endif
- default:
- error("Language not supported.");
- }
- fprintf_filtered(stream, ";\n");
-}
-
-
-/* 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 (type, varstring, stream, show)
- struct type *type;
- char *varstring;
- FILE *stream;
- int show;
-{
- type_print_1 (type, varstring, stream, show, 0);
-}
-
-/* LEVEL is the depth to indent lines by. */
-
-void
-type_print_1 (type, varstring, stream, show, level)
- struct type *type;
- char *varstring;
- FILE *stream;
- int show;
- int level;
-{
- register enum type_code code;
- type_print_base (type, stream, show, level);
- code = TYPE_CODE (type);
- if ((varstring && *varstring)
- ||
- /* 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)))
- fprintf_filtered (stream, " ");
- type_print_varspec_prefix (type, stream, show, 0);
- fputs_demangled (varstring, stream, -1); /* Print demangled name
- without arguments */
- type_print_varspec_suffix (type, stream, show, 0);