diff --git a/gcc/c-family/c-pretty-print.cc b/gcc/c-family/c-pretty-print.cc
index 26038818d759..9be0154af7ac 100644
--- a/gcc/c-family/c-pretty-print.cc
+++ b/gcc/c-family/c-pretty-print.cc
@@ -748,7 +748,8 @@ c_pretty_printer::storage_class_specifier (tree t)
     pp_c_ws_string (this, "typedef");
   else if (DECL_P (t))
     {
-      if (DECL_REGISTER (t))
+      if ((TREE_CODE (t) == PARM_DECL || VAR_P (t))
+	  && DECL_REGISTER (t))
 	pp_c_ws_string (this, "register");
       else if (TREE_STATIC (t) && VAR_P (t))
 	pp_c_ws_string (this, "static");
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index a3edaa842d9d..416202ed3e88 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -34,6 +34,115 @@ along with GCC; see the file COPYING3.  If not see
 #include "hash-map.h"
 #include "coroutines.h"
 
+/* ================= Debug. ================= */
+
+#include "langhooks.h"
+#include "cxx-pretty-print.h"
+
+static void
+dump_record_fields (cxx_pretty_printer *pp, tree typ)
+{
+  pp->type_id (typ);
+  pp_newline_and_indent (pp, 2);
+  pp_left_brace (pp);
+  pp_indentation (pp) += 2;
+
+  /* We'll be on a new line, we don't need padding.  */
+  pp->set_padding (pp_none);
+
+  for (tree tmp = TYPE_FIELDS (typ); tmp; tmp = DECL_CHAIN (tmp))
+    {
+      pp_newline_and_indent (pp, 0);
+      pp->declaration (tmp);
+    }
+
+  pp_newline_and_indent (pp, -2);
+  pp_right_brace (pp);
+  pp_newline_and_indent (pp, -2);
+}
+
+static FILE *dmp_str = NULL;
+int coro_dump_id;
+static dump_flags_t coro_dump_flags;
+
+/* Pretty print the function FNDECL, which ought to be a coroutine before
+   co_await expansion, into the lang-coro dump, if it is enabled.  */
+
+static void
+coro_maybe_dump_initial_function (tree fndecl)
+{
+  if (!dmp_str)
+    return;
+
+  bool lambda_p = LAMBDA_TYPE_P (DECL_CONTEXT (fndecl));
+  fprintf (dmp_str, "%s %s original:\n",
+	   (lambda_p ? "Lambda" : "Function"),
+	    lang_hooks.decl_printable_name (fndecl, 2));
+
+  cxx_pretty_printer pp;
+  pp.set_output_stream (dmp_str);
+  pp.flags = coro_dump_flags;
+  pp.declaration (fndecl);
+  pp_newline_and_flush (&pp);
+}
+
+/* Pretty print the RAMP function to the lang-coro dump, if it is enabled.  */
+
+static void
+coro_maybe_dump_ramp (tree ramp)
+{
+  if (!dmp_str)
+    return;
+
+  cxx_pretty_printer pp;
+  pp.set_output_stream (dmp_str);
+  pp.flags = coro_dump_flags;
+
+  pp_string (&pp, "Ramp function:");
+  pp_newline_and_indent (&pp, 0);
+  pp.declaration (ramp);
+  pp_newline_and_flush (&pp);
+}
+
+/* For a given ACTOR, DESTROY and FRAME_TYPE, if lang-coro dumping is enabled,
+   pretty-print their contents to the lang-coro dump.  */
+
+static void
+coro_maybe_dump_transformed_functions (tree actor, tree destroy)
+{
+  if (!dmp_str)
+    return;
+
+  cxx_pretty_printer pp;
+  pp.set_output_stream (dmp_str);
+  pp.flags = coro_dump_flags;
+
+  if (!actor || actor == error_mark_node)
+    {
+      pp_string (&pp, "Transform failed");
+      pp_newline_and_flush (&pp);
+      return;
+    }
+
+  tree frame = TREE_TYPE (TREE_TYPE (DECL_ARGUMENTS (actor)));
+  pp_string (&pp, "Frame type:");
+  pp_newline (&pp);
+  dump_record_fields (&pp, frame);
+  pp_newline_and_flush (&pp);
+
+  pp_string (&pp, "Actor/resumer:");
+  pp_newline (&pp);
+  pp.declaration (actor);
+  pp_newline_and_flush (&pp);
+
+  pp_string (&pp, "Destroyer:");
+  pp_newline (&pp);
+  pp.declaration (destroy);
+  pp_newline_and_flush (&pp);
+}
+
+/* ================= END Debug. ================= */
+
 static bool coro_promise_type_found_p (tree, location_t);
 
 /* GCC C++ coroutines implementation.
@@ -5214,6 +5323,10 @@ cp_coroutine_transform::~cp_coroutine_transform ()
 void
 cp_coroutine_transform::apply_transforms ()
 {
+  if (dmp_str == NULL)
+    dmp_str = dump_begin (coro_dump_id, &coro_dump_flags);
+
+  coro_maybe_dump_initial_function (orig_fn_decl);
 
   coroutine_body
     = split_coroutine_body_from_ramp (orig_fn_decl);
@@ -5261,6 +5374,7 @@ cp_coroutine_transform::apply_transforms ()
   frame_type = finish_struct (frame_type, NULL_TREE);
 
   valid_coroutine = build_ramp_function ();
+  coro_maybe_dump_ramp (orig_fn_decl);
 }
 
 /* Having analysed and collected the necessary data we are now in a position
@@ -5279,6 +5393,8 @@ cp_coroutine_transform::finish_transforms ()
 
   current_function_decl = destroyer;
   build_destroy_fn (fn_start, frame_type, destroyer, resumer, inline_p);
+
+  coro_maybe_dump_transformed_functions (resumer, destroyer);
 }
 
 #include "gt-cp-coroutines.h"
diff --git a/gcc/cp/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc
index cd379514991d..248119b05fe1 100644
--- a/gcc/cp/cp-objcp-common.cc
+++ b/gcc/cp/cp-objcp-common.cc
@@ -607,6 +607,8 @@ cp_register_dumps (gcc::dump_manager *dumps)
 
   raw_dump_id = dumps->dump_register
     (".raw", "lang-raw", "lang-raw", DK_lang, OPTGROUP_NONE, false);
+  coro_dump_id = dumps->dump_register
+    (".coro", "lang-coro", "lang-coro", DK_lang, OPTGROUP_NONE, false);
 }
 
 void
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 72ed4f1a4741..886b5e2b2f99 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6680,6 +6680,7 @@ extern cp_parameter_declarator *no_parameters;
 extern int class_dump_id;
 extern int module_dump_id;
 extern int raw_dump_id;
+extern int coro_dump_id;
 
 /* Whether the current context is manifestly constant-evaluated.
    Used by the constexpr machinery to control folding of
diff --git a/gcc/cp/cxx-pretty-print.cc b/gcc/cp/cxx-pretty-print.cc
index e690354e08e9..4184bb87768e 100644
--- a/gcc/cp/cxx-pretty-print.cc
+++ b/gcc/cp/cxx-pretty-print.cc
@@ -2277,7 +2277,7 @@ pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
     {
     case TYPE_DECL:
       pp_cxx_ws_string (pp, "class");
-      if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
+      if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parameter)))
 	pp_cxx_ws_string (pp, "...");
       if (DECL_NAME (parameter))
 	pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
@@ -2463,6 +2463,7 @@ cxx_pretty_printer::declaration (tree t)
       }
   else switch (TREE_CODE (t))
     {
+    case FIELD_DECL:
     case VAR_DECL:
     case TYPE_DECL:
       pp_cxx_simple_declaration (this, t);
diff --git a/gcc/dumpfile.cc b/gcc/dumpfile.cc
index 074da7df2169..5977e938b636 100644
--- a/gcc/dumpfile.cc
+++ b/gcc/dumpfile.cc
@@ -108,7 +108,7 @@ static struct dump_file_info dump_files[TDI_end] =
   DUMP_FILE_INFO (".lto-stream-out", "ipa-lto-stream-out", DK_ipa, 0),
   DUMP_FILE_INFO (".profile-report", "profile-report", DK_ipa, 0),
 #define FIRST_AUTO_NUMBERED_DUMP 1
-#define FIRST_ME_AUTO_NUMBERED_DUMP 5
+#define FIRST_ME_AUTO_NUMBERED_DUMP 6
 
   DUMP_FILE_INFO (NULL, "lang-all", DK_lang, 0),
   DUMP_FILE_INFO (NULL, "tree-all", DK_tree, 0),
