aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/parser.cc
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2023-06-29 09:36:58 -0400
committerPatrick Palka <ppalka@redhat.com>2023-06-29 09:36:58 -0400
commite972bdce61cc5213a4b0309ef88fb611617843dc (patch)
treeee91d7caa98a5f5e95f9dd950538502b6d8f343a /gcc/cp/parser.cc
parentc7ed2ccd590d9c0d0146f61c97ca6500910936b8 (diff)
downloadgcc-e972bdce61cc5213a4b0309ef88fb611617843dc.zip
gcc-e972bdce61cc5213a4b0309ef88fb611617843dc.tar.gz
gcc-e972bdce61cc5213a4b0309ef88fb611617843dc.tar.bz2
c++: cache partial template specialization selection
There's currently no cheap way to obtain the partial template specialization (and arguments relative to it) that was selected for a class or variable template specialization. Our only option is to compute the result from scratch via most_specialized_partial_spec. For class templates this isn't really an issue because we usually need this information just once, upon instantiation. But for variable templates we need it upon specialization and also later upon instantiation. We could implement an ad-hoc cache for variable templates only, but it'd be nice for this information to be readily available in general. To that end, this patch adds a TI_PARTIAL_INFO field to TEMPLATE_INFO that holds another TEMPLATE_INFO consisting of the partial template and arguments relative to it, which most_specialized_partial_spec then uses to transparently cache its (now TEMPLATE_INFO) result. Similarly, there's no easy way to go from the DECL_TEMPLATE_RESULT of a partial TEMPLATE_DECL back to that TEMPLATE_DECL. (Our best option is to walk the DECL_TEMPLATE_SPECIALIZATIONS list of the primary TEMPLATE_DECL.) So this patch also uses this new field to link these entities in both directions. gcc/cp/ChangeLog: * cp-tree.h (tree_template_info::partial): New data member. (TI_PARTIAL_INFO): New tree accessor. (most_specialized_partial_spec): Add defaulted bool parameter. * module.cc (trees_out::core_vals) <case TEMPLATE_INFO>: Stream TI_PARTIAL_INFO. (trees_in::core_vals) <case TEMPLATE_INFO>: Likewise. * parser.cc (specialization_of): Adjust after making most_specialized_partial_spec return TEMPLATE_INFO instead of TREE_LIST. * pt.cc (process_partial_specialization): Set TI_PARTIAL_INFO of 'decl' to point back to the partial TEMPLATE_DECL. Likewise (and pass rechecking=true to most_specialization_partial_spec). (instantiate_class_template): Likewise. (instantiate_template): Set TI_PARTIAL_INFO to the result of most_specialization_partial_spec after forming a variable template specialization. (most_specialized_partial_spec): Add 'rechecking' parameter. Exit early if the template is not primary. Use the TI_PARTIAL_INFO of the corresponding TEMPLATE_INFO as a cache unless 'rechecking' is true. Don't bother setting TREE_TYPE of each TREE_LIST. (instantiate_decl): Adjust after making most_specialized_partial_spec return TEMPLATE_INFO instead of TREE_LIST. * ptree.cc (cxx_print_xnode) <case TEMPLATE_INFO>: Dump TI_PARTIAL_INFO.
Diffstat (limited to 'gcc/cp/parser.cc')
-rw-r--r--gcc/cp/parser.cc6
1 files changed, 3 insertions, 3 deletions
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 9501050..5e2b5cb 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -34352,9 +34352,9 @@ specialization_of (tree type)
/* Determine the template or its partial specialization to which TYPE
corresponds. */
- if (tree spec = most_specialized_partial_spec (type, tf_none))
- if (spec != error_mark_node)
- ret = TREE_TYPE (TREE_VALUE (spec));
+ if (tree ti = most_specialized_partial_spec (type, tf_none))
+ if (ti != error_mark_node)
+ ret = TREE_TYPE (TI_TEMPLATE (ti));
if (ret == type)
ret = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (type);