diff mbox series

[pushed] c++: alias CTAD refactoring [PR104470]

Message ID 20220504215929.2688464-1-jason@redhat.com
State New
Headers show
Series [pushed] c++: alias CTAD refactoring [PR104470] | expand

Commit Message

Jason Merrill May 4, 2022, 9:59 p.m. UTC
In my previous PR104470 patch I added yet another place that needs to handle
dependent member rewriting for deduction guides; this patches centralizes
rewriting into maybe_dependent_member_ref.  tsubst_baselink still has its
own handling because that's simpler than teaching maybe_dependent_member_ref
about BASELINKs.

Tested x86_64-pc-linux-gnu, applying to trunk.

	PR c++/104470

gcc/cp/ChangeLog:

	* pt.cc (maybe_dependent_member_ref): Handle types.
	(tsubst, tsubst_copy): Use it.
	(tsubst_aggr_type, instantiate_alias_template): Don't handle
	tf_dguide here.
---
 gcc/cp/pt.cc | 104 ++++++++++++++++++++++++++-------------------------
 1 file changed, 54 insertions(+), 50 deletions(-)


base-commit: c8df7208864d863f58da55d42ff82663059930b1
diff mbox series

Patch

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index ac002907a41..d8d36f35692 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -220,6 +220,7 @@  static tree make_argument_pack (tree);
 static void register_parameter_specializations (tree, tree);
 static tree enclosing_instantiation_of (tree tctx);
 static void instantiate_body (tree pattern, tree args, tree d, bool nested);
+static tree maybe_dependent_member_ref (tree, tree, tsubst_flags_t, tree);
 
 /* Make the current scope suitable for access checking when we are
    processing T.  T can be FUNCTION_DECL for instantiated function
@@ -13725,18 +13726,6 @@  tsubst_aggr_type (tree t,
 					 complain, in_decl);
 	  if (argvec == error_mark_node)
 	    r = error_mark_node;
-	  else if (!entering_scope && (complain & tf_dguide)
-		   && dependent_scope_p (context))
-	    {
-	      /* See maybe_dependent_member_ref.  */
-	      tree name = TYPE_IDENTIFIER (t);
-	      tree fullname = name;
-	      if (instantiates_primary_template_p (t))
-		fullname = build_nt (TEMPLATE_ID_EXPR, name,
-				     INNERMOST_TEMPLATE_ARGS (argvec));
-	      return build_typename_type (context, name, fullname,
-					  typename_type);
-	    }
 	  else
 	    {
 	      r = lookup_template_class (t, argvec, in_decl, context,
@@ -15586,6 +15575,9 @@  tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
   gcc_assert (type != unknown_type_node);
 
+  if (tree d = maybe_dependent_member_ref (t, args, complain, in_decl))
+    return d;
+
   /* Reuse typedefs.  We need to do this to handle dependent attributes,
      such as attribute aligned.  */
   if (TYPE_P (t)
@@ -16815,16 +16807,58 @@  maybe_dependent_member_ref (tree t, tree args, tsubst_flags_t complain,
   if (!(complain & tf_dguide))
     return NULL_TREE;
 
-  tree ctx = context_for_name_lookup (t);
+  tree decl = (t && TYPE_P (t)) ? TYPE_NAME (t) : t;
+  if (!decl || !DECL_P (decl))
+    return NULL_TREE;
+
+  tree ctx = context_for_name_lookup (decl);
   if (!CLASS_TYPE_P (ctx))
     return NULL_TREE;
 
   ctx = tsubst (ctx, args, complain, in_decl);
-  if (dependent_scope_p (ctx))
-    return build_qualified_name (NULL_TREE, ctx, DECL_NAME (t),
-				 /*template_p=*/false);
+  if (!dependent_scope_p (ctx))
+    return NULL_TREE;
 
-  return NULL_TREE;
+  if (TYPE_P (t))
+    {
+      if (typedef_variant_p (t))
+	t = strip_typedefs (t);
+      tree decl = TYPE_NAME (t);
+      if (decl)
+	decl = maybe_dependent_member_ref (decl, args, complain, in_decl);
+      if (!decl)
+	return NULL_TREE;
+      return cp_build_qualified_type_real (TREE_TYPE (decl), cp_type_quals (t),
+					   complain);
+    }
+
+  tree name = DECL_NAME (t);
+  tree fullname = name;
+  if (instantiates_primary_template_p (t))
+    {
+      tree tinfo = get_template_info (t);
+      name = DECL_NAME (TI_TEMPLATE (tinfo));
+      tree targs = INNERMOST_TEMPLATE_ARGS (TI_ARGS (tinfo));
+      targs = tsubst_template_args (targs, args, complain, in_decl);
+      fullname = build_nt (TEMPLATE_ID_EXPR, name, targs);
+    }
+
+  if (TREE_CODE (t) == TYPE_DECL)
+    {
+      if (TREE_CODE (TREE_TYPE (t)) == TYPENAME_TYPE
+	  && TYPE_NAME (TREE_TYPE (t)) == t)
+	/* The TYPE_DECL for a typename has DECL_CONTEXT of the typename
+	   scope, but it doesn't need to be rewritten again.  */
+	return NULL_TREE;
+      tree type = build_typename_type (ctx, name, fullname, typename_type);
+      return TYPE_NAME (type);
+    }
+  else if (DECL_TYPE_TEMPLATE_P (t))
+    return make_unbound_class_template (ctx, name,
+					NULL_TREE, complain);
+  else
+    return build_qualified_name (NULL_TREE, ctx, fullname,
+				 TREE_CODE (t) == TEMPLATE_DECL);
 }
 
 /* Like tsubst, but deals with expressions.  This function just replaces
@@ -16840,6 +16874,9 @@  tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
   if (t == NULL_TREE || t == error_mark_node || args == NULL_TREE)
     return t;
 
+  if (tree d = maybe_dependent_member_ref (t, args, complain, in_decl))
+    return d;
+
   code = TREE_CODE (t);
 
   switch (code)
@@ -16885,9 +16922,6 @@  tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 	if (args == NULL_TREE)
 	  return scalar_constant_value (t);
 
-	if (tree ref = maybe_dependent_member_ref (t, args, complain, in_decl))
-	  return ref;
-
 	/* Unfortunately, we cannot just call lookup_name here.
 	   Consider:
 
@@ -16938,9 +16972,6 @@  tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       return t;
 
     case VAR_DECL:
-      if (tree ref = maybe_dependent_member_ref (t, args, complain, in_decl))
-	return ref;
-      gcc_fallthrough();
     case FUNCTION_DECL:
       if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t))
 	r = tsubst (t, args, complain, in_decl);
@@ -17070,18 +17101,6 @@  tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 	     have to substitute this with one having context `D<int>'.  */
 
 	  tree context = tsubst (DECL_CONTEXT (t), args, complain, in_decl);
-	  if ((complain & tf_dguide) && dependent_scope_p (context))
-	    {
-	      /* When rewriting a constructor into a deduction guide, a
-		 non-dependent name can become dependent, so memtmpl<args>
-		 becomes context::template memtmpl<args>.  */
-	      if (DECL_TYPE_TEMPLATE_P (t))
-		return make_unbound_class_template (context, DECL_NAME (t),
-						    NULL_TREE, complain);
-	      tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
-	      return build_qualified_name (type, context, DECL_NAME (t),
-					   /*template*/true);
-	    }
 	  return lookup_field (context, DECL_NAME(t), 0, false);
 	}
       else
@@ -21711,21 +21730,6 @@  instantiate_alias_template (tree tmpl, tree args, tsubst_flags_t complain)
   if (tmpl == error_mark_node || args == error_mark_node)
     return error_mark_node;
 
-  /* See maybe_dependent_member_ref.  */
-  if (complain & tf_dguide)
-    {
-      tree ctx = tsubst_aggr_type (DECL_CONTEXT (tmpl), args, complain,
-				   tmpl, true);
-      if (dependent_scope_p (ctx))
-	{
-	  tree name = DECL_NAME (tmpl);
-	  tree fullname = build_nt (TEMPLATE_ID_EXPR, name,
-				    INNERMOST_TEMPLATE_ARGS (args));
-	  tree tname = build_typename_type (ctx, name, fullname, typename_type);
-	  return TYPE_NAME (tname);
-	}
-    }
-
   args =
     coerce_innermost_template_parms (DECL_TEMPLATE_PARMS (tmpl),
 				     args, tmpl, complain,