📄 valprint.c
字号:
else fputs_filtered ("???", stream); } } break; case TYPE_CODE_UNION: if (recurse && !unionprint) { fprintf_filtered (stream, "{...}"); break; } /* Fall through. */ case TYPE_CODE_STRUCT: if (vtblprint && is_vtbl_ptr_type(type)) { /* Print the unmangled name if desired. */ print_address_demangle(*((int *) (valaddr + /* FIXME bytesex */ TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8)), stream, demangle); break; } val_print_fields (type, valaddr, stream, format, recurse, pretty, 0); break; case TYPE_CODE_ENUM: if (format) { print_scalar_formatted (valaddr, type, format, 0, stream); break; } len = TYPE_NFIELDS (type); val = unpack_long (builtin_type_int, valaddr); for (i = 0; i < len; i++) { QUIT; if (val == TYPE_FIELD_BITPOS (type, i)) break; } if (i < len) fputs_filtered (TYPE_FIELD_NAME (type, i), stream); else#ifdef LONG_LONG fprintf_filtered (stream, "%lld", val);#else fprintf_filtered (stream, "%ld", val);#endif break; case TYPE_CODE_FUNC: if (format) { print_scalar_formatted (valaddr, type, format, 0, stream); break; } /* FIXME, we should consider, at least for ANSI C language, eliminating the distinction made between FUNCs and POINTERs to FUNCs. */ fprintf_filtered (stream, "{"); type_print (type, "", stream, -1); fprintf_filtered (stream, "} "); /* Try to print what function it points to, and its address. */ print_address_demangle (address, stream, demangle); break; case TYPE_CODE_INT: if (format || output_format) { print_scalar_formatted (valaddr, type, format? format: output_format, 0, stream); break; } if (TYPE_LENGTH (type) > sizeof (LONGEST)) { if (TYPE_UNSIGNED (type)) { /* First figure out whether the number in fact has zeros in all its bytes more significant than least significant sizeof (LONGEST) ones. */ char *p; /* Pointer to first (i.e. lowest address) nonzero character. */ char *first_addr; len = TYPE_LENGTH (type);#if TARGET_BYTE_ORDER == BIG_ENDIAN for (p = valaddr; len > sizeof (LONGEST) && p < valaddr + TYPE_LENGTH (type); p++)#else /* Little endian. */ first_addr = valaddr; for (p = valaddr + TYPE_LENGTH (type); len > sizeof (LONGEST) && p >= valaddr; p--)#endif /* Little endian. */ { if (*p == 0) len--; else break; }#if TARGET_BYTE_ORDER == BIG_ENDIAN first_addr = p;#endif if (len <= sizeof (LONGEST)) { /* We can print it in decimal. */ fprintf_filtered (stream, #if defined (LONG_LONG) "%llu",#else "%lu",#endif unpack_long (BUILTIN_TYPE_LONGEST, first_addr)); } else { /* It is big, so print it in hex. */ print_hex_chars (stream, (unsigned char *)first_addr, len); } } else { /* Signed. One could assume two's complement (a reasonable assumption, I think) and do better than this. */ print_hex_chars (stream, (unsigned char *)valaddr, TYPE_LENGTH (type)); } break; }#ifdef PRINT_TYPELESS_INTEGER PRINT_TYPELESS_INTEGER (stream, type, unpack_long (type, valaddr));#else /* No format type is specified. Just use /x for unsigned and /d for signed. */ print_scalar_formatted (valaddr, type, TYPE_UNSIGNED (type) ? 'x' : 'd', 0, stream);#endif if (TYPE_LENGTH (type) == 1) { fprintf_filtered (stream, " '"); printchar ((unsigned char) unpack_long (type, valaddr), stream, '\''); fprintf_filtered (stream, "'"); } break; case TYPE_CODE_FLT: if (format) print_scalar_formatted (valaddr, type, format, 0, stream); else print_floating (valaddr, type, stream); break; case TYPE_CODE_VOID: fprintf_filtered (stream, "void"); break; case TYPE_CODE_UNDEF: /* This happens (without TYPE_FLAG_STUB set) on systems which don't use dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar" and no complete type for struct foo in that file. */ fprintf_filtered (stream, "<unknown struct>"); break; case TYPE_CODE_ERROR: fprintf_filtered (stream, "?"); break; case TYPE_CODE_RANGE: /* FIXME, we should not ever have to print one of these yet. */ fprintf_filtered (stream, "<range type>"); break; default: error ("Invalid type code in symbol table."); } fflush (stream); return 0;}/* Print a description of a type in the format of a typedef for the current language. NEW is the new name for a type TYPE. */voidtypedef_print (type, new, stream) struct type *type; struct symbol *new; FILE *stream;{ switch (current_language->la_language) {#ifdef _LANG_c case language_c: case language_cplus: fprintf_filtered(stream, "typedef "); type_print(type,"",stream,0); if(TYPE_NAME ((SYMBOL_TYPE (new))) == 0 || 0 != strcmp (TYPE_NAME ((SYMBOL_TYPE (new))), SYMBOL_NAME (new))) fprintf_filtered(stream, " %s", SYMBOL_NAME(new)); break;#endif#ifdef _LANG_m2 case language_m2: fprintf_filtered(stream, "TYPE "); if(!TYPE_NAME(SYMBOL_TYPE(new)) || strcmp (TYPE_NAME(SYMBOL_TYPE(new)), SYMBOL_NAME(new))) fprintf_filtered(stream, "%s = ", SYMBOL_NAME(new)); else fprintf_filtered(stream, "<builtin> = "); type_print(type,"",stream,0); break;#endif default: error("Language not supported."); } fprintf_filtered(stream, ";\n");}/* Print a description of a type TYPE in the form of a declaration of a variable named VARSTRING. (VARSTRING is demangled if necessary.) Output goes to STREAM (via stdio). If SHOW is positive, we show the contents of the outermost level of structure even if there is a type name that could be used instead. If SHOW is negative, we never show the details of elements' types. */voidtype_print (type, varstring, stream, show) struct type *type; char *varstring; FILE *stream; int show;{ type_print_1 (type, varstring, stream, show, 0);}/* LEVEL is the depth to indent lines by. */voidtype_print_1 (type, varstring, stream, show, level) struct type *type; char *varstring; FILE *stream; int show; int level;{ register enum type_code code; char *demangled = NULL; int demangled_args; type_print_base (type, stream, show, level); code = TYPE_CODE (type); if ((varstring && *varstring) || /* Need a space if going to print stars or brackets; but not if we will print just a type name. */ ((show > 0 || TYPE_NAME (type) == 0) && (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC || code == TYPE_CODE_METHOD || code == TYPE_CODE_ARRAY || code == TYPE_CODE_MEMBER || code == TYPE_CODE_REF))) fprintf_filtered (stream, " "); type_print_varspec_prefix (type, stream, show, 0); /* See if the name has a C++ demangled equivalent, and if so, print that instead. */ if (demangle) { demangled = cplus_demangle (varstring, DMGL_ANSI | DMGL_PARAMS); } fputs_filtered ((demangled != NULL) ? demangled : varstring, stream); /* For demangled function names, we have the arglist as part of the name, so don't print an additional pair of ()'s */ demangled_args = (demangled != NULL) && (code == TYPE_CODE_FUNC); type_print_varspec_suffix (type, stream, show, 0, demangled_args); if (demangled) { free (demangled); }}/* Print the method arguments ARGS to the file STREAM. */static voidtype_print_method_args (args, prefix, varstring, staticp, stream) struct type **args; char *prefix, *varstring; int staticp; FILE *stream;{ int i; fputs_demangled (prefix, stream, DMGL_ANSI | DMGL_PARAMS); fputs_demangled (varstring, stream, DMGL_ANSI | DMGL_PARAMS); fputs_filtered (" (", stream); if (args && args[!staticp] && args[!staticp]->code != TYPE_CODE_VOID) { i = !staticp; /* skip the class variable */ while (1) { type_print (args[i++], "", stream, 0); if (!args[i]) { fprintf_filtered (stream, " ..."); break; } else if (args[i]->code != TYPE_CODE_VOID) { fprintf_filtered (stream, ", "); } else break; } } fprintf_filtered (stream, ")");} /* If TYPE is a derived type, then print out derivation information. Print only the actual base classes of this type, not the base classes of the base classes. I.E. for the derivation hierarchy: class A { int a; }; class B : public A {int b; }; class C : public B {int c; }; Print the type of class C as: class C : public B { int c; } Not as the following (like gdb used to), which is not legal C++ syntax for derived types and may be confused with the multiple inheritance form: class C : public B : public A { int c; } In general, gdb should try to print the types as closely as possible to the form that they appear in the source code. */static voidtype_print_derivation_info (stream, type) FILE *stream; struct type *type;{ char *name; int i; for (i = 0; i < TYPE_N_BASECLASSES (type); i++) { fputs_filtered (i == 0 ? ": " : ", ", stream); fprintf_filtered (stream, "%s%s ", BASETYPE_VIA_PUBLIC (type, i) ? "public" : "private", BASETYPE_VIA_VIRTUAL(type, i) ? " virtual" : ""); name = type_name_no_tag (TYPE_BASECLASS (type, i)); fprintf_filtered (stream, "%s", name ? name : "(null)"); } if (i > 0) { fputs_filtered (" ", stream); }}/* Print any asterisks or open-parentheses needed before the variable name (to describe its type). On outermost call, pass 0 for PASSED_A_PTR. On outermost call, SHOW > 0 means should ignore any typename for TYPE and show its details. SHOW is always zero on recursive calls. */static voidtype_print_varspec_prefix (type, stream, show, passed_a_ptr) struct type *type; FILE *stream; int show; int passed_a_ptr;{ char *name; if (type == 0) return; if (TYPE_NAME (type) && show <= 0) return; QUIT; switch (TYPE_CODE (type)) { case TYPE_CODE_PTR: type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1); fprintf_filtered (stream, "*"); break; case TYPE_CODE_MEMBER: if (passed_a_ptr) fprintf_filtered (stream, "("); type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0); fprintf_filtered (stream, " "); name = type_name_no_tag (TYPE_DOMAIN_TYPE (type)); if (name) fputs_filtered (name, stream); else type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0, passed_a_ptr); fprintf_filtered (stream, "::"); break; case TYPE_CODE_METHOD: if (passed_a_ptr) fprintf (stream, "("); type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0); if (passed_a_ptr) { fprintf_filtered (stream, " "); type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0, passed_a_ptr); fprintf_filtered (stream, "::"); } break; case TYPE_CODE_REF: type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1); fprintf_filtered (stream, "&"); break; case TYPE_CODE_FUNC: type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0); if (passed_a_ptr) fprintf_filtered (stream, "("); break; case TYPE_CODE_ARRAY: type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0); if (passed_a_ptr) fprintf_filtered (stream, "("); 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_PASCAL_ARRAY: /* These types need no prefix. They are listed here so that gcc -Wall will reveal any types that haven't been handled. */ break; }}static voidtype_print_args (type, stream) struct type *type; FILE *stream;{ int i; struct type **args; fprintf_filtered (stream, "("); args = TYPE_ARG_TYPES (type); if (args != NULL) { if (args[1] == NULL) { fprintf_filtered (stream, "..."); } else { for (i = 1; args[i] != NULL && args[i]->code != TYPE_CODE_VOID; i++) { type_print_1 (args[i], "", stream, -1, 0); if (args[i+1] == NULL) { fprintf_filtered (stream, "..."); } else if (args[i+1]->code != TYPE_CODE_VOID) { fprintf_filtered (stream, ","); wrap_here (" "); } } } } fprintf_filtered (stream, ")");}/* Print any array sizes, function arguments or close parentheses needed after the variable name (to describe its type). Args work like type_print_varspec_prefix. */static voidtype_print_varspec_suffix (type, stream, show, passed_a_ptr, demangled_args) struct type *type; 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) fprintf_filtered (stream, "%d", (TYPE_LENGTH (type) / TYPE_LENGTH (TYPE_TARGET_TYPE (type)))); fprintf_filtered (stream, "]"); type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0); break; case TYPE_CODE_MEMBER: if (passed_a_ptr) fprintf_filtered (stream, ")"); type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0); break; case TYPE_CODE_METHOD: if (passed_a_ptr)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -