Hi,
On 11/14/2013 03:41 PM, Jason Merrill wrote:
I don't think we need a new parameter; just pass the FIELD_DECL into
maybe_end_member_template_processing and adjust it appropriately.
Also, call m_e_m_t_p from cp_parser_late_parsing_nsdmi rather than
cp_parser_class_specifier_1.
Thanks, much simpler indeed. I'm finishing testing the below.
Paolo.
////////////////////////
/cp
2013-11-14 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/57887
* parser.c (cp_parser_late_parsing_nsdmi): Call
maybe_begin_member_template_processing.
* pt.c (maybe_begin_member_template_processing): Handle NSDMIs.
(inline_needs_template_parms): Adjust.
/testsuite
2013-11-14 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/57887
* g++.dg/cpp0x/nsdmi-template3.C: New.
* g++.dg/cpp0x/nsdmi-template4.C: Likewise.
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 204780)
+++ cp/parser.c (working copy)
@@ -23378,12 +23378,16 @@ cp_parser_late_parsing_nsdmi (cp_parser *parser, t
{
tree def;
+ maybe_begin_member_template_processing (field);
+
push_unparsed_function_queues (parser);
def = cp_parser_late_parse_one_default_arg (parser, field,
DECL_INITIAL (field),
NULL_TREE);
pop_unparsed_function_queues (parser);
+ maybe_end_member_template_processing ();
+
DECL_INITIAL (field) = def;
}
Index: cp/pt.c
===================================================================
--- cp/pt.c (revision 204780)
+++ cp/pt.c (working copy)
@@ -151,7 +151,7 @@ static int for_each_template_parm (tree, tree_fn_t
struct pointer_set_t*, bool);
static tree expand_template_argument_pack (tree);
static tree build_template_parm_index (int, int, int, tree, tree);
-static bool inline_needs_template_parms (tree);
+static bool inline_needs_template_parms (tree, bool);
static void push_inline_template_parms_recursive (tree, int);
static tree retrieve_local_specialization (tree);
static void register_local_specialization (tree, tree);
@@ -377,9 +377,9 @@ template_class_depth (tree type)
Returns true if processing DECL needs us to push template parms. */
static bool
-inline_needs_template_parms (tree decl)
+inline_needs_template_parms (tree decl, bool nsdmi)
{
- if (! DECL_TEMPLATE_INFO (decl))
+ if (!decl || (!nsdmi && ! DECL_TEMPLATE_INFO (decl)))
return false;
return (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (most_general_template (decl)))
@@ -448,16 +448,23 @@ push_inline_template_parms_recursive (tree parmlis
}
}
-/* Restore the template parameter context for a member template or
- a friend template defined in a class definition. */
+/* Restore the template parameter context for a member template, a
+ friend template defined in a class definition, or a non-template
+ member of template class. */
void
maybe_begin_member_template_processing (tree decl)
{
tree parms;
int levels = 0;
+ bool nsdmi = TREE_CODE (decl) == FIELD_DECL;
- if (inline_needs_template_parms (decl))
+ if (nsdmi)
+ decl = (CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (decl))
+ ? TREE_TYPE (CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (decl)))
+ : NULL_TREE);
+
+ if (inline_needs_template_parms (decl, nsdmi))
{
parms = DECL_TEMPLATE_PARMS (most_general_template (decl));
levels = TMPL_PARMS_DEPTH (parms) - processing_template_decl;
Index: testsuite/g++.dg/cpp0x/nsdmi-template3.C
===================================================================
--- testsuite/g++.dg/cpp0x/nsdmi-template3.C (revision 0)
+++ testsuite/g++.dg/cpp0x/nsdmi-template3.C (working copy)
@@ -0,0 +1,16 @@
+// PR c++/58760
+// { dg-do compile { target c++11 } }
+
+enum en
+{
+ a,b,c
+};
+
+struct B
+{
+ template<en N>
+ struct A
+ {
+ const int X = N;
+ };
+};
Index: testsuite/g++.dg/cpp0x/nsdmi-template4.C
===================================================================
--- testsuite/g++.dg/cpp0x/nsdmi-template4.C (revision 0)
+++ testsuite/g++.dg/cpp0x/nsdmi-template4.C (working copy)
@@ -0,0 +1,24 @@
+// PR c++/57887
+// { dg-do compile { target c++11 } }
+
+struct B
+{
+ template<int N>
+ struct A
+ {
+ int X = N;
+ };
+};
+
+template<int M>
+struct C
+{
+ int Y = M;
+
+ template<int N>
+ struct A
+ {
+ int X = N;
+ int Y = M;
+ };
+};