From 5bedc7801448fdfc2923a48ce61c7798691167e7 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Wed, 13 Dec 2017 16:39:28 -0500
Subject: [PATCH 25/34] FIXME: WIP on template support

FIXME: Don't add wrapper nodes for decls of type TYPE_PACK_EXPANSION

FIXME: handle PACK_EXPANSION_P for VIEW_CONVERT_EXPR in tsubst_copy

FIXME: don't add wrappers around decls of type TEMPLATE_TYPE_PARM

FIXME: disable the exclusion on TYPE_PACK_EXPANSION again

FIXME: tsubst_copy: improve the handling of wrapper nodes
---
 gcc/cp/cp-tree.h | 16 ++++++++++++++++
 gcc/cp/parser.c  | 12 ++++--------
 gcc/cp/pt.c      | 11 +++++++++++
 3 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f828178..d0dd174 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -95,6 +95,22 @@ public:
 
   cp_expr& maybe_add_location_wrapper ()
   {
+#if 1
+    /* Don't add wrapper nodes for decls of type TYPE_PACK_EXPANSION,
+       since tsubst can't handle them.  */
+    if (DECL_P (m_value))
+      {
+#if 0
+	if (TREE_CODE (TREE_TYPE (m_value)) == TYPE_PACK_EXPANSION)
+	  return *this;
+#endif
+
+	/* Similarly, don't wrap TEMPLATE_TYPE_PARM, since there's
+	   an unknown amount of code that might not handle such wrappers.  */
+	if (TREE_CODE (TREE_TYPE (m_value)) == TEMPLATE_TYPE_PARM)
+	  return *this;
+      }
+#endif
     m_value = maybe_wrap_with_location (m_value, m_loc);
     return *this;
   }
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index adfca60..069467d 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -6842,8 +6842,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
 	    location_t typeid_loc
 	      = make_location (start_loc, start_loc, close_paren->location);
 	    postfix_expression.set_location (typeid_loc);
-	    if (!processing_template_decl)
-	      postfix_expression.maybe_add_location_wrapper ();
+	    postfix_expression.maybe_add_location_wrapper ();
 	  }
       }
       break;
@@ -7740,8 +7739,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
               }
 
 	    if (wrap_locations_p)
-	      if (!processing_template_decl)
-		expr.maybe_add_location_wrapper ();
+	      expr.maybe_add_location_wrapper ();
 
 	     /* Add it to the list.  We add error_mark_node
 		expressions to the list, so that we can still tell if
@@ -8013,8 +8011,7 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
 
 	    cp_expr ret_expr (ret);
 	    ret_expr.set_location (compound_loc);
-	    if (!processing_template_decl)
-	      ret_expr = ret_expr.maybe_add_location_wrapper ();
+	    ret_expr = ret_expr.maybe_add_location_wrapper ();
 	    return ret_expr;
 	  }
 
@@ -9854,8 +9851,7 @@ cp_parser_builtin_offsetof (cp_parser *parser)
   parser->integral_constant_expression_p = save_ice_p;
   parser->non_integral_constant_expression_p = save_non_ice_p;
 
-  if (!processing_template_decl)
-    expr = expr.maybe_add_location_wrapper ();
+  expr = expr.maybe_add_location_wrapper ();
   return expr;
 }
 
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 252712e..3304173 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -14928,6 +14928,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 	/* Ordinary template template argument.  */
 	return t;
 
+    case VIEW_CONVERT_EXPR:
+    case NON_LVALUE_EXPR:
     case CAST_EXPR:
     case REINTERPRET_CAST_EXPR:
     case CONST_CAST_EXPR:
@@ -14937,6 +14939,15 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case CONVERT_EXPR:
     case NOP_EXPR:
       {
+	if (location_wrapper_p (t))
+	  {
+	    /* Handle location wrappers by substituting the wrapped node
+	       first, then reusing the resulting type (which also avoids
+	       incorrectly attempting to substitute the type for the case
+	       of parameter pack expansions).  */
+	    tree op0 = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
+	    return build1 (code, TREE_TYPE (op0), op0);
+	  }
 	tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
 	tree op0 = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
 	return build1 (code, type, op0);
-- 
1.8.5.3

