struct type * expr_typecheck(struct expr *e) { if(!e) return type_create(TYPE_VOID, 0, 0, 0); struct type *L = expr_typecheck(e->left); struct type *R = expr_typecheck(e->right); switch(e->kind) { case EXPR_ASSIGNMENT: if(L->kind == TYPE_FUNCTION){ printf("type error: cannot use assignment operator on function "); expr_print(e->left); error_count++; } if(R->kind == TYPE_FUNCTION){ printf("type error: cannot use assignment operator on function "); expr_print(e->right); error_count++; } if(!type_compare(L, R)){ printf("type error: cannot assign "); type_print(R); printf(" "); expr_print(e->right); printf(" to "); type_print(L); printf(" "); expr_print(e->left); printf("\n"); error_count++; } return L; break; case EXPR_GE: if(L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER){ printf("type error: cannot use operator >= to compare "); type_print(L); printf(" "); expr_print(e->left); printf(" and "); type_print(R); printf(" "); expr_print(e->right); printf(". This operator can only be used on two integers.\n"); error_count++; } return type_create(TYPE_BOOLEAN, 0, 0, 0); break; case EXPR_LE: if(L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER){ printf("type error: cannot use operator <= to compare "); type_print(L); expr_print(e->left); printf(" and "); type_print(R); expr_print(e->right); printf(". This operator can only be used on two integers.\n"); error_count++; } return type_create(TYPE_BOOLEAN, 0, 0, 0); break; case EXPR_GT: if(L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER){ printf("type error: cannot use operator > to compare "); type_print(L); printf(" "); expr_print(e->left); printf(" and "); type_print(R); printf(" "); expr_print(e->right); printf(". This operator can only be used on two integers.\n"); error_count++; } return type_create(TYPE_BOOLEAN, 0, 0, 0); break; case EXPR_LT: if(L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER){ printf("type error: cannot use operator < to compare "); type_print(L); printf(" "); expr_print(e->left); printf(" and "); type_print(R); printf(" "); expr_print(e->right); printf(". This operator can only be used on two integers.\n"); error_count++; } return type_create(TYPE_BOOLEAN, 0, 0, 0); break; case EXPR_EQ: if(L->kind == TYPE_ARRAY){ printf("type error: cannot use operator == on array "); expr_print(e->left); printf("\n"); error_count++; } else if(L->kind == TYPE_FUNCTION){ printf("type error: cannot use operator == on function "); expr_print(e->left); printf("\n"); error_count++; } if(R->kind == TYPE_ARRAY){ printf("type error: cannot use operator == on array "); expr_print(e->right); printf("\n"); error_count++; } else if(R->kind == TYPE_FUNCTION){ printf("type error: cannot use operator == on function "); expr_print(e->right); printf("\n"); error_count++; } if(L->kind != R->kind){ printf("type error: cannot use operator == to compare "); type_print(L); printf(" "); expr_print(e->left); printf(" and "); type_print(R); printf(" "); expr_print(e->right); printf("\n"); error_count++; } return type_create(TYPE_BOOLEAN, 0, 0, 0); break; case EXPR_NE: if(L->kind == TYPE_ARRAY){ printf("type error: cannot use operator != on array "); expr_print(e->left); printf("\n"); error_count++; } else if(L->kind == TYPE_FUNCTION){ printf("type error: cannot use operator != on function "); expr_print(e->left); printf("\n"); error_count++; } if(R->kind == TYPE_ARRAY){ printf("type error: cannot use operator != on array "); expr_print(e->right); printf("\n"); error_count++; } else if(R->kind == TYPE_FUNCTION){ printf("type error: cannot use operator != on function "); expr_print(e->right); printf("\n"); error_count++; } if(L->kind != R->kind){ printf("type error: cannot use operator != to compare "); type_print(L); printf(" "); expr_print(e->left); printf(" and "); type_print(R); printf(" "); expr_print(e->right); printf("\n"); error_count++; } return type_create(TYPE_BOOLEAN, 0, 0, 0); break; case EXPR_ADD: if(L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER){ printf("type error: cannot add "); type_print(L); printf(" "); expr_print(e->left); printf(" to "); type_print(R); printf(" "); expr_print(e->right); printf("\n"); error_count++; } return type_create(TYPE_INTEGER, 0, 0, 0); break; case EXPR_SUB: if((L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER) && L->kind != TYPE_VOID){ printf("type error: cannot subtract "); type_print(R); printf(" "); expr_print(e->right); printf(" from "); type_print(L); printf(" "); expr_print(e->left); printf("\n"); error_count++; } return type_create(TYPE_INTEGER, 0, 0, 0); break; case EXPR_MUL: if(L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER){ printf("type error: cannot multiply "); type_print(L); printf(" "); expr_print(e->left); printf(" with "); type_print(R); printf(" "); expr_print(e->right); printf("\n"); error_count++; } return type_create(TYPE_INTEGER, 0, 0, 0); break; case EXPR_DIV: if(L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER){ printf("type error: cannot divide "); type_print(R); printf(" "); expr_print(e->right); printf(" from "); type_print(L); printf(" "); expr_print(e->left); printf("\n"); error_count++; } return type_create(TYPE_INTEGER, 0, 0, 0); break; case EXPR_MOD: if(L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER){ printf("type error: cannot perform modular division "); type_print(L); printf(" "); expr_print(e->left); printf(" mod "); type_print(R); printf(" "); expr_print(e->right); printf("\n"); error_count++; } return type_create(TYPE_INTEGER, 0, 0, 0); break; case EXPR_POW: if(L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER){ printf("type error: cannot exponentiate "); type_print(L); printf(" "); expr_print(e->left); printf(" ^ "); type_print(R); printf(" "); expr_print(e->right); printf("\n"); error_count++; } return type_create(TYPE_INTEGER, 0, 0, 0); break; case EXPR_POSTFIX_PLUS: if(L->kind != TYPE_INTEGER){ printf("type error: cannot increment "); type_print(L); printf(" "); expr_print(e->left); printf("\n"); error_count++; } if(e->left->kind != EXPR_IDENT) { printf("type error: cannot increment non-variable "); expr_print(e->left); printf("\n"); error_count++; } return type_create(TYPE_INTEGER, 0, 0, 0); break; case EXPR_POSTFIX_MINUS: if(L->kind != TYPE_INTEGER){ printf("type error: cannot decrement "); type_print(L); printf(" "); expr_print(e->left); printf("\n"); error_count++; } if(e->left->kind != EXPR_IDENT) { printf("type error: cannot decrement non-variable "); expr_print(e->left); printf("\n"); error_count++; } return type_create(TYPE_INTEGER, 0, 0, 0); break; case EXPR_LOGICAL_NOT: if(R->kind != TYPE_BOOLEAN){ printf("type error: cannot negate non-boolean "); type_print(R); printf(" "); expr_print(e->right); printf("\n"); error_count++; } return type_create(TYPE_BOOLEAN, 0, 0, 0); break; case EXPR_LOGICAL_AND: if(L->kind != TYPE_BOOLEAN || R->kind != TYPE_BOOLEAN){ printf("type error: cannot use && to compare non-boolean "); type_print(L); printf(" "); expr_print(e->left); printf(" and "); type_print(R); printf(" "); expr_print(e->right); printf("\n"); error_count++; } return type_create(TYPE_BOOLEAN, 0, 0, 0); break; case EXPR_LOGICAL_OR: if(L->kind != TYPE_BOOLEAN || R->kind != TYPE_BOOLEAN){ printf("type error: cannot use && to compare non-boolean "); type_print(L); printf(" "); expr_print(e->left); printf(" and "); type_print(R); printf(" "); expr_print(e->right); printf("\n"); error_count++; } return type_create(TYPE_BOOLEAN, 0, 0, 0); break; case EXPR_INTEGER_LITERAL: return type_create(TYPE_INTEGER, 0, 0, 0); break; case EXPR_STRING_LITERAL: return type_create(TYPE_STRING, 0, 0, 0); break; case EXPR_CHAR_LITERAL: return type_create(TYPE_CHARACTER, 0, 0, 0); break; case EXPR_TRUE: return type_create(TYPE_BOOLEAN, 0, 0, 0); break; case EXPR_FALSE: return type_create(TYPE_BOOLEAN, 0, 0, 0); break; case EXPR_IDENT: return e->symbol->type; break; case EXPR_FCALL: if(L->kind != TYPE_FUNCTION) { printf("type error: cannot execute function call to non-function "); type_print(L); printf(" "); expr_print(e->left); printf("\n"); error_count++; } function_typecheck(e->left->name, e->right, e->left->symbol->type->params, 1, function_params(e)+1); return L->subtype; break; case EXPR_ARRCALL: if(L->kind != TYPE_ARRAY) { printf("type error: cannot index into non-array "); type_print(L); printf(" "); expr_print(e->left); printf("\n"); error_count++; } //return the number of subtypes that the index requires int i; struct type *T = L; for(i = 0; i < array_call_subtypes(e->right); i++){ T = T->subtype; } return T; break; case EXPR_ARRINDEX: if(L->kind != TYPE_INTEGER){ printf("type error: cannot index an array using non-integer "); type_print(L); printf(" "); expr_print(e->left); printf("\n"); error_count++; } return type_create(TYPE_INTEGER, 0, 0, 0); break; case EXPR_PARENS: return R; break; case EXPR_BLOCK: return type_create(TYPE_ARRAY, 0, R, exprs_in_block(e)-1); break; case EXPR_BLOCK_COMMA: if(L->kind != R->kind && R->kind != TYPE_VOID){ printf("type error: cannot have "); type_print(L); printf(" "); expr_print(e->left); printf(" and "); type_print(R); printf(" "); expr_print(e->right); printf(" in the same expression list\n"); error_count++; return type_create(TYPE_VOID,0,0,0); } return L; break; case EXPR_COMMA: return R; break; } }
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); }
int dump_subexp_body_standard (struct expression *exp, struct ui_file *stream, int elt) { int opcode = exp->elts[elt++].opcode; switch (opcode) { case TERNOP_COND: case TERNOP_SLICE: case TERNOP_SLICE_COUNT: elt = dump_subexp (exp, stream, elt); case BINOP_ADD: case BINOP_SUB: case BINOP_MUL: case BINOP_DIV: case BINOP_REM: case BINOP_MOD: case BINOP_LSH: case BINOP_RSH: case BINOP_LOGICAL_AND: case BINOP_LOGICAL_OR: case BINOP_BITWISE_AND: case BINOP_BITWISE_IOR: case BINOP_BITWISE_XOR: case BINOP_EQUAL: case BINOP_NOTEQUAL: case BINOP_LESS: case BINOP_GTR: case BINOP_LEQ: case BINOP_GEQ: case BINOP_REPEAT: case BINOP_ASSIGN: case BINOP_COMMA: case BINOP_SUBSCRIPT: case BINOP_EXP: case BINOP_MIN: case BINOP_MAX: case BINOP_INTDIV: case BINOP_ASSIGN_MODIFY: case BINOP_VAL: case BINOP_INCL: case BINOP_EXCL: case BINOP_CONCAT: case BINOP_IN: case BINOP_RANGE: case BINOP_END: elt = dump_subexp (exp, stream, elt); case UNOP_NEG: case UNOP_LOGICAL_NOT: case UNOP_COMPLEMENT: case UNOP_IND: case UNOP_ADDR: case UNOP_PREINCREMENT: case UNOP_POSTINCREMENT: case UNOP_PREDECREMENT: case UNOP_POSTDECREMENT: case UNOP_SIZEOF: case UNOP_PLUS: case UNOP_CAP: case UNOP_CHR: case UNOP_ORD: case UNOP_ABS: case UNOP_FLOAT: case UNOP_HIGH: case UNOP_MAX: case UNOP_MIN: case UNOP_ODD: case UNOP_TRUNC: case UNOP_LOWER: case UNOP_UPPER: case UNOP_LENGTH: case UNOP_CARD: case UNOP_CHMAX: case UNOP_CHMIN: elt = dump_subexp (exp, stream, elt); break; case OP_LONG: fprintf_filtered (stream, "Type @"); gdb_print_host_address (exp->elts[elt].type, stream); fprintf_filtered (stream, " ("); type_print (exp->elts[elt].type, NULL, stream, 0); fprintf_filtered (stream, "), value %ld (0x%lx)", (long) exp->elts[elt + 1].longconst, (long) exp->elts[elt + 1].longconst); elt += 3; break; case OP_DOUBLE: fprintf_filtered (stream, "Type @"); gdb_print_host_address (exp->elts[elt].type, stream); fprintf_filtered (stream, " ("); type_print (exp->elts[elt].type, NULL, stream, 0); fprintf_filtered (stream, "), value %g", (double) exp->elts[elt + 1].doubleconst); elt += 3; break; case OP_VAR_VALUE: fprintf_filtered (stream, "Block @"); gdb_print_host_address (exp->elts[elt].block, stream); fprintf_filtered (stream, ", symbol @"); gdb_print_host_address (exp->elts[elt + 1].symbol, stream); fprintf_filtered (stream, " (%s)", DEPRECATED_SYMBOL_NAME (exp->elts[elt + 1].symbol)); elt += 3; break; case OP_LAST: fprintf_filtered (stream, "History element %ld", (long) exp->elts[elt].longconst); elt += 2; break; case OP_REGISTER: fprintf_filtered (stream, "Register %ld", (long) exp->elts[elt].longconst); elt += 2; break; case OP_INTERNALVAR: fprintf_filtered (stream, "Internal var @"); gdb_print_host_address (exp->elts[elt].internalvar, stream); fprintf_filtered (stream, " (%s)", exp->elts[elt].internalvar->name); elt += 2; break; case OP_FUNCALL: { int i, nargs; nargs = longest_to_int (exp->elts[elt].longconst); fprintf_filtered (stream, "Number of args: %d", nargs); elt += 2; for (i = 1; i <= nargs + 1; i++) elt = dump_subexp (exp, stream, elt); } break; case OP_ARRAY: { int lower, upper; int i; lower = longest_to_int (exp->elts[elt].longconst); upper = longest_to_int (exp->elts[elt + 1].longconst); fprintf_filtered (stream, "Bounds [%d:%d]", lower, upper); elt += 3; for (i = 1; i <= upper - lower + 1; i++) elt = dump_subexp (exp, stream, elt); } break; case UNOP_MEMVAL: case UNOP_CAST: fprintf_filtered (stream, "Type @"); gdb_print_host_address (exp->elts[elt].type, stream); fprintf_filtered (stream, " ("); type_print (exp->elts[elt].type, NULL, stream, 0); fprintf_filtered (stream, ")"); elt = dump_subexp (exp, stream, elt + 2); break; case OP_TYPE: fprintf_filtered (stream, "Type @"); gdb_print_host_address (exp->elts[elt].type, stream); fprintf_filtered (stream, " ("); type_print (exp->elts[elt].type, NULL, stream, 0); fprintf_filtered (stream, ")"); elt += 2; break; case STRUCTOP_STRUCT: case STRUCTOP_PTR: { char *elem_name; int len; len = longest_to_int (exp->elts[elt].longconst); elem_name = &exp->elts[elt + 1].string; fprintf_filtered (stream, "Element name: `%.*s'", len, elem_name); elt = dump_subexp (exp, stream, elt + 3 + BYTES_TO_EXP_ELEM (len + 1)); } break; case OP_SCOPE: { char *elem_name; int len; fprintf_filtered (stream, "Type @"); gdb_print_host_address (exp->elts[elt].type, stream); fprintf_filtered (stream, " ("); type_print (exp->elts[elt].type, NULL, stream, 0); fprintf_filtered (stream, ") "); len = longest_to_int (exp->elts[elt + 1].longconst); elem_name = &exp->elts[elt + 2].string; fprintf_filtered (stream, "Field name: `%.*s'", len, elem_name); elt += 4 + BYTES_TO_EXP_ELEM (len + 1); } break; default: case OP_NULL: case STRUCTOP_MEMBER: case STRUCTOP_MPTR: case MULTI_SUBSCRIPT: case OP_F77_UNDETERMINED_ARGLIST: case OP_COMPLEX: case OP_STRING: case OP_BITSTRING: case OP_BOOL: case OP_M2_STRING: case OP_THIS: case OP_LABELED: case OP_NAME: case OP_EXPRSTRING: fprintf_filtered (stream, "Unknown format"); } return elt; }
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; }
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; } }
static void java_type_print_base (struct type *type, struct ui_file *stream, int show, int level, const struct type_print_options *flags) { 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; } type = check_typedef (type); switch (TYPE_CODE (type)) { case TYPE_CODE_PTR: java_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level, flags); 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 (startswith (TYPE_FIELD_NAME (type, i), "_vptr") && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5])) continue; /* Don't print the dummy field "class". */ if (startswith (TYPE_FIELD_NAME (type, i), "class")) 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, flags); 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; const char *method_name; const 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++) { const char *real_physname; const char *p; char *physname; 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 = (char *) alloca (p - real_physname + 1); memcpy (physname, real_physname, p - real_physname); physname[p - real_physname] = '\0'; is_full_physname_constructor = (TYPE_FN_FIELD_CONSTRUCTOR (f, j) || 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 = gdb_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, flags); } }
int dump_subexp_body_standard (struct expression *exp, struct ui_file *stream, int elt) { int opcode = exp->elts[elt++].opcode; switch (opcode) { case TERNOP_COND: case TERNOP_SLICE: elt = dump_subexp (exp, stream, elt); /* FALL THROUGH */ case BINOP_ADD: case BINOP_SUB: case BINOP_MUL: case BINOP_DIV: case BINOP_REM: case BINOP_MOD: case BINOP_LSH: case BINOP_RSH: case BINOP_LOGICAL_AND: case BINOP_LOGICAL_OR: case BINOP_BITWISE_AND: case BINOP_BITWISE_IOR: case BINOP_BITWISE_XOR: case BINOP_EQUAL: case BINOP_NOTEQUAL: case BINOP_LESS: case BINOP_GTR: case BINOP_LEQ: case BINOP_GEQ: case BINOP_REPEAT: case BINOP_ASSIGN: case BINOP_COMMA: case BINOP_SUBSCRIPT: case BINOP_EXP: case BINOP_MIN: case BINOP_MAX: case BINOP_INTDIV: case BINOP_ASSIGN_MODIFY: case BINOP_VAL: case BINOP_CONCAT: case BINOP_IN: case BINOP_RANGE: case BINOP_END: case STRUCTOP_MEMBER: case STRUCTOP_MPTR: elt = dump_subexp (exp, stream, elt); /* FALL THROUGH */ case UNOP_NEG: case UNOP_LOGICAL_NOT: case UNOP_COMPLEMENT: case UNOP_IND: case UNOP_ADDR: case UNOP_PREINCREMENT: case UNOP_POSTINCREMENT: case UNOP_PREDECREMENT: case UNOP_POSTDECREMENT: case UNOP_SIZEOF: case UNOP_PLUS: case UNOP_CAP: case UNOP_CHR: case UNOP_ORD: case UNOP_ABS: case UNOP_FLOAT: case UNOP_HIGH: case UNOP_MAX: case UNOP_MIN: case UNOP_ODD: case UNOP_TRUNC: elt = dump_subexp (exp, stream, elt); break; case OP_LONG: fprintf_filtered (stream, "Type @"); gdb_print_host_address (exp->elts[elt].type, stream); fprintf_filtered (stream, " ("); type_print (exp->elts[elt].type, NULL, stream, 0); fprintf_filtered (stream, "), value %ld (0x%lx)", (long) exp->elts[elt + 1].longconst, (long) exp->elts[elt + 1].longconst); elt += 3; break; case OP_DOUBLE: fprintf_filtered (stream, "Type @"); gdb_print_host_address (exp->elts[elt].type, stream); fprintf_filtered (stream, " ("); type_print (exp->elts[elt].type, NULL, stream, 0); fprintf_filtered (stream, "), value %g", (double) exp->elts[elt + 1].doubleconst); elt += 3; break; case OP_VAR_VALUE: fprintf_filtered (stream, "Block @"); gdb_print_host_address (exp->elts[elt].block, stream); fprintf_filtered (stream, ", symbol @"); gdb_print_host_address (exp->elts[elt + 1].symbol, stream); fprintf_filtered (stream, " (%s)", SYMBOL_PRINT_NAME (exp->elts[elt + 1].symbol)); elt += 3; break; case OP_VAR_ENTRY_VALUE: fprintf_filtered (stream, "Entry value of symbol @"); gdb_print_host_address (exp->elts[elt].symbol, stream); fprintf_filtered (stream, " (%s)", SYMBOL_PRINT_NAME (exp->elts[elt].symbol)); elt += 2; break; case OP_LAST: fprintf_filtered (stream, "History element %ld", (long) exp->elts[elt].longconst); elt += 2; break; case OP_REGISTER: fprintf_filtered (stream, "Register $%s", &exp->elts[elt + 1].string); elt += 3 + BYTES_TO_EXP_ELEM (exp->elts[elt].longconst + 1); break; case OP_INTERNALVAR: fprintf_filtered (stream, "Internal var @"); gdb_print_host_address (exp->elts[elt].internalvar, stream); fprintf_filtered (stream, " (%s)", internalvar_name (exp->elts[elt].internalvar)); elt += 2; break; case OP_FUNCALL: { int i, nargs; nargs = longest_to_int (exp->elts[elt].longconst); fprintf_filtered (stream, "Number of args: %d", nargs); elt += 2; for (i = 1; i <= nargs + 1; i++) elt = dump_subexp (exp, stream, elt); } break; case OP_ARRAY: { int lower, upper; int i; lower = longest_to_int (exp->elts[elt].longconst); upper = longest_to_int (exp->elts[elt + 1].longconst); fprintf_filtered (stream, "Bounds [%d:%d]", lower, upper); elt += 3; for (i = 1; i <= upper - lower + 1; i++) elt = dump_subexp (exp, stream, elt); } break; case UNOP_DYNAMIC_CAST: case UNOP_REINTERPRET_CAST: case UNOP_CAST_TYPE: case UNOP_MEMVAL_TYPE: fprintf_filtered (stream, " ("); elt = dump_subexp (exp, stream, elt); fprintf_filtered (stream, ")"); elt = dump_subexp (exp, stream, elt); break; case UNOP_MEMVAL: case UNOP_CAST: fprintf_filtered (stream, "Type @"); gdb_print_host_address (exp->elts[elt].type, stream); fprintf_filtered (stream, " ("); type_print (exp->elts[elt].type, NULL, stream, 0); fprintf_filtered (stream, ")"); elt = dump_subexp (exp, stream, elt + 2); break; case UNOP_MEMVAL_TLS: fprintf_filtered (stream, "TLS type @"); gdb_print_host_address (exp->elts[elt + 1].type, stream); fprintf_filtered (stream, " (__thread /* \"%s\" */ ", (exp->elts[elt].objfile == NULL ? "(null)" : exp->elts[elt].objfile->name)); type_print (exp->elts[elt + 1].type, NULL, stream, 0); fprintf_filtered (stream, ")"); elt = dump_subexp (exp, stream, elt + 3); break; case OP_TYPE: fprintf_filtered (stream, "Type @"); gdb_print_host_address (exp->elts[elt].type, stream); fprintf_filtered (stream, " ("); type_print (exp->elts[elt].type, NULL, stream, 0); fprintf_filtered (stream, ")"); elt += 2; break; case OP_TYPEOF: case OP_DECLTYPE: fprintf_filtered (stream, "Typeof ("); elt = dump_subexp (exp, stream, elt); fprintf_filtered (stream, ")"); break; case OP_TYPEID: fprintf_filtered (stream, "typeid ("); elt = dump_subexp (exp, stream, elt); fprintf_filtered (stream, ")"); break; case STRUCTOP_STRUCT: case STRUCTOP_PTR: { char *elem_name; int len; len = longest_to_int (exp->elts[elt].longconst); elem_name = &exp->elts[elt + 1].string; fprintf_filtered (stream, "Element name: `%.*s'", len, elem_name); elt = dump_subexp (exp, stream, elt + 3 + BYTES_TO_EXP_ELEM (len + 1)); } break; case OP_SCOPE: { char *elem_name; int len; fprintf_filtered (stream, "Type @"); gdb_print_host_address (exp->elts[elt].type, stream); fprintf_filtered (stream, " ("); type_print (exp->elts[elt].type, NULL, stream, 0); fprintf_filtered (stream, ") "); len = longest_to_int (exp->elts[elt + 1].longconst); elem_name = &exp->elts[elt + 2].string; fprintf_filtered (stream, "Field name: `%.*s'", len, elem_name); elt += 4 + BYTES_TO_EXP_ELEM (len + 1); } break; case TYPE_INSTANCE: { LONGEST len; len = exp->elts[elt++].longconst; fprintf_filtered (stream, "%s TypeInstance: ", plongest (len)); while (len-- > 0) { fprintf_filtered (stream, "Type @"); gdb_print_host_address (exp->elts[elt].type, stream); fprintf_filtered (stream, " ("); type_print (exp->elts[elt].type, NULL, stream, 0); fprintf_filtered (stream, ")"); elt++; if (len > 0) fputs_filtered (", ", stream); } /* Ending LEN and ending TYPE_INSTANCE. */ elt += 2; elt = dump_subexp (exp, stream, elt); } break; default: case OP_NULL: case MULTI_SUBSCRIPT: case OP_F77_UNDETERMINED_ARGLIST: case OP_COMPLEX: case OP_STRING: case OP_BOOL: case OP_M2_STRING: case OP_THIS: case OP_NAME: fprintf_filtered (stream, "Unknown format"); } return elt; }
static void ada_val_print_num (struct type *type, const gdb_byte *valaddr, int offset, int offset_aligned, CORE_ADDR address, struct ui_file *stream, int recurse, struct value *original_value, const struct value_print_options *options, const struct language_defn *language) { if (ada_is_fixed_point_type (type)) { LONGEST v = unpack_long (type, valaddr + offset_aligned); fprintf_filtered (stream, TYPE_LENGTH (type) < 4 ? "%.11g" : "%.17g", (double) ada_fixed_to_float (type, v)); return; } else if (TYPE_CODE (type) == TYPE_CODE_RANGE) { struct type *target_type = TYPE_TARGET_TYPE (type); if (TYPE_LENGTH (type) != TYPE_LENGTH (target_type)) { /* Obscure case of range type that has different length from its base type. Perform a conversion, or we will get a nonsense value. Actually, we could use the same code regardless of lengths; I'm just avoiding a cast. */ struct value *v1 = value_from_contents_and_address (type, valaddr + offset, 0); struct value *v = value_cast (target_type, v1); val_print (target_type, value_embedded_offset (v), 0, stream, recurse + 1, v, options, language); } else val_print (TYPE_TARGET_TYPE (type), offset, address, stream, recurse, original_value, options, language); return; } else { int format = (options->format ? options->format : options->output_format); if (format) { struct value_print_options opts = *options; opts.format = format; val_print_scalar_formatted (type, offset_aligned, original_value, &opts, 0, stream); } else if (ada_is_system_address_type (type)) { /* FIXME: We want to print System.Address variables using the same format as for any access type. But for some reason GNAT encodes the System.Address type as an int, so we have to work-around this deficiency by handling System.Address values as a special case. */ struct gdbarch *gdbarch = get_type_arch (type); struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; CORE_ADDR addr = extract_typed_address (valaddr + offset_aligned, ptr_type); fprintf_filtered (stream, "("); type_print (type, "", stream, -1); fprintf_filtered (stream, ") "); fputs_filtered (paddress (gdbarch, addr), stream); } else { val_print_type_code_int (type, valaddr + offset_aligned, stream); if (ada_is_character_type (type)) { LONGEST c; fputs_filtered (" ", stream); c = unpack_long (type, valaddr + offset_aligned); ada_printchar (c, type, stream); } } return; } }
void decl_typecheck(struct decl *d){ if(!d)return; if(d->value){ if(d->type->kind!=TYPE_ARRAY){ struct type* t; t = expr_typecheck(d->value); if(d->type-> kind != t->kind){ printf("Cannot assign "); expr_print(d->value); printf(" to "); type_print(d->type); printf("\n"); get_incrementError(2); } }else { if(d->value->kind!=EXPR_ARRAY_LIST){ printf("Cannot assign "); expr_print(d->value); printf(" to array %s\n",d->name); get_incrementError(2); } else{ struct type* aux_type = d->type; int lenght = 1; if(aux_type->expression){ while(aux_type->kind == TYPE_ARRAY){ if(aux_type->expression && aux_type->expression->kind!= EXPR_INTEGER_LITERAL){ printf("Array %s must have a literal value as index\n",d->name); lenght = 99999; break; } else{ lenght*=aux_type->expression->literal_value; } aux_type = aux_type->subtype; } } else{ lenght = 99999; while(aux_type->kind == TYPE_ARRAY)aux_type = aux_type->subtype; } resolve_array_values(d->value,aux_type,d->name); if(const_expr > lenght){ get_incrementError(2); printf("Too many arguments on inicialization of array %s\n",d->name); } } } } if(d->symbol->kind == SYMBOL_GLOBAL) { const_expr = 0; expr_constant(d->value); if(const_expr>0){ get_incrementError(1); printf("Tried to assign not constant variable in the declaration of %s\n",d->name); } } if(d->code)stmt_typecheck(d->code,d->type->subtype); decl_typecheck(d->next); }
int c_value_print (struct value *val, struct ui_file *stream, const struct value_print_options *options) { struct type *type, *real_type, *val_type; int full, top, using_enc; struct value_print_options opts = *options; opts.deref_ref = 1; /* 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. */ /* Preserve the original type before stripping typedefs. We prefer to pass down the original type when possible, but for local checks it is better to look past the typedefs. */ val_type = value_type (val); type = check_typedef (val_type); 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. (Don't use c_textual_element_type here; quoted strings are always exactly (char *), (wchar_t *), or the like. */ if (TYPE_CODE (val_type) == TYPE_CODE_PTR && TYPE_NAME (val_type) == NULL && TYPE_NAME (TYPE_TARGET_TYPE (val_type)) != NULL && (strcmp (TYPE_NAME (TYPE_TARGET_TYPE (val_type)), "char") == 0 || textual_name (TYPE_NAME (TYPE_TARGET_TYPE (val_type))))) { /* Print nothing */ } else if (options->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, ") "); val_type = type; } else { /* normal case */ fprintf_filtered (stream, "("); type_print (value_type (val), "", stream, -1); fprintf_filtered (stream, ") "); } } if (!value_initialized (val)) fprintf_filtered (stream, " [uninitialized] "); if (options->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, 0, &opts, current_language); /* 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, 0, &opts, current_language); } /* Otherwise, we end up at the return outside this "if" */ } return val_print (val_type, value_contents_all (val), value_embedded_offset (val), value_address (val), stream, 0, &opts, current_language); }
static int ada_val_print_1 (struct type *type, char *valaddr0, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int format, int deref_ref, int recurse, enum val_prettyprint pretty) { unsigned int len; int i; struct type *elttype; unsigned int eltlen; LONGEST val; char *valaddr = valaddr0 + embedded_offset; CHECK_TYPEDEF (type); if (ada_is_array_descriptor_type (type) || ada_is_packed_array_type (type)) { int retn; struct value *mark = value_mark (); struct value *val; val = value_from_contents_and_address (type, valaddr, address); val = ada_coerce_to_simple_array_ptr (val); if (val == NULL) { fprintf_filtered (stream, "(null)"); retn = 0; } else retn = ada_val_print_1 (VALUE_TYPE (val), VALUE_CONTENTS (val), 0, VALUE_ADDRESS (val), stream, format, deref_ref, recurse, pretty); value_free_to_mark (mark); return retn; } valaddr = ada_aligned_value_addr (type, valaddr); embedded_offset -= valaddr - valaddr0 - embedded_offset; type = printable_val_type (type, valaddr); switch (TYPE_CODE (type)) { default: return c_val_print (type, valaddr0, embedded_offset, address, stream, format, deref_ref, recurse, pretty); case TYPE_CODE_PTR: { int ret = c_val_print (type, valaddr0, embedded_offset, address, stream, format, deref_ref, recurse, pretty); if (ada_is_tag_type (type)) { struct value *val = value_from_contents_and_address (type, valaddr, address); const char *name = ada_tag_name (val); if (name != NULL) fprintf_filtered (stream, " (%s)", name); return 0; } return ret; } case TYPE_CODE_INT: case TYPE_CODE_RANGE: if (ada_is_fixed_point_type (type)) { LONGEST v = unpack_long (type, valaddr); int len = TYPE_LENGTH (type); fprintf_filtered (stream, len < 4 ? "%.11g" : "%.17g", (double) ada_fixed_to_float (type, v)); return 0; } else if (ada_is_vax_floating_type (type)) { struct value *val = value_from_contents_and_address (type, valaddr, address); struct value *func = ada_vax_float_print_function (type); if (func != 0) { static struct type *parray_of_char = NULL; struct value *printable_val; if (parray_of_char == NULL) parray_of_char = make_pointer_type (create_array_type (NULL, builtin_type_char, create_range_type (NULL, builtin_type_int, 0, 32)), NULL); printable_val = value_ind (value_cast (parray_of_char, call_function_by_hand (func, 1, &val))); fprintf_filtered (stream, "%s", VALUE_CONTENTS (printable_val)); return 0; } /* No special printing function. Do as best we can. */ } else if (TYPE_CODE (type) == TYPE_CODE_RANGE) { struct type *target_type = TYPE_TARGET_TYPE (type); if (TYPE_LENGTH (type) != TYPE_LENGTH (target_type)) { /* Obscure case of range type that has different length from its base type. Perform a conversion, or we will get a nonsense value. Actually, we could use the same code regardless of lengths; I'm just avoiding a cast. */ struct value *v = value_cast (target_type, value_from_contents_and_address (type, valaddr, 0)); return ada_val_print_1 (target_type, VALUE_CONTENTS (v), 0, 0, stream, format, 0, recurse + 1, pretty); } else return ada_val_print_1 (TYPE_TARGET_TYPE (type), valaddr0, embedded_offset, address, stream, format, deref_ref, recurse, pretty); } else { format = format ? format : output_format; if (format) { print_scalar_formatted (valaddr, type, format, 0, stream); } else if (ada_is_system_address_type (type)) { /* FIXME: We want to print System.Address variables using the same format as for any access type. But for some reason GNAT encodes the System.Address type as an int, so we have to work-around this deficiency by handling System.Address values as a special case. */ fprintf_filtered (stream, "("); type_print (type, "", stream, -1); fprintf_filtered (stream, ") "); print_address_numeric (extract_typed_address (valaddr, builtin_type_void_data_ptr), 1, stream); } else { val_print_type_code_int (type, valaddr, stream); if (ada_is_character_type (type)) { fputs_filtered (" ", stream); ada_printchar ((unsigned char) unpack_long (type, valaddr), stream); } } return 0; } case TYPE_CODE_ENUM: if (format) { print_scalar_formatted (valaddr, type, format, 0, stream); break; } len = TYPE_NFIELDS (type); val = unpack_long (type, valaddr); for (i = 0; i < len; i++) { QUIT; if (val == TYPE_FIELD_BITPOS (type, i)) { break; } } if (i < len) { const char *name = ada_enum_name (TYPE_FIELD_NAME (type, i)); if (name[0] == '\'') fprintf_filtered (stream, "%ld %s", (long) val, name); else fputs_filtered (name, stream); } else { print_longest (stream, 'd', 0, val); } break; case TYPE_CODE_FLT: if (format) return c_val_print (type, valaddr0, embedded_offset, address, stream, format, deref_ref, recurse, pretty); else ada_print_floating (valaddr0 + embedded_offset, type, stream); break; case TYPE_CODE_UNION: case TYPE_CODE_STRUCT: if (ada_is_bogus_array_descriptor (type)) { fprintf_filtered (stream, "(...?)"); return 0; } else { print_record (type, valaddr, stream, format, recurse, pretty); return 0; } case TYPE_CODE_ARRAY: elttype = TYPE_TARGET_TYPE (type); if (elttype == NULL) eltlen = 0; else eltlen = TYPE_LENGTH (elttype); /* FIXME: This doesn't deal with non-empty arrays of 0-length items (not a typical case!) */ if (eltlen == 0) len = 0; else len = TYPE_LENGTH (type) / eltlen; /* For an array of chars, print with string syntax. */ if (ada_is_string_type (type) && (format == 0 || format == 's')) { if (prettyprint_arrays) { print_spaces_filtered (2 + 2 * recurse, stream); } /* If requested, look for the first null char and only print elements up to it. */ if (stop_print_at_null) { int temp_len; /* Look for a NULL char. */ for (temp_len = 0; temp_len < len && temp_len < print_max && char_at (valaddr, temp_len, eltlen) != 0; temp_len += 1); len = temp_len; } printstr (stream, valaddr, len, 0, eltlen); } else { len = 0; fprintf_filtered (stream, "("); print_optional_low_bound (stream, type); if (TYPE_FIELD_BITSIZE (type, 0) > 0) val_print_packed_array_elements (type, valaddr, 0, stream, format, recurse, pretty); else val_print_array_elements (type, valaddr, address, stream, format, deref_ref, recurse, pretty, 0); fprintf_filtered (stream, ")"); } gdb_flush (stream); return len; case TYPE_CODE_REF: elttype = check_typedef (TYPE_TARGET_TYPE (type)); /* De-reference the reference */ if (deref_ref) { if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) { LONGEST deref_val_int = (LONGEST) unpack_pointer (lookup_pointer_type (builtin_type_void), valaddr); if (deref_val_int != 0) { struct value *deref_val = ada_value_ind (value_from_longest (lookup_pointer_type (elttype), deref_val_int)); val_print (VALUE_TYPE (deref_val), VALUE_CONTENTS (deref_val), 0, VALUE_ADDRESS (deref_val), stream, format, deref_ref, recurse + 1, pretty); } else fputs_filtered ("(null)", stream); } else fputs_filtered ("???", stream); } break; } gdb_flush (stream); return 0; }
int c_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); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); unsigned int i = 0; /* Number of characters printed */ unsigned len; struct type *elttype, *unresolved_elttype; struct type *unresolved_type = type; unsigned eltlen; LONGEST val; CORE_ADDR addr; CHECK_TYPEDEF (type); switch (TYPE_CODE (type)) { case TYPE_CODE_ARRAY: unresolved_elttype = TYPE_TARGET_TYPE (type); elttype = check_typedef (unresolved_elttype); if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (unresolved_elttype) > 0) { eltlen = TYPE_LENGTH (elttype); len = TYPE_LENGTH (type) / eltlen; if (options->prettyprint_arrays) { print_spaces_filtered (2 + 2 * recurse, stream); } /* Print arrays of textual chars with a string syntax. */ if (c_textual_element_type (unresolved_elttype, options->format)) { /* If requested, look for the first null char and only print elements up to it. */ if (options->stop_print_at_null) { unsigned int temp_len; for (temp_len = 0; (temp_len < len && temp_len < options->print_max && extract_unsigned_integer (valaddr + embedded_offset + temp_len * eltlen, eltlen, byte_order) != 0); ++temp_len) ; len = temp_len; } LA_PRINT_STRING (stream, unresolved_elttype, valaddr + embedded_offset, len, NULL, 0, options); 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; } val_print_array_elements (type, valaddr + embedded_offset, address, stream, recurse, options, i); fprintf_filtered (stream, "}"); } break; } /* Array of unspecified length: treat like pointer to first elt. */ addr = address; goto print_unpacked_pointer; case TYPE_CODE_MEMBERPTR: if (options->format) { print_scalar_formatted (valaddr + embedded_offset, type, options, 0, stream); break; } cp_print_class_member (valaddr + embedded_offset, type, stream, "&"); break; case TYPE_CODE_METHODPTR: cplus_print_method_ptr (valaddr + embedded_offset, type, stream); break; case TYPE_CODE_PTR: if (options->format && options->format != 's') { print_scalar_formatted (valaddr + embedded_offset, type, options, 0, stream); break; } 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.) */ CORE_ADDR addr = extract_typed_address (valaddr + embedded_offset, type); print_function_pointer_address (gdbarch, addr, stream, options->addressprint); break; } unresolved_elttype = TYPE_TARGET_TYPE (type); elttype = check_typedef (unresolved_elttype); { 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 (gdbarch, addr, stream, options->addressprint); /* Return value is irrelevant except for string pointers. */ return (0); } if (options->addressprint) fputs_filtered (paddress (gdbarch, addr), stream); /* For a pointer to a textual type, also print the string pointed to, unless pointer is null. */ if (c_textual_element_type (unresolved_elttype, options->format) && addr != 0) { i = val_print_string (unresolved_elttype, addr, -1, stream, options); } 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 && options->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 (SYMBOL_LINKAGE_NAME (msymbol), block, VAR_DOMAIN, &is_this_fld); if (wsym) { wtype = SYMBOL_TYPE (wsym); } else { wtype = unresolved_elttype; } vt_val = value_at (wtype, vt_address); common_val_print (vt_val, stream, recurse + 1, options, current_language); if (options->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_REF: elttype = check_typedef (TYPE_TARGET_TYPE (type)); if (options->addressprint) { CORE_ADDR addr = extract_typed_address (valaddr + embedded_offset, type); fprintf_filtered (stream, "@"); fputs_filtered (paddress (gdbarch, addr), stream); if (options->deref_ref) fputs_filtered (": ", stream); } /* De-reference the reference. */ if (options->deref_ref) { if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) { struct value *deref_val = value_at (TYPE_TARGET_TYPE (type), unpack_pointer (type, valaddr + embedded_offset)); common_val_print (deref_val, stream, recurse, options, current_language); } else fputs_filtered ("???", stream); } break; case TYPE_CODE_UNION: if (recurse && !options->unionprint) { fprintf_filtered (stream, "{...}"); break; } /* Fall through. */ case TYPE_CODE_STRUCT: /*FIXME: Abstract this away */ if (options->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 (gdbarch, addr, stream, options->addressprint); } else cp_print_value_fields_rtti (type, valaddr, embedded_offset, address, stream, recurse, options, NULL, 0); break; case TYPE_CODE_ENUM: if (options->format) { print_scalar_formatted (valaddr + embedded_offset, type, options, 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_FLAGS: if (options->format) print_scalar_formatted (valaddr + embedded_offset, type, options, 0, stream); else val_print_type_code_flags (type, valaddr + embedded_offset, stream); break; case TYPE_CODE_FUNC: case TYPE_CODE_METHOD: if (options->format) { print_scalar_formatted (valaddr + embedded_offset, type, options, 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 (gdbarch, address, stream, demangle); break; case TYPE_CODE_BOOL: 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 + embedded_offset, type, &opts, 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: 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 + embedded_offset, type, &opts, 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 (c_textual_element_type (unresolved_type, options->format)) { fputs_filtered (" ", stream); LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr + embedded_offset), unresolved_type, stream); } } break; case TYPE_CODE_CHAR: 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 + embedded_offset, type, &opts, 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, unresolved_type, stream); } break; case TYPE_CODE_FLT: if (options->format) { print_scalar_formatted (valaddr + embedded_offset, type, options, 0, stream); } else { print_floating (valaddr + embedded_offset, type, stream); } break; case TYPE_CODE_DECFLOAT: if (options->format) print_scalar_formatted (valaddr + embedded_offset, type, options, 0, stream); else print_decimal_floating (valaddr + embedded_offset, 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_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 (options->format) print_scalar_formatted (valaddr + embedded_offset, TYPE_TARGET_TYPE (type), options, 0, stream); else print_floating (valaddr + embedded_offset, TYPE_TARGET_TYPE (type), stream); fprintf_filtered (stream, " + "); if (options->format) print_scalar_formatted (valaddr + embedded_offset + TYPE_LENGTH (TYPE_TARGET_TYPE (type)), TYPE_TARGET_TYPE (type), options, 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 int inspect_type (struct demangle_parse_info *info, struct demangle_component *ret_comp, canonicalization_ftype *finder, void *data) { int i; char *name; struct symbol *sym; /* Copy the symbol's name from RET_COMP and look it up in the symbol table. */ name = (char *) alloca (ret_comp->u.s_name.len + 1); memcpy (name, ret_comp->u.s_name.s, ret_comp->u.s_name.len); name[ret_comp->u.s_name.len] = '\0'; /* Ignore any typedefs that should not be substituted. */ for (i = 0; i < ARRAY_SIZE (ignore_typedefs); ++i) { if (strcmp (name, ignore_typedefs[i]) == 0) return 0; } sym = NULL; TRY { sym = lookup_symbol (name, 0, VAR_DOMAIN, 0); } CATCH (except, RETURN_MASK_ALL) { return 0; } END_CATCH if (sym != NULL) { struct type *otype = SYMBOL_TYPE (sym); if (finder != NULL) { const char *new_name = (*finder) (otype, data); if (new_name != NULL) { ret_comp->u.s_name.s = new_name; ret_comp->u.s_name.len = strlen (new_name); return 1; } return 0; } /* If the type is a typedef or namespace alias, replace it. */ if (TYPE_CODE (otype) == TYPE_CODE_TYPEDEF || TYPE_CODE (otype) == TYPE_CODE_NAMESPACE) { long len; int is_anon; struct type *type; struct demangle_parse_info *i; struct ui_file *buf; /* Get the real type of the typedef. */ type = check_typedef (otype); /* If the symbol is a namespace and its type name is no different than the name we looked up, this symbol is not a namespace alias and does not need to be substituted. */ if (TYPE_CODE (otype) == TYPE_CODE_NAMESPACE && strcmp (TYPE_NAME (type), name) == 0) return 0; is_anon = (TYPE_TAG_NAME (type) == NULL && (TYPE_CODE (type) == TYPE_CODE_ENUM || TYPE_CODE (type) == TYPE_CODE_STRUCT || TYPE_CODE (type) == TYPE_CODE_UNION)); if (is_anon) { struct type *last = otype; /* Find the last typedef for the type. */ while (TYPE_TARGET_TYPE (last) != NULL && (TYPE_CODE (TYPE_TARGET_TYPE (last)) == TYPE_CODE_TYPEDEF)) last = TYPE_TARGET_TYPE (last); /* If there is only one typedef for this anonymous type, do not substitute it. */ if (type == otype) return 0; else /* Use the last typedef seen as the type for this anonymous type. */ type = last; } buf = mem_fileopen (); TRY { type_print (type, "", buf, -1); } /* If type_print threw an exception, there is little point in continuing, so just bow out gracefully. */ CATCH (except, RETURN_MASK_ERROR) { ui_file_delete (buf); return 0; } END_CATCH name = ui_file_obsavestring (buf, &info->obstack, &len); ui_file_delete (buf); /* Turn the result into a new tree. Note that this tree will contain pointers into NAME, so NAME cannot be free'd until all typedef conversion is done and the final result is converted into a string. */ i = cp_demangled_name_to_comp (name, NULL); if (i != NULL) { /* Merge the two trees. */ cp_merge_demangle_parse_infos (info, ret_comp, i); /* Replace any newly introduced typedefs -- but not if the type is anonymous (that would lead to infinite looping). */ if (!is_anon) replace_typedefs (info, ret_comp, finder, data); } else { /* This shouldn't happen unless the type printer has output something that the name parser cannot grok. Nonetheless, an ounce of prevention... Canonicalize the name again, and store it in the current node (RET_COMP). */ char *canon = cp_canonicalize_string_no_typedefs (name); if (canon != NULL) { /* Copy the canonicalization into the obstack and free CANON. */ name = copy_string_to_obstack (&info->obstack, canon, &len); xfree (canon); } ret_comp->u.s_name.s = name; ret_comp->u.s_name.len = len; } return 1; }
/* Print a list of the locals or the arguments for the currently selected frame. If the argument passed is 0, printonly the names of the variables, if an argument of 1 is passed, print the values as well. */ static void list_args_or_locals (int locals, int values, struct frame_info *fi) { struct block *block; struct symbol *sym; struct dict_iterator iter; int nsyms; struct cleanup *cleanup_list; static struct ui_stream *stb = NULL; struct type *type; stb = ui_out_stream_new (uiout); block = get_frame_block (fi, 0); cleanup_list = make_cleanup_ui_out_list_begin_end (uiout, locals ? "locals" : "args"); while (block != 0) { ALL_BLOCK_SYMBOLS (block, iter, sym) { int print_me = 0; switch (SYMBOL_CLASS (sym)) { default: case LOC_UNDEF: /* catches errors */ case LOC_CONST: /* constant */ case LOC_TYPEDEF: /* local typedef */ case LOC_LABEL: /* local label */ case LOC_BLOCK: /* local function */ case LOC_CONST_BYTES: /* loc. byte seq. */ case LOC_UNRESOLVED: /* unresolved static */ case LOC_OPTIMIZED_OUT: /* optimized out */ print_me = 0; break; case LOC_ARG: /* argument */ case LOC_REF_ARG: /* reference arg */ case LOC_REGPARM: /* register arg */ case LOC_REGPARM_ADDR: /* indirect register arg */ case LOC_LOCAL_ARG: /* stack arg */ case LOC_BASEREG_ARG: /* basereg arg */ case LOC_COMPUTED_ARG: /* arg with computed location */ if (!locals) print_me = 1; break; case LOC_LOCAL: /* stack local */ case LOC_BASEREG: /* basereg local */ case LOC_STATIC: /* static */ case LOC_REGISTER: /* register */ case LOC_COMPUTED: /* computed location */ if (locals) print_me = 1; break; } if (print_me) { struct cleanup *cleanup_tuple = NULL; struct symbol *sym2; if (values != PRINT_NO_VALUES) cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ui_out_field_string (uiout, "name", SYMBOL_PRINT_NAME (sym)); if (!locals) sym2 = lookup_symbol (SYMBOL_NATURAL_NAME (sym), block, VAR_DOMAIN, (int *) NULL, (struct symtab **) NULL); else sym2 = sym; switch (values) { case PRINT_SIMPLE_VALUES: type = check_typedef (sym2->type); type_print (sym2->type, "", stb->stream, -1); ui_out_field_stream (uiout, "type", stb); if (TYPE_CODE (type) != TYPE_CODE_ARRAY && TYPE_CODE (type) != TYPE_CODE_STRUCT && TYPE_CODE (type) != TYPE_CODE_UNION) { print_variable_value (sym2, fi, stb->stream); ui_out_field_stream (uiout, "value", stb); } do_cleanups (cleanup_tuple); break; case PRINT_ALL_VALUES: print_variable_value (sym2, fi, stb->stream); ui_out_field_stream (uiout, "value", stb); do_cleanups (cleanup_tuple); break; } } } if (BLOCK_FUNCTION (block)) break; else block = BLOCK_SUPERBLOCK (block); }
STATIC void cpp_basic_data_type(type *t) { char c; int i; //printf("cpp_basic_data_type(t)\n"); //type_print(t); switch (tybasic(t->Tty)) { case TYschar: c = 'C'; goto dochar; case TYchar: c = 'D'; goto dochar; case TYuchar: c = 'E'; goto dochar; case TYshort: c = 'F'; goto dochar; case TYushort: c = 'G'; goto dochar; case TYint: c = 'H'; goto dochar; case TYuint: c = 'I'; goto dochar; case TYlong: c = 'J'; goto dochar; case TYulong: c = 'K'; goto dochar; case TYfloat: c = 'M'; goto dochar; case TYdouble: c = 'N'; goto dochar; case TYdouble_alias: if (intsize == 4) { c = 'O'; goto dochar; } c = 'Z'; goto dochar2; case TYldouble: if (intsize == 2) { c = 'O'; goto dochar; } c = 'Z'; goto dochar2; dochar: CHAR(c); break; case TYllong: c = 'J'; goto dochar2; case TYullong: c = 'K'; goto dochar2; case TYbool: c = 'N'; goto dochar2; // was 'X' prior to 8.1b8 case TYwchar_t: if (config.flags4 & CFG4nowchar_t) { c = 'G'; goto dochar; // same as TYushort } else { pstate.STflags |= PFLmfc; c = 'Y'; goto dochar2; } // Digital Mars extensions case TYifloat: c = 'R'; goto dochar2; case TYidouble: c = 'S'; goto dochar2; case TYildouble: c = 'T'; goto dochar2; case TYcfloat: c = 'U'; goto dochar2; case TYcdouble: c = 'V'; goto dochar2; case TYcldouble: c = 'W'; goto dochar2; case TYchar16: c = 'X'; goto dochar2; case TYdchar: c = 'Y'; goto dochar2; case TYnullptr: c = 'Z'; goto dochar2; dochar2: CHAR('_'); goto dochar; #if TARGET_SEGMENTED case TYsptr: case TYcptr: case TYf16ptr: case TYfptr: case TYhptr: case TYvptr: #endif #if !MARS case TYmemptr: #endif case TYnptr: c = 'P' + cpp_cvidx(t->Tty); CHAR(c); if(I64) CHAR('E'); // __ptr64 modifier cpp_pointer_type(t); break; case TYstruct: case TYenum: cpp_ecsu_data_type(t); break; case TYarray: i = cpp_cvidx(t->Tty); i |= 1; // always const CHAR('P' + i); cpp_pointer_type(t); break; case TYvoid: c = 'X'; goto dochar; #if !MARS case TYident: if (pstate.STintemplate) { CHAR('V'); // pretend to be a class name cpp_zname(t->Tident); } else { #if SCPP cpperr(EM_no_type,t->Tident); // no type for argument #endif c = 'X'; goto dochar; } break; case TYtemplate: if (pstate.STintemplate) { CHAR('V'); // pretend to be a class name cpp_zname(((typetemp_t *)t)->Tsym->Sident); } else goto Ldefault; break; #endif default: Ldefault: if (tyfunc(t->Tty)) cpp_function_type(t); else { #if SCPP #ifdef DEBUG if (!errcnt) type_print(t); #endif assert(errcnt); #endif } } }
int java_value_print (struct value *val, struct ui_file *stream, int format, enum val_prettyprint pretty) { struct type *type; CORE_ADDR address; int i; char *name; type = VALUE_TYPE (val); address = VALUE_ADDRESS (val) + VALUE_OFFSET (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 (java_class_from_object (val)); type = lookup_pointer_type (type); val = value_at (type, address, NULL); } } 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] == ']')) { char buf4[4]; long length; unsigned int things_printed = 0; int reps; struct type *el_type = java_primitive_type_from_name (name, i - 2); i = 0; read_memory (address + JAVA_OBJECT_SIZE, buf4, 4); length = (long) extract_signed_integer (buf4, 4); fprintf_filtered (stream, "{length: %ld", length); if (el_type == NULL) { CORE_ADDR element; CORE_ADDR next_element = -1; /* dummy initial value */ address += JAVA_OBJECT_SIZE + 4; /* Skip object header and length. */ while (i < length && things_printed < print_max) { char *buf; buf = alloca (TARGET_PTR_BIT / 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 += TARGET_PTR_BIT / HOST_CHAR_BIT; element = extract_address (buf, sizeof (buf)); } for (reps = 1; i + reps < length; reps++) { read_memory (address, buf, sizeof (buf)); address += TARGET_PTR_BIT / HOST_CHAR_BIT; next_element = extract_address (buf, sizeof (buf)); 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", paddr_nz (element)); things_printed++; i += reps; } } else { struct value *v = allocate_value (el_type); struct value *next_v = allocate_value (el_type); VALUE_ADDRESS (v) = address + JAVA_OBJECT_SIZE + 4; VALUE_ADDRESS (next_v) = VALUE_ADDRESS (v); while (i < length && things_printed < 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 { VALUE_LAZY (v) = 1; VALUE_OFFSET (v) = 0; } VALUE_OFFSET (next_v) = VALUE_OFFSET (v); for (reps = 1; i + reps < length; reps++) { VALUE_LAZY (next_v) = 1; 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); val_print (VALUE_TYPE (v), VALUE_CONTENTS (v), 0, 0, stream, format, 2, 1, pretty); 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_NAME (TYPE_TARGET_TYPE (type)) && strcmp (TYPE_NAME (TYPE_TARGET_TYPE (type)), "java.lang.String") == 0 && (format == 0 || format == 's') && address != 0 && value_as_address (val) != 0) { 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 */ val_print_string (data + boffset, count, 2, stream); return 0; } return (val_print (type, VALUE_CONTENTS (val), 0, address, stream, format, 1, 0, pretty)); }
struct type *expr_typecheck(struct expr *e) { if(!e) return type_create(TYPE_VOID, 0, 0, 0); struct param_list *param_ptr; struct expr *expr_ptr; struct type *left; struct type *right; switch(e->kind) { case EXPR_LIST: left = expr_typecheck(e->left); right = expr_typecheck(e->right); return type_create(TYPE_VOID, 0, 0, 0); break; case EXPR_ASSIGNMENT: left = expr_typecheck(e->left); right = expr_typecheck(e->right); while(left->kind == TYPE_ARRAY) left = left->subtype; while(right->kind == TYPE_ARRAY) left = left->subtype; if(type_equal(left, right) && left->kind != TYPE_FUNCTION) { return type_copy(left); } else { printf("Cannot assign "); type_print(right); printf(" to "); type_print(left); if(e->left->name) { printf(" %s\n", e->left->name); } else { printf("\n"); } type_check_errors++; return left; } break; case EXPR_NOT_EQUALS: case EXPR_EQUALS: left = expr_typecheck(e->left); right = expr_typecheck(e->right); if(type_equal(left, right) && left->kind != TYPE_FUNCTION && left->kind != TYPE_ARRAY) { return type_create(TYPE_BOOLEAN, 0, 0, 0); } else { printf("Cannot perform logical equals operation on "); type_print(left); printf(" and "); type_print(right); printf("\n"); type_check_errors++; return type_create(TYPE_BOOLEAN, 0, 0, 0); } break; case EXPR_LT: case EXPR_GT: case EXPR_LE: case EXPR_GE: left = expr_typecheck(e->left); right = expr_typecheck(e->right); if(left->kind == TYPE_INTEGER && right->kind == TYPE_INTEGER) { return type_create(TYPE_BOOLEAN, 0, 0, 0); } else { printf("Cannot perform boolean operations on "); type_print(left); printf(" and "); type_print(right); printf("\n"); type_check_errors++; return type_create(TYPE_BOOLEAN, 0, 0, 0); } break; case EXPR_ADD: case EXPR_MINUS: case EXPR_TIMES: case EXPR_DIVIDES: case EXPR_MOD: case EXPR_POWER: left = expr_typecheck(e->left); right = expr_typecheck(e->right); if(left->kind == TYPE_INTEGER && right->kind == TYPE_INTEGER) { return type_create(TYPE_INTEGER, 0, 0, 0); } else { printf("Cannot perform arithmetic operations on "); type_print(left); printf(" and "); type_print(right); printf("\n"); type_check_errors++; return type_create(TYPE_INTEGER, 0, 0, 0); } break; case EXPR_NEGATIVE: right = expr_typecheck(e->right); if(right->kind == TYPE_INTEGER) { return type_create(TYPE_INTEGER, 0, 0, 0); } else { printf("Cannot take the negative of "); type_print(right); printf("\n"); type_check_errors++; return type_create(TYPE_INTEGER, 0, 0, 0); } break; case EXPR_OR: case EXPR_AND: left = expr_typecheck(e->left); right = expr_typecheck(e->right); if(left->kind == TYPE_BOOLEAN && right->kind == TYPE_BOOLEAN) { return type_create(TYPE_BOOLEAN, 0, 0, 0); } else { printf("Cannot perform logical operations on "); type_print(left); printf(" and "); type_print(right); printf("\n"); type_check_errors++; return type_create(TYPE_BOOLEAN, 0, 0, 0); } break; case EXPR_NOT: right = expr_typecheck(e->right); if(right->kind == TYPE_BOOLEAN) { return type_create(TYPE_BOOLEAN, 0, 0, 0); } else { printf("Cannot perform a logical not on "); type_print(right); printf("\n"); type_check_errors++; return type_create(TYPE_BOOLEAN, 0, 0, 0); } break; case EXPR_PRE_INCREMENT: case EXPR_PRE_DECREMENT: right = expr_typecheck(e->right); if(right->kind == TYPE_INTEGER) { return type_create(TYPE_INTEGER, 0, 0, 0); } else { printf("Cannot perform integer operations on "); type_print(right); printf("\n"); type_check_errors++; return type_create(TYPE_INTEGER, 0, 0, 0); } break; case EXPR_POST_INCREMENT: case EXPR_POST_DECREMENT: left = expr_typecheck(e->left); if(left->kind == TYPE_INTEGER) { return type_create(TYPE_INTEGER, 0, 0, 0); } else { printf("Cannot perform integer operations on "); type_print(left); printf("\n"); type_check_errors++; return type_create(TYPE_INTEGER, 0, 0, 0); } break; case EXPR_FUNCTION: param_ptr = e->left->symbol->type->params; expr_ptr = e->right; while(param_ptr) { if(!expr_ptr) { printf("Not enough arguments given for function %s\n", e->left->name); type_check_errors++; break; } if(!type_equal(param_ptr->type, expr_typecheck(expr_ptr->left))) { printf("Function %s requires a paramater of type ", e->left->name); type_print(param_ptr->type); printf(" but "); expr_print(expr_ptr->left); printf(" is of type "); type_print(expr_typecheck(expr_ptr->left)); printf("\n"); type_check_errors++; break; } param_ptr = param_ptr->next; expr_ptr = expr_ptr->right; } if(expr_ptr) { printf("Too many arguments given for function %s\n", e->left->name); type_check_errors++; } return e->left->symbol->type->subtype; break; case EXPR_BOOLEAN: return type_create(TYPE_BOOLEAN, 0, 0, 0); break; case EXPR_INT: return type_create(TYPE_INTEGER, 0, 0, 0); break; case EXPR_CHAR: return type_create(TYPE_CHARACTER, 0, 0, 0); break; case EXPR_STRING: return type_create(TYPE_STRING, 0, 0, 0); break; case EXPR_NAME: if (e->symbol) return e->symbol->type; return type_create(TYPE_VOID, 0, 0, 0); break; case EXPR_ARRAY: left = expr_typecheck(e->left); right = expr_typecheck(e->right); if(right->kind == TYPE_INTEGER) { return type_create(left->subtype->kind, 0, 0, 0); } else { printf("Cannot use "); type_print(right); printf(" as an array index. Must use an integer\n"); type_check_errors++; return type_create(left->subtype->kind, 0, 0, 0); } break; case EXPR_ARRAY_LITERAL: left = expr_typecheck(e->right->left); return type_create(TYPE_ARRAY, 0, 0, left->subtype); break; } return type_create(TYPE_VOID, 0, 0, 0); }
struct type * expr_typecheck( struct expr *e ) { if (!e) return type_create(TYPE_VOID, 0, 0); struct type *L; struct type *R; switch (e->kind) { case EXPR_INT_VAL: return type_create(TYPE_INTEGER, 0, 0); case EXPR_NAME: return type_copy(e->symbol->type); case EXPR_STRING_VAL: return type_create(TYPE_STRING, 0, 0); case EXPR_CHAR_VAL: return type_create(TYPE_CHARACTER, 0, 0); case EXPR_BOOLEAN_VAL: return type_create(TYPE_BOOLEAN, 0, 0); case EXPR_ARRAY_VAL: { struct expr *vals = e->right; struct type *subtype = 0; int num_subtype = 0; while (vals) { struct type *cur_t = expr_typecheck(vals); if (!subtype) { subtype = cur_t; } if (!type_compare(subtype, cur_t)) { decl_has_error = 1; printf("type error: array of element type "); type_print(subtype); printf(" cannot have expression of type "); type_print(cur_t); printf("\n"); } num_subtype++; vals = vals->next; } struct type *t = type_create(TYPE_ARRAY, 0, subtype); t->num_subtype = expr_create_integer_literal(num_subtype); return t; } //return type_copy(e->symbol->type); case EXPR_ARRAY_SUB: L = expr_typecheck(e->left); R = expr_typecheck(e->right); if (R->kind != TYPE_INTEGER) { decl_has_error = 1; printf("type error: cannot use "); type_print(R); printf(" as index to an array\n"); } if (L->kind != TYPE_ARRAY) { decl_has_error = 1; printf("type error: access an "); type_print(R); printf(" as an array\n"); } return type_copy(L->subtype); case EXPR_FUNCTION_VAL: // need to check function params!!!!! param_list_typecheck(e->right, e->symbol->params, e->name); return type_copy(e->symbol->type->subtype); case EXPR_ADD: L = expr_typecheck(e->left); R = expr_typecheck(e->right); if (L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER) { decl_has_error = 1; printf("type error: cannot add "); type_print(L); printf(" to a "); type_print(R); printf("\n"); } return type_create(TYPE_INTEGER, 0, 0); case EXPR_SUB: L = expr_typecheck(e->left); R = expr_typecheck(e->right); if ( !(L->kind == TYPE_INTEGER && L->kind == TYPE_INTEGER) || R->kind != TYPE_INTEGER) { decl_has_error = 1; printf("type error: cannot subtract "); type_print(L); printf(" to a "); type_print(R); printf("\n"); } return type_create(TYPE_INTEGER, 0, 0); case EXPR_MUL: L = expr_typecheck(e->left); R = expr_typecheck(e->right); if (L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER) { decl_has_error = 1; printf("type error: cannot multiply "); type_print(L); printf(" to a "); type_print(R); printf("\n"); } return type_create(TYPE_INTEGER, 0, 0); case EXPR_DIV: L = expr_typecheck(e->left); R = expr_typecheck(e->right); if (L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER) { decl_has_error = 1; printf("type error: cannot divide "); type_print(L); printf(" to a "); type_print(R); printf("\n"); } return type_create(TYPE_INTEGER, 0, 0); case EXPR_MODULO: L = expr_typecheck(e->left); R = expr_typecheck(e->right); if (L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER) { decl_has_error = 1; printf("type error: cannot module "); type_print(L); printf(" to a "); type_print(R); printf("\n"); } return type_create(TYPE_INTEGER, 0, 0); case EXPR_EXPO: L = expr_typecheck(e->left); R = expr_typecheck(e->right); if (L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER) { decl_has_error = 1; printf("type error: cannot expo "); type_print(L); printf(" to a "); type_print(R); printf("\n"); } return type_create(TYPE_INTEGER, 0, 0); case EXPR_POST_DECREASE: L = expr_typecheck(e->left); if (L->kind != TYPE_INTEGER ) { decl_has_error = 1; printf("type error: cannot decrease a "); type_print(L); printf("\n"); } return type_create(TYPE_INTEGER, 0, 0); case EXPR_POST_INCREASE: L = expr_typecheck(e->left); if (L->kind != TYPE_INTEGER ) { decl_has_error = 1; printf("type error: cannot add a "); type_print(L); printf("\n"); } return type_create(TYPE_INTEGER, 0, 0); case EXPR_GE: L = expr_typecheck(e->left); R = expr_typecheck(e->right); if (L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER) { decl_has_error = 1; printf("type error: cannot make greater equal than compare "); type_print(L); printf(" with a "); type_print(R); printf("\n"); } return type_create(TYPE_BOOLEAN, 0, 0); case EXPR_LE: L = expr_typecheck(e->left); R = expr_typecheck(e->right); if (L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER) { decl_has_error = 1; printf("type error: cannot make less equal compare "); type_print(L); printf(" with a "); type_print(R); printf("\n"); } return type_create(TYPE_BOOLEAN, 0, 0); case EXPR_GT: L = expr_typecheck(e->left); R = expr_typecheck(e->right); if (L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER) { decl_has_error = 1; printf("type error: cannot make greater than compare "); type_print(L); printf(" with a "); type_print(R); printf("\n"); } return type_create(TYPE_BOOLEAN, 0, 0); case EXPR_LT: L = expr_typecheck(e->left); R = expr_typecheck(e->right); if (L->kind != TYPE_INTEGER || R->kind != TYPE_INTEGER) { decl_has_error = 1; printf("type error: cannot make less than compare "); type_print(L); printf(" with a "); type_print(R); printf("\n"); } return type_create(TYPE_BOOLEAN, 0, 0); case EXPR_AND: L = expr_typecheck(e->left); R = expr_typecheck(e->right); if (L->kind != TYPE_BOOLEAN || R->kind != TYPE_BOOLEAN) { decl_has_error = 1; printf("type error: cannot and "); type_print(L); printf(" with a "); type_print(R); printf("\n"); } return type_create(TYPE_BOOLEAN, 0, 0); case EXPR_NOT: R = expr_typecheck(e->right); if (R->kind != TYPE_BOOLEAN) { decl_has_error = 1; printf("type error: cannot not a "); type_print(R); printf("\n"); } return type_create(TYPE_BOOLEAN, 0, 0); case EXPR_OR: L = expr_typecheck(e->left); R = expr_typecheck(e->right); if (L->kind != TYPE_BOOLEAN || R->kind != TYPE_BOOLEAN) { decl_has_error = 1; printf("type error: cannot or "); type_print(L); printf(" with a "); type_print(R); printf("\n"); } return type_create(TYPE_BOOLEAN, 0, 0); case EXPR_EQ: L = expr_typecheck(e->left); R = expr_typecheck(e->right); if (L->kind == TYPE_FUNCTION || R->kind == TYPE_FUNCTION || L->kind == TYPE_ARRAY || R->kind == TYPE_ARRAY) { decl_has_error = 1; printf("type error: cannot compare equality "); type_print(L); printf(" with a "); type_print(R); printf("\n"); } return type_create(TYPE_BOOLEAN, 0, 0); case EXPR_NEQ: L = expr_typecheck(e->left); R = expr_typecheck(e->right); if (L->kind == TYPE_FUNCTION || R->kind == TYPE_FUNCTION || L->kind == TYPE_ARRAY || R->kind == TYPE_ARRAY) { decl_has_error = 1; printf("type error: cannot compare non equality "); type_print(L); printf(" with a "); type_print(R); printf("\n"); } return type_create(TYPE_BOOLEAN, 0, 0); case EXPR_ASSIGN: L = expr_typecheck(e->left); R = expr_typecheck(e->right); if (L->kind == TYPE_FUNCTION || R->kind == TYPE_FUNCTION) { decl_has_error = 1; printf("type error: cannot assign "); type_print(R); printf(" to a "); type_print(L); printf("\n"); } if (!type_compare(L, R)) { decl_has_error = 1; printf("type error: cannot assign "); type_print(R); printf(" to a "); type_print(L); printf("\n"); } return type_copy(R); } }
void pascal_type_print_base (struct type *type, struct ui_file *stream, int show, int level) { int i; int len; int lastval; enum { s_none, s_public, s_private, s_protected } section_type; QUIT; wrap_here (" "); if (type == NULL) { fputs_filtered ("<type unknown>", stream); return; } /* void pointer */ if ((TYPE_CODE (type) == TYPE_CODE_PTR) && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_VOID)) { fputs_filtered (TYPE_NAME (type) ? TYPE_NAME (type) : "pointer", 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_TYPEDEF: case TYPE_CODE_PTR: case TYPE_CODE_MEMBER: case TYPE_CODE_REF: /* case TYPE_CODE_FUNC: case TYPE_CODE_METHOD: */ pascal_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level); break; case TYPE_CODE_ARRAY: /* pascal_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0); pascal_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level); pascal_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0); */ pascal_print_type (TYPE_TARGET_TYPE (type), NULL, stream, 0, 0); break; case TYPE_CODE_FUNC: case TYPE_CODE_METHOD: /* pascal_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level); only after args !! */ break; case TYPE_CODE_STRUCT: if (TYPE_TAG_NAME (type) != NULL) { fputs_filtered (TYPE_TAG_NAME (type), stream); fputs_filtered (" = ", stream); } if (HAVE_CPLUS_STRUCT (type)) { fprintf_filtered (stream, "class "); } else { fprintf_filtered (stream, "record "); } goto struct_union; case TYPE_CODE_UNION: if (TYPE_TAG_NAME (type) != NULL) { fputs_filtered (TYPE_TAG_NAME (type), stream); fputs_filtered (" = ", stream); } fprintf_filtered (stream, "case <?> of "); struct_union: 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) { pascal_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; /* 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 (DEPRECATED_STREQN (TYPE_FIELD_NAME (type, i), "_vptr", 5) && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5])) continue; /* If this is a pascal object or class we can print the various section labels. */ if (HAVE_CPLUS_STRUCT (type)) { 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 "); } pascal_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 space between. */ len = TYPE_NFN_FIELDS (type); if (len && section_type != s_none) fprintf_filtered (stream, "\n"); /* Pbject pascal: 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); /* this is GNU C++ specific how can we know constructor/destructor? It might work for GNU pascal */ for (j = 0; j < len2; j++) { char *physname = TYPE_FN_FIELD_PHYSNAME (f, j); int is_constructor = DEPRECATED_STREQN (physname, "__ct__", 6); int is_destructor = DEPRECATED_STREQN (physname, "__dt__", 6); 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_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; } if (is_constructor) { fprintf_filtered (stream, "constructor "); } else if (is_destructor) { fprintf_filtered (stream, "destructor "); } else if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) != 0 && TYPE_CODE (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j))) != TYPE_CODE_VOID) { fprintf_filtered (stream, "function "); } else { fprintf_filtered (stream, "procedure "); } /* this does not work, no idea why !! */ pascal_type_print_method_args (physname, method_name, stream); if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) != 0 && TYPE_CODE (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j))) != TYPE_CODE_VOID) { fputs_filtered (" : ", stream); type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)), "", stream, -1); } if (TYPE_FN_FIELD_VIRTUAL_P (f, j)) fprintf_filtered (stream, "; virtual"); fprintf_filtered (stream, ";\n"); } } fprintfi_filtered (level, stream, "end"); } break; case TYPE_CODE_ENUM: if (TYPE_TAG_NAME (type) != NULL) { fputs_filtered (TYPE_TAG_NAME (type), stream); if (show > 0) fputs_filtered (" ", stream); } /* enum is just defined by type enume_name = (enum_member1,enum_member2,...) */ fprintf_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)) { fprintf_filtered (stream, " := %d", TYPE_FIELD_BITPOS (type, i)); 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, "record <unknown>"); break; case TYPE_CODE_ERROR: fprintf_filtered (stream, "<unknown type>"); break; /* this probably does not work for enums */ case TYPE_CODE_RANGE: { struct type *target = TYPE_TARGET_TYPE (type); if (target == NULL) target = builtin_type_long; print_type_scalar (target, TYPE_LOW_BOUND (type), stream); fputs_filtered ("..", stream); print_type_scalar (target, TYPE_HIGH_BOUND (type), stream); } break; case TYPE_CODE_SET: fputs_filtered ("set of ", stream); pascal_print_type (TYPE_INDEX_TYPE (type), "", stream, show - 1, level); break; case TYPE_CODE_BITSTRING: fputs_filtered ("BitString", stream); break; case TYPE_CODE_STRING: fputs_filtered ("String", 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) { 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 unnamed pascal type code %d>", TYPE_CODE (type)); } break; } }
int f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value *original_value, const struct value_print_options *options) { struct gdbarch *gdbarch = get_type_arch (type); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); unsigned int i = 0; /* Number of characters printed */ struct type *elttype; LONGEST val; CORE_ADDR addr; int index; CHECK_TYPEDEF (type); switch (TYPE_CODE (type)) { case TYPE_CODE_STRING: f77_get_dynamic_length_of_aggregate (type); LA_PRINT_STRING (stream, builtin_type (gdbarch)->builtin_char, valaddr, TYPE_LENGTH (type), NULL, 0, options); break; case TYPE_CODE_ARRAY: fprintf_filtered (stream, "("); f77_print_array (type, valaddr, address, stream, recurse, original_value, options); fprintf_filtered (stream, ")"); break; case TYPE_CODE_PTR: if (options->format && options->format != 's') { print_scalar_formatted (valaddr, type, options, 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 (gdbarch, addr, stream, demangle); /* Return value is irrelevant except for string pointers. */ return 0; } if (options->addressprint && options->format != 's') fputs_filtered (paddress (gdbarch, addr), 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 && (options->format == 0 || options->format == 's') && addr != 0) i = val_print_string (TYPE_TARGET_TYPE (type), addr, -1, stream, options); /* 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 (options->addressprint) { CORE_ADDR addr = extract_typed_address (valaddr + embedded_offset, type); fprintf_filtered (stream, "@"); fputs_filtered (paddress (gdbarch, addr), stream); if (options->deref_ref) fputs_filtered (": ", stream); } /* De-reference the reference. */ if (options->deref_ref) { if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) { struct value *deref_val = value_at (TYPE_TARGET_TYPE (type), unpack_pointer (type, valaddr + embedded_offset)); common_val_print (deref_val, stream, recurse, options, current_language); } else fputs_filtered ("???", stream); } break; case TYPE_CODE_FUNC: if (options->format) { print_scalar_formatted (valaddr, type, options, 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 (gdbarch, address, stream, demangle); break; case TYPE_CODE_INT: 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 { 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), type, stream); } } break; case TYPE_CODE_FLAGS: if (options->format) print_scalar_formatted (valaddr, type, options, 0, stream); else val_print_type_code_flags (type, valaddr, stream); break; case TYPE_CODE_FLT: if (options->format) print_scalar_formatted (valaddr, type, options, 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, "%s", TYPE_ERROR_NAME (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: 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 { val = extract_unsigned_integer (valaddr, TYPE_LENGTH (type), byte_order); 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; val_print (type, valaddr, 0, address, stream, recurse, original_value, options, current_language); /* Restore the type code so later uses work as intended. */ TYPE_CODE (type) = TYPE_CODE_BOOL; } } break; case TYPE_CODE_COMPLEX: type = TYPE_TARGET_TYPE (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; case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: /* Starting from the Fortran 90 standard, Fortran supports derived types. */ fprintf_filtered (stream, "( "); for (index = 0; index < TYPE_NFIELDS (type); index++) { int offset = TYPE_FIELD_BITPOS (type, index) / 8; val_print (TYPE_FIELD_TYPE (type, index), valaddr + offset, embedded_offset, address, stream, recurse + 1, original_value, options, current_language); if (index != TYPE_NFIELDS (type) - 1) fputs_filtered (", ", stream); } fprintf_filtered (stream, " )"); break; default: error (_("Invalid F77 type code %d in symbol table."), TYPE_CODE (type)); } gdb_flush (stream); return 0; }
void c_value_print (struct value *val, struct ui_file *stream, const struct value_print_options *options) { struct type *type, *real_type, *val_type; int full, top, using_enc; struct value_print_options opts = *options; opts.deref_ref = 1; /* 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. */ /* Preserve the original type before stripping typedefs. We prefer to pass down the original type when possible, but for local checks it is better to look past the typedefs. */ val_type = value_type (val); type = check_typedef (val_type); 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. (Don't use c_textual_element_type here; quoted strings are always exactly (char *), (wchar_t *), or the like. */ if (TYPE_CODE (val_type) == TYPE_CODE_PTR && TYPE_NAME (val_type) == NULL && TYPE_NAME (TYPE_TARGET_TYPE (val_type)) != NULL && (strcmp (TYPE_NAME (TYPE_TARGET_TYPE (val_type)), "char") == 0 || textual_name (TYPE_NAME (TYPE_TARGET_TYPE (val_type))))) { /* Print nothing. */ } else if (options->objectprint && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS)) { int is_ref = TYPE_CODE (type) == TYPE_CODE_REF; if (is_ref) val = value_addr (val); /* Pointer to class, check real type of object. */ fprintf_filtered (stream, "("); if (value_entirely_available (val)) { real_type = value_rtti_indirect_type (val, &full, &top, &using_enc); if (real_type) { /* RTTI entry found. */ type = real_type; /* Need to adjust pointer value. */ val = value_from_pointer (real_type, value_as_address (val) - top); if (is_ref) { val = value_ref (value_ind (val)); type = value_type (val); } /* 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, ") "); val_type = type; } else { /* normal case */ fprintf_filtered (stream, "("); type_print (value_type (val), "", stream, -1); fprintf_filtered (stream, ") "); } } if (!value_initialized (val)) fprintf_filtered (stream, " [uninitialized] "); if (options->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. */ val_print (value_enclosing_type (val), value_contents_for_printing (val), 0, value_address (val), stream, 0, val, &opts, current_language); return; /* 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))); val_print (value_enclosing_type (val), value_contents_for_printing (val), 0, value_address (val), stream, 0, val, &opts, current_language); return; } /* Otherwise, we end up at the return outside this "if". */ } val_print (val_type, value_contents_for_printing (val), value_embedded_offset (val), value_address (val), stream, 0, val, &opts, current_language); }
void type_print(type *t) { type_debug(t); dbg_printf("Tty="); WRTYxx(t->Tty); dbg_printf(" Tmangle=%d",t->Tmangle); dbg_printf(" Tflags=x%x",t->Tflags); dbg_printf(" Tcount=%d",t->Tcount); if (!(t->Tflags & TFsizeunknown) && tybasic(t->Tty) != TYvoid && tybasic(t->Tty) != TYident && tybasic(t->Tty) != TYmfunc && tybasic(t->Tty) != TYarray && tybasic(t->Tty) != TYtemplate) dbg_printf(" Tsize=%ld",type_size(t)); dbg_printf(" Tnext=%p",t->Tnext); switch (tybasic(t->Tty)) { case TYstruct: case TYmemptr: dbg_printf(" Ttag=%p,'%s'",t->Ttag,t->Ttag->Sident); //dbg_printf(" Sfldlst=%p",t->Ttag->Sstruct->Sfldlst); break; case TYarray: dbg_printf(" Tdim=%ld",t->Tdim); break; case TYident: dbg_printf(" Tident='%s'",t->Tident); break; case TYtemplate: dbg_printf(" Tsym='%s'",((typetemp_t *)t)->Tsym->Sident); { param_t *p; int i; i = 1; for (p = t->Tparamtypes; p; p = p->Pnext) { dbg_printf("\nTP%d (%p): ",i++,p); fflush(stdout); dbg_printf("Pident=%p,Ptype=%p,Pelem=%p,Pnext=%p ",p->Pident,p->Ptype,p->Pelem,p->Pnext); param_debug(p); if (p->Pident) printf("'%s' ", p->Pident); if (p->Ptype) type_print(p->Ptype); if (p->Pelem) elem_print(p->Pelem); } } break; default: if (tyfunc(t->Tty)) { param_t *p; int i; i = 1; for (p = t->Tparamtypes; p; p = p->Pnext) { dbg_printf("\nP%d (%p): ",i++,p); fflush(stdout); dbg_printf("Pident=%p,Ptype=%p,Pelem=%p,Pnext=%p ",p->Pident,p->Ptype,p->Pelem,p->Pnext); param_debug(p); if (p->Pident) printf("'%s' ", p->Pident); type_print(p->Ptype); } } break; } dbg_printf("\n"); if (t->Tnext) type_print(t->Tnext); }
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); }
int m2_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; int length_pos, length_size, string_pos; int char_size; LONGEST val; CORE_ADDR addr; CHECK_TYPEDEF (type); switch (TYPE_CODE (type)) { case TYPE_CODE_ARRAY: if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0) { elttype = check_typedef (TYPE_TARGET_TYPE (type)); eltlen = TYPE_LENGTH (elttype); len = TYPE_LENGTH (type) / eltlen; if (prettyprint_arrays) print_spaces_filtered (2 + 2 * recurse, stream); /* 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')) { /* 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, 1, 0); i = len; } else { fprintf_filtered (stream, "{"); val_print_array_elements (type, valaddr + embedded_offset, address, stream, format, deref_ref, recurse, pretty, 0); fprintf_filtered (stream, "}"); } break; } /* Array of unspecified length: treat like pointer to first elt. */ print_unpacked_pointer (type, address, address, format, stream); break; case TYPE_CODE_PTR: if (TYPE_CONST (type)) print_variable_at_address (type, valaddr + embedded_offset, stream, format, deref_ref, recurse, pretty); else if (format && format != 's') print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); else { addr = unpack_pointer (type, valaddr + embedded_offset); print_unpacked_pointer (type, addr, address, format, stream); } break; case TYPE_CODE_MEMBER: error (_("not implemented: member type in m2_val_print")); 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, "@"); fputs_filtered (paddress (addr), 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: if (m2_is_long_set (type)) m2_print_long_set (type, valaddr, embedded_offset, address, stream, format, pretty); 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 fprintf_filtered (stream, "%ld)", (long int) val); } break; case TYPE_CODE_RANGE: if (TYPE_LENGTH (type) == TYPE_LENGTH (TYPE_TARGET_TYPE (type))) { m2_val_print (TYPE_TARGET_TYPE (type), valaddr, embedded_offset, address, stream, format, deref_ref, recurse, pretty); break; } /* 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); 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: break; case TYPE_CODE_BITSTRING: case TYPE_CODE_SET: elttype = TYPE_INDEX_TYPE (type); CHECK_TYPEDEF (elttype); if (TYPE_STUB (elttype)) { fprintf_filtered (stream, _("<incomplete type>")); gdb_flush (stream); break; } else { struct type *range = elttype; LONGEST low_bound, high_bound; int i; int is_bitstring = TYPE_CODE (type) == TYPE_CODE_BITSTRING; int need_comma = 0; if (is_bitstring) fputs_filtered ("B'", stream); else fputs_filtered ("{", stream); i = get_discrete_bounds (range, &low_bound, &high_bound); maybe_bad_bstring: if (i < 0) { fputs_filtered (_("<error value>"), stream); goto done; } for (i = low_bound; i <= high_bound; i++) { int element = value_bit_index (type, valaddr + embedded_offset, i); if (element < 0) { i = element; goto maybe_bad_bstring; } if (is_bitstring) fprintf_filtered (stream, "%d", element); else if (element) { if (need_comma) fputs_filtered (", ", stream); print_type_scalar (range, i, stream); need_comma = 1; if (i + 1 <= high_bound && value_bit_index (type, valaddr + embedded_offset, ++i)) { int j = i; fputs_filtered ("..", stream); while (i + 1 <= high_bound && value_bit_index (type, valaddr + embedded_offset, ++i)) j = i; print_type_scalar (range, j, stream); } } } done: if (is_bitstring) fputs_filtered ("'", stream); else fputs_filtered ("}", stream); } break; case TYPE_CODE_VOID: fprintf_filtered (stream, "void"); break; case TYPE_CODE_ERROR: fprintf_filtered (stream, _("<error type>")); break; case TYPE_CODE_UNDEF: /* This happens (without TYPE_FLAG_STUB set) on systems which don't use dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar" and no complete type for struct foo in that file. */ fprintf_filtered (stream, _("<incomplete type>")); break; default: error (_("Invalid m2 type code %d in symbol table."), TYPE_CODE (type)); } gdb_flush (stream); return (0); }
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); }
int pascal_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; int length_pos, length_size, string_pos; int char_size; LONGEST val; CORE_ADDR addr; CHECK_TYPEDEF (type); switch (TYPE_CODE (type)) { case TYPE_CODE_ARRAY: if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0) { elttype = check_typedef (TYPE_TARGET_TYPE (type)); eltlen = TYPE_LENGTH (elttype); len = TYPE_LENGTH (type) / eltlen; if (prettyprint_arrays) { print_spaces_filtered (2 + 2 * recurse, stream); } /* For an array of chars, print with string syntax. */ if (eltlen == 1 && ((TYPE_CODE (elttype) == TYPE_CODE_INT) || ((current_language->la_language == language_pascal) && (TYPE_CODE (elttype) == TYPE_CODE_CHAR))) && (format == 0 || format == 's')) { /* 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, 1, 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 (pascal_object_is_vtbl_ptr_type (elttype)) { i = 1; fprintf_filtered (stream, "%d vtable entries", len - 1); } else { i = 0; } 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 && pascal_object_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 the address, assume that it is unsigned. */ print_address_demangle (extract_unsigned_integer (valaddr + embedded_offset, TYPE_LENGTH (type)), stream, demangle); break; } elttype = check_typedef (TYPE_TARGET_TYPE (type)); { addr = unpack_pointer (type, valaddr + embedded_offset); print_unpacked_pointer: 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') { fputs_filtered (paddress (addr), 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 || TYPE_CODE(elttype) == TYPE_CODE_CHAR) && (format == 0 || format == 's') && addr != 0) { /* no wide string yet */ i = val_print_string (addr, -1, 1, stream); } /* also for pointers to pascal strings */ /* Note: this is Free Pascal specific: as GDB does not recognize stabs pascal strings Pascal strings are mapped to records with lowercase names PM */ if (is_pascal_string_type (elttype, &length_pos, &length_size, &string_pos, &char_size, NULL) && addr != 0) { ULONGEST string_length; void *buffer; buffer = xmalloc (length_size); read_memory (addr + length_pos, buffer, length_size); string_length = extract_unsigned_integer (buffer, length_size); xfree (buffer); i = val_print_string (addr + string_pos, string_length, char_size, stream); } else if (pascal_object_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 (SYMBOL_LINKAGE_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_REF: elttype = check_typedef (TYPE_TARGET_TYPE (type)); if (addressprint) { fprintf_filtered (stream, "@"); /* Extract the address, assume that it is unsigned. */ fputs_filtered (paddress ( extract_unsigned_integer (valaddr + embedded_offset, gdbarch_ptr_bit (current_gdbarch) / HOST_CHAR_BIT)), 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 + 1, pretty); } else fputs_filtered ("???", stream); } break; case TYPE_CODE_UNION: if (recurse && !unionprint) { fprintf_filtered (stream, "{...}"); break; } /* Fall through. */ case TYPE_CODE_STRUCT: if (vtblprint && pascal_object_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.) */ /* Extract the address, assume that it is unsigned. */ print_address_demangle (extract_unsigned_integer (valaddr + embedded_offset + TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8, TYPE_LENGTH (TYPE_FIELD_TYPE (type, VTBL_FNADDR_OFFSET))), stream, demangle); } else { if (is_pascal_string_type (type, &length_pos, &length_size, &string_pos, &char_size, NULL)) { len = extract_unsigned_integer (valaddr + embedded_offset + length_pos, length_size); LA_PRINT_STRING (stream, valaddr + embedded_offset + string_pos, len, char_size, 0); } else pascal_object_print_value_fields (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_FLAGS: if (format) print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); else val_print_type_code_flags (type, valaddr + embedded_offset, stream); 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 { fputs_filtered ("true (", stream); fprintf_filtered (stream, "%ld)", (long int) 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); } 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_BITSTRING: case TYPE_CODE_SET: elttype = TYPE_INDEX_TYPE (type); CHECK_TYPEDEF (elttype); if (TYPE_STUB (elttype)) { fprintf_filtered (stream, "<incomplete type>"); gdb_flush (stream); break; } else { struct type *range = elttype; LONGEST low_bound, high_bound; int i; int is_bitstring = TYPE_CODE (type) == TYPE_CODE_BITSTRING; int need_comma = 0; if (is_bitstring) fputs_filtered ("B'", stream); else fputs_filtered ("[", stream); i = get_discrete_bounds (range, &low_bound, &high_bound); maybe_bad_bstring: if (i < 0) { fputs_filtered ("<error value>", stream); goto done; } for (i = low_bound; i <= high_bound; i++) { int element = value_bit_index (type, valaddr + embedded_offset, i); if (element < 0) { i = element; goto maybe_bad_bstring; } if (is_bitstring) fprintf_filtered (stream, "%d", element); else if (element) { if (need_comma) fputs_filtered (", ", stream); print_type_scalar (range, i, stream); need_comma = 1; if (i + 1 <= high_bound && value_bit_index (type, valaddr + embedded_offset, ++i)) { int j = i; fputs_filtered ("..", stream); while (i + 1 <= high_bound && value_bit_index (type, valaddr + embedded_offset, ++i)) j = i; print_type_scalar (range, j, stream); } } } done: if (is_bitstring) fputs_filtered ("'", stream); else fputs_filtered ("]", stream); } break; case TYPE_CODE_VOID: fprintf_filtered (stream, "void"); break; case TYPE_CODE_ERROR: fprintf_filtered (stream, "<error type>"); break; case TYPE_CODE_UNDEF: /* This happens (without TYPE_FLAG_STUB set) on systems which don't use dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar" and no complete type for struct foo in that file. */ fprintf_filtered (stream, "<incomplete type>"); break; default: error (_("Invalid pascal 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 void list_arg_or_local (const struct frame_arg *arg, enum what_to_list what, enum print_values values, int skip_unavailable) { struct cleanup *old_chain; struct ui_out *uiout = current_uiout; struct ui_file *stb; gdb_assert (!arg->val || !arg->error); gdb_assert ((values == PRINT_NO_VALUES && arg->val == NULL && arg->error == NULL) || values == PRINT_SIMPLE_VALUES || (values == PRINT_ALL_VALUES && (arg->val != NULL || arg->error != NULL))); gdb_assert (arg->entry_kind == print_entry_values_no || (arg->entry_kind == print_entry_values_only && (arg->val || arg->error))); if (skip_unavailable && arg->val != NULL && (value_entirely_unavailable (arg->val) /* A scalar object that does not have all bits available is also considered unavailable, because all bits contribute to its representation. */ || (val_print_scalar_type_p (value_type (arg->val)) && !value_bytes_available (arg->val, value_embedded_offset (arg->val), TYPE_LENGTH (value_type (arg->val)))))) return; stb = mem_fileopen (); old_chain = make_cleanup_ui_file_delete (stb); if (values != PRINT_NO_VALUES || what == all) make_cleanup_ui_out_tuple_begin_end (uiout, NULL); fputs_filtered (SYMBOL_PRINT_NAME (arg->sym), stb); if (arg->entry_kind == print_entry_values_only) fputs_filtered ("@entry", stb); ui_out_field_stream (uiout, "name", stb); if (what == all && SYMBOL_IS_ARGUMENT (arg->sym)) ui_out_field_int (uiout, "arg", 1); if (values == PRINT_SIMPLE_VALUES) { check_typedef (arg->sym->type); type_print (arg->sym->type, "", stb, -1); ui_out_field_stream (uiout, "type", stb); } if (arg->val || arg->error) { const char *error_message = NULL; if (arg->error) error_message = arg->error; else { TRY { struct value_print_options opts; get_no_prettyformat_print_options (&opts); opts.deref_ref = 1; common_val_print (arg->val, stb, 0, &opts, language_def (SYMBOL_LANGUAGE (arg->sym))); } CATCH (except, RETURN_MASK_ERROR) { error_message = except.message; } END_CATCH } if (error_message != NULL) fprintf_filtered (stb, _("<error reading variable: %s>"), error_message); ui_out_field_stream (uiout, "value", stb); } do_cleanups (old_chain); }
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; } }
struct ast * ast_new_builtin(struct scan_st *sc, struct builtin *bi, struct ast *right) { struct ast *a; struct type *t, *tr; int unify = 0; t = bi->ty(); type_ensure_routine(t); #ifdef DEBUG if (trace_type_inference) { printf("(builtin `"); fputsu8(stdout, bi->name); printf("`)*****\n"); printf("type of args is: "); if (right != NULL) type_print(stdout, right->datatype); printf("\ntype of builtin is: "); type_print(stdout, t); } #endif if (right == NULL) tr = type_new(TYPE_VOID); else tr = right->datatype; unify = type_unify_crit(sc, type_representative(t)->t.closure.domain, tr); #ifdef DEBUG if (trace_type_inference) { printf("\nthese unify? --> %d <--", unify); printf("\n****\n"); } #endif /* * Fold constants. */ if (bi->is_pure && ast_is_constant(right)) { struct value v; struct activation *ar; struct ast *g; int i = 0; int varity; if (bi->arity == -1) { varity = ast_count_args(right); } else { varity = bi->arity; } if (unify) { ar = activation_new_on_heap(varity, NULL, NULL); for (g = right, i = 0; g != NULL && g->type == AST_ARG && i < varity; g = g->u.arg.right, i++) { if (g->u.arg.left != NULL) activation_initialize_value(ar, i, g->u.arg.left->u.value.value); } v = bi->fn(ar); } else { a = NULL; } a = ast_new_value(v, type_representative(t)->t.closure.range); return(a); } a = ast_new(AST_BUILTIN); a->u.builtin.bi = bi; a->u.builtin.right = right; a->datatype = type_representative(t)->t.closure.range; return(a); }