aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2012-06-12 14:32:13 -0400
committerJason Merrill <jason@gcc.gnu.org>2012-06-12 14:32:13 -0400
commit637f68e8d28582ef5112ed6c3b4c2c2399d9799f (patch)
tree02046b2845928e6fc1099d3bc8dab7826a4378df /gcc
parentfdaf2f48c02dcb5dcf9bbca130b2de56fc947f75 (diff)
downloadgcc-637f68e8d28582ef5112ed6c3b4c2c2399d9799f.zip
gcc-637f68e8d28582ef5112ed6c3b4c2c2399d9799f.tar.gz
gcc-637f68e8d28582ef5112ed6c3b4c2c2399d9799f.tar.bz2
pt.c (tsubst_expr): Instantiate local class.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/class.c4
-rw-r--r--gcc/cp/decl2.c4
-rw-r--r--gcc/cp/pt.c16
4 files changed, 25 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 203955e..9d3fdfe 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 4bb9dd2..021344b 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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;
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 78e17af..2e3c9a6 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 04f7be8..5e02c8c 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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: