[gcc r16-880] c++: add -fdump-lang-tinst
Jason Merrill
jason@gcc.gnu.org
Mon May 26 13:56:38 GMT 2025
https://gcc.gnu.org/g:f59ff19bc3d37f4dd159db541ed4f07efb10fcc8
commit r16-880-gf59ff19bc3d37f4dd159db541ed4f07efb10fcc8
Author: Jason Merrill <jason@redhat.com>
Date: Fri Apr 18 09:50:04 2025 -0400
c++: add -fdump-lang-tinst
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.
Diff:
---
gcc/doc/invoke.texi | 72 ++++++++++++++++++++----------
gcc/cp/cp-tree.h | 1 +
gcc/cp/cp-objcp-common.cc | 2 +
gcc/cp/pt.cc | 111 +++++++++++++++++++++++++++++++++++++++-------
4 files changed, 145 insertions(+), 41 deletions(-)
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index fe47ce564873..e3bc833c59bd 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -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
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 7433b8962199..19c0b452d868 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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
diff --git a/gcc/cp/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc
index 8336d0bb8f7c..7665b9454dc5 100644
--- a/gcc/cp/cp-objcp-common.cc
+++ b/gcc/cp/cp-objcp-common.cc
@@ -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
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 1973d25b61a0..c687fdc71a3c 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -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;
}
More information about the Gcc-cvs
mailing list