From 6c659fc2c7cd2da6d2b9a3d7c38597ad3821832a Mon Sep 17 00:00:00 2001 From: Siva Chandra Date: Tue, 11 Nov 2014 05:43:03 -0800 Subject: 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". --- gdb/thread.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) (limited to 'gdb/thread.c') diff --git a/gdb/thread.c b/gdb/thread.c index 5c94264..a3040a7 100644 --- a/gdb/thread.c +++ b/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) { -- cgit v1.1