+2017-09-04 Pedro Alves <palves@redhat.com>
+
+ * ax-gdb.c: Include "typeprint.h".
+ (gen_expr_for_cast): New function.
+ (gen_expr) <OP_CAST, OP_CAST_TYPE>: Use it.
+ <OP_VAR_VALUE, OP_MSYM_VAR_VALUE>: Error out if the variable's
+ type is unknown.
+ * dwarf2read.c (new_symbol_full): Fallback to int instead of
+ nodebug_data_symbol.
+ * eval.c: Include "typeprint.h".
+ (evaluate_subexp_standard) <OP_VAR_VALUE, OP_VAR_MSYM_VALUE>:
+ Error out if symbol has unknown type.
+ <UNOP_CAST, UNOP_CAST_TYPE>: Common bits factored out to
+ evaluate_subexp_for_cast.
+ (evaluate_subexp_for_address, evaluate_subexp_for_sizeof): Handle
+ OP_VAR_MSYM_VALUE.
+ (evaluate_subexp_for_cast): New function.
+ * gdbtypes.c (init_nodebug_var_type): New function.
+ (objfile_type): Use it to initialize types of variables with no
+ debug info.
+ * typeprint.c (error_unknown_type): New.
+ * typeprint.h (error_unknown_type): New declaration.
+ * compile/compile-c-types.c (convert_type_basic): Handle
+ TYPE_CODE_ERROR; warn and fallback to int for variables with
+ unknown type.
+
2017-09-04 Pedro Alves <palves@redhat.com>
* eval.c (evaluate_var_value): New function, factored out from ...
#include "linespec.h"
#include "location.h"
#include "objfiles.h"
-
+#include "typeprint.h"
#include "valprint.h"
#include "c-lang.h"
}
\f
+/* Generate bytecode for a cast to TO_TYPE. Advance *PC over the
+ subexpression. */
+
+static void
+gen_expr_for_cast (struct expression *exp, union exp_element **pc,
+ struct agent_expr *ax, struct axs_value *value,
+ struct type *to_type)
+{
+ enum exp_opcode op = (*pc)[0].opcode;
+
+ /* Don't let symbols be handled with gen_expr because that throws an
+ "unknown type" error for no-debug data symbols. Instead, we want
+ the cast to reinterpret such symbols. */
+ if (op == OP_VAR_MSYM_VALUE || op == OP_VAR_VALUE)
+ {
+ if (op == OP_VAR_VALUE)
+ {
+ gen_var_ref (ax, value, (*pc)[2].symbol);
+
+ if (value->optimized_out)
+ error (_("`%s' has been optimized out, cannot use"),
+ SYMBOL_PRINT_NAME ((*pc)[2].symbol));
+ }
+ else
+ gen_msym_var_ref (ax, value, (*pc)[2].msymbol, (*pc)[1].objfile);
+ if (TYPE_CODE (value->type) == TYPE_CODE_ERROR)
+ value->type = to_type;
+ (*pc) += 4;
+ }
+ else
+ gen_expr (exp, pc, ax, value);
+ gen_cast (ax, value, to_type);
+}
+
/* Generating bytecode from GDB expressions: general recursive thingy */
/* XXX: i18n */
error (_("`%s' has been optimized out, cannot use"),
SYMBOL_PRINT_NAME ((*pc)[2].symbol));
+ if (TYPE_CODE (value->type) == TYPE_CODE_ERROR)
+ error_unknown_type (SYMBOL_PRINT_NAME ((*pc)[2].symbol));
+
(*pc) += 4;
break;
case OP_VAR_MSYM_VALUE:
gen_msym_var_ref (ax, value, (*pc)[2].msymbol, (*pc)[1].objfile);
+
+ if (TYPE_CODE (value->type) == TYPE_CODE_ERROR)
+ error_unknown_type (MSYMBOL_PRINT_NAME ((*pc)[2].msymbol));
+
(*pc) += 4;
break;
struct type *type = (*pc)[1].type;
(*pc) += 3;
- gen_expr (exp, pc, ax, value);
- gen_cast (ax, value, type);
+ gen_expr_for_cast (exp, pc, ax, value, type);
}
break;
val = evaluate_subexp (NULL, exp, &offset, EVAL_AVOID_SIDE_EFFECTS);
type = value_type (val);
*pc = &exp->elts[offset];
-
- gen_expr (exp, pc, ax, value);
- gen_cast (ax, value, type);
+ gen_expr_for_cast (exp, pc, ax, value, type);
}
break;
case TYPE_CODE_COMPLEX:
return convert_complex (context, type);
+
+ case TYPE_CODE_ERROR:
+ {
+ /* Ideally, if we get here due to a cast expression, we'd use
+ the cast-to type as the variable's type, like GDB's
+ built-in parser does. For now, assume "int" like GDB's
+ built-in parser used to do, but at least warn. */
+ struct type *fallback;
+ if (TYPE_OBJFILE_OWNED (type))
+ fallback = objfile_type (TYPE_OWNER (type).objfile)->builtin_int;
+ else
+ fallback = builtin_type (TYPE_OWNER (type).gdbarch)->builtin_int;
+ warning (_("variable has unknown type; assuming int"));
+ return convert_int (context, fallback);
+ }
}
return C_CTX (context)->c_ops->error (C_CTX (context),
variables with missing type entries. Change the
misleading `void' type to something sensible. */
if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_VOID)
- SYMBOL_TYPE (sym)
- = objfile_type (objfile)->nodebug_data_symbol;
+ SYMBOL_TYPE (sym) = objfile_type (objfile)->builtin_int;
attr = dwarf2_attr (die, DW_AT_const_value, cu);
/* In the case of DW_TAG_member, we should only be called for
#include "valprint.h"
#include "gdb_obstack.h"
#include "objfiles.h"
+#include "typeprint.h"
#include <ctype.h>
/* This is defined in valops.c */
static struct value *evaluate_subexp_for_address (struct expression *,
int *, enum noside);
+static value *evaluate_subexp_for_cast (expression *exp, int *pos,
+ enum noside noside,
+ struct type *type);
+
static struct value *evaluate_struct_tuple (struct value *,
struct expression *, int *,
enum noside, int);
(*pos) += 3;
if (noside == EVAL_SKIP)
return eval_skip_value (exp);
- return evaluate_var_value (noside,
- exp->elts[pc + 1].block,
- exp->elts[pc + 2].symbol);
+
+ {
+ symbol *var = exp->elts[pc + 2].symbol;
+ if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_ERROR)
+ error_unknown_type (SYMBOL_PRINT_NAME (var));
+
+ return evaluate_var_value (noside, exp->elts[pc + 1].block, var);
+ }
+
case OP_VAR_MSYM_VALUE:
- (*pos) += 3;
- return evaluate_var_msym_value (noside,
- exp->elts[pc + 1].objfile,
- exp->elts[pc + 2].msymbol);
+ {
+ (*pos) += 3;
+
+ minimal_symbol *msymbol = exp->elts[pc + 2].msymbol;
+ value *val = evaluate_var_msym_value (noside,
+ exp->elts[pc + 1].objfile,
+ msymbol);
+
+ type = value_type (val);
+ if (TYPE_CODE (type) == TYPE_CODE_ERROR
+ && (noside != EVAL_AVOID_SIDE_EFFECTS || pc != 0))
+ error_unknown_type (MSYMBOL_PRINT_NAME (msymbol));
+ return val;
+ }
case OP_VAR_ENTRY_VALUE:
(*pos) += 2;
case UNOP_CAST:
(*pos) += 2;
type = exp->elts[pc + 1].type;
- arg1 = evaluate_subexp (type, exp, pos, noside);
- if (noside == EVAL_SKIP)
- return eval_skip_value (exp);
- if (type != value_type (arg1))
- arg1 = value_cast (type, arg1);
- return arg1;
+ return evaluate_subexp_for_cast (exp, pos, noside, type);
case UNOP_CAST_TYPE:
arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
type = value_type (arg1);
- arg1 = evaluate_subexp (type, exp, pos, noside);
- if (noside == EVAL_SKIP)
- return eval_skip_value (exp);
- if (type != value_type (arg1))
- arg1 = value_cast (type, arg1);
- return arg1;
+ return evaluate_subexp_for_cast (exp, pos, noside, type);
case UNOP_DYNAMIC_CAST:
arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
else
return address_of_variable (var, exp->elts[pc + 1].block);
+ case OP_VAR_MSYM_VALUE:
+ {
+ (*pos) += 4;
+
+ value *val = evaluate_var_msym_value (noside,
+ exp->elts[pc + 1].objfile,
+ exp->elts[pc + 2].msymbol);
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ {
+ struct type *type = lookup_pointer_type (value_type (val));
+ return value_zero (type, not_lval);
+ }
+ else
+ return value_addr (val);
+ }
+
case OP_SCOPE:
tem = longest_to_int (exp->elts[pc + 2].longconst);
(*pos) += 5 + BYTES_TO_EXP_ELEM (tem + 1);
(*pos) += 4;
break;
+ case OP_VAR_MSYM_VALUE:
+ {
+ (*pos) += 4;
+
+ minimal_symbol *msymbol = exp->elts[pc + 2].msymbol;
+ value *val = evaluate_var_msym_value (noside,
+ exp->elts[pc + 1].objfile,
+ msymbol);
+
+ type = value_type (val);
+ if (TYPE_CODE (type) == TYPE_CODE_ERROR)
+ error_unknown_type (MSYMBOL_PRINT_NAME (msymbol));
+
+ return value_from_longest (size_type, TYPE_LENGTH (type));
+ }
+ break;
+
/* Deal with the special case if NOSIDE is EVAL_NORMAL and the resulting
type of the subscript is a variable length array type. In this case we
must re-evaluate the right hand side of the subcription to allow
return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
}
+/* Evaluate a subexpression of EXP, at index *POS, and return a value
+ for that subexpression cast to TO_TYPE. Advance *POS over the
+ subexpression. */
+
+static value *
+evaluate_subexp_for_cast (expression *exp, int *pos,
+ enum noside noside,
+ struct type *to_type)
+{
+ int pc = *pos;
+
+ /* Don't let symbols be evaluated with evaluate_subexp because that
+ throws an "unknown type" error for no-debug data symbols.
+ Instead, we want the cast to reinterpret the symbol. */
+ if (exp->elts[pc].opcode == OP_VAR_MSYM_VALUE
+ || exp->elts[pc].opcode == OP_VAR_VALUE)
+ {
+ (*pos) += 4;
+
+ value *val;
+ if (exp->elts[pc].opcode == OP_VAR_MSYM_VALUE)
+ {
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return value_zero (to_type, not_lval);
+
+ val = evaluate_var_msym_value (noside,
+ exp->elts[pc + 1].objfile,
+ exp->elts[pc + 2].msymbol);
+ }
+ else
+ val = evaluate_var_value (noside,
+ exp->elts[pc + 1].block,
+ exp->elts[pc + 2].symbol);
+
+ if (noside == EVAL_SKIP)
+ return eval_skip_value (exp);
+
+ val = value_cast (to_type, val);
+
+ /* Don't allow e.g. '&(int)var_with_no_debug_info'. */
+ if (VALUE_LVAL (val) == lval_memory)
+ {
+ if (value_lazy (val))
+ value_fetch_lazy (val);
+ VALUE_LVAL (val) = not_lval;
+ }
+ return val;
+ }
+
+ value *val = evaluate_subexp (to_type, exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ return eval_skip_value (exp);
+ return value_cast (to_type, val);
+}
+
/* Parse a type expression in the string [P..P+LENGTH). */
struct type *
return type;
}
+/* Allocate a TYPE_CODE_ERROR type structure associated with OBJFILE,
+ to use with variables that have no debug info. NAME is the type
+ name. */
+
+static struct type *
+init_nodebug_var_type (struct objfile *objfile, const char *name)
+{
+ return init_type (objfile, TYPE_CODE_ERROR, 0, name);
+}
+
/* Allocate a TYPE_CODE_INT type structure associated with OBJFILE.
BIT is the type size in bits. If UNSIGNED_P is non-zero, set
the type's TYPE_UNSIGNED flag. NAME is the type name. */
"<text from jump slot in .got.plt, no debug info>",
objfile_type->nodebug_text_symbol);
objfile_type->nodebug_data_symbol
- = init_integer_type (objfile, gdbarch_int_bit (gdbarch), 0,
- "<data variable, no debug info>");
+ = init_nodebug_var_type (objfile, "<data variable, no debug info>");
objfile_type->nodebug_unknown_symbol
- = init_integer_type (objfile, TARGET_CHAR_BIT, 0,
- "<variable (not text or data), no debug info>");
+ = init_nodebug_var_type (objfile, "<variable (not text or data), no debug info>");
objfile_type->nodebug_tls_symbol
- = init_integer_type (objfile, gdbarch_int_bit (gdbarch), 0,
- "<thread local variable, no debug info>");
+ = init_nodebug_var_type (objfile, "<thread local variable, no debug info>");
/* NOTE: on some targets, addresses and pointers are not necessarily
the same.
+2017-09-04 Pedro Alves <palves@redhat.com>
+
+ * gdb.asm/asm-source.exp: Add casts to int.
+ * gdb.base/nodebug.c (dataglobal8, dataglobal32_1, dataglobal32_2)
+ (dataglobal64_1, dataglobal64_2): New globals.
+ * gdb.base/nodebug.exp: Test different expressions involving the
+ new globals, with print, whatis and ptype. Add casts to int.
+ * gdb.base/solib-display.exp: Add casts to int.
+ * gdb.compile/compile-ifunc.exp: Expect warning. Add cast to int.
+ * gdb.cp/m-static.exp: Add cast to int.
+ * gdb.dwarf2/dw2-skip-prologue.exp: Add cast to int.
+ * gdb.threads/tls-nodebug.exp: Check that gdb errors out printing
+ tls variable with no debug info without a cast. Test with a cast
+ to int too.
+ * gdb.trace/entry-values.exp: Add casts.
+
2017-09-04 Pedro Alves <palves@redhat.com>
* gdb.base/nodebug.exp: Test that ptype's error about functions
}
# See if we can look at a global variable, three ways
-gdb_test "print globalvar" ".* = 11" "look at global variable"
+gdb_test "print (int) globalvar" ".* = 11" "look at global variable"
test_dis "x/i &globalvar" "globalvar"
-test_dis "disassem &globalvar, &globalvar+1" "globalvar"
+test_dis "disassem &globalvar, (int *) &globalvar+1" "globalvar"
# See if we can look at a static variable, three ways
-gdb_test "print staticvar" ".* = 5" "look at static variable"
+gdb_test "print (int) staticvar" ".* = 5" "look at static variable"
test_dis "x/i &staticvar" "staticvar"
-test_dis "disassem &staticvar, &staticvar+1" "staticvar"
+test_dis "disassem &staticvar, (int *) &staticvar+1" "staticvar"
# See if we can look at a static function
gdb_test "disassem foostatic" ".*<\\+0>:.*End of assembler dump." \
int bssglobal; /* Should go in global bss */
static int bsslocal; /* Should go in local bss */
+/* Non-int-sized global data variables. */
+uint8_t dataglobal8 = 0xff;
+uint32_t dataglobal32_1 = 0x7fffffff;
+uint32_t dataglobal32_2 = 0x000000ff;
+uint64_t dataglobal64_1 = 0x7fffffffffffffff;
+uint64_t dataglobal64_2 = 0x00000000000000ff;
+
int
inner (int x)
{
# we may or may not have debug info for those (depending on
# whether we have debug info for the C runtime, for example).
gdb_test_no_output "macro define uint8 unsigned char"
-
- gdb_test "p dataglobal" "= 3"
- gdb_test "whatis dataglobal" \
- "<(data variable|variable), no debug info>|int"
- gdb_test "ptype dataglobal" "<(data variable|variable), no debug info>|int"
+ gdb_test_no_output "macro define uint32 unsigned int"
+ gdb_test_no_output "macro define uint64 unsigned long long"
+
+ set data_var_type "<data variable, no debug info>"
+ set unk_type_re "has unknown type.*to its declared type"
+ set ptr_math_re "Cannot perform pointer math on incomplete type \"$data_var_type\", try casting to a known type, or void \\*\\."
+ set not_mem_re "Attempt to take address of value not located in memory\\."
+
+ set dataglobal_unk_re "dataglobal.*$unk_type_re"
+
+ #exp #fmt #print #ptype/whatis
+ foreach line {
+ {"dataglobal" "" $dataglobal_unk_re " = $data_var_type"}
+ {"(int) dataglobal" "" "= 3" " = int"}
+ {"sizeof(dataglobal)" "" $dataglobal_unk_re $dataglobal_unk_re}
+ {"sizeof(dataglobal + 1)" "" $dataglobal_unk_re $dataglobal_unk_re}
+ {"sizeof((int) dataglobal)" "" " = $decimal" " = int"}
+ {"dataglobal + 1" "" $dataglobal_unk_re $dataglobal_unk_re}
+ {"&dataglobal" "" "\\($data_var_type \\*\\) $hex <dataglobal>" " = $data_var_type \\*"}
+ {"&dataglobal + 1" "" $ptr_math_re $ptr_math_re}
+ {"(int *) &dataglobal + 1" "" " = \\(int \\*\\) $hex <datalocal>" "int \\*"}
+ {"&(int) dataglobal + 1" "" $not_mem_re $not_mem_re}
+ {"&dataglobal, &dataglobal" "" "\\($data_var_type \\*\\) $hex <dataglobal>" " = $data_var_type \\*"}
+ {"*dataglobal" "" $dataglobal_unk_re $dataglobal_unk_re}
+
+ {"dataglobal8" "/x" $dataglobal_unk_re " = $data_var_type"}
+ {"(uint8) dataglobal8" "/x" " = 0xff" "unsigned char"}
+
+ {"dataglobal32_1" "/x" $dataglobal_unk_re " = $data_var_type"}
+ {"(uint32) dataglobal32_1" "/x" " = 0x7fffffff" "unsigned int"}
+ {"dataglobal32_2" "/x" $dataglobal_unk_re " = $data_var_type"}
+ {"(uint32) dataglobal32_2" "/x" " = 0xff" "unsigned int"}
+
+ {"dataglobal64_1" "/x" $dataglobal_unk_re " = $data_var_type"}
+ {"(uint64) dataglobal64_1" "/x" " = 0x7fffffffffffffff" "unsigned long long"}
+ {"dataglobal64_2" "/x" $dataglobal_unk_re " = $data_var_type"}
+ {"(uint64) dataglobal64_2" "/x" " = 0xff" "unsigned long long"}
+ } {
+ set exp [lindex $line 0]
+ # Expand variables.
+ set fmt [subst -nobackslashes [lindex $line 1]]
+ set print [subst -nobackslashes [lindex $line 2]]
+ set whatis [subst -nobackslashes [lindex $line 3]]
+ if {$fmt == ""} {
+ gdb_test "p $exp" $print
+ } else {
+ gdb_test "p $fmt $exp" $print
+ }
+ gdb_test "whatis $exp" $whatis
+ gdb_test "ptype $exp" $whatis
+ }
# The only symbol xcoff puts out for statics is for the TOC entry.
# Possible, but hairy, for gdb to deal. Right now it doesn't, it
setup_xfail "rs6000*-*-aix*"
setup_xfail "powerpc*-*-aix*"
- gdb_test "p datalocal" "= 4"
+ gdb_test "p datalocal" "datalocal.*$unk_type_re"
+ gdb_test "p (int) datalocal" "= 4"
setup_xfail "rs6000*-*-aix*"
setup_xfail "powerpc*-*-aix*"
- gdb_test "whatis datalocal" "<(data variable|variable), no debug info>"
+ gdb_test "whatis datalocal" "datalocal.*$data_var_type"
setup_xfail "rs6000*-*-aix*"
setup_xfail "powerpc*-*-aix*"
- gdb_test "ptype datalocal" "<(data variable|variable), no debug info>"
- gdb_test "p bssglobal" "= 0"
- gdb_test "whatis bssglobal" "<(data variable|variable), no debug info>|int"
- gdb_test "ptype bssglobal" "<(data variable|variable), no debug info>|int"
+ gdb_test "ptype datalocal" "datalocal.*$data_var_type"
+
+ gdb_test "p bssglobal" "bssglobal.*$unk_type_re"
+ gdb_test "p (int) bssglobal" "= 0"
+ gdb_test "whatis bssglobal" $data_var_type
+ gdb_test "ptype bssglobal" $data_var_type
setup_xfail "rs6000*-*-aix*"
setup_xfail "powerpc*-*-aix*"
- gdb_test "p bsslocal" "= 0"
+ gdb_test "p bsslocal" "bsslocal.*$unk_type_re"
+ gdb_test "p (int) bsslocal" "= 0"
setup_xfail "rs6000*-*-aix*"
setup_xfail "powerpc*-*-aix*"
- gdb_test "whatis bsslocal" "<(data variable|variable), no debug info>"
+ gdb_test "whatis bsslocal" $data_var_type
setup_xfail "rs6000*-*-aix*"
setup_xfail "powerpc*-*-aix*"
- gdb_test "ptype bsslocal" "<(data variable|variable), no debug info>"
+ gdb_test "ptype bsslocal" $data_var_type
gdb_test "backtrace 10" "#0.*inner.*#1.*middle.*#2.*top.*#3.*main.*" \
"backtrace from inner in nodebug.exp"
return 0
}
- gdb_test "display a_global" "1: a_global = 41"
- gdb_test "display b_global" "2: b_global = 42"
- gdb_test "display c_global" "3: c_global = 43"
+ gdb_test "display (int) a_global" "1: \\(int\\) a_global = 41"
+ gdb_test "display (int) b_global" "2: \\(int\\) b_global = 42"
+ gdb_test "display (int) c_global" "3: \\(int\\) c_global = 43"
if { [gdb_start_cmd] < 0 } {
fail "can't run to main (2)"
}
gdb_test "" [multi_line \
- "1: a_global = 41" \
- "2: b_global = 42" \
- "3: c_global = 43" \
+ "1: \\(int\\) a_global = 41" \
+ "2: \\(int\\) b_global = 42" \
+ "3: \\(int\\) c_global = 43" \
] "after rerun"
# Now rebuild the library without b_global
gdb_test "" [multi_line \
- "1: a_global = 41" \
+ "1: \\(int\\) a_global = 41" \
"warning: .*b_global.*" \
- "3: c_global = 43" \
+ "3: \\(int\\) c_global = 43" \
] "after rerun (2)"
# Now verify that displays which are not in the shared library
return -1
}
- gdb_test_no_output "compile code resultvar = gnu_ifunc (10);"
+ gdb_test "compile code resultvar = gnu_ifunc (10);" \
+ "warning: variable has unknown type; assuming int"
- gdb_test "p resultvar" " = 11"
+ gdb_test "p (int) resultvar" " = 11"
}
# simple object, static const int, accessing via 'class::method::variable'
# Regression test for PR c++/15203 and PR c++/15210
-gdb_test "print 'gnu_obj_1::method()::sintvar'" "\\$\[0-9\]+ = 4" \
- "simple object, static const int, accessing via 'class::method::variable"
+gdb_test "print (int) 'gnu_obj_1::method()::sintvar'" "\\$\[0-9\]+ = 4" \
+ "simple object, static int, accessing via 'class::method::variable'"
# simple object, static const bool
gdb_test "print test1.test" "\\$\[0-9\]* = true" "simple object, static const bool"
# Sanity check GDB has really found 2 locations
gdb_test {info break $bpnum} "\r\n2\\.1\[ \t\]\[^\n\]*\r\n2\\.2\[ \t\]\[^\n\]*" "2 locations found"
-gdb_test "p v" " = 0" "no statement got executed"
+gdb_test "p (int) v" " = 0" "no statement got executed"
}
# Formerly: Cannot access memory at address 0x0
-gdb_test "p thread_local" "= 42" "thread local storage"
+gdb_test "p thread_local" "'thread_local' has unknown type; cast it to its declared type" \
+ "thread local storage, unknown type"
+gdb_test "p (int) thread_local" "= 42" \
+ "thread local storage, cast"
# Done!
#
# Update global variables 'global1' and 'global2' and test that the
# entry values are updated too.
-gdb_test_no_output "set var global1=10"
-gdb_test_no_output "set var global2=11"
+gdb_test_no_output "set var *(int *) &global1=10"
+gdb_test_no_output "set var *(int *) &global2=11"
gdb_test_sequence "bt" "bt (2)" {
"\[\r\n\]#0 .* foo \\(i=[-]?[0-9]+, i@entry=10, j=[-]?[0-9]+, j@entry=11\\)"
# argument j.
gdb_trace_setactions "set action for tracepoint 1" "" \
- "collect i, j, global1, \(\*\(void \*\*\) \(\$$spreg\)\) @ 128" "^$"
+ "collect i, j, (int) global1, \(\*\(void \*\*\) \(\$$spreg\)\) @ 128" "^$"
gdb_test_no_output "tstart"
fprintf_filtered (stream, _("<unknown return type>"));
}
+/* See typeprint.h. */
+
+void
+error_unknown_type (const char *sym_print_name)
+{
+ error (_("'%s' has unknown type; cast it to its declared type"),
+ sym_print_name);
+}
+
/* Print type of EXP, or last thing in value history if EXP == NULL.
show is passed to type_print. */
void type_print_unknown_return_type (struct ui_file *stream);
+/* Throw an error indicating that the user tried to use a symbol that
+ has unknown type. SYM_PRINT_NAME is the name of the symbol, to be
+ included in the error message. */
+extern void error_unknown_type (const char *sym_print_name);
+
extern void val_print_not_allocated (struct ui_file *stream);
extern void val_print_not_associated (struct ui_file *stream);