forked from Imagelibrary/binutils-gdb
Enable chained function calls in C++ expressions.
gdb/ChangeLog: * eval.c: Include gdbthread.h. (evaluate_subexp): Enable thread stack temporaries before evaluating a complete expression and clean them up after the evaluation is complete. * gdbthread.h: Include common/vec.h. (value_ptr): New typedef. (VEC (value_ptr)): New vector type. (value_vec): New typedef. (struct thread_info): Add new fields stack_temporaries_enabled and stack_temporaries. (enable_thread_stack_temporaries) (thread_stack_temporaries_enabled_p, push_thread_stack_temporary) (get_last_thread_stack_temporary) (value_in_thread_stack_temporaries): Declare. * gdbtypes.c (class_or_union_p): New function. * gdbtypes.h (class_or_union_p): Declare. * infcall.c (call_function_by_hand): Store return values of class type as temporaries on stack. * thread.c (enable_thread_stack_temporaries): New function. (thread_stack_temporaries_enabled_p, push_thread_stack_temporary) (get_last_thread_stack_temporary): Likewise. (value_in_thread_stack_temporaries): Likewise. * value.c (value_force_lval): New function. * value.h (value_force_lval): Declare. gdb/testsuite/ChangeLog: * gdb.cp/chained-calls.cc: New file. * gdb.cp/chained-calls.exp: New file. * gdb.cp/smartp.exp: Remove KFAIL for "p c2->inta".
This commit is contained in:
102
gdb/thread.c
102
gdb/thread.c
@@ -636,6 +636,108 @@ prune_threads (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable storing stack temporaries for the thread whose id is
|
||||
stored in DATA. */
|
||||
|
||||
static void
|
||||
disable_thread_stack_temporaries (void *data)
|
||||
{
|
||||
ptid_t *pd = data;
|
||||
struct thread_info *tp = find_thread_ptid (*pd);
|
||||
|
||||
if (tp != NULL)
|
||||
{
|
||||
tp->stack_temporaries_enabled = 0;
|
||||
VEC_free (value_ptr, tp->stack_temporaries);
|
||||
}
|
||||
|
||||
xfree (pd);
|
||||
}
|
||||
|
||||
/* Enable storing stack temporaries for thread with id PTID and return a
|
||||
cleanup which can disable and clear the stack temporaries. */
|
||||
|
||||
struct cleanup *
|
||||
enable_thread_stack_temporaries (ptid_t ptid)
|
||||
{
|
||||
struct thread_info *tp = find_thread_ptid (ptid);
|
||||
ptid_t *data;
|
||||
struct cleanup *c;
|
||||
|
||||
gdb_assert (tp != NULL);
|
||||
|
||||
tp->stack_temporaries_enabled = 1;
|
||||
tp->stack_temporaries = NULL;
|
||||
data = (ptid_t *) xmalloc (sizeof (ptid_t));
|
||||
*data = ptid;
|
||||
c = make_cleanup (disable_thread_stack_temporaries, data);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/* Return non-zero value if stack temporaies are enabled for the thread
|
||||
with id PTID. */
|
||||
|
||||
int
|
||||
thread_stack_temporaries_enabled_p (ptid_t ptid)
|
||||
{
|
||||
struct thread_info *tp = find_thread_ptid (ptid);
|
||||
|
||||
if (tp == NULL)
|
||||
return 0;
|
||||
else
|
||||
return tp->stack_temporaries_enabled;
|
||||
}
|
||||
|
||||
/* Push V on to the stack temporaries of the thread with id PTID. */
|
||||
|
||||
void
|
||||
push_thread_stack_temporary (ptid_t ptid, struct value *v)
|
||||
{
|
||||
struct thread_info *tp = find_thread_ptid (ptid);
|
||||
|
||||
gdb_assert (tp != NULL && tp->stack_temporaries_enabled);
|
||||
VEC_safe_push (value_ptr, tp->stack_temporaries, v);
|
||||
}
|
||||
|
||||
/* Return 1 if VAL is among the stack temporaries of the thread
|
||||
with id PTID. Return 0 otherwise. */
|
||||
|
||||
int
|
||||
value_in_thread_stack_temporaries (struct value *val, ptid_t ptid)
|
||||
{
|
||||
struct thread_info *tp = find_thread_ptid (ptid);
|
||||
|
||||
gdb_assert (tp != NULL && tp->stack_temporaries_enabled);
|
||||
if (!VEC_empty (value_ptr, tp->stack_temporaries))
|
||||
{
|
||||
struct value *v;
|
||||
int i;
|
||||
|
||||
for (i = 0; VEC_iterate (value_ptr, tp->stack_temporaries, i, v); i++)
|
||||
if (v == val)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return the last of the stack temporaries for thread with id PTID.
|
||||
Return NULL if there are no stack temporaries for the thread. */
|
||||
|
||||
struct value *
|
||||
get_last_thread_stack_temporary (ptid_t ptid)
|
||||
{
|
||||
struct value *lastval = NULL;
|
||||
struct thread_info *tp = find_thread_ptid (ptid);
|
||||
|
||||
gdb_assert (tp != NULL);
|
||||
if (!VEC_empty (value_ptr, tp->stack_temporaries))
|
||||
lastval = VEC_last (value_ptr, tp->stack_temporaries);
|
||||
|
||||
return lastval;
|
||||
}
|
||||
|
||||
void
|
||||
thread_change_ptid (ptid_t old_ptid, ptid_t new_ptid)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user