]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: add -fdump-lang-tinst
authorJason Merrill <jason@redhat.com>
Fri, 18 Apr 2025 13:50:04 +0000 (09:50 -0400)
committerJason Merrill <jason@redhat.com>
Mon, 26 May 2025 13:56:27 +0000 (09:56 -0400)
This patch adds a dump with a trace of template instantiations, indented
based on the depth of recursive instantiation. -lineno adds the location
that triggered the instantiation, -details adds non-instantiation
sbustitutions.

The instantiate_pending_templates change is to avoid a bunch of entries for
reopening tinst scopes that we then don't instantiate anything with; it also
seems a bit cleaner this way.

gcc/cp/ChangeLog:

* cp-tree.h: Declare tinst_dump_id.
* cp-objcp-common.cc (cp_register_dumps): Set it.
* pt.cc (push_tinst_level_loc): Dump it.
(reopen_tinst_level): Here too.
(tinst_complete_p): New.
(instantiate_pending_templates): Don't reopen_tinst_level for
already-complete instantiations.

gcc/ChangeLog:

* doc/invoke.texi: Move C++ -fdump-lang to C++ section.
Add -fdump-lang-tinst.

gcc/cp/cp-objcp-common.cc
gcc/cp/cp-tree.h
gcc/cp/pt.cc
gcc/doc/invoke.texi

index 8336d0bb8f7cb6b374d1e268e7a8be5dc2091b20..7665b9454dc5e2bdcf1a1fe9894331ed3c15d0c7 100644 (file)
@@ -614,6 +614,8 @@ cp_register_dumps (gcc::dump_manager *dumps)
     (".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);
+  tinst_dump_id = dumps->dump_register
+    (".tinst", "lang-tinst", "lang-tinst", DK_lang, OPTGROUP_NONE, false);
 }
 
 void
index 7433b8962199e4fb644d3c8955c241919fe19c3b..19c0b452d8689d96c67317e101891f96ccd5c8c6 100644 (file)
@@ -6822,6 +6822,7 @@ extern int class_dump_id;
 extern int module_dump_id;
 extern int raw_dump_id;
 extern int coro_dump_id;
+extern int tinst_dump_id;
 
 /* Whether the current context is manifestly constant-evaluated.
    Used by the constexpr machinery to control folding of
index 1973d25b61a01452847e9313fd9a7a09a8506de2..c687fdc71a3c3867d055241fc8f610dd78c9e9e7 100644 (file)
@@ -11378,6 +11378,7 @@ limit_bad_template_recursion (tree decl)
 static int tinst_depth;
 extern int max_tinst_depth;
 int depth_reached;
+int tinst_dump_id;
 
 static GTY(()) struct tinst_level *last_error_tinst_level;
 
@@ -11430,6 +11431,40 @@ push_tinst_level_loc (tree tldcl, tree targs, location_t loc)
   set_refcount_ptr (new_level->next, current_tinst_level);
   set_refcount_ptr (current_tinst_level, new_level);
 
+  if (cxx_dump_pretty_printer pp {tinst_dump_id})
+    {
+#if __GNUC__ >= 10
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-diag"
+#endif
+      bool list_p = new_level->list_p ();
+      if (list_p && !pp.has_flag (TDF_DETAILS))
+       /* Skip non-instantiations unless -details.  */;
+      else
+       {
+         if (tinst_depth == 0)
+           pp_newline (&pp);
+         if (loc && pp.has_flag (TDF_LINENO))
+           {
+             for (int i = 0; i < tinst_depth; ++i)
+               pp_space (&pp);
+             const expanded_location el = expand_location (loc);
+             pp_printf (&pp, "%s:%d:%d", el.file, el.line, el.column);
+             pp_newline (&pp);
+           }
+         for (int i = 0; i < tinst_depth; ++i)
+           pp_space (&pp);
+         if (list_p)
+           pp_printf (&pp, "S %S", new_level->get_node ());
+         else
+           pp_printf (&pp, "I %D", tldcl);
+         pp_newline (&pp);
+       }
+#if __GNUC__ >= 10
+#pragma GCC diagnostic pop
+#endif
+    }
+
   ++tinst_depth;
   if (GATHER_STATISTICS && (tinst_depth > depth_reached))
     depth_reached = tinst_depth;
@@ -11481,6 +11516,20 @@ pop_tinst_level (void)
   --tinst_depth;
 }
 
+/* True if the instantiation represented by LEVEL is complete.  */
+
+static bool
+tinst_complete_p (struct tinst_level *level)
+{
+  gcc_assert (!level->list_p ());
+  tree node = level->get_node ();
+  if (TYPE_P (node))
+    return COMPLETE_TYPE_P (node);
+  else
+    return (DECL_TEMPLATE_INSTANTIATED (node)
+           || DECL_TEMPLATE_SPECIALIZATION (node));
+}
+
 /* We're instantiating a deferred template; restore the template
    instantiation context in which the instantiation was requested, which
    is one step out from LEVEL.  Return the corresponding DECL or TYPE.  */
@@ -11499,6 +11548,38 @@ reopen_tinst_level (struct tinst_level *level)
   if (current_tinst_level && !current_tinst_level->had_errors)
     current_tinst_level->errors = errorcount+sorrycount;
 
+  if (cxx_dump_pretty_printer pp {tinst_dump_id})
+    {
+#if __GNUC__ >= 10
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-diag"
+#endif
+      /* Dump the reopened instantiation context.  */
+      t = current_tinst_level;
+      if (!pp.has_flag (TDF_DETAILS))
+       /* Skip non-instantiations unless -details.  */
+       while (t && t->list_p ())
+         t = t->next;
+      if (t)
+       {
+         static tree last_ctx = NULL_TREE;
+         tree ctx = t->get_node ();
+         if (ctx != last_ctx)
+           {
+             last_ctx = ctx;
+             pp_newline (&pp);
+             if (t->list_p ())
+               pp_printf (&pp, "RS %S", ctx);
+             else
+               pp_printf (&pp, "RI %D", ctx);
+             pp_newline (&pp);
+           }
+       }
+#if __GNUC__ >= 10
+#pragma GCC diagnostic pop
+#endif
+    }
+
   tree decl = level->maybe_get_node ();
   if (decl && modules_p ())
     {
@@ -28068,14 +28149,16 @@ instantiate_pending_templates (int retries)
       reconsider = 0;
       while (*t)
        {
-         tree instantiation = reopen_tinst_level ((*t)->tinst);
-         bool complete = false;
+         struct tinst_level *tinst = (*t)->tinst;
+         bool complete = tinst_complete_p (tinst);
 
-         if (limit_bad_template_recursion (instantiation))
-           /* Do nothing.  */;
-         else if (TYPE_P (instantiation))
+         if (!complete)
            {
-             if (!COMPLETE_TYPE_P (instantiation))
+             tree instantiation = reopen_tinst_level (tinst);
+
+             if (limit_bad_template_recursion (instantiation))
+               /* Do nothing.  */;
+             else if (TYPE_P (instantiation))
                {
                  instantiate_class_template (instantiation);
                  if (CLASSTYPE_TEMPLATE_INSTANTIATION (instantiation))
@@ -28092,13 +28175,7 @@ instantiate_pending_templates (int retries)
                  if (COMPLETE_TYPE_P (instantiation))
                    reconsider = 1;
                }
-
-             complete = COMPLETE_TYPE_P (instantiation);
-           }
-         else
-           {
-             if (!DECL_TEMPLATE_SPECIALIZATION (instantiation)
-                 && !DECL_TEMPLATE_INSTANTIATED (instantiation))
+             else
                {
                  instantiation
                    = instantiate_decl (instantiation,
@@ -28108,8 +28185,10 @@ instantiate_pending_templates (int retries)
                    reconsider = 1;
                }
 
-             complete = (DECL_TEMPLATE_SPECIALIZATION (instantiation)
-                         || DECL_TEMPLATE_INSTANTIATED (instantiation));
+             complete = tinst_complete_p (tinst);
+
+             tinst_depth = 0;
+             set_refcount_ptr (current_tinst_level);
            }
 
          if (complete)
@@ -28126,8 +28205,6 @@ instantiate_pending_templates (int retries)
              last = *t;
              t = &(*t)->next;
            }
-         tinst_depth = 0;
-         set_refcount_ptr (current_tinst_level);
        }
       last_pending_template = last;
     }
index fe47ce56487391a94d69eac5264c4a9aa57f77bc..e3bc833c59bd865677ae90f6d29d412bcf1fad5b 100644 (file)
@@ -3297,6 +3297,50 @@ Enable support for the C++ coroutines extension (experimental).
 Permit the C++ front end to note all candidates during overload resolution
 failure, including when a deleted function is selected.
 
+@item -fdump-lang-
+@itemx -fdump-lang-@var{switch}
+@itemx -fdump-lang-@var{switch}-@var{options}
+@itemx -fdump-lang-@var{switch}-@var{options}=@var{filename}
+Control the dumping of C++-specific information.  The @var{options}
+and @var{filename} portions behave as described in the
+@option{-fdump-tree} option.  The following @var{switch} values are
+accepted:
+
+@table @samp
+@item all
+Enable all of the below.
+
+@opindex fdump-lang-class
+@item class
+Dump class hierarchy information.  Virtual table information is emitted
+unless '@option{slim}' is specified.
+
+@opindex fdump-lang-module
+@item module
+Dump module information.  Options @option{lineno} (locations),
+@option{graph} (reachability), @option{blocks} (clusters),
+@option{uid} (serialization), @option{alias} (mergeable),
+@option{asmname} (Elrond), @option{eh} (mapper) & @option{vops}
+(macros) may provide additional information.
+
+@opindex fdump-lang-raw
+@item raw
+Dump the raw internal tree data.
+
+@opindex fdump-lang-tinst
+@item tinst
+Dump the sequence of template instantiations, indented to show the
+depth of recursion.  The @option{lineno} option adds the source
+location where the instantiation was triggered, and the
+@option{details} option also dumps pre-instantiation substitutions
+such as those performed during template argument deduction.
+
+Lines in the .tinst dump start with @samp{I} for an instantiation,
+@samp{S} for another substitution, and @samp{R[IS]} for the reopened
+context of a deferred instantiation.
+
+@end table
+
 @opindex fno-elide-constructors
 @opindex felide-constructors
 @item -fno-elide-constructors
@@ -20891,30 +20935,10 @@ Dump language-specific information.  The file name is made by appending
 @itemx -fdump-lang-@var{switch}-@var{options}=@var{filename}
 Control the dumping of language-specific information.  The @var{options}
 and @var{filename} portions behave as described in the
-@option{-fdump-tree} option.  The following @var{switch} values are
-accepted:
-
-@table @samp
-@item all
-
-Enable all language-specific dumps.
-
-@item class
-Dump class hierarchy information.  Virtual table information is emitted
-unless '@option{slim}' is specified.  This option is applicable to C++ only.
-
-@item module
-Dump module information.  Options @option{lineno} (locations),
-@option{graph} (reachability), @option{blocks} (clusters),
-@option{uid} (serialization), @option{alias} (mergeable),
-@option{asmname} (Elrond), @option{eh} (mapper) & @option{vops}
-(macros) may provide additional information.  This option is
-applicable to C++ only.
-
-@item raw
-Dump the raw internal tree data.  This option is applicable to C++ only.
-
-@end table
+@option{-fdump-tree} option.  @option{-fdump-tree-all} enables all
+language-specific dumps; other options vary with the language.  For
+instance, see @xref{C++ Dialect Options} for the @option{-fdump-lang}
+flags supported by the C++ front-end.
 
 @opindex fdump-passes
 @item -fdump-passes