summaryrefslogtreecommitdiff
path: root/gcc/cp/pt.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r--gcc/cp/pt.c64
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));
}