aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2025-04-18 09:50:04 -0400
committerJason Merrill <jason@redhat.com>2025-05-26 09:56:27 -0400
commitf59ff19bc3d37f4dd159db541ed4f07efb10fcc8 (patch)
tree44d56a6fd6f01fba08c1ba41371ac001f580fcd9
parentd424245c7abb2871b977ddc5c1e73b827a78ad07 (diff)
downloadgcc-f59ff19bc3d37f4dd159db541ed4f07efb10fcc8.zip
gcc-f59ff19bc3d37f4dd159db541ed4f07efb10fcc8.tar.gz
gcc-f59ff19bc3d37f4dd159db541ed4f07efb10fcc8.tar.bz2
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.
-rw-r--r--gcc/cp/cp-objcp-common.cc2
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/pt.cc111
-rw-r--r--gcc/doc/invoke.texi72
4 files changed, 145 insertions, 41 deletions
diff --git a/gcc/cp/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc
index 8336d0b..7665b94 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/cp-tree.h b/gcc/cp/cp-tree.h
index 7433b89..19c0b45 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/pt.cc b/gcc/cp/pt.cc
index 1973d25..c687fdc 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;
}
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index fe47ce5..e3bc833 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