pt.c (tsubst_expr): Instantiate local class.
authorJason Merrill <jason@redhat.com>
Tue, 12 Jun 2012 18:32:13 +0000 (14:32 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 12 Jun 2012 18:32:13 +0000 (14:32 -0400)
* pt.c (tsubst_expr) [TAG_DEFN]: Instantiate local class.
* class.c (finish_struct): Don't add a TAG_DEFN for a lambda.
* decl2.c (finish_static_data_member_decl): Avoid redundant error.

From-SVN: r188474

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/decl2.c
gcc/cp/pt.c

index 203955e3bc7d8bce5d556551576fe04ec5c25c87..9d3fdfefa89f33ce5319443b6cec415b0fdfcbe8 100644 (file)
@@ -1,5 +1,9 @@
 2012-06-09  Jason Merrill  <jason@redhat.com>
 
+       * pt.c (tsubst_expr) [TAG_DEFN]: Instantiate local class.
+       * class.c (finish_struct): Don't add a TAG_DEFN for a lambda.
+       * decl2.c (finish_static_data_member_decl): Avoid redundant error.
+
        PR c++/53599
        * name-lookup.c (pushtag_1): Add a DECL_EXPR for a local class.
        * semantics.c (finish_cond): Build a COMPOUND_EXPR.
index 4bb9dd2c1684a627fe58e3024195717190ab4efc..021344bad7c401d241382a3e9b24d4d16a8a512d 100644 (file)
@@ -6337,7 +6337,9 @@ finish_struct (tree t, tree attributes)
   else
     error ("trying to finish struct, but kicked out due to previous parse errors");
 
-  if (processing_template_decl && at_function_scope_p ())
+  if (processing_template_decl && at_function_scope_p ()
+      /* Lambdas are defined by the LAMBDA_EXPR.  */
+      && !LAMBDA_TYPE_P (t))
     add_stmt (build_min (TAG_DEFN, t));
 
   return t;
index 78e17af61a4e9403fa2fd0e012e33cf4bc4a571c..2e3c9a633625275cf01c3e3a4b73187e5d6b6437 100644 (file)
@@ -770,7 +770,9 @@ finish_static_data_member_decl (tree decl,
   if (! processing_template_decl)
     VEC_safe_push (tree, gc, pending_statics, decl);
 
-  if (LOCAL_CLASS_P (current_class_type))
+  if (LOCAL_CLASS_P (current_class_type)
+      /* We already complained about the template definition.  */
+      && !DECL_TEMPLATE_INSTANTIATION (decl))
     permerror (input_location, "local class %q#T shall not have static data member %q#D",
               current_class_type, decl);
 
index 04f7be81f3e7f23a3fb62ad01088b8355687f90b..5e02c8c41930c2bc60c56f3a91221be2e71dfca7 100644 (file)
@@ -13123,7 +13123,21 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
       break;
 
     case TAG_DEFN:
-      tsubst (TREE_TYPE (t), args, complain, NULL_TREE);
+      tmp = tsubst (TREE_TYPE (t), args, complain, NULL_TREE);
+      if (CLASS_TYPE_P (tmp))
+       {
+         /* Local classes are not independent templates; they are
+            instantiated along with their containing function.  And this
+            way we don't have to deal with pushing out of one local class
+            to instantiate a member of another local class.  */
+         tree fn;
+         /* Closures are handled by the LAMBDA_EXPR.  */
+         gcc_assert (!LAMBDA_TYPE_P (TREE_TYPE (t)));
+         complete_type (tmp);
+         for (fn = TYPE_METHODS (tmp); fn; fn = DECL_CHAIN (fn))
+           if (!DECL_ARTIFICIAL (fn))
+             instantiate_decl (fn, /*defer_ok*/0, /*expl_inst_class*/false);
+       }
       break;
 
     case STATIC_ASSERT: