diff mbox series

PATCH 3/8] coroutines: Support for debugging implementation state.

Message ID C9F65FED-7179-4744-812C-79A8400128BB@sandoe.co.uk
State New
Headers show
Series PATCH 3/8] coroutines: Support for debugging implementation state. | expand

Commit Message

Iain Sandoe Sept. 1, 2021, 10:53 a.m. UTC
Some of the state that is associated with the implementation
is of interest to a user debugging a coroutine.  In particular
items such as the suspend point, promise object, and current
suspend point.

These variables live in the coroutine frame, but we can inject
proxies for them into the outermost bind expression of the
coroutine.  Such variables are automatically moved into the
coroutine frame (if they need to persist across a suspend
expression).  PLacing the proxies thus allows the user to
inspect them by name in the debugger.

To implement this, we ensure that (at the outermost scope) the
frame entries are not mangled (coroutine frame variables are
usually mangled with scope nesting information so that they do
not clash).  We can safely avoid doing this for the outermost
scope so that we can map frame entries directly to the variables.

This is partial contribution to debug support (PR 99215).

Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>

gcc/cp/ChangeLog:

	* coroutines.cc (register_local_var_uses): Do not mangle
	frame entries for the outermost scope.  Record the outer
	scope as nesting depth 0.
---
 gcc/cp/coroutines.cc | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

--

Comments

Jason Merrill Sept. 3, 2021, 1:31 p.m. UTC | #1
On 9/1/21 6:53 AM, Iain Sandoe wrote:
> 
> Some of the state that is associated with the implementation
> is of interest to a user debugging a coroutine.  In particular
> items such as the suspend point, promise object, and current
> suspend point.
> 
> These variables live in the coroutine frame, but we can inject
> proxies for them into the outermost bind expression of the
> coroutine.  Such variables are automatically moved into the
> coroutine frame (if they need to persist across a suspend
> expression).  PLacing the proxies thus allows the user to
> inspect them by name in the debugger.
> 
> To implement this, we ensure that (at the outermost scope) the
> frame entries are not mangled (coroutine frame variables are
> usually mangled with scope nesting information so that they do
> not clash).  We can safely avoid doing this for the outermost
> scope so that we can map frame entries directly to the variables.
> 
> This is partial contribution to debug support (PR 99215).

OK.

> Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
> 
> gcc/cp/ChangeLog:
> 
> 	* coroutines.cc (register_local_var_uses): Do not mangle
> 	frame entries for the outermost scope.  Record the outer
> 	scope as nesting depth 0.
> ---
>   gcc/cp/coroutines.cc | 16 +++++++++++-----
>   1 file changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
> index b8501032969..a12714ea67e 100644
> --- a/gcc/cp/coroutines.cc
> +++ b/gcc/cp/coroutines.cc
> @@ -3885,8 +3885,6 @@ register_local_var_uses (tree *stmt, int *do_subtree, void *d)
>   
>     if (TREE_CODE (*stmt) == BIND_EXPR)
>       {
> -      lvd->bind_indx++;
> -      lvd->nest_depth++;
>         tree lvar;
>         for (lvar = BIND_EXPR_VARS (*stmt); lvar != NULL;
>   	   lvar = DECL_CHAIN (lvar))
> @@ -3925,11 +3923,17 @@ register_local_var_uses (tree *stmt, int *do_subtree, void *d)
>   	    continue;
>   
>   	  /* Make names depth+index unique, so that we can support nested
> -	     scopes with identically named locals.  */
> +	     scopes with identically named locals and still be able to
> +	     identify them in the coroutine frame.  */
>   	  tree lvname = DECL_NAME (lvar);
>   	  char *buf;
> -	  if (lvname != NULL_TREE)
> -	    buf = xasprintf ("__%s.%u.%u", IDENTIFIER_POINTER (lvname),
> +	  /* The outermost bind scope contains the artificial variables that
> +	     we inject to implement the coro state machine.  We want to be able
> +	     to inspect these in debugging.  */
> +	  if (lvname != NULL_TREE && lvd->nest_depth == 0)
> +	    buf = xasprintf ("%s", IDENTIFIER_POINTER (lvname));
> +	  else if (lvname != NULL_TREE)
> +	    buf = xasprintf ("%s_%u_%u", IDENTIFIER_POINTER (lvname),
>   			     lvd->nest_depth, lvd->bind_indx);
>   	  else
>   	    buf = xasprintf ("_D%u.%u.%u", DECL_UID (lvar), lvd->nest_depth,
> @@ -3942,6 +3946,8 @@ register_local_var_uses (tree *stmt, int *do_subtree, void *d)
>   	  /* We don't walk any of the local var sub-trees, they won't contain
>   	     any bind exprs.  */
>   	}
> +      lvd->bind_indx++;
> +      lvd->nest_depth++;
>         cp_walk_tree (&BIND_EXPR_BODY (*stmt), register_local_var_uses, d, NULL);
>         *do_subtree = 0; /* We've done this.  */
>         lvd->nest_depth--;
>
diff mbox series

Patch

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index b8501032969..a12714ea67e 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -3885,8 +3885,6 @@  register_local_var_uses (tree *stmt, int *do_subtree, void *d)
 
   if (TREE_CODE (*stmt) == BIND_EXPR)
     {
-      lvd->bind_indx++;
-      lvd->nest_depth++;
       tree lvar;
       for (lvar = BIND_EXPR_VARS (*stmt); lvar != NULL;
 	   lvar = DECL_CHAIN (lvar))
@@ -3925,11 +3923,17 @@  register_local_var_uses (tree *stmt, int *do_subtree, void *d)
 	    continue;
 
 	  /* Make names depth+index unique, so that we can support nested
-	     scopes with identically named locals.  */
+	     scopes with identically named locals and still be able to
+	     identify them in the coroutine frame.  */
 	  tree lvname = DECL_NAME (lvar);
 	  char *buf;
-	  if (lvname != NULL_TREE)
-	    buf = xasprintf ("__%s.%u.%u", IDENTIFIER_POINTER (lvname),
+	  /* The outermost bind scope contains the artificial variables that
+	     we inject to implement the coro state machine.  We want to be able
+	     to inspect these in debugging.  */
+	  if (lvname != NULL_TREE && lvd->nest_depth == 0)
+	    buf = xasprintf ("%s", IDENTIFIER_POINTER (lvname));
+	  else if (lvname != NULL_TREE)
+	    buf = xasprintf ("%s_%u_%u", IDENTIFIER_POINTER (lvname),
 			     lvd->nest_depth, lvd->bind_indx);
 	  else
 	    buf = xasprintf ("_D%u.%u.%u", DECL_UID (lvar), lvd->nest_depth,
@@ -3942,6 +3946,8 @@  register_local_var_uses (tree *stmt, int *do_subtree, void *d)
 	  /* We don't walk any of the local var sub-trees, they won't contain
 	     any bind exprs.  */
 	}
+      lvd->bind_indx++;
+      lvd->nest_depth++;
       cp_walk_tree (&BIND_EXPR_BODY (*stmt), register_local_var_uses, d, NULL);
       *do_subtree = 0; /* We've done this.  */
       lvd->nest_depth--;