diff options
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r-- | gcc/cp/pt.c | 64 |
1 files changed, 40 insertions, 24 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 85a5ea51132..f150d8f6130 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -907,8 +907,16 @@ maybe_process_partial_specialization (tree type) } else if (processing_specialization) { - error ("explicit specialization of non-template %qT", type); - return error_mark_node; + /* Someday C++0x may allow for enum template specialization. */ + if (cxx_dialect > cxx98 && TREE_CODE (type) == ENUMERAL_TYPE + && CLASS_TYPE_P (context) && CLASSTYPE_USE_TEMPLATE (context)) + pedwarn (input_location, OPT_pedantic, "template specialization " + "of %qD not allowed by ISO C++", type); + else + { + error ("explicit specialization of non-template %qT", type); + return error_mark_node; + } } return type; @@ -6587,13 +6595,17 @@ lookup_template_class (tree d1, arglist = bound_args; } else - arglist - = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parmlist), - INNERMOST_TEMPLATE_ARGS (arglist), - gen_tmpl, - complain, - /*require_all_args=*/true, - /*use_default_args=*/true); + { + push_tinst_level (templ); + arglist + = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parmlist), + INNERMOST_TEMPLATE_ARGS (arglist), + gen_tmpl, + complain, + /*require_all_args=*/true, + /*use_default_args=*/true); + pop_tinst_level (); + } if (arglist == error_mark_node) /* We were unable to bind the arguments. */ @@ -6657,10 +6669,10 @@ lookup_template_class (tree d1, if (!is_dependent_type) { set_current_access_from_decl (TYPE_NAME (template_type)); - t = start_enum (TYPE_IDENTIFIER (template_type), - tsubst (ENUM_UNDERLYING_TYPE (template_type), - arglist, complain, in_decl), - SCOPED_ENUM_P (template_type)); + t = start_enum (TYPE_IDENTIFIER (template_type), NULL_TREE, + tsubst (ENUM_UNDERLYING_TYPE (template_type), + arglist, complain, in_decl), + SCOPED_ENUM_P (template_type), NULL); } else { @@ -6671,6 +6683,7 @@ lookup_template_class (tree d1, t = cxx_make_type (ENUMERAL_TYPE); SET_SCOPED_ENUM_P (t, SCOPED_ENUM_P (template_type)); } + SET_OPAQUE_ENUM_P (t, OPAQUE_ENUM_P (template_type)); } else { @@ -8238,17 +8251,12 @@ instantiate_class_template (tree type) finish_struct_1 (type); TYPE_BEING_DEFINED (type) = 0; - /* Now that the class is complete, instantiate default arguments for - any member functions. We don't do this earlier because the - default arguments may reference members of the class. */ - if (!PRIMARY_TEMPLATE_P (templ)) - for (t = TYPE_METHODS (type); t; t = DECL_CHAIN (t)) - if (TREE_CODE (t) == FUNCTION_DECL - /* Implicitly generated member functions will not have template - information; they are not instantiations, but instead are - created "fresh" for each instantiation. */ - && DECL_TEMPLATE_INFO (t)) - tsubst_default_arguments (t); + /* We don't instantiate default arguments for member functions. 14.7.1: + + The implicit instantiation of a class template specialization causes + the implicit instantiation of the declarations, but not of the + definitions or default arguments, of the class member functions, + member classes, static data members and member templates.... */ /* Some typedefs referenced from within the template code need to be access checked at template instantiation time, i.e now. These types were @@ -17314,6 +17322,9 @@ tsubst_enum (tree tag, tree newtag, tree args) { tree e; + if (SCOPED_ENUM_P (newtag)) + begin_scope (sk_scoped_enum, newtag); + for (e = TYPE_VALUES (tag); e; e = TREE_CHAIN (e)) { tree value; @@ -17334,7 +17345,12 @@ tsubst_enum (tree tag, tree newtag, tree args) (DECL_NAME (decl), value, newtag, DECL_SOURCE_LOCATION (decl)); } + if (SCOPED_ENUM_P (newtag)) + finish_scope (); + + finish_enum_value_list (newtag); finish_enum (newtag); + DECL_SOURCE_LOCATION (TYPE_NAME (newtag)) = DECL_SOURCE_LOCATION (TYPE_NAME (tag)); } |