void go_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value *val, const struct value_print_options *options) { CHECK_TYPEDEF (type); switch (TYPE_CODE (type)) { case TYPE_CODE_STRUCT: { enum go_type go_type = go_classify_struct_type (type); switch (go_type) { case GO_TYPE_STRING: if (! options->raw) { print_go_string (type, valaddr, embedded_offset, address, stream, recurse, val, options); return; } break; default: break; } } /* Fall through. */ default: c_val_print (type, valaddr, embedded_offset, address, stream, recurse, val, options); break; } }
int c_textual_element_type (struct type *type, char format) { struct type *true_type, *iter_type; if (format != 0 && format != 's') return 0; /* We also rely on this for its side effect of setting up all the typedef pointers. */ true_type = check_typedef (type); /* TYPE_CODE_CHAR is always textual. */ if (TYPE_CODE (true_type) == TYPE_CODE_CHAR) return 1; /* Any other character-like types must be integral. */ if (TYPE_CODE (true_type) != TYPE_CODE_INT) return 0; /* We peel typedefs one by one, looking for a match. */ iter_type = type; while (iter_type) { /* Check the name of the type. */ if (TYPE_NAME (iter_type) && textual_name (TYPE_NAME (iter_type))) return 1; if (TYPE_CODE (iter_type) != TYPE_CODE_TYPEDEF) break; /* Peel a single typedef. If the typedef doesn't have a target type, we use check_typedef and hope the result is ok -- it might be for C++, where wchar_t is a built-in type. */ if (TYPE_TARGET_TYPE (iter_type)) iter_type = TYPE_TARGET_TYPE (iter_type); else iter_type = check_typedef (iter_type); } if (format == 's') { /* Print this as a string if we can manage it. For now, no wide character support. */ if (TYPE_CODE (true_type) == TYPE_CODE_INT && TYPE_LENGTH (true_type) == 1) return 1; } else { /* If a one-byte TYPE_CODE_INT is missing the not-a-character flag, then we treat it as text; otherwise, we assume it's being used as data. */ if (TYPE_CODE (true_type) == TYPE_CODE_INT && TYPE_LENGTH (true_type) == 1 && !TYPE_NOTTEXT (true_type)) return 1; } return 0; }
/* Return a virtual function as a value. ARG1 is the object which provides the virtual function table pointer. *ARG1P is side-effected in calling this function. F is the list of member functions which contains the desired virtual function. J is an index into F which provides the desired virtual function. TYPE is the type in which F is located. */ static struct value * gnuv2_virtual_fn_field (struct value **arg1p, struct fn_field * f, int j, struct type * type, int offset) { struct value *arg1 = *arg1p; struct type *type1 = check_typedef (value_type (arg1)); struct type *entry_type; /* First, get the virtual function table pointer. That comes with a strange type, so cast it to type `pointer to long' (which should serve just fine as a function type). Then, index into the table, and convert final value to appropriate function type. */ struct value *entry; struct value *vfn; struct value *vtbl; struct value *vi = value_from_longest (builtin_type_int, (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j)); struct type *fcontext = TYPE_FN_FIELD_FCONTEXT (f, j); struct type *context; if (fcontext == NULL) /* We don't have an fcontext (e.g. the program was compiled with g++ version 1). Try to get the vtbl from the TYPE_VPTR_BASETYPE. This won't work right for multiple inheritance, but at least we should do as well as GDB 3.x did. */ fcontext = TYPE_VPTR_BASETYPE (type); context = lookup_pointer_type (fcontext); /* Now context is a pointer to the basetype containing the vtbl. */ if (TYPE_TARGET_TYPE (context) != type1) { struct value *tmp = value_cast (context, value_addr (arg1)); arg1 = value_ind (tmp); type1 = check_typedef (value_type (arg1)); } context = type1; /* Now context is the basetype containing the vtbl. */ /* This type may have been defined before its virtual function table was. If so, fill in the virtual function table entry for the type now. */ if (TYPE_VPTR_FIELDNO (context) < 0) fill_in_vptr_fieldno (context); /* The virtual function table is now an array of structures which have the form { int16 offset, delta; void *pfn; }. */ vtbl = value_primitive_field (arg1, 0, TYPE_VPTR_FIELDNO (context), TYPE_VPTR_BASETYPE (context)); /* With older versions of g++, the vtbl field pointed to an array of structures. Nowadays it points directly to the structure. */ if (TYPE_CODE (value_type (vtbl)) == TYPE_CODE_PTR && TYPE_CODE (TYPE_TARGET_TYPE (value_type (vtbl))) == TYPE_CODE_ARRAY) { /* Handle the case where the vtbl field points to an array of structures. */ vtbl = value_ind (vtbl); /* Index into the virtual function table. This is hard-coded because looking up a field is not cheap, and it may be important to save time, e.g. if the user has set a conditional breakpoint calling a virtual function. */ entry = value_subscript (vtbl, vi); } else { /* Handle the case where the vtbl field points directly to a structure. */ vtbl = value_add (vtbl, vi); entry = value_ind (vtbl); } entry_type = check_typedef (value_type (entry)); if (TYPE_CODE (entry_type) == TYPE_CODE_STRUCT) { /* Move the `this' pointer according to the virtual function table. */ set_value_offset (arg1, value_offset (arg1) + value_as_long (value_field (entry, 0))); if (!value_lazy (arg1)) { set_value_lazy (arg1, 1); value_fetch_lazy (arg1); } vfn = value_field (entry, 2); } else if (TYPE_CODE (entry_type) == TYPE_CODE_PTR) vfn = entry; else error (_("I'm confused: virtual function table has bad type")); /* Reinstantiate the function pointer with the correct type. */ deprecated_set_value_type (vfn, lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j))); *arg1p = arg1; return vfn; }
void m2_print_type (struct type *type, char *varstring, struct ui_file *stream, int show, int level) { enum type_code code; int demangled_args; CHECK_TYPEDEF (type); code = TYPE_CODE (type); QUIT; wrap_here (" "); if (type == NULL) { fputs_filtered (_("<type unknown>"), stream); return; } switch (TYPE_CODE (type)) { case TYPE_CODE_SET: m2_short_set(type, stream, show, level); break; case TYPE_CODE_STRUCT: if (m2_long_set (type, stream, show, level)) break; m2_record_fields (type, stream, show, level); break; case TYPE_CODE_TYPEDEF: m2_typedef (type, stream, show, level); break; case TYPE_CODE_ARRAY: m2_array (type, stream, show, level); break; case TYPE_CODE_PTR: m2_pointer (type, stream, show, level); break; case TYPE_CODE_REF: m2_ref (type, stream, show, level); break; case TYPE_CODE_MEMBER: m2_unknown (_("member"), type, stream, show, level); break; case TYPE_CODE_METHOD: m2_unknown (_("method"), type, stream, show, level); break; case TYPE_CODE_FUNC: m2_procedure (type, stream, show, level); break; case TYPE_CODE_UNION: m2_union (type, stream); break; case TYPE_CODE_ENUM: m2_enum (type, stream, show, level); break; case TYPE_CODE_VOID: break; case TYPE_CODE_UNDEF: /* i18n: Do not translate the "struct" part! */ m2_unknown (_("undef"), type, stream, show, level); break; case TYPE_CODE_ERROR: m2_unknown (_("error"), type, stream, show, level); break; case TYPE_CODE_RANGE: m2_range (type, stream, show, level); break; case TYPE_CODE_TEMPLATE: break; default: m2_type_name (type, stream); break; } }
void c_type_print_base (struct type *type, struct ui_file *stream, int show, int level) { int i; int len, real_len; enum { s_none, s_public, s_private, s_protected } section_type; int need_access_label = 0; int j, len2; QUIT; wrap_here (" "); if (type == NULL) { fputs_filtered (_("<type unknown>"), 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 <= 0 && TYPE_NAME (type) != NULL) { c_type_print_modifier (type, stream, 0, 1); 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) == NULL); gdb_assert (TYPE_TARGET_TYPE (type) == NULL); fprintf_filtered (stream, _("<unnamed typedef>")); 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: case TYPE_CODE_UNION: 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 "); /* 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) { struct type *basetype; int vptr_fieldno; cp_type_print_derivation_info (stream, 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, _("<incomplete type>\n")); else fprintfi_filtered (level + 4, stream, _("<no data fields>\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) { 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; } } } 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)) { need_access_label = 1; 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_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; } } } /* 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) { 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"); } } } 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 = TYPE_NFN_FIELDS (type); real_len = 0; for (i = 0; i < len; i++) { struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i); int len2 = TYPE_FN_FIELDLIST_LENGTH (type, i); int j; for (j = 0; j < len2; j++) if (!TYPE_FN_FIELD_ARTIFICIAL (f, j)) real_len++; } if (real_len > 0 && section_type != s_none) fprintf_filtered (stream, "\n"); /* 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); 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++) { 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 = 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)) { if (section_type != s_protected) { section_type = s_protected; fprintfi_filtered (level + 2, stream, "protected:\n"); } } else if (TYPE_FN_FIELD_PRIVATE (f, j)) { 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"); } } 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)) == 0) { /* Keep GDB from crashing here. */ fprintf_filtered (stream, _("<undefined type> %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 = gdb_mangle_name (type, i, j); make_cleanup (xfree, tem); mangled_name = tem; } else mangled_name = TYPE_FN_FIELD_PHYSNAME (f, j); demangled_name = cplus_demangle (mangled_name, 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. */ if (!TYPE_FN_FIELD_STUB (f, j)) { 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); } else fprintf_filtered (stream, _("<badly mangled name '%s'>"), mangled_name); } else { char *p; char *demangled_no_class = remove_qualifiers (demangled_name); /* Get rid of the `static' appended by the demangler. */ p = strstr (demangled_no_class, " static"); if (p != NULL) { int length = p - demangled_no_class; 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); } 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) != 0) { 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); /* 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 "); 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 >= 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) != 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) { LONGEST lastval = 0; fprintf_filtered (stream, "{"); len = TYPE_NFIELDS (type); for (i = 0; i < len; i++) { QUIT; if (i) fprintf_filtered (stream, ", "); wrap_here (" "); fputs_filtered (TYPE_FIELD_NAME (type, i), stream); if (lastval != TYPE_FIELD_ENUMVAL (type, i)) { fprintf_filtered (stream, " = %s", plongest (TYPE_FIELD_ENUMVAL (type, i))); lastval = TYPE_FIELD_ENUMVAL (type, i); } lastval++; } fprintf_filtered (stream, "}"); } break; case TYPE_CODE_VOID: fprintf_filtered (stream, "void"); break; case TYPE_CODE_UNDEF: fprintf_filtered (stream, _("struct <unknown>")); 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, _("<range type>")); 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) != NULL) { c_type_print_modifier (type, stream, 0, 1); fputs_filtered (TYPE_NAME (type), stream); } else { /* At least for dump_symtab, it is important that this not be an error (). */ fprintf_filtered (stream, _("<invalid type code %d>"), TYPE_CODE (type)); } break; } }
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 char *name; if (type == 0) return; if (TYPE_NAME (type) && show <= 0) return; QUIT; switch (TYPE_CODE (type)) { case TYPE_CODE_PTR: c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, show, 1, 1); fprintf_filtered (stream, "*"); c_type_print_modifier (type, stream, 1, need_post_space); break; case TYPE_CODE_MEMBERPTR: c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, show, 0, 0); name = type_name_no_tag (TYPE_DOMAIN_TYPE (type)); if (name) fputs_filtered (name, stream); else c_type_print_base (TYPE_DOMAIN_TYPE (type), stream, -1, passed_a_ptr); fprintf_filtered (stream, "::*"); break; case TYPE_CODE_METHODPTR: c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, show, 0, 0); fprintf_filtered (stream, "("); name = type_name_no_tag (TYPE_DOMAIN_TYPE (type)); if (name) fputs_filtered (name, stream); else c_type_print_base (TYPE_DOMAIN_TYPE (type), stream, -1, passed_a_ptr); fprintf_filtered (stream, "::*"); break; case TYPE_CODE_REF: c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, show, 1, 0); fprintf_filtered (stream, "&"); 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, show, 0, 0); if (passed_a_ptr) fprintf_filtered (stream, "("); break; case TYPE_CODE_ARRAY: c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, show, 0, 0); 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); break; case TYPE_CODE_UNDEF: case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: case TYPE_CODE_ENUM: case TYPE_CODE_INT: case TYPE_CODE_FLT: case TYPE_CODE_VOID: case TYPE_CODE_ERROR: case TYPE_CODE_CHAR: case TYPE_CODE_BOOL: case TYPE_CODE_SET: case TYPE_CODE_RANGE: case TYPE_CODE_STRING: case TYPE_CODE_COMPLEX: 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()")); break; } }
static struct type * java_link_class_type (struct gdbarch *gdbarch, struct type *type, struct value *clas) { struct value *temp; const char *unqualified_name; const char *name = TYPE_TAG_NAME (type); int ninterfaces, nfields, nmethods; int type_is_object = 0; struct fn_field *fn_fields; struct fn_fieldlist *fn_fieldlists; struct value *fields; struct value *methods; struct value *method = NULL; struct value *field = NULL; int i, j; struct objfile *objfile = get_dynamics_objfile (gdbarch); struct type *tsuper; gdb_assert (name != NULL); unqualified_name = strrchr (name, '.'); if (unqualified_name == NULL) unqualified_name = name; temp = clas; temp = value_struct_elt (&temp, NULL, "superclass", NULL, "structure"); if (strcmp (name, "java.lang.Object") == 0) { tsuper = get_java_object_type (); if (tsuper && TYPE_CODE (tsuper) == TYPE_CODE_PTR) tsuper = TYPE_TARGET_TYPE (tsuper); type_is_object = 1; } else tsuper = type_from_class (gdbarch, temp); #if 1 ninterfaces = 0; #else temp = clas; ninterfaces = value_as_long (value_struct_elt (&temp, NULL, "interface_len", NULL, "structure")); #endif TYPE_N_BASECLASSES (type) = (tsuper == NULL ? 0 : 1) + ninterfaces; temp = clas; nfields = value_as_long (value_struct_elt (&temp, NULL, "field_count", NULL, "structure")); nfields += TYPE_N_BASECLASSES (type); nfields++; /* Add one for dummy "class" field. */ TYPE_NFIELDS (type) = nfields; TYPE_FIELDS (type) = (struct field *) TYPE_ALLOC (type, sizeof (struct field) * nfields); memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields); TYPE_FIELD_PRIVATE_BITS (type) = (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields)); B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields); TYPE_FIELD_PROTECTED_BITS (type) = (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields)); B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields); TYPE_FIELD_IGNORE_BITS (type) = (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields)); B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields); TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *) TYPE_ALLOC (type, B_BYTES (TYPE_N_BASECLASSES (type))); B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), TYPE_N_BASECLASSES (type)); if (tsuper != NULL) { TYPE_BASECLASS (type, 0) = tsuper; if (type_is_object) SET_TYPE_FIELD_PRIVATE (type, 0); } i = strlen (name); if (i > 2 && name[i - 1] == ']' && tsuper != NULL) { /* FIXME */ TYPE_LENGTH (type) = TYPE_LENGTH (tsuper) + 4; /* size with "length" */ } else { temp = clas; temp = value_struct_elt (&temp, NULL, "size_in_bytes", NULL, "structure"); TYPE_LENGTH (type) = value_as_long (temp); } fields = NULL; nfields--; /* First set up dummy "class" field. */ SET_FIELD_PHYSADDR (TYPE_FIELD (type, nfields), value_address (clas)); TYPE_FIELD_NAME (type, nfields) = "class"; TYPE_FIELD_TYPE (type, nfields) = value_type (clas); SET_TYPE_FIELD_PRIVATE (type, nfields); for (i = TYPE_N_BASECLASSES (type); i < nfields; i++) { int accflags; int boffset; if (fields == NULL) { temp = clas; fields = value_struct_elt (&temp, NULL, "fields", NULL, "structure"); field = value_ind (fields); } else { /* Re-use field value for next field. */ CORE_ADDR addr = value_address (field) + TYPE_LENGTH (value_type (field)); set_value_address (field, addr); set_value_lazy (field, 1); } temp = field; temp = value_struct_elt (&temp, NULL, "name", NULL, "structure"); TYPE_FIELD_NAME (type, i) = get_java_utf8_name (&objfile->objfile_obstack, temp); temp = field; accflags = value_as_long (value_struct_elt (&temp, NULL, "accflags", NULL, "structure")); temp = field; temp = value_struct_elt (&temp, NULL, "info", NULL, "structure"); boffset = value_as_long (value_struct_elt (&temp, NULL, "boffset", NULL, "structure")); if (accflags & 0x0001) /* public access */ { /* ??? */ } if (accflags & 0x0002) /* private access */ { SET_TYPE_FIELD_PRIVATE (type, i); } if (accflags & 0x0004) /* protected access */ { SET_TYPE_FIELD_PROTECTED (type, i); } if (accflags & 0x0008) /* ACC_STATIC */ SET_FIELD_PHYSADDR (TYPE_FIELD (type, i), boffset); else SET_FIELD_BITPOS (TYPE_FIELD (type, i), 8 * boffset); if (accflags & 0x8000) /* FIELD_UNRESOLVED_FLAG */ { TYPE_FIELD_TYPE (type, i) = get_java_object_type (); /* FIXME */ } else { struct type *ftype; temp = field; temp = value_struct_elt (&temp, NULL, "type", NULL, "structure"); ftype = type_from_class (gdbarch, temp); if (TYPE_CODE (ftype) == TYPE_CODE_STRUCT) ftype = lookup_pointer_type (ftype); TYPE_FIELD_TYPE (type, i) = ftype; } } temp = clas; nmethods = value_as_long (value_struct_elt (&temp, NULL, "method_count", NULL, "structure")); j = nmethods * sizeof (struct fn_field); fn_fields = (struct fn_field *) obstack_alloc (&objfile->objfile_obstack, j); memset (fn_fields, 0, j); fn_fieldlists = (struct fn_fieldlist *) alloca (nmethods * sizeof (struct fn_fieldlist)); methods = NULL; for (i = 0; i < nmethods; i++) { const char *mname; int k; if (methods == NULL) { temp = clas; methods = value_struct_elt (&temp, NULL, "methods", NULL, "structure"); method = value_ind (methods); } else { /* Re-use method value for next method. */ CORE_ADDR addr = value_address (method) + TYPE_LENGTH (value_type (method)); set_value_address (method, addr); set_value_lazy (method, 1); } /* Get method name. */ temp = method; temp = value_struct_elt (&temp, NULL, "name", NULL, "structure"); mname = get_java_utf8_name (&objfile->objfile_obstack, temp); if (strcmp (mname, "<init>") == 0) mname = unqualified_name; /* Check for an existing method with the same name. * This makes building the fn_fieldslists an O(nmethods**2) * operation. That could be using hashing, but I doubt it * is worth it. Note that we do maintain the order of methods * in the inferior's Method table (as long as that is grouped * by method name), which I think is desirable. --PB */ for (k = 0, j = TYPE_NFN_FIELDS (type);;) { if (--j < 0) { /* No match - new method name. */ j = TYPE_NFN_FIELDS (type)++; fn_fieldlists[j].name = mname; fn_fieldlists[j].length = 1; fn_fieldlists[j].fn_fields = &fn_fields[i]; k = i; break; } if (strcmp (mname, fn_fieldlists[j].name) == 0) { /* Found an existing method with the same name. */ int l; if (mname != unqualified_name) obstack_free (&objfile->objfile_obstack, mname); mname = fn_fieldlists[j].name; fn_fieldlists[j].length++; k = i - k; /* Index of new slot. */ /* Shift intervening fn_fields (between k and i) down. */ for (l = i; l > k; l--) fn_fields[l] = fn_fields[l - 1]; for (l = TYPE_NFN_FIELDS (type); --l > j;) fn_fieldlists[l].fn_fields++; break; } k += fn_fieldlists[j].length; } fn_fields[k].physname = ""; fn_fields[k].is_stub = 1; /* FIXME */ fn_fields[k].type = lookup_function_type (builtin_java_type (gdbarch)->builtin_void); TYPE_CODE (fn_fields[k].type) = TYPE_CODE_METHOD; } j = TYPE_NFN_FIELDS (type) * sizeof (struct fn_fieldlist); TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *) obstack_alloc (&objfile->objfile_obstack, j); memcpy (TYPE_FN_FIELDLISTS (type), fn_fieldlists, j); return type; }
static CORE_ADDR rs6000_lynx178_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int ii; int len = 0; int argno; /* current argument number */ int argbytes; /* current argument byte */ gdb_byte tmp_buffer[50]; int f_argno = 0; /* current floating point argno */ int wordsize = gdbarch_tdep (gdbarch)->wordsize; CORE_ADDR func_addr = find_function_addr (function, NULL); struct value *arg = 0; struct type *type; ULONGEST saved_sp; /* The calling convention this function implements assumes the processor has floating-point registers. We shouldn't be using it on PPC variants that lack them. */ gdb_assert (ppc_floating_point_unit_p (gdbarch)); /* The first eight words of ther arguments are passed in registers. Copy them appropriately. */ ii = 0; /* If the function is returning a `struct', then the first word (which will be passed in r3) is used for struct return address. In that case we should advance one word and start from r4 register to copy parameters. */ if (struct_return) { regcache_raw_write_unsigned (regcache, tdep->ppc_gp0_regnum + 3, struct_addr); ii++; } /* Effectively indirect call... gcc does... return_val example( float, int); eabi: float in fp0, int in r3 offset of stack on overflow 8/16 for varargs, must go by type. power open: float in r3&r4, int in r5 offset of stack on overflow different both: return in r3 or f0. If no float, must study how gcc emulates floats; pay attention to arg promotion. User may have to cast\args to handle promotion correctly since gdb won't know if prototype supplied or not. */ for (argno = 0, argbytes = 0; argno < nargs && ii < 8; ++ii) { int reg_size = register_size (gdbarch, ii + 3); arg = args[argno]; type = check_typedef (value_type (arg)); len = TYPE_LENGTH (type); if (TYPE_CODE (type) == TYPE_CODE_FLT) { /* Floating point arguments are passed in fpr's, as well as gpr's. There are 13 fpr's reserved for passing parameters. At this point there is no way we would run out of them. Always store the floating point value using the register's floating-point format. */ const int fp_regnum = tdep->ppc_fp0_regnum + 1 + f_argno; gdb_byte reg_val[MAX_REGISTER_SIZE]; struct type *reg_type = register_type (gdbarch, fp_regnum); gdb_assert (len <= 8); convert_typed_floating (value_contents (arg), type, reg_val, reg_type); regcache_cooked_write (regcache, fp_regnum, reg_val); ++f_argno; } if (len > reg_size) { /* Argument takes more than one register. */ while (argbytes < len) { gdb_byte word[MAX_REGISTER_SIZE]; memset (word, 0, reg_size); memcpy (word, ((char *) value_contents (arg)) + argbytes, (len - argbytes) > reg_size ? reg_size : len - argbytes); regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3 + ii, word); ++ii, argbytes += reg_size; if (ii >= 8) goto ran_out_of_registers_for_arguments; } argbytes = 0; --ii; } else { /* Argument can fit in one register. No problem. */ int adj = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? reg_size - len : 0; gdb_byte word[MAX_REGISTER_SIZE]; memset (word, 0, reg_size); memcpy (word, value_contents (arg), len); regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3 +ii, word); } ++argno; } ran_out_of_registers_for_arguments: regcache_cooked_read_unsigned (regcache, gdbarch_sp_regnum (gdbarch), &saved_sp); /* Location for 8 parameters are always reserved. */ sp -= wordsize * 8; /* Another six words for back chain, TOC register, link register, etc. */ sp -= wordsize * 6; /* Stack pointer must be quadword aligned. */ sp = align_down (sp, 16); /* If there are more arguments, allocate space for them in the stack, then push them starting from the ninth one. */ if ((argno < nargs) || argbytes) { int space = 0, jj; if (argbytes) { space += align_up (len - argbytes, 4); jj = argno + 1; } else jj = argno; for (; jj < nargs; ++jj) { struct value *val = args[jj]; space += align_up (TYPE_LENGTH (value_type (val)), 4); } /* Add location required for the rest of the parameters. */ space = align_up (space, 16); sp -= space; /* This is another instance we need to be concerned about securing our stack space. If we write anything underneath %sp (r1), we might conflict with the kernel who thinks he is free to use this area. So, update %sp first before doing anything else. */ regcache_raw_write_signed (regcache, gdbarch_sp_regnum (gdbarch), sp); /* If the last argument copied into the registers didn't fit there completely, push the rest of it into stack. */ if (argbytes) { write_memory (sp + 24 + (ii * 4), value_contents (arg) + argbytes, len - argbytes); ++argno; ii += align_up (len - argbytes, 4) / 4; } /* Push the rest of the arguments into stack. */ for (; argno < nargs; ++argno) { arg = args[argno]; type = check_typedef (value_type (arg)); len = TYPE_LENGTH (type); /* Float types should be passed in fpr's, as well as in the stack. */ if (TYPE_CODE (type) == TYPE_CODE_FLT && f_argno < 13) { gdb_assert (len <= 8); regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1 + f_argno, value_contents (arg)); ++f_argno; } write_memory (sp + 24 + (ii * 4), value_contents (arg), len); ii += align_up (len, 4) / 4; } } /* Set the stack pointer. According to the ABI, the SP is meant to be set _before_ the corresponding stack space is used. On AIX, this even applies when the target has been completely stopped! Not doing this can lead to conflicts with the kernel which thinks that it still has control over this not-yet-allocated stack region. */ regcache_raw_write_signed (regcache, gdbarch_sp_regnum (gdbarch), sp); /* Set back chain properly. */ store_unsigned_integer (tmp_buffer, wordsize, byte_order, saved_sp); write_memory (sp, tmp_buffer, wordsize); /* Point the inferior function call's return address at the dummy's breakpoint. */ regcache_raw_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr); target_store_registers (regcache, -1); return sp; }
void c_type_print_varspec_suffix (struct type *type, struct ui_file *stream, int show, int passed_a_ptr, int demangled_args) { if (type == 0) return; if (TYPE_NAME (type) && show <= 0) return; QUIT; switch (TYPE_CODE (type)) { case TYPE_CODE_ARRAY: if (passed_a_ptr) fprintf_filtered (stream, ")"); 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, "]"); c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, 0, 0); break; case TYPE_CODE_MEMBER: if (passed_a_ptr) fprintf_filtered (stream, ")"); c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, 0, 0); break; case TYPE_CODE_METHOD: if (passed_a_ptr) fprintf_filtered (stream, ")"); c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, 0, 0); if (passed_a_ptr) { c_type_print_args (type, stream); } break; case TYPE_CODE_PTR: case TYPE_CODE_REF: c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, 1, 0); break; 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 && (TYPE_PROTOTYPED (type) /* APPLE LOCAL begin Objective-C++ */ || current_language->la_language == language_cplus || current_language->la_language == language_objcplus)) /* APPLE LOCAL end Objective-C++ */ { 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, show, passed_a_ptr, 0); break; case TYPE_CODE_TYPEDEF: c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, passed_a_ptr, 0); break; case TYPE_CODE_UNDEF: case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: case TYPE_CODE_ENUM: case TYPE_CODE_INT: case TYPE_CODE_FLT: case TYPE_CODE_VOID: case TYPE_CODE_ERROR: case TYPE_CODE_CHAR: case TYPE_CODE_BOOL: case TYPE_CODE_SET: case TYPE_CODE_RANGE: case TYPE_CODE_STRING: case TYPE_CODE_BITSTRING: case TYPE_CODE_COMPLEX: case TYPE_CODE_TEMPLATE: case TYPE_CODE_NAMESPACE: /* These types do not need a suffix. They are listed so that gcc -Wall will report types that may not have been considered. */ break; default: error (_("type not handled in c_type_print_varspec_suffix()")); break; } }
int java_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value_print_options *options) { struct gdbarch *gdbarch = get_type_arch (type); unsigned int i = 0; /* Number of characters printed */ struct type *target_type; CORE_ADDR addr; CHECK_TYPEDEF (type); switch (TYPE_CODE (type)) { case TYPE_CODE_PTR: if (options->format && options->format != 's') { print_scalar_formatted (valaddr, type, options, 0, stream); break; } #if 0 if (options->vtblprint && cp_is_vtbl_ptr_type (type)) { /* Print the unmangled name if desired. */ /* Print vtable entry - we only get here if we ARE using -fvtable_thunks. (Otherwise, look under TYPE_CODE_STRUCT.) */ /* Extract an address, assume that it is unsigned. */ print_address_demangle (gdbarch, extract_unsigned_integer (valaddr, TYPE_LENGTH (type)), stream, demangle); break; } #endif addr = unpack_pointer (type, valaddr); if (addr == 0) { fputs_filtered ("null", stream); return i; } target_type = check_typedef (TYPE_TARGET_TYPE (type)); if (TYPE_CODE (target_type) == TYPE_CODE_FUNC) { /* Try to print what function it points to. */ print_address_demangle (gdbarch, addr, stream, demangle); /* Return value is irrelevant except for string pointers. */ return (0); } if (options->addressprint && options->format != 's') { fputs_filtered ("@", stream); print_longest (stream, 'x', 0, (ULONGEST) addr); } return i; case TYPE_CODE_CHAR: case TYPE_CODE_INT: /* Can't just call c_val_print because that prints bytes as C chars. */ if (options->format || options->output_format) { struct value_print_options opts = *options; opts.format = (options->format ? options->format : options->output_format); print_scalar_formatted (valaddr, type, &opts, 0, stream); } else if (TYPE_CODE (type) == TYPE_CODE_CHAR || (TYPE_CODE (type) == TYPE_CODE_INT && TYPE_LENGTH (type) == 2 && strcmp (TYPE_NAME (type), "char") == 0)) LA_PRINT_CHAR ((int) unpack_long (type, valaddr), type, stream); else val_print_type_code_int (type, valaddr, stream); break; case TYPE_CODE_STRUCT: java_print_value_fields (type, valaddr, address, stream, recurse, options); break; default: return c_val_print (type, valaddr, embedded_offset, address, stream, recurse, options); } return 0; }
int java_value_print (struct value *val, struct ui_file *stream, const struct value_print_options *options) { struct gdbarch *gdbarch = get_type_arch (value_type (val)); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct type *type; CORE_ADDR address; int i; char *name; struct value_print_options opts; type = value_type (val); address = value_address (val); if (is_object_type (type)) { CORE_ADDR obj_addr; /* Get the run-time type, and cast the object into that */ obj_addr = unpack_pointer (type, value_contents (val)); if (obj_addr != 0) { type = type_from_class (gdbarch, java_class_from_object (val)); type = lookup_pointer_type (type); val = value_at (type, address); } } if (TYPE_CODE (type) == TYPE_CODE_PTR && !value_logical_not (val)) type_print (TYPE_TARGET_TYPE (type), "", stream, -1); name = TYPE_TAG_NAME (type); if (TYPE_CODE (type) == TYPE_CODE_STRUCT && name != NULL && (i = strlen (name), name[i - 1] == ']')) { gdb_byte buf4[4]; long length; unsigned int things_printed = 0; int reps; struct type *el_type = java_primitive_type_from_name (gdbarch, name, i - 2); i = 0; read_memory (address + get_java_object_header_size (gdbarch), buf4, 4); length = (long) extract_signed_integer (buf4, 4, byte_order); fprintf_filtered (stream, "{length: %ld", length); if (el_type == NULL) { CORE_ADDR element; CORE_ADDR next_element = -1; /* dummy initial value */ /* Skip object header and length. */ address += get_java_object_header_size (gdbarch) + 4; while (i < length && things_printed < options->print_max) { gdb_byte *buf; buf = alloca (gdbarch_ptr_bit (gdbarch) / HOST_CHAR_BIT); fputs_filtered (", ", stream); wrap_here (n_spaces (2)); if (i > 0) element = next_element; else { read_memory (address, buf, sizeof (buf)); address += gdbarch_ptr_bit (gdbarch) / HOST_CHAR_BIT; /* FIXME: cagney/2003-05-24: Bogus or what. It pulls a host sized pointer out of the target and then extracts that as an address (while assuming that the address is unsigned)! */ element = extract_unsigned_integer (buf, sizeof (buf), byte_order); } for (reps = 1; i + reps < length; reps++) { read_memory (address, buf, sizeof (buf)); address += gdbarch_ptr_bit (gdbarch) / HOST_CHAR_BIT; /* FIXME: cagney/2003-05-24: Bogus or what. It pulls a host sized pointer out of the target and then extracts that as an address (while assuming that the address is unsigned)! */ next_element = extract_unsigned_integer (buf, sizeof (buf), byte_order); if (next_element != element) break; } if (reps == 1) fprintf_filtered (stream, "%d: ", i); else fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1); if (element == 0) fprintf_filtered (stream, "null"); else fprintf_filtered (stream, "@%s", paddress (gdbarch, element)); things_printed++; i += reps; } } else { struct value *v = allocate_value (el_type); struct value *next_v = allocate_value (el_type); set_value_address (v, (address + get_java_object_header_size (gdbarch) + 4)); set_value_address (next_v, value_raw_address (v)); while (i < length && things_printed < options->print_max) { fputs_filtered (", ", stream); wrap_here (n_spaces (2)); if (i > 0) { struct value *tmp; tmp = next_v; next_v = v; v = tmp; } else { set_value_lazy (v, 1); set_value_offset (v, 0); } set_value_offset (next_v, value_offset (v)); for (reps = 1; i + reps < length; reps++) { set_value_lazy (next_v, 1); set_value_offset (next_v, value_offset (next_v) + TYPE_LENGTH (el_type)); if (memcmp (value_contents (v), value_contents (next_v), TYPE_LENGTH (el_type)) != 0) break; } if (reps == 1) fprintf_filtered (stream, "%d: ", i); else fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1); opts = *options; opts.deref_ref = 1; common_val_print (v, stream, 1, &opts, current_language); things_printed++; i += reps; } } if (i < length) fprintf_filtered (stream, "..."); fprintf_filtered (stream, "}"); return 0; } /* If it's type String, print it */ if (TYPE_CODE (type) == TYPE_CODE_PTR && TYPE_TARGET_TYPE (type) && TYPE_TAG_NAME (TYPE_TARGET_TYPE (type)) && strcmp (TYPE_TAG_NAME (TYPE_TARGET_TYPE (type)), "java.lang.String") == 0 && (options->format == 0 || options->format == 's') && address != 0 && value_as_address (val) != 0) { struct type *char_type; struct value *data_val; CORE_ADDR data; struct value *boffset_val; unsigned long boffset; struct value *count_val; unsigned long count; struct value *mark; mark = value_mark (); /* Remember start of new values */ data_val = value_struct_elt (&val, NULL, "data", NULL, NULL); data = value_as_address (data_val); boffset_val = value_struct_elt (&val, NULL, "boffset", NULL, NULL); boffset = value_as_address (boffset_val); count_val = value_struct_elt (&val, NULL, "count", NULL, NULL); count = value_as_address (count_val); value_free_to_mark (mark); /* Release unnecessary values */ char_type = builtin_java_type (gdbarch)->builtin_char; val_print_string (char_type, data + boffset, count, stream, options); return 0; } opts = *options; opts.deref_ref = 1; return common_val_print (val, stream, 0, &opts, current_language); }
static void java_print_value_fields (struct type *type, const gdb_byte *valaddr, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value_print_options *options) { int i, len, n_baseclasses; CHECK_TYPEDEF (type); fprintf_filtered (stream, "{"); len = TYPE_NFIELDS (type); n_baseclasses = TYPE_N_BASECLASSES (type); if (n_baseclasses > 0) { int i, n_baseclasses = TYPE_N_BASECLASSES (type); for (i = 0; i < n_baseclasses; i++) { int boffset; struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i)); char *basename = TYPE_NAME (baseclass); const gdb_byte *base_valaddr; if (BASETYPE_VIA_VIRTUAL (type, i)) continue; if (basename != NULL && strcmp (basename, "java.lang.Object") == 0) continue; boffset = 0; if (options->pretty) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 * (recurse + 1), stream); } fputs_filtered ("<", stream); /* Not sure what the best notation is in the case where there is no baseclass name. */ fputs_filtered (basename ? basename : "", stream); fputs_filtered ("> = ", stream); base_valaddr = valaddr; java_print_value_fields (baseclass, base_valaddr, address + boffset, stream, recurse + 1, options); fputs_filtered (", ", stream); } } if (!len && n_baseclasses == 1) fprintf_filtered (stream, "<No data fields>"); else { int fields_seen = 0; for (i = n_baseclasses; i < len; i++) { /* If requested, skip printing of static fields. */ if (field_is_static (&TYPE_FIELD (type, i))) { char *name = TYPE_FIELD_NAME (type, i); if (!options->static_field_print) continue; if (name != NULL && strcmp (name, "class") == 0) continue; } if (fields_seen) fprintf_filtered (stream, ", "); else if (n_baseclasses > 0) { if (options->pretty) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 + 2 * recurse, stream); fputs_filtered ("members of ", stream); fputs_filtered (type_name_no_tag (type), stream); fputs_filtered (": ", stream); } } fields_seen = 1; if (options->pretty) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 + 2 * recurse, stream); } else { wrap_here (n_spaces (2 + 2 * recurse)); } if (options->inspect_it) { if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR) fputs_filtered ("\"( ptr \"", stream); else fputs_filtered ("\"( nodef \"", stream); if (field_is_static (&TYPE_FIELD (type, i))) fputs_filtered ("static ", stream); fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), language_cplus, DMGL_PARAMS | DMGL_ANSI); fputs_filtered ("\" \"", stream); fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), language_cplus, DMGL_PARAMS | DMGL_ANSI); fputs_filtered ("\") \"", stream); } else { annotate_field_begin (TYPE_FIELD_TYPE (type, i)); if (field_is_static (&TYPE_FIELD (type, i))) fputs_filtered ("static ", stream); fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), language_cplus, DMGL_PARAMS | DMGL_ANSI); annotate_field_name_end (); fputs_filtered (": ", stream); annotate_field_value (); } if (!field_is_static (&TYPE_FIELD (type, i)) && TYPE_FIELD_PACKED (type, i)) { struct value *v; /* Bitfields require special handling, especially due to byte order problems. */ if (TYPE_FIELD_IGNORE (type, i)) { fputs_filtered ("<optimized out or zero length>", stream); } else { struct value_print_options opts; v = value_from_longest (TYPE_FIELD_TYPE (type, i), unpack_field_as_long (type, valaddr, i)); opts = *options; opts.deref_ref = 0; common_val_print (v, stream, recurse + 1, &opts, current_language); } } else { if (TYPE_FIELD_IGNORE (type, i)) { fputs_filtered ("<optimized out or zero length>", stream); } else if (field_is_static (&TYPE_FIELD (type, i))) { struct value *v = value_static_field (type, i); if (v == NULL) fputs_filtered ("<optimized out>", stream); else { struct value_print_options opts; struct type *t = check_typedef (value_type (v)); if (TYPE_CODE (t) == TYPE_CODE_STRUCT) v = value_addr (v); opts = *options; opts.deref_ref = 0; common_val_print (v, stream, recurse + 1, &opts, current_language); } } else if (TYPE_FIELD_TYPE (type, i) == NULL) fputs_filtered ("<unknown type>", stream); else { struct value_print_options opts = *options; opts.deref_ref = 0; val_print (TYPE_FIELD_TYPE (type, i), valaddr + TYPE_FIELD_BITPOS (type, i) / 8, 0, address + TYPE_FIELD_BITPOS (type, i) / 8, stream, recurse + 1, &opts, current_language); } } annotate_field_end (); } if (options->pretty) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 * recurse, stream); } } fprintf_filtered (stream, "}"); }
static CORE_ADDR arm_linux_push_arguments (int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) { char *fp; int argnum, argreg, nstack_size; /* Walk through the list of args and determine how large a temporary stack is required. Need to take care here as structs may be passed on the stack, and we have to to push them. */ nstack_size = -4 * REGISTER_SIZE; /* Some arguments go into A1-A4. */ if (struct_return) /* The struct address goes in A1. */ nstack_size += REGISTER_SIZE; /* Walk through the arguments and add their size to nstack_size. */ for (argnum = 0; argnum < nargs; argnum++) { int len; struct type *arg_type; arg_type = check_typedef (VALUE_TYPE (args[argnum])); len = TYPE_LENGTH (arg_type); /* ANSI C code passes float arguments as integers, K&R code passes float arguments as doubles. Correct for this here. */ if (TYPE_CODE_FLT == TYPE_CODE (arg_type) && REGISTER_SIZE == len) nstack_size += FP_REGISTER_VIRTUAL_SIZE; else nstack_size += len; } /* Allocate room on the stack, and initialize our stack frame pointer. */ fp = NULL; if (nstack_size > 0) { sp -= nstack_size; fp = (char *) sp; } /* Initialize the integer argument register pointer. */ argreg = ARM_A1_REGNUM; /* The struct_return pointer occupies the first parameter passing register. */ if (struct_return) write_register (argreg++, struct_addr); /* Process arguments from left to right. Store as many as allowed in the parameter passing registers (A1-A4), and save the rest on the temporary stack. */ for (argnum = 0; argnum < nargs; argnum++) { int len; char *val; CORE_ADDR regval; enum type_code typecode; struct type *arg_type, *target_type; arg_type = check_typedef (VALUE_TYPE (args[argnum])); target_type = TYPE_TARGET_TYPE (arg_type); len = TYPE_LENGTH (arg_type); typecode = TYPE_CODE (arg_type); val = (char *) VALUE_CONTENTS (args[argnum]); /* ANSI C code passes float arguments as integers, K&R code passes float arguments as doubles. The .stabs record for for ANSI prototype floating point arguments records the type as FP_INTEGER, while a K&R style (no prototype) .stabs records the type as FP_FLOAT. In this latter case the compiler converts the float arguments to double before calling the function. */ if (TYPE_CODE_FLT == typecode && REGISTER_SIZE == len) { DOUBLEST dblval; dblval = extract_floating (val, len); len = TARGET_DOUBLE_BIT / TARGET_CHAR_BIT; val = alloca (len); store_floating (val, len, dblval); } /* If the argument is a pointer to a function, and it is a Thumb function, set the low bit of the pointer. */ if (TYPE_CODE_PTR == typecode && NULL != target_type && TYPE_CODE_FUNC == TYPE_CODE (target_type)) { CORE_ADDR regval = extract_address (val, len); if (arm_pc_is_thumb (regval)) store_address (val, len, MAKE_THUMB_ADDR (regval)); } /* Copy the argument to general registers or the stack in register-sized pieces. Large arguments are split between registers and stack. */ while (len > 0) { int partial_len = len < REGISTER_SIZE ? len : REGISTER_SIZE; if (argreg <= ARM_LAST_ARG_REGNUM) { /* It's an argument being passed in a general register. */ regval = extract_address (val, partial_len); write_register (argreg++, regval); } else { /* Push the arguments onto the stack. */ write_memory ((CORE_ADDR) fp, val, REGISTER_SIZE); fp += REGISTER_SIZE; } len -= partial_len; val += partial_len; } } /* Return adjusted stack pointer. */ return sp; }
static CORE_ADDR mn10300_push_dummy_call (struct gdbarch *gdbarch, struct value *target_func, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) { const int push_size = register_size (gdbarch, E_PC_REGNUM); int regs_used; int len, arg_len; int stack_offset = 0; int argnum; char *val, valbuf[MAX_REGISTER_SIZE]; /* This should be a nop, but align the stack just in case something went wrong. Stacks are four byte aligned on the mn10300. */ sp &= ~3; /* Now make space on the stack for the args. XXX This doesn't appear to handle pass-by-invisible reference arguments. */ regs_used = struct_return ? 1 : 0; for (len = 0, argnum = 0; argnum < nargs; argnum++) { arg_len = (TYPE_LENGTH (value_type (args[argnum])) + 3) & ~3; while (regs_used < 2 && arg_len > 0) { regs_used++; arg_len -= push_size; } len += arg_len; } /* Allocate stack space. */ sp -= len; if (struct_return) { regs_used = 1; write_register (E_D0_REGNUM, struct_addr); } else regs_used = 0; /* Push all arguments onto the stack. */ for (argnum = 0; argnum < nargs; argnum++) { /* FIXME what about structs? Unions? */ if (TYPE_CODE (value_type (*args)) == TYPE_CODE_STRUCT && TYPE_LENGTH (value_type (*args)) > 8) { /* Change to pointer-to-type. */ arg_len = push_size; store_unsigned_integer (valbuf, push_size, VALUE_ADDRESS (*args)); val = &valbuf[0]; } else { arg_len = TYPE_LENGTH (value_type (*args)); val = (char *) value_contents (*args); } while (regs_used < 2 && arg_len > 0) { write_register (regs_used, extract_unsigned_integer (val, push_size)); val += push_size; arg_len -= push_size; regs_used++; } while (arg_len > 0) { write_memory (sp + stack_offset, val, push_size); arg_len -= push_size; val += push_size; stack_offset += push_size; } args++; } /* Make space for the flushback area. */ sp -= 8; /* Push the return address that contains the magic breakpoint. */ sp -= 4; write_memory_unsigned_integer (sp, push_size, bp_addr); /* Update $sp. */ regcache_cooked_write_unsigned (regcache, E_SP_REGNUM, sp); return sp; }
int f_val_print (struct type *type, char *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int format, int deref_ref, int recurse, enum val_prettyprint pretty) { unsigned int i = 0; /* Number of characters printed */ struct type *elttype; LONGEST val; CORE_ADDR addr; CHECK_TYPEDEF (type); switch (TYPE_CODE (type)) { case TYPE_CODE_STRING: f77_get_dynamic_length_of_aggregate (type); LA_PRINT_STRING (stream, valaddr, TYPE_LENGTH (type), 1, 0); break; case TYPE_CODE_ARRAY: fprintf_filtered (stream, "("); f77_print_array (type, valaddr, address, stream, format, deref_ref, recurse, pretty); fprintf_filtered (stream, ")"); break; case TYPE_CODE_PTR: if (format && format != 's') { print_scalar_formatted (valaddr, type, format, 0, stream); break; } else { addr = unpack_pointer (type, valaddr); elttype = check_typedef (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') print_address_numeric (addr, 1, stream); /* For a pointer to char or unsigned char, also print the string pointed to, unless pointer is null. */ if (TYPE_LENGTH (elttype) == 1 && TYPE_CODE (elttype) == TYPE_CODE_INT && (format == 0 || format == 's') && addr != 0) i = val_print_string (addr, -1, TYPE_LENGTH (elttype), stream); /* Return number of characters printed, including the terminating '\0' if we reached the end. val_print_string takes care including the terminating '\0' if necessary. */ return i; } break; case TYPE_CODE_REF: elttype = check_typedef (TYPE_TARGET_TYPE (type)); if (addressprint) { CORE_ADDR addr = extract_typed_address (valaddr + embedded_offset, type); fprintf_filtered (stream, "@"); print_address_numeric (addr, 1, stream); if (deref_ref) fputs_filtered (": ", stream); } /* De-reference the reference. */ if (deref_ref) { if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) { struct value *deref_val = value_at (TYPE_TARGET_TYPE (type), unpack_pointer (lookup_pointer_type (builtin_type_void), valaddr + embedded_offset), NULL); val_print (VALUE_TYPE (deref_val), VALUE_CONTENTS (deref_val), 0, VALUE_ADDRESS (deref_val), stream, format, deref_ref, recurse, pretty); } else fputs_filtered ("???", stream); } 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_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_BOOL: format = format ? format : output_format; if (format) print_scalar_formatted (valaddr, type, format, 0, stream); else { val = 0; switch (TYPE_LENGTH (type)) { case 1: val = unpack_long (builtin_type_f_logical_s1, valaddr); break; case 2: val = unpack_long (builtin_type_f_logical_s2, valaddr); break; case 4: val = unpack_long (builtin_type_f_logical, valaddr); break; default: error ("Logicals of length %d bytes not supported", TYPE_LENGTH (type)); } if (val == 0) fprintf_filtered (stream, ".FALSE."); else if (val == 1) fprintf_filtered (stream, ".TRUE."); else /* Not a legitimate logical type, print as an integer. */ { /* Bash the type code temporarily. */ TYPE_CODE (type) = TYPE_CODE_INT; f_val_print (type, valaddr, 0, address, stream, format, deref_ref, recurse, pretty); /* Restore the type code so later uses work as intended. */ TYPE_CODE (type) = TYPE_CODE_BOOL; } } break; case TYPE_CODE_COMPLEX: switch (TYPE_LENGTH (type)) { case 8: type = builtin_type_f_real; break; case 16: type = builtin_type_f_real_s8; break; case 32: type = builtin_type_f_real_s16; break; default: error ("Cannot print out complex*%d variables", TYPE_LENGTH (type)); } fputs_filtered ("(", stream); print_floating (valaddr, type, stream); fputs_filtered (",", stream); print_floating (valaddr + TYPE_LENGTH (type), type, stream); fputs_filtered (")", stream); 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 F77 type code %d in symbol table.", TYPE_CODE (type)); } gdb_flush (stream); return 0; }
/* Standard implementation of print_subexp for use in language_defn vectors. */ void print_subexp_standard (struct expression *exp, int *pos, struct ui_file *stream, enum precedence prec) { unsigned tem; const struct op_print *op_print_tab; int pc; unsigned nargs; char *op_str; int assign_modify = 0; enum exp_opcode opcode; enum precedence myprec = PREC_NULL; /* Set to 1 for a right-associative operator. */ int assoc = 0; struct value *val; char *tempstr = NULL; op_print_tab = exp->language_defn->la_op_print_tab; pc = (*pos)++; opcode = exp->elts[pc].opcode; switch (opcode) { /* Common ops */ case OP_SCOPE: myprec = PREC_PREFIX; assoc = 0; fputs_filtered (type_name_no_tag (exp->elts[pc + 1].type), stream); fputs_filtered ("::", stream); nargs = longest_to_int (exp->elts[pc + 2].longconst); (*pos) += 4 + BYTES_TO_EXP_ELEM (nargs + 1); fputs_filtered (&exp->elts[pc + 3].string, stream); return; case OP_LONG: (*pos) += 3; value_print (value_from_longest (exp->elts[pc + 1].type, exp->elts[pc + 2].longconst), stream, 0, Val_no_prettyprint); return; case OP_DOUBLE: (*pos) += 3; value_print (value_from_double (exp->elts[pc + 1].type, exp->elts[pc + 2].doubleconst), stream, 0, Val_no_prettyprint); return; case OP_VAR_VALUE: { struct block *b; (*pos) += 3; b = exp->elts[pc + 1].block; if (b != NULL && BLOCK_FUNCTION (b) != NULL && SYMBOL_PRINT_NAME (BLOCK_FUNCTION (b)) != NULL) { fputs_filtered (SYMBOL_PRINT_NAME (BLOCK_FUNCTION (b)), stream); fputs_filtered ("::", stream); } fputs_filtered (SYMBOL_PRINT_NAME (exp->elts[pc + 2].symbol), stream); } return; case OP_LAST: (*pos) += 2; fprintf_filtered (stream, "$%d", longest_to_int (exp->elts[pc + 1].longconst)); return; case OP_REGISTER: { int regnum = longest_to_int (exp->elts[pc + 1].longconst); const char *name = user_reg_map_regnum_to_name (current_gdbarch, regnum); (*pos) += 2; fprintf_filtered (stream, "$%s", name); return; } case OP_BOOL: (*pos) += 2; fprintf_filtered (stream, "%s", longest_to_int (exp->elts[pc + 1].longconst) ? "TRUE" : "FALSE"); return; case OP_INTERNALVAR: (*pos) += 2; fprintf_filtered (stream, "$%s", internalvar_name (exp->elts[pc + 1].internalvar)); return; case OP_FUNCALL: (*pos) += 2; nargs = longest_to_int (exp->elts[pc + 1].longconst); print_subexp (exp, pos, stream, PREC_SUFFIX); fputs_filtered (" (", stream); for (tem = 0; tem < nargs; tem++) { if (tem != 0) fputs_filtered (", ", stream); print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); } fputs_filtered (")", stream); return; case OP_NAME: case OP_EXPRSTRING: nargs = longest_to_int (exp->elts[pc + 1].longconst); (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1); fputs_filtered (&exp->elts[pc + 2].string, stream); return; case OP_STRING: nargs = longest_to_int (exp->elts[pc + 1].longconst); (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1); /* LA_PRINT_STRING will print using the current repeat count threshold. If necessary, we can temporarily set it to zero, or pass it as an additional parameter to LA_PRINT_STRING. -fnf */ LA_PRINT_STRING (stream, &exp->elts[pc + 2].string, nargs, 1, 0); return; case OP_BITSTRING: nargs = longest_to_int (exp->elts[pc + 1].longconst); (*pos) += 3 + BYTES_TO_EXP_ELEM ((nargs + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT); fprintf_unfiltered (stream, "B'<unimplemented>'"); return; case OP_OBJC_NSSTRING: /* Objective-C Foundation Class NSString constant. */ nargs = longest_to_int (exp->elts[pc + 1].longconst); (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1); fputs_filtered ("@\"", stream); LA_PRINT_STRING (stream, &exp->elts[pc + 2].string, nargs, 1, 0); fputs_filtered ("\"", stream); return; case OP_OBJC_MSGCALL: { /* Objective C message (method) call. */ char *selector; (*pos) += 3; nargs = longest_to_int (exp->elts[pc + 2].longconst); fprintf_unfiltered (stream, "["); print_subexp (exp, pos, stream, PREC_SUFFIX); if (0 == target_read_string (exp->elts[pc + 1].longconst, &selector, 1024, NULL)) { error (_("bad selector")); return; } if (nargs) { char *s, *nextS; s = alloca (strlen (selector) + 1); strcpy (s, selector); for (tem = 0; tem < nargs; tem++) { nextS = strchr (s, ':'); *nextS = '\0'; fprintf_unfiltered (stream, " %s: ", s); s = nextS + 1; print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); } } else { fprintf_unfiltered (stream, " %s", selector); } fprintf_unfiltered (stream, "]"); /* "selector" was malloc'd by target_read_string. Free it. */ xfree (selector); return; } case OP_ARRAY: (*pos) += 3; nargs = longest_to_int (exp->elts[pc + 2].longconst); nargs -= longest_to_int (exp->elts[pc + 1].longconst); nargs++; tem = 0; if (exp->elts[pc + 4].opcode == OP_LONG && exp->elts[pc + 5].type == builtin_type_char && exp->language_defn->la_language == language_c) { /* Attempt to print C character arrays using string syntax. Walk through the args, picking up one character from each of the OP_LONG expression elements. If any array element does not match our expection of what we should find for a simple string, revert back to array printing. Note that the last expression element is an explicit null terminator byte, which doesn't get printed. */ tempstr = alloca (nargs); pc += 4; while (tem < nargs) { if (exp->elts[pc].opcode != OP_LONG || exp->elts[pc + 1].type != builtin_type_char) { /* Not a simple array of char, use regular array printing. */ tem = 0; break; } else { tempstr[tem++] = longest_to_int (exp->elts[pc + 2].longconst); pc += 4; } } } if (tem > 0) { LA_PRINT_STRING (stream, tempstr, nargs - 1, 1, 0); (*pos) = pc; } else { fputs_filtered (" {", stream); for (tem = 0; tem < nargs; tem++) { if (tem != 0) { fputs_filtered (", ", stream); } print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); } fputs_filtered ("}", stream); } return; case OP_LABELED: tem = longest_to_int (exp->elts[pc + 1].longconst); (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); /* Gcc support both these syntaxes. Unsure which is preferred. */ #if 1 fputs_filtered (&exp->elts[pc + 2].string, stream); fputs_filtered (": ", stream); #else fputs_filtered (".", stream); fputs_filtered (&exp->elts[pc + 2].string, stream); fputs_filtered ("=", stream); #endif print_subexp (exp, pos, stream, PREC_SUFFIX); return; case TERNOP_COND: if ((int) prec > (int) PREC_COMMA) fputs_filtered ("(", stream); /* Print the subexpressions, forcing parentheses around any binary operations within them. This is more parentheses than are strictly necessary, but it looks clearer. */ print_subexp (exp, pos, stream, PREC_HYPER); fputs_filtered (" ? ", stream); print_subexp (exp, pos, stream, PREC_HYPER); fputs_filtered (" : ", stream); print_subexp (exp, pos, stream, PREC_HYPER); if ((int) prec > (int) PREC_COMMA) fputs_filtered (")", stream); return; case TERNOP_SLICE: case TERNOP_SLICE_COUNT: print_subexp (exp, pos, stream, PREC_SUFFIX); fputs_filtered ("(", stream); print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); fputs_filtered (opcode == TERNOP_SLICE ? " : " : " UP ", stream); print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); fputs_filtered (")", stream); return; case STRUCTOP_STRUCT: tem = longest_to_int (exp->elts[pc + 1].longconst); (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); print_subexp (exp, pos, stream, PREC_SUFFIX); fputs_filtered (".", stream); fputs_filtered (&exp->elts[pc + 2].string, stream); return; /* Will not occur for Modula-2 */ case STRUCTOP_PTR: tem = longest_to_int (exp->elts[pc + 1].longconst); (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); print_subexp (exp, pos, stream, PREC_SUFFIX); fputs_filtered ("->", stream); fputs_filtered (&exp->elts[pc + 2].string, stream); return; case BINOP_SUBSCRIPT: print_subexp (exp, pos, stream, PREC_SUFFIX); fputs_filtered ("[", stream); print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); fputs_filtered ("]", stream); return; case UNOP_POSTINCREMENT: print_subexp (exp, pos, stream, PREC_SUFFIX); fputs_filtered ("++", stream); return; case UNOP_POSTDECREMENT: print_subexp (exp, pos, stream, PREC_SUFFIX); fputs_filtered ("--", stream); return; case UNOP_CAST: (*pos) += 2; if ((int) prec > (int) PREC_PREFIX) fputs_filtered ("(", stream); fputs_filtered ("(", stream); type_print (exp->elts[pc + 1].type, "", stream, 0); fputs_filtered (") ", stream); print_subexp (exp, pos, stream, PREC_PREFIX); if ((int) prec > (int) PREC_PREFIX) fputs_filtered (")", stream); return; case UNOP_MEMVAL: (*pos) += 2; if ((int) prec > (int) PREC_PREFIX) fputs_filtered ("(", stream); if (TYPE_CODE (exp->elts[pc + 1].type) == TYPE_CODE_FUNC && exp->elts[pc + 3].opcode == OP_LONG) { /* We have a minimal symbol fn, probably. It's encoded as a UNOP_MEMVAL (function-type) of an OP_LONG (int, address). Swallow the OP_LONG (including both its opcodes); ignore its type; print the value in the type of the MEMVAL. */ (*pos) += 4; val = value_at_lazy (exp->elts[pc + 1].type, (CORE_ADDR) exp->elts[pc + 5].longconst); value_print (val, stream, 0, Val_no_prettyprint); } else { fputs_filtered ("{", stream); type_print (exp->elts[pc + 1].type, "", stream, 0); fputs_filtered ("} ", stream); print_subexp (exp, pos, stream, PREC_PREFIX); } if ((int) prec > (int) PREC_PREFIX) fputs_filtered (")", stream); return; case BINOP_ASSIGN_MODIFY: opcode = exp->elts[pc + 1].opcode; (*pos) += 2; myprec = PREC_ASSIGN; assoc = 1; assign_modify = 1; op_str = "???"; for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++) if (op_print_tab[tem].opcode == opcode) { op_str = op_print_tab[tem].string; break; } if (op_print_tab[tem].opcode != opcode) /* Not found; don't try to keep going because we don't know how to interpret further elements. */ error (_("Invalid expression")); break; /* C++ ops */ case OP_THIS: ++(*pos); fputs_filtered ("this", stream); return; /* Objective-C ops */ case OP_OBJC_SELF: ++(*pos); fputs_filtered ("self", stream); /* The ObjC equivalent of "this". */ return; /* Modula-2 ops */ case MULTI_SUBSCRIPT: (*pos) += 2; nargs = longest_to_int (exp->elts[pc + 1].longconst); print_subexp (exp, pos, stream, PREC_SUFFIX); fprintf_unfiltered (stream, " ["); for (tem = 0; tem < nargs; tem++) { if (tem != 0) fprintf_unfiltered (stream, ", "); print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); } fprintf_unfiltered (stream, "]"); return; case BINOP_VAL: (*pos) += 2; fprintf_unfiltered (stream, "VAL("); type_print (exp->elts[pc + 1].type, "", stream, 0); fprintf_unfiltered (stream, ","); print_subexp (exp, pos, stream, PREC_PREFIX); fprintf_unfiltered (stream, ")"); return; case BINOP_INCL: case BINOP_EXCL: error (_("print_subexp: Not implemented.")); /* Default ops */ default: op_str = "???"; for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++) if (op_print_tab[tem].opcode == opcode) { op_str = op_print_tab[tem].string; myprec = op_print_tab[tem].precedence; assoc = op_print_tab[tem].right_assoc; break; } if (op_print_tab[tem].opcode != opcode) /* Not found; don't try to keep going because we don't know how to interpret further elements. For example, this happens if opcode is OP_TYPE. */ error (_("Invalid expression")); } /* Note that PREC_BUILTIN will always emit parentheses. */ if ((int) myprec < (int) prec) fputs_filtered ("(", stream); if ((int) opcode > (int) BINOP_END) { if (assoc) { /* Unary postfix operator. */ print_subexp (exp, pos, stream, PREC_SUFFIX); fputs_filtered (op_str, stream); } else { /* Unary prefix operator. */ fputs_filtered (op_str, stream); if (myprec == PREC_BUILTIN_FUNCTION) fputs_filtered ("(", stream); print_subexp (exp, pos, stream, PREC_PREFIX); if (myprec == PREC_BUILTIN_FUNCTION) fputs_filtered (")", stream); } } else { /* Binary operator. */ /* Print left operand. If operator is right-associative, increment precedence for this operand. */ print_subexp (exp, pos, stream, (enum precedence) ((int) myprec + assoc)); /* Print the operator itself. */ if (assign_modify) fprintf_filtered (stream, " %s= ", op_str); else if (op_str[0] == ',') fprintf_filtered (stream, "%s ", op_str); else fprintf_filtered (stream, " %s ", op_str); /* Print right operand. If operator is left-associative, increment precedence for this operand. */ print_subexp (exp, pos, stream, (enum precedence) ((int) myprec + !assoc)); } if ((int) myprec < (int) prec) fputs_filtered (")", stream); }
static enum return_value_convention rs6000_lynx178_return_value (struct gdbarch *gdbarch, struct value *function, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* The calling convention this function implements assumes the processor has floating-point registers. We shouldn't be using it on PowerPC variants that lack them. */ gdb_assert (ppc_floating_point_unit_p (gdbarch)); /* AltiVec extension: Functions that declare a vector data type as a return value place that return value in VR2. */ if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY && TYPE_VECTOR (valtype) && TYPE_LENGTH (valtype) == 16) { if (readbuf) regcache_cooked_read (regcache, tdep->ppc_vr0_regnum + 2, readbuf); if (writebuf) regcache_cooked_write (regcache, tdep->ppc_vr0_regnum + 2, writebuf); return RETURN_VALUE_REGISTER_CONVENTION; } /* If the called subprogram returns an aggregate, there exists an implicit first argument, whose value is the address of a caller- allocated buffer into which the callee is assumed to store its return value. All explicit parameters are appropriately relabeled. */ if (TYPE_CODE (valtype) == TYPE_CODE_STRUCT || TYPE_CODE (valtype) == TYPE_CODE_UNION || TYPE_CODE (valtype) == TYPE_CODE_ARRAY) return RETURN_VALUE_STRUCT_CONVENTION; /* Scalar floating-point values are returned in FPR1 for float or double, and in FPR1:FPR2 for quadword precision. Fortran complex*8 and complex*16 are returned in FPR1:FPR2, and complex*32 is returned in FPR1:FPR4. */ if (TYPE_CODE (valtype) == TYPE_CODE_FLT && (TYPE_LENGTH (valtype) == 4 || TYPE_LENGTH (valtype) == 8)) { struct type *regtype = register_type (gdbarch, tdep->ppc_fp0_regnum); gdb_byte regval[8]; /* FIXME: kettenis/2007-01-01: Add support for quadword precision and complex. */ if (readbuf) { regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1, regval); convert_typed_floating (regval, regtype, readbuf, valtype); } if (writebuf) { convert_typed_floating (writebuf, valtype, regval, regtype); regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1, regval); } return RETURN_VALUE_REGISTER_CONVENTION; } /* Values of the types int, long, short, pointer, and char (length is less than or equal to four bytes), as well as bit values of lengths less than or equal to 32 bits, must be returned right justified in GPR3 with signed values sign extended and unsigned values zero extended, as necessary. */ if (TYPE_LENGTH (valtype) <= tdep->wordsize) { if (readbuf) { ULONGEST regval; /* For reading we don't have to worry about sign extension. */ regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum + 3, ®val); store_unsigned_integer (readbuf, TYPE_LENGTH (valtype), byte_order, regval); } if (writebuf) { /* For writing, use unpack_long since that should handle any required sign extension. */ regcache_cooked_write_unsigned (regcache, tdep->ppc_gp0_regnum + 3, unpack_long (valtype, writebuf)); } return RETURN_VALUE_REGISTER_CONVENTION; } /* Eight-byte non-floating-point scalar values must be returned in GPR3:GPR4. */ if (TYPE_LENGTH (valtype) == 8) { gdb_assert (TYPE_CODE (valtype) != TYPE_CODE_FLT); gdb_assert (tdep->wordsize == 4); if (readbuf) { gdb_byte regval[8]; regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, regval); regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 4, regval + 4); memcpy (readbuf, regval, 8); } if (writebuf) { regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3, writebuf); regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 4, writebuf + 4); } return RETURN_VALUE_REGISTER_CONVENTION; } return RETURN_VALUE_STRUCT_CONVENTION; }
void c_type_print_base (struct type *type, struct ui_file *stream, 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 = 0; int j, len2; QUIT; wrap_here (" "); if (type == NULL) { fputs_filtered (_("<type unknown>"), 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 <= 0 && TYPE_NAME (type) != NULL) { c_type_print_modifier (type, stream, 0, 1); fputs_filtered (TYPE_NAME (type), stream); return; } CHECK_TYPEDEF (type); switch (TYPE_CODE (type)) { case TYPE_CODE_TYPEDEF: case TYPE_CODE_ARRAY: case TYPE_CODE_PTR: case TYPE_CODE_MEMBER: case TYPE_CODE_REF: case TYPE_CODE_FUNC: case TYPE_CODE_METHOD: c_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level); break; case TYPE_CODE_STRUCT: c_type_print_modifier (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 */ 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) != 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); fprintf_filtered (stream, "{\n"); if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0)) { if (TYPE_STUB (type)) fprintfi_filtered (level + 4, stream, _("<incomplete type>\n")); else fprintfi_filtered (level + 4, stream, _("<no data fields>\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_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)) { need_access_label = 1; break; } QUIT; if (!need_access_label) { 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; } } } 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)) { need_access_label = 1; 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)) { need_access_label = 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 = TYPE_NFIELDS (type); for (i = TYPE_N_BASECLASSES (type); i < len; i++) { QUIT; /* Don't print out virtual function table. */ /* HP ANSI C++ case */ if (TYPE_HAS_VTABLE (type) && (strncmp (TYPE_FIELD_NAME (type, i), "__vfp", 5) == 0)) continue; /* Other compilers */ if (strncmp (TYPE_FIELD_NAME (type, i), "_vptr", 5) == 0 && 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"); } } } 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"); } /* 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); real_len = 0; for (i = 0; i < len; i++) { struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i); int len2 = TYPE_FN_FIELDLIST_LENGTH (type, i); int j; for (j = 0; j < len2; j++) if (!TYPE_FN_FIELD_ARTIFICIAL (f, j)) real_len++; } if (real_len > 0 && section_type != s_none) fprintf_filtered (stream, "\n"); /* 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 && strcmp (method_name, name) == 0; for (j = 0; j < len2; j++) { char *physname = TYPE_FN_FIELD_PHYSNAME (f, j); int is_full_physname_constructor = 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; QUIT; if (TYPE_FN_FIELD_PROTECTED (f, j)) { if (section_type != s_protected) { section_type = s_protected; fprintfi_filtered (level + 2, stream, "protected:\n"); } } else if (TYPE_FN_FIELD_PRIVATE (f, j)) { 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"); } } 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)) == 0) { /* Keep GDB from crashing here. */ fprintf_filtered (stream, _("<undefined type> %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)) /* Build something we can demangle. */ mangled_name = gdb_mangle_name (type, i, j); else mangled_name = TYPE_FN_FIELD_PHYSNAME (f, j); demangled_name = cplus_demangle (mangled_name, 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 */ if (!TYPE_FN_FIELD_STUB (f, j)) { 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); } else fprintf_filtered (stream, _("<badly mangled name '%s'>"), mangled_name); } else { char *p; char *demangled_no_class = remove_qualifiers (demangled_name); /* 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); *(demangled_no_static + length) = '\0'; fputs_filtered (demangled_no_static, stream); xfree (demangled_no_static); } else fputs_filtered (demangled_no_class, stream); xfree (demangled_name); } if (TYPE_FN_FIELD_STUB (f, j)) xfree (mangled_name); fprintf_filtered (stream, ";\n"); } } fprintfi_filtered (level, stream, "}"); 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; break; case TYPE_CODE_ENUM: c_type_print_modifier (type, stream, 0, 1); /* HP C supports sized enums */ if (deprecated_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; } 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)) { 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) { fprintf_filtered (stream, "{"); len = TYPE_NFIELDS (type); lastval = 0; for (i = 0; i < len; i++) { QUIT; if (i) fprintf_filtered (stream, ", "); wrap_here (" "); fputs_filtered (TYPE_FIELD_NAME (type, i), stream); if (lastval != TYPE_FIELD_BITPOS (type, i)) { /* APPLE LOCAL begin print unsigned */ if (TYPE_FLAGS (type) & TYPE_FLAG_UNSIGNED) fprintf_filtered (stream, " = %u", TYPE_FIELD_BITPOS (type, i)); else fprintf_filtered (stream, " = %d", TYPE_FIELD_BITPOS (type, i)); /* APPLE LOCAL end print unsigned */ lastval = 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 <unknown>")); break; case TYPE_CODE_ERROR: fprintf_filtered (stream, _("<unknown type>")); break; case TYPE_CODE_RANGE: /* This should not occur */ fprintf_filtered (stream, _("<range type>")); break; case TYPE_CODE_TEMPLATE: /* Called on "ptype t" where "t" is a template. Prints the template header (with args), e.g.: template <class T1, class T2> class " and then merges with the struct/union/class code to print the rest of the definition. */ c_type_print_modifier (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"); } } 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) != NULL) { c_type_print_modifier (type, stream, 0, 1); fputs_filtered (TYPE_NAME (type), stream); } else { /* At least for dump_symtab, it is important that this not be an error (). */ fprintf_filtered (stream, _("<invalid type code %d>"), TYPE_CODE (type)); } break; } }
struct type * type_from_class (struct gdbarch *gdbarch, struct value *clas) { struct type *type; char *name; struct value *temp; struct objfile *objfile; struct value *utf8_name; char *nptr; CORE_ADDR addr; type = check_typedef (value_type (clas)); if (TYPE_CODE (type) == TYPE_CODE_PTR) { if (value_logical_not (clas)) return NULL; clas = value_ind (clas); } addr = value_address (clas); objfile = get_dynamics_objfile (gdbarch); if (java_class_is_primitive (clas)) { struct value *sig; temp = clas; sig = value_struct_elt (&temp, NULL, "method_count", NULL, "structure"); return java_primitive_type (gdbarch, value_as_long (sig)); } /* Get Class name. */ /* If clasloader non-null, prepend loader address. FIXME */ temp = clas; utf8_name = value_struct_elt (&temp, NULL, "name", NULL, "structure"); name = get_java_utf8_name (&objfile->objfile_obstack, utf8_name); for (nptr = name; *nptr != 0; nptr++) { if (*nptr == '/') *nptr = '.'; } type = java_lookup_class (name); if (type != NULL) return type; type = alloc_type (objfile); TYPE_CODE (type) = TYPE_CODE_STRUCT; INIT_CPLUS_SPECIFIC (type); if (name[0] == '[') { char *signature = name; int namelen = java_demangled_signature_length (signature); if (namelen > strlen (name)) name = obstack_alloc (&objfile->objfile_obstack, namelen + 1); java_demangled_signature_copy (name, signature); name[namelen] = '\0'; temp = clas; /* Set array element type. */ temp = value_struct_elt (&temp, NULL, "methods", NULL, "structure"); deprecated_set_value_type (temp, lookup_pointer_type (value_type (clas))); TYPE_TARGET_TYPE (type) = type_from_class (gdbarch, temp); } ALLOCATE_CPLUS_STRUCT_TYPE (type); TYPE_TAG_NAME (type) = name; add_class_symtab_symbol (add_class_symbol (type, addr)); return java_link_class_type (gdbarch, type, clas); }
static void ada_varobj_describe_struct_child (struct value *parent_value, struct type *parent_type, const char *parent_name, const char *parent_path_expr, int child_index, char **child_name, struct value **child_value, struct type **child_type, char **child_path_expr) { int fieldno; int childno = 0; gdb_assert (TYPE_CODE (parent_type) == TYPE_CODE_STRUCT); for (fieldno = 0; fieldno < TYPE_NFIELDS (parent_type); fieldno++) { if (ada_is_ignored_field (parent_type, fieldno)) continue; if (ada_is_wrapper_field (parent_type, fieldno)) { struct value *elt_value; struct type *elt_type; int elt_n_children; ada_varobj_struct_elt (parent_value, parent_type, fieldno, &elt_value, &elt_type); if (ada_is_tagged_type (elt_type, 0)) { /* Same as in ada_varobj_get_struct_number_of_children: For tagged types, we must be careful to not call ada_varobj_get_number_of_children, to prevent our element from being fixed back into the parent. */ elt_n_children = ada_varobj_get_struct_number_of_children (elt_value, elt_type); } else elt_n_children = ada_varobj_get_number_of_children (elt_value, elt_type); /* Is the child we're looking for one of the children of this wrapper field? */ if (child_index - childno < elt_n_children) { if (ada_is_tagged_type (elt_type, 0)) { /* Same as in ada_varobj_get_struct_number_of_children: For tagged types, we must be careful to not call ada_varobj_describe_child, to prevent our element from being fixed back into the parent. */ ada_varobj_describe_struct_child (elt_value, elt_type, parent_name, parent_path_expr, child_index - childno, child_name, child_value, child_type, child_path_expr); } else ada_varobj_describe_child (elt_value, elt_type, parent_name, parent_path_expr, child_index - childno, child_name, child_value, child_type, child_path_expr); return; } /* The child we're looking for is beyond this wrapper field, so skip all its children. */ childno += elt_n_children; continue; } else if (ada_is_variant_part (parent_type, fieldno)) { /* In normal situations, the variant part of the record should have been "fixed". Or, in other words, it should have been replaced by the branch of the variant part that is relevant for our value. But there are still situations where this can happen, however (Eg. when our parent is a NULL pointer). We do not support showing this part of the record for now, so just pretend this field does not exist. */ continue; } if (childno == child_index) { if (child_name) { /* The name of the child is none other than the field's name, except that we need to strip suffixes from it. For instance, fields with alignment constraints will have an __XVA suffix added to them. */ const char *field_name = TYPE_FIELD_NAME (parent_type, fieldno); int child_name_len = ada_name_prefix_len (field_name); *child_name = xstrprintf ("%.*s", child_name_len, field_name); } if (child_value && parent_value) ada_varobj_struct_elt (parent_value, parent_type, fieldno, child_value, NULL); if (child_type) ada_varobj_struct_elt (parent_value, parent_type, fieldno, NULL, child_type); if (child_path_expr) { /* The name of the child is none other than the field's name, except that we need to strip suffixes from it. For instance, fields with alignment constraints will have an __XVA suffix added to them. */ const char *field_name = TYPE_FIELD_NAME (parent_type, fieldno); int child_name_len = ada_name_prefix_len (field_name); *child_path_expr = xstrprintf ("(%s).%.*s", parent_path_expr, child_name_len, field_name); } return; } childno++; } /* Something went wrong. Either we miscounted the number of children, or CHILD_INDEX was too high. But we should never reach here. We don't have enough information to recover nicely, so just raise an assertion failure. */ gdb_assert_not_reached ("unexpected code path"); }
static struct value * evaluate_subexp_java (struct type *expect_type, struct expression *exp, int *pos, enum noside noside) { int pc = *pos; int i; const char *name; enum exp_opcode op = exp->elts[*pos].opcode; struct value *arg1; struct value *arg2; struct type *type; switch (op) { case UNOP_IND: if (noside == EVAL_SKIP) goto standard; (*pos)++; arg1 = evaluate_subexp_java (NULL_TYPE, exp, pos, EVAL_NORMAL); if (is_object_type (value_type (arg1))) { struct type *type; type = type_from_class (exp->gdbarch, java_class_from_object (arg1)); arg1 = value_cast (lookup_pointer_type (type), arg1); } return value_ind (arg1); case BINOP_SUBSCRIPT: (*pos)++; arg1 = evaluate_subexp_with_coercion (exp, pos, noside); arg2 = evaluate_subexp_with_coercion (exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; /* If the user attempts to subscript something that is not an array or pointer type (like a plain int variable for example), then report this as an error. */ arg1 = coerce_ref (arg1); type = check_typedef (value_type (arg1)); if (TYPE_CODE (type) == TYPE_CODE_PTR) type = check_typedef (TYPE_TARGET_TYPE (type)); name = TYPE_NAME (type); if (name == NULL) name = TYPE_TAG_NAME (type); i = name == NULL ? 0 : strlen (name); if (TYPE_CODE (type) == TYPE_CODE_STRUCT && i > 2 && name[i - 1] == ']') { enum bfd_endian byte_order = gdbarch_byte_order (exp->gdbarch); CORE_ADDR address; long length, index; struct type *el_type; gdb_byte buf4[4]; struct value *clas = java_class_from_object (arg1); struct value *temp = clas; /* Get CLASS_ELEMENT_TYPE of the array type. */ temp = value_struct_elt (&temp, NULL, "methods", NULL, "structure"); deprecated_set_value_type (temp, value_type (clas)); el_type = type_from_class (exp->gdbarch, temp); if (TYPE_CODE (el_type) == TYPE_CODE_STRUCT) el_type = lookup_pointer_type (el_type); if (noside == EVAL_AVOID_SIDE_EFFECTS) return value_zero (el_type, VALUE_LVAL (arg1)); address = value_as_address (arg1); address += get_java_object_header_size (exp->gdbarch); read_memory (address, buf4, 4); length = (long) extract_signed_integer (buf4, 4, byte_order); index = (long) value_as_long (arg2); if (index >= length || index < 0) error (_("array index (%ld) out of bounds (length: %ld)"), index, length); address = (address + 4) + index * TYPE_LENGTH (el_type); return value_at (el_type, address); } else if (TYPE_CODE (type) == TYPE_CODE_ARRAY) { if (noside == EVAL_AVOID_SIDE_EFFECTS) return value_zero (TYPE_TARGET_TYPE (type), VALUE_LVAL (arg1)); else return value_subscript (arg1, value_as_long (arg2)); } if (name) error (_("cannot subscript something of type `%s'"), name); else error (_("cannot subscript requested type")); case OP_STRING: (*pos)++; i = longest_to_int (exp->elts[pc + 1].longconst); (*pos) += 3 + BYTES_TO_EXP_ELEM (i + 1); if (noside == EVAL_SKIP) goto nosideret; return java_value_string (&exp->elts[pc + 2].string, i); case STRUCTOP_PTR: arg1 = evaluate_subexp_standard (expect_type, exp, pos, noside); /* Convert object field (such as TYPE.class) to reference. */ if (TYPE_CODE (value_type (arg1)) == TYPE_CODE_STRUCT) arg1 = value_addr (arg1); return arg1; default: break; } standard: return evaluate_subexp_standard (expect_type, exp, pos, noside); nosideret: return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1); }
static void ada_varobj_describe_simple_array_child (struct value *parent_value, struct type *parent_type, const char *parent_name, const char *parent_path_expr, int child_index, char **child_name, struct value **child_value, struct type **child_type, char **child_path_expr) { struct type *index_type; int real_index; gdb_assert (TYPE_CODE (parent_type) == TYPE_CODE_ARRAY); index_type = TYPE_INDEX_TYPE (parent_type); real_index = child_index + ada_discrete_type_low_bound (index_type); if (child_name) *child_name = ada_varobj_scalar_image (index_type, real_index); if (child_value && parent_value) ada_varobj_simple_array_elt (parent_value, parent_type, real_index, child_value, NULL); if (child_type) ada_varobj_simple_array_elt (parent_value, parent_type, real_index, NULL, child_type); if (child_path_expr) { char *index_img = ada_varobj_scalar_image (index_type, real_index); struct cleanup *cleanups = make_cleanup (xfree, index_img); /* Enumeration litterals by themselves are potentially ambiguous. For instance, consider the following package spec: package Pck is type Color is (Red, Green, Blue, White); type Blood_Cells is (White, Red); end Pck; In this case, the litteral "red" for instance, or even the fully-qualified litteral "pck.red" cannot be resolved by itself. Type qualification is needed to determine which enumeration litterals should be used. The following variable will be used to contain the name of the array index type when such type qualification is needed. */ const char *index_type_name = NULL; /* If the index type is a range type, find the base type. */ while (TYPE_CODE (index_type) == TYPE_CODE_RANGE) index_type = TYPE_TARGET_TYPE (index_type); if (TYPE_CODE (index_type) == TYPE_CODE_ENUM || TYPE_CODE (index_type) == TYPE_CODE_BOOL) { index_type_name = ada_type_name (index_type); if (index_type_name) index_type_name = ada_decode (index_type_name); } if (index_type_name != NULL) *child_path_expr = xstrprintf ("(%s)(%.*s'(%s))", parent_path_expr, ada_name_prefix_len (index_type_name), index_type_name, index_img); else *child_path_expr = xstrprintf ("(%s)(%s)", parent_path_expr, index_img); do_cleanups (cleanups); } }
void c_type_print_varspec_suffix (struct type *type, struct ui_file *stream, int show, int passed_a_ptr, int demangled_args) { if (type == 0) return; if (TYPE_NAME (type) && show <= 0) return; QUIT; switch (TYPE_CODE (type)) { case TYPE_CODE_ARRAY: { LONGEST low_bound, high_bound; int is_vector = TYPE_VECTOR (type); if (passed_a_ptr) fprintf_filtered (stream, ")"); 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); } break; case TYPE_CODE_MEMBERPTR: c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, 0, 0); break; case TYPE_CODE_METHODPTR: fprintf_filtered (stream, ")"); c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, 0, 0); break; case TYPE_CODE_PTR: case TYPE_CODE_REF: c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, 1, 0); break; case TYPE_CODE_METHOD: case TYPE_CODE_FUNC: if (passed_a_ptr) fprintf_filtered (stream, ")"); if (!demangled_args) c_type_print_args (type, stream, 0, current_language->la_language); c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, passed_a_ptr, 0); break; case TYPE_CODE_TYPEDEF: c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, passed_a_ptr, 0); break; case TYPE_CODE_UNDEF: case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: case TYPE_CODE_ENUM: case TYPE_CODE_INT: case TYPE_CODE_FLT: case TYPE_CODE_VOID: case TYPE_CODE_ERROR: case TYPE_CODE_CHAR: case TYPE_CODE_BOOL: case TYPE_CODE_SET: case TYPE_CODE_RANGE: case TYPE_CODE_STRING: case TYPE_CODE_COMPLEX: 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. */ break; default: error (_("type not handled in c_type_print_varspec_suffix()")); break; } }
static void ada_varobj_describe_child (struct value *parent_value, struct type *parent_type, const char *parent_name, const char *parent_path_expr, int child_index, char **child_name, struct value **child_value, struct type **child_type, char **child_path_expr) { /* We cannot compute the child's path expression without the parent's path expression. This is a pre-condition for calling this function. */ if (child_path_expr) gdb_assert (parent_path_expr != NULL); ada_varobj_decode_var (&parent_value, &parent_type); ada_varobj_adjust_for_child_access (&parent_value, &parent_type); if (child_name) *child_name = NULL; if (child_value) *child_value = NULL; if (child_type) *child_type = NULL; if (child_path_expr) *child_path_expr = NULL; if (ada_is_array_descriptor_type (parent_type) && TYPE_CODE (parent_type) == TYPE_CODE_TYPEDEF) { ada_varobj_describe_ptr_child (parent_value, parent_type, parent_name, parent_path_expr, child_index, child_name, child_value, child_type, child_path_expr); return; } if (TYPE_CODE (parent_type) == TYPE_CODE_ARRAY) { ada_varobj_describe_simple_array_child (parent_value, parent_type, parent_name, parent_path_expr, child_index, child_name, child_value, child_type, child_path_expr); return; } if (TYPE_CODE (parent_type) == TYPE_CODE_STRUCT) { ada_varobj_describe_struct_child (parent_value, parent_type, parent_name, parent_path_expr, child_index, child_name, child_value, child_type, child_path_expr); return; } if (TYPE_CODE (parent_type) == TYPE_CODE_PTR) { ada_varobj_describe_ptr_child (parent_value, parent_type, parent_name, parent_path_expr, child_index, child_name, child_value, child_type, child_path_expr); return; } /* It should never happen. But rather than crash, report dummy names and return a NULL child_value. */ if (child_name) *child_name = xstrdup ("???"); }
static void java_type_print_base (struct type *type, struct ui_file *stream, int show, int level) { int i; int len; char *mangled_name; char *demangled_name; QUIT; wrap_here (" "); if (type == NULL) { fputs_filtered ("<type unknown>", 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 (show <= 0 && TYPE_NAME (type) != NULL) { fputs_filtered (TYPE_NAME (type), stream); return; } CHECK_TYPEDEF (type); switch (TYPE_CODE (type)) { case TYPE_CODE_PTR: java_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level); break; case TYPE_CODE_STRUCT: if (TYPE_TAG_NAME (type) != NULL && TYPE_TAG_NAME (type)[0] == '[') { /* array type */ char *name = java_demangle_type_signature (TYPE_TAG_NAME (type)); fputs_filtered (name, stream); xfree (name); break; } if (show >= 0) fprintf_filtered (stream, "class "); if (TYPE_TAG_NAME (type) != NULL) { 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) { java_type_print_derivation_info (stream, type); fprintf_filtered (stream, "{\n"); if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0)) { if (TYPE_STUB (type)) fprintfi_filtered (level + 4, stream, "<incomplete type>\n"); else fprintfi_filtered (level + 4, stream, "<no data fields>\n"); } /* If there is a base class for this type, do not print the field that it occupies. */ len = TYPE_NFIELDS (type); for (i = TYPE_N_BASECLASSES (type); i < len; i++) { QUIT; /* Don't print out virtual function table. */ if (strncmp (TYPE_FIELD_NAME (type, i), "_vptr", 5) == 0 && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5])) continue; /* Don't print the dummy field "class". */ if (strncmp (TYPE_FIELD_NAME (type, i), "class", 5) == 0) continue; print_spaces_filtered (level + 4, stream); if (HAVE_CPLUS_STRUCT (type)) { if (TYPE_FIELD_PROTECTED (type, i)) fprintf_filtered (stream, "protected "); else if (TYPE_FIELD_PRIVATE (type, i)) fprintf_filtered (stream, "private "); else fprintf_filtered (stream, "public "); } if (field_is_static (&TYPE_FIELD (type, i))) fprintf_filtered (stream, "static "); java_print_type (TYPE_FIELD_TYPE (type, i), TYPE_FIELD_NAME (type, i), stream, show - 1, level + 4); fprintf_filtered (stream, ";\n"); } /* If there are both fields and methods, put a space between. */ len = TYPE_NFN_FIELDS (type); if (len) fprintf_filtered (stream, "\n"); /* Print out the methods */ for (i = 0; i < len; i++) { struct fn_field *f; int j; char *method_name; char *name; int is_constructor; int n_overloads; f = TYPE_FN_FIELDLIST1 (type, i); n_overloads = TYPE_FN_FIELDLIST_LENGTH (type, i); method_name = TYPE_FN_FIELDLIST_NAME (type, i); name = type_name_no_tag (type); is_constructor = name && strcmp (method_name, name) == 0; for (j = 0; j < n_overloads; j++) { char *real_physname, *physname, *p; int is_full_physname_constructor; real_physname = TYPE_FN_FIELD_PHYSNAME (f, j); /* The physname will contain the return type after the final closing parenthesis. Strip it off. */ p = strrchr (real_physname, ')'); gdb_assert (p != NULL); ++p; /* Keep the trailing ')'. */ physname = alloca (p - real_physname + 1); memcpy (physname, real_physname, p - real_physname); physname[p - real_physname] = '\0'; is_full_physname_constructor = (is_constructor_name (physname) || is_destructor_name (physname)); QUIT; print_spaces_filtered (level + 4, stream); if (TYPE_FN_FIELD_PROTECTED (f, j)) fprintf_filtered (stream, "protected "); else if (TYPE_FN_FIELD_PRIVATE (f, j)) fprintf_filtered (stream, "private "); else if (TYPE_FN_FIELD_PUBLIC (f, j)) fprintf_filtered (stream, "public "); if (TYPE_FN_FIELD_ABSTRACT (f, j)) fprintf_filtered (stream, "abstract "); if (TYPE_FN_FIELD_STATIC (f, j)) fprintf_filtered (stream, "static "); if (TYPE_FN_FIELD_FINAL (f, j)) fprintf_filtered (stream, "final "); if (TYPE_FN_FIELD_SYNCHRONIZED (f, j)) fprintf_filtered (stream, "synchronized "); if (TYPE_FN_FIELD_NATIVE (f, j)) fprintf_filtered (stream, "native "); if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0) { /* Keep GDB from crashing here. */ fprintf_filtered (stream, "<undefined type> %s;\n", TYPE_FN_FIELD_PHYSNAME (f, j)); break; } else if (!is_constructor && !is_full_physname_constructor) { type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)), "", stream, -1); fputs_filtered (" ", stream); } if (TYPE_FN_FIELD_STUB (f, j)) /* Build something we can demangle. */ mangled_name = gdb_mangle_name (type, i, j); else mangled_name = physname; demangled_name = cplus_demangle (mangled_name, DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA); if (demangled_name == NULL) demangled_name = xstrdup (mangled_name); { char *demangled_no_class; char *ptr; ptr = demangled_no_class = demangled_name; while (1) { char c; c = *ptr++; if (c == 0 || c == '(') break; if (c == '.') demangled_no_class = ptr; } fputs_filtered (demangled_no_class, stream); xfree (demangled_name); } if (TYPE_FN_FIELD_STUB (f, j)) xfree (mangled_name); fprintf_filtered (stream, ";\n"); } } fprintfi_filtered (level, stream, "}"); } break; default: c_type_print_base (type, stream, show, level); } }
int c_value_print (struct value *val, struct ui_file *stream, int format, enum val_prettyprint pretty) { struct type *type, *real_type; int full, top, using_enc; /* If it is a pointer, indicate what it points to. Print type also if it is a reference. C++: if it is a member pointer, we will take care of that when we print it. */ type = check_typedef (value_type (val)); if (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_CODE (type) == TYPE_CODE_REF) { /* Hack: remove (char *) for char strings. Their type is indicated by the quoted string anyway. */ if (TYPE_CODE (type) == TYPE_CODE_PTR && TYPE_NAME (type) == NULL && TYPE_NAME (TYPE_TARGET_TYPE (type)) != NULL && strcmp (TYPE_NAME (TYPE_TARGET_TYPE (type)), "char") == 0) { /* Print nothing */ } else if (objectprint && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS)) { if (TYPE_CODE(type) == TYPE_CODE_REF) { /* Copy value, change to pointer, so we don't get an * error about a non-pointer type in value_rtti_target_type */ struct value *temparg; temparg=value_copy(val); deprecated_set_value_type (temparg, lookup_pointer_type (TYPE_TARGET_TYPE(type))); val=temparg; } /* Pointer to class, check real type of object */ fprintf_filtered (stream, "("); real_type = value_rtti_target_type (val, &full, &top, &using_enc); if (real_type) { /* RTTI entry found */ if (TYPE_CODE (type) == TYPE_CODE_PTR) { /* create a pointer type pointing to the real type */ type = lookup_pointer_type (real_type); } else { /* create a reference type referencing the real type */ type = lookup_reference_type (real_type); } /* JYG: Need to adjust pointer value. */ /* NOTE: cagney/2005-01-02: THIS IS BOGUS. */ value_contents_writeable (val)[0] -= top; /* Note: When we look up RTTI entries, we don't get any information on const or volatile attributes */ } type_print (type, "", stream, -1); fprintf_filtered (stream, ") "); } else { /* normal case */ fprintf_filtered (stream, "("); type_print (value_type (val), "", stream, -1); fprintf_filtered (stream, ") "); } } /* APPLE LOCAL begin variable initialized status. */ if (value_var_status (val) == 0) fprintf_filtered (stream, " [uninitialized] "); /* APPLE LOCAL end variable initialized status. */ if (objectprint && (TYPE_CODE (type) == TYPE_CODE_CLASS)) { /* Attempt to determine real type of object */ real_type = value_rtti_type (val, &full, &top, &using_enc); if (real_type) { /* We have RTTI information, so use it */ val = value_full_object (val, real_type, full, top, using_enc); fprintf_filtered (stream, "(%s%s) ", TYPE_NAME (real_type), full ? "" : _(" [incomplete object]")); /* Print out object: enclosing type is same as real_type if full */ return val_print (value_enclosing_type (val), value_contents_all (val), 0, VALUE_ADDRESS (val), stream, format, 1, 0, pretty); /* Note: When we look up RTTI entries, we don't get any information on const or volatile attributes */ } else if (type != check_typedef (value_enclosing_type (val))) { /* No RTTI information, so let's do our best */ fprintf_filtered (stream, "(%s ?) ", TYPE_NAME (value_enclosing_type (val))); return val_print (value_enclosing_type (val), value_contents_all (val), 0, VALUE_ADDRESS (val), stream, format, 1, 0, pretty); } /* Otherwise, we end up at the return outside this "if" */ } real_type = get_closure_dynamic_type (val); if (real_type) type = real_type; return val_print (type, value_contents_all (val), value_embedded_offset (val), VALUE_ADDRESS (val) + value_offset (val), stream, format, 1, 0, pretty); }
static struct type * gnuv2_value_rtti_type (struct value *v, int *full, int *top, int *using_enc) { struct type *known_type; struct type *rtti_type; CORE_ADDR vtbl; struct minimal_symbol *minsym; char *demangled_name; struct type *btype; if (full) *full = 0; if (top) *top = -1; if (using_enc) *using_enc = 0; /* Get declared type */ known_type = value_type (v); CHECK_TYPEDEF (known_type); /* RTTI works only or class objects */ if (TYPE_CODE (known_type) != TYPE_CODE_CLASS) return NULL; /* Plan on this changing in the future as i get around to setting the vtables properly for G++ compiled stuff. Also, I'll be using the type info functions, which are always right. Deal with it until then. JCI - This pretty much useless. This gets the "true" type correctly when there is single inheritance - but in all such cases that I could find gdb already knows that. In cases where this points INTO the object (like non-virtual diamond graphs) the demangled name is something like OUTER::INNER and this is not a symbol gdb can resolve, so we fail & return NULL anyway. Seems like this really isn't going to work till we actually call the RTTI function & parse it. */ /* If the type has no vptr fieldno, try to get it filled in */ if (TYPE_VPTR_FIELDNO(known_type) < 0) fill_in_vptr_fieldno(known_type); /* If we still can't find one, give up */ if (TYPE_VPTR_FIELDNO(known_type) < 0) return NULL; /* Make sure our basetype and known type match, otherwise, cast so we can get at the vtable properly. */ btype = TYPE_VPTR_BASETYPE (known_type); CHECK_TYPEDEF (btype); if (btype != known_type ) { v = value_cast (btype, v); if (using_enc) *using_enc=1; } /* We can't use value_ind here, because it would want to use RTTI, and we'd waste a bunch of time figuring out we already know the type. Besides, we don't care about the type, just the actual pointer */ if (VALUE_ADDRESS (value_field (v, TYPE_VPTR_FIELDNO (known_type))) == 0) return NULL; vtbl=value_as_address(value_field(v,TYPE_VPTR_FIELDNO(known_type))); /* Try to find a symbol that is the vtable */ minsym=lookup_minimal_symbol_by_pc(vtbl); if (minsym==NULL || (demangled_name=DEPRECATED_SYMBOL_NAME (minsym))==NULL || !is_vtable_name (demangled_name)) return NULL; /* If we just skip the prefix, we get screwed by namespaces */ demangled_name=cplus_demangle(demangled_name,DMGL_PARAMS|DMGL_ANSI); *(strchr(demangled_name,' '))=0; /* Lookup the type for the name */ /* FIXME: chastain/2003-11-26: block=NULL is bogus. See pr gdb/1465. */ rtti_type = cp_lookup_rtti_type (demangled_name, NULL); if (rtti_type == NULL) return NULL; if (TYPE_N_BASECLASSES(rtti_type) > 1 && full && (*full) != 1) { if (top) *top=TYPE_BASECLASS_BITPOS(rtti_type,TYPE_VPTR_FIELDNO(rtti_type))/8; if (top && ((*top) >0)) { if (TYPE_LENGTH(rtti_type) > TYPE_LENGTH(known_type)) { if (full) *full=0; } else { if (full) *full=1; } } } else { if (full) *full=1; } return rtti_type; }
int c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int format, int deref_ref, int recurse, enum val_prettyprint pretty) { unsigned int i = 0; /* Number of characters printed */ unsigned len; struct type *elttype; unsigned eltlen; LONGEST val; CORE_ADDR addr; int vector_int8s = 0; int vector_floats = 0; CHECK_TYPEDEF (type); switch (TYPE_CODE (type)) { case TYPE_CODE_ARRAY: elttype = check_typedef (TYPE_TARGET_TYPE (type)); if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0) { eltlen = TYPE_LENGTH (elttype); len = TYPE_LENGTH (type) / eltlen; if (prettyprint_arrays) { print_spaces_filtered (2 + 2 * recurse, stream); } /* APPLE LOCAL: gdb will print the int8_t elements of a vector register as a string or as characters -- neither of which is what the user expects 99% of the time. Instead, detect that we're looking at a vector's int8_t array and treat it specially. */ if (eltlen == 1 && TYPE_VECTOR (type) && TYPE_CODE (elttype) == TYPE_CODE_INT && format == 0) { vector_int8s = 1; } /* APPLE LOCAL: Detect if we're about to print an array of v4_float or v2_doubles in a vector register */ if ((eltlen == 4 || eltlen == 8) && TYPE_VECTOR (type) && TYPE_CODE (elttype) == TYPE_CODE_FLT) { vector_floats = 1; } /* For an array of chars, print with string syntax. */ if (eltlen == 1 && ((TYPE_CODE (elttype) == TYPE_CODE_INT) || ((current_language->la_language == language_m2) && (TYPE_CODE (elttype) == TYPE_CODE_CHAR))) && (format == 0 || format == 's') && vector_int8s == 0) { /* If requested, look for the first null char and only print elements up to it. */ if (stop_print_at_null) { unsigned int temp_len; /* Look for a NULL char. */ for (temp_len = 0; (valaddr + embedded_offset)[temp_len] && temp_len < len && temp_len < print_max; temp_len++); len = temp_len; } LA_PRINT_STRING (stream, valaddr + embedded_offset, len, eltlen, 0); i = len; } else { fprintf_filtered (stream, "{"); /* 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; } /* If this is an array of int8_t's in a vector register, force it to print as decimal by default, not as decimal value + octal escaped char. */ if (format == 0 && vector_int8s) format = 'd'; /* If this is an array of v4_float or v2_doubles in a vector register, force it to print with the '%a' floating point hex formatter when "p/x" is used. Default formatter remains the '%g' style. */ if (format == 'x' && vector_floats) format = 'A'; val_print_array_elements (type, valaddr + embedded_offset, address, stream, format, deref_ref, recurse, pretty, i); fprintf_filtered (stream, "}"); } break; } /* Array of unspecified length: treat like pointer to first elt. */ addr = address; goto print_unpacked_pointer; case TYPE_CODE_PTR: if (format && format != 's') { print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); break; } if (vtblprint && cp_is_vtbl_ptr_type (type)) { /* Print the unmangled name if desired. */ /* Print vtable entry - we only get here if we ARE using -fvtable_thunks. (Otherwise, look under TYPE_CODE_STRUCT.) */ CORE_ADDR addr = extract_typed_address (valaddr + embedded_offset, type); print_function_pointer_address (addr, stream); break; } elttype = check_typedef (TYPE_TARGET_TYPE (type)); if (TYPE_CODE (elttype) == TYPE_CODE_METHOD) { cp_print_class_method (valaddr + embedded_offset, type, stream); } else if (TYPE_CODE (elttype) == TYPE_CODE_MEMBER) { cp_print_class_member (valaddr + embedded_offset, TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)), stream, "&"); } else { addr = unpack_pointer (type, valaddr + embedded_offset); print_unpacked_pointer: if (TYPE_CODE (elttype) == TYPE_CODE_FUNC) { /* Try to print what function it points to. */ print_function_pointer_address (addr, stream); /* Return value is irrelevant except for string pointers. */ return (0); } if (addressprint && format != 's') { deprecated_print_address_numeric (addr, 1, stream); } /* For a pointer to char or unsigned char, also print the string pointed to, unless pointer is null. */ /* FIXME: need to handle wchar_t here... */ if (TYPE_LENGTH (elttype) == 1 && TYPE_CODE (elttype) == TYPE_CODE_INT && (format == 0 || format == 's') && addr != 0) { i = val_print_string (addr, -1, TYPE_LENGTH (elttype), stream); } else if (cp_is_vtbl_member (type)) { /* print vtbl's nicely */ CORE_ADDR vt_address = unpack_pointer (type, valaddr + embedded_offset); struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (vt_address); if ((msymbol != NULL) && (vt_address == SYMBOL_VALUE_ADDRESS (msymbol))) { fputs_filtered (" <", stream); fputs_filtered (SYMBOL_PRINT_NAME (msymbol), stream); fputs_filtered (">", stream); } if (vt_address && vtblprint) { struct value *vt_val; struct symbol *wsym = (struct symbol *) NULL; struct type *wtype; struct block *block = (struct block *) NULL; int is_this_fld; if (msymbol != NULL) wsym = lookup_symbol (DEPRECATED_SYMBOL_NAME (msymbol), block, VAR_DOMAIN, &is_this_fld, NULL); if (wsym) { wtype = SYMBOL_TYPE (wsym); } else { wtype = TYPE_TARGET_TYPE (type); } vt_val = value_at (wtype, vt_address); common_val_print (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, including the terminating '\0' if we reached the end. val_print_string takes care including the terminating '\0' if necessary. */ return i; } break; case TYPE_CODE_MEMBER: error (_("not implemented: member type in c_val_print")); break; case TYPE_CODE_REF: elttype = check_typedef (TYPE_TARGET_TYPE (type)); if (TYPE_CODE (elttype) == TYPE_CODE_MEMBER) { cp_print_class_member (valaddr + embedded_offset, TYPE_DOMAIN_TYPE (elttype), stream, ""); break; } if (addressprint) { CORE_ADDR addr = extract_typed_address (valaddr + embedded_offset, type); fprintf_filtered (stream, "@"); deprecated_print_address_numeric (addr, 1, stream); if (deref_ref) fputs_filtered (": ", stream); } /* De-reference the reference. */ if (deref_ref) { if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) { struct value *deref_val = value_at (TYPE_TARGET_TYPE (type), unpack_pointer (lookup_pointer_type (builtin_type_void), valaddr + embedded_offset)); common_val_print (deref_val, stream, format, deref_ref, recurse, pretty); } else fputs_filtered ("???", stream); } break; case TYPE_CODE_UNION: if (recurse && !unionprint) { fprintf_filtered (stream, "{...}"); break; } /* Fall through. */ case TYPE_CODE_STRUCT: /*FIXME: Abstract this away */ if (vtblprint && cp_is_vtbl_ptr_type (type)) { /* Print the unmangled name if desired. */ /* Print vtable entry - we only get here if NOT using -fvtable_thunks. (Otherwise, look under TYPE_CODE_PTR.) */ int offset = (embedded_offset + TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8); struct type *field_type = TYPE_FIELD_TYPE (type, VTBL_FNADDR_OFFSET); CORE_ADDR addr = extract_typed_address (valaddr + offset, field_type); print_function_pointer_address (addr, stream); } else cp_print_value_fields (type, type, valaddr, embedded_offset, address, stream, format, recurse, pretty, NULL, 0); break; case TYPE_CODE_ENUM: if (format) { print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); break; } len = TYPE_NFIELDS (type); val = unpack_long (type, valaddr + embedded_offset); 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 { print_longest (stream, 'd', 0, val); } break; case TYPE_CODE_FUNC: if (format) { print_scalar_formatted (valaddr + embedded_offset, 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_BOOL: format = format ? format : output_format; if (format) print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); else { val = unpack_long (type, valaddr + embedded_offset); if (val == 0) fputs_filtered ("false", stream); else if (val == 1) fputs_filtered ("true", stream); else print_longest (stream, 'd', 0, val); } break; case TYPE_CODE_RANGE: /* FIXME: create_range_type does not set the unsigned bit in a range type (I think it probably should copy it from the target type), so we won't print values which are too large to fit in a signed integer correctly. */ /* FIXME: Doesn't handle ranges of enums correctly. (Can't just print with the target type, though, because the size of our type and the target type might differ). */ /* FALLTHROUGH */ case TYPE_CODE_INT: format = format ? format : output_format; if (format) { print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); } else { val_print_type_code_int (type, valaddr + embedded_offset, 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 + embedded_offset), stream); } } break; case TYPE_CODE_CHAR: format = format ? format : output_format; if (format) { print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); } else { val = unpack_long (type, valaddr + embedded_offset); if (TYPE_UNSIGNED (type)) fprintf_filtered (stream, "%u", (unsigned int) val); else fprintf_filtered (stream, "%d", (int) val); fputs_filtered (" ", stream); LA_PRINT_CHAR ((unsigned char) val, stream); } break; case TYPE_CODE_FLT: if (format) { print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); } else { print_floating (valaddr + embedded_offset, type, stream); } break; case TYPE_CODE_METHOD: { struct value *v = value_at (type, address); cp_print_class_method (value_contents (value_addr (v)), lookup_pointer_type (type), stream); break; } case TYPE_CODE_VOID: fprintf_filtered (stream, "void"); break; case TYPE_CODE_ERROR: /* APPLE LOCAL display error as unknown type */ fprintf_filtered (stream, _("<unknown 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; case TYPE_CODE_COMPLEX: if (format) print_scalar_formatted (valaddr + embedded_offset, TYPE_TARGET_TYPE (type), format, 0, stream); else print_floating (valaddr + embedded_offset, TYPE_TARGET_TYPE (type), stream); fprintf_filtered (stream, " + "); if (format) print_scalar_formatted (valaddr + embedded_offset + TYPE_LENGTH (TYPE_TARGET_TYPE (type)), TYPE_TARGET_TYPE (type), format, 0, stream); else print_floating (valaddr + embedded_offset + TYPE_LENGTH (TYPE_TARGET_TYPE (type)), TYPE_TARGET_TYPE (type), stream); fprintf_filtered (stream, " * I"); break; default: error (_("Invalid C/C++ type code %d in symbol table."), TYPE_CODE (type)); } gdb_flush (stream); return (0); }
static CORE_ADDR lm32_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int first_arg_reg = SIM_LM32_R1_REGNUM; int num_arg_regs = 8; int i; /* Set the return address. */ regcache_cooked_write_signed (regcache, SIM_LM32_RA_REGNUM, bp_addr); /* If we're returning a large struct, a pointer to the address to store it at is passed as a first hidden parameter. */ if (struct_return) { regcache_cooked_write_unsigned (regcache, first_arg_reg, struct_addr); first_arg_reg++; num_arg_regs--; sp -= 4; } /* Setup parameters. */ for (i = 0; i < nargs; i++) { struct value *arg = args[i]; struct type *arg_type = check_typedef (value_type (arg)); gdb_byte *contents; int len; int j; int reg; ULONGEST val; /* Promote small integer types to int. */ switch (TYPE_CODE (arg_type)) { case TYPE_CODE_INT: case TYPE_CODE_BOOL: case TYPE_CODE_CHAR: case TYPE_CODE_RANGE: case TYPE_CODE_ENUM: if (TYPE_LENGTH (arg_type) < 4) { arg_type = builtin_type (gdbarch)->builtin_int32; arg = value_cast (arg_type, arg); } break; } /* FIXME: Handle structures. */ contents = (gdb_byte *) value_contents (arg); len = TYPE_LENGTH (arg_type); val = extract_unsigned_integer (contents, len, byte_order); /* First num_arg_regs parameters are passed by registers, and the rest are passed on the stack. */ if (i < num_arg_regs) regcache_cooked_write_unsigned (regcache, first_arg_reg + i, val); else { write_memory (sp, (void *) &val, len); sp -= 4; } } /* Update stack pointer. */ regcache_cooked_write_signed (regcache, SIM_LM32_SP_REGNUM, sp); /* Return adjusted stack pointer. */ return sp; }
static void convert_one_symbol (struct compile_c_instance *context, struct symbol *sym, int is_global, int is_local) { gcc_type sym_type; const char *filename = symbol_symtab (sym)->filename; unsigned short line = SYMBOL_LINE (sym); error_symbol_once (context, sym); if (SYMBOL_CLASS (sym) == LOC_LABEL) sym_type = 0; else sym_type = convert_type (context, SYMBOL_TYPE (sym)); if (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN) { /* Binding a tag, so we don't need to build a decl. */ C_CTX (context)->c_ops->tagbind (C_CTX (context), SYMBOL_NATURAL_NAME (sym), sym_type, filename, line); } else { gcc_decl decl; enum gcc_c_symbol_kind kind; CORE_ADDR addr = 0; char *symbol_name = NULL; switch (SYMBOL_CLASS (sym)) { case LOC_TYPEDEF: kind = GCC_C_SYMBOL_TYPEDEF; break; case LOC_LABEL: kind = GCC_C_SYMBOL_LABEL; addr = SYMBOL_VALUE_ADDRESS (sym); break; case LOC_BLOCK: kind = GCC_C_SYMBOL_FUNCTION; addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); if (is_global && TYPE_GNU_IFUNC (SYMBOL_TYPE (sym))) addr = gnu_ifunc_resolve_addr (target_gdbarch (), addr); break; case LOC_CONST: if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_ENUM) { /* Already handled by convert_enum. */ return; } C_CTX (context)->c_ops->build_constant (C_CTX (context), sym_type, SYMBOL_NATURAL_NAME (sym), SYMBOL_VALUE (sym), filename, line); return; case LOC_CONST_BYTES: error (_("Unsupported LOC_CONST_BYTES for symbol \"%s\"."), SYMBOL_PRINT_NAME (sym)); case LOC_UNDEF: internal_error (__FILE__, __LINE__, _("LOC_UNDEF found for \"%s\"."), SYMBOL_PRINT_NAME (sym)); case LOC_COMMON_BLOCK: error (_("Fortran common block is unsupported for compilation " "evaluaton of symbol \"%s\"."), SYMBOL_PRINT_NAME (sym)); case LOC_OPTIMIZED_OUT: error (_("Symbol \"%s\" cannot be used for compilation evaluation " "as it is optimized out."), SYMBOL_PRINT_NAME (sym)); case LOC_COMPUTED: if (is_local) goto substitution; /* Probably TLS here. */ warning (_("Symbol \"%s\" is thread-local and currently can only " "be referenced from the current thread in " "compiled code."), SYMBOL_PRINT_NAME (sym)); /* FALLTHROUGH */ case LOC_UNRESOLVED: /* 'symbol_name' cannot be used here as that one is used only for local variables from compile_dwarf_expr_to_c. Global variables can be accessed by GCC only by their address, not by their name. */ { struct value *val; struct frame_info *frame = NULL; if (symbol_read_needs_frame (sym)) { frame = get_selected_frame (NULL); if (frame == NULL) error (_("Symbol \"%s\" cannot be used because " "there is no selected frame"), SYMBOL_PRINT_NAME (sym)); } val = read_var_value (sym, frame); if (VALUE_LVAL (val) != lval_memory) error (_("Symbol \"%s\" cannot be used for compilation " "evaluation as its address has not been found."), SYMBOL_PRINT_NAME (sym)); kind = GCC_C_SYMBOL_VARIABLE; addr = value_address (val); } break; case LOC_REGISTER: case LOC_ARG: case LOC_REF_ARG: case LOC_REGPARM_ADDR: case LOC_LOCAL: substitution: kind = GCC_C_SYMBOL_VARIABLE; symbol_name = symbol_substitution_name (sym); break; case LOC_STATIC: kind = GCC_C_SYMBOL_VARIABLE; addr = SYMBOL_VALUE_ADDRESS (sym); break; case LOC_FINAL_VALUE: default: gdb_assert_not_reached ("Unreachable case in convert_one_symbol."); } /* Don't emit local variable decls for a raw expression. */ if (context->base.scope != COMPILE_I_RAW_SCOPE || symbol_name == NULL) { decl = C_CTX (context)->c_ops->build_decl (C_CTX (context), SYMBOL_NATURAL_NAME (sym), kind, sym_type, symbol_name, addr, filename, line); C_CTX (context)->c_ops->bind (C_CTX (context), decl, is_global); } xfree (symbol_name); } }