Commit e4c04ff0 by Paolo Carlini Committed by Paolo Carlini

re PR c++/57734 (Returning template alias to enum class fails with "invalid declarator")

/cp
2013-11-12  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/57734
	* pt.c (lookup_template_class_1): Handle alias template declarations
	of enumeration types.

/testsuite
2013-11-12  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/57734
	* g++.dg/cpp0x/alias-decl-enum-1.C: New.

From-SVN: r204697
parent 801a661c
2013-11-12 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/57734
* pt.c (lookup_template_class_1): Handle alias template declarations
of enumeration types.
2013-11-10 Paolo Carlini <paolo.carlini@oracle.com> 2013-11-10 Paolo Carlini <paolo.carlini@oracle.com>
* cvt.c (cp_convert_to_pointer): Call build_ptrmemfunc before * cvt.c (cp_convert_to_pointer): Call build_ptrmemfunc before
......
...@@ -7458,30 +7458,7 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, ...@@ -7458,30 +7458,7 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
context = global_namespace; context = global_namespace;
/* Create the type. */ /* Create the type. */
if (TREE_CODE (template_type) == ENUMERAL_TYPE) if (DECL_ALIAS_TEMPLATE_P (gen_tmpl))
{
if (!is_dependent_type)
{
set_current_access_from_decl (TYPE_NAME (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
{
/* We don't want to call start_enum for this type, since
the values for the enumeration constants may involve
template parameters. And, no one should be interested
in the enumeration constants for such a type. */
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));
ENUM_FIXED_UNDERLYING_TYPE_P (t)
= ENUM_FIXED_UNDERLYING_TYPE_P (template_type);
}
else if (DECL_ALIAS_TEMPLATE_P (gen_tmpl))
{ {
/* The user referred to a specialization of an alias /* The user referred to a specialization of an alias
template represented by GEN_TMPL. template represented by GEN_TMPL.
...@@ -7505,6 +7482,29 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, ...@@ -7505,6 +7482,29 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
if (t == error_mark_node) if (t == error_mark_node)
return t; return t;
} }
else if (TREE_CODE (template_type) == ENUMERAL_TYPE)
{
if (!is_dependent_type)
{
set_current_access_from_decl (TYPE_NAME (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
{
/* We don't want to call start_enum for this type, since
the values for the enumeration constants may involve
template parameters. And, no one should be interested
in the enumeration constants for such a type. */
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));
ENUM_FIXED_UNDERLYING_TYPE_P (t)
= ENUM_FIXED_UNDERLYING_TYPE_P (template_type);
}
else if (CLASS_TYPE_P (template_type)) else if (CLASS_TYPE_P (template_type))
{ {
t = make_class_type (TREE_CODE (template_type)); t = make_class_type (TREE_CODE (template_type));
...@@ -7661,7 +7661,8 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, ...@@ -7661,7 +7661,8 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
= tree_cons (arglist, t, = tree_cons (arglist, t,
DECL_TEMPLATE_INSTANTIATIONS (templ)); DECL_TEMPLATE_INSTANTIATIONS (templ));
if (TREE_CODE (template_type) == ENUMERAL_TYPE && !is_dependent_type) if (TREE_CODE (template_type) == ENUMERAL_TYPE && !is_dependent_type
&& !DECL_ALIAS_TEMPLATE_P (gen_tmpl))
/* Now that the type has been registered on the instantiations /* Now that the type has been registered on the instantiations
list, we set up the enumerators. Because the enumeration list, we set up the enumerators. Because the enumeration
constants may involve the enumeration type itself, we make constants may involve the enumeration type itself, we make
......
2013-11-12 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/57734
* g++.dg/cpp0x/alias-decl-enum-1.C: New.
2013-11-11 Martin Liska <marxin.liska@gmail.com> 2013-11-11 Martin Liska <marxin.liska@gmail.com>
* gcc.dg/time-profiler-1.c: New test. * gcc.dg/time-profiler-1.c: New test.
......
// PR c++/57734
// { dg-do compile { target c++11 } }
template<typename T, typename U>
struct same_type { static const bool value = false; };
template<typename T>
struct same_type<T, T> { static const bool value = true; };
enum e { zero };
enum class eclass { one };
template<typename T>
using enum_alias = e;
template<typename T>
using eclass_alias = eclass;
typedef enum_alias<void> etest0;
typedef enum_alias<void> etest0;
typedef enum_alias<int> etest0;
typedef enum_alias<int> etest1;
static_assert (same_type<etest0, etest1>::value, "");
typedef eclass_alias<void> ectest0;
typedef eclass_alias<void> ectest0;
typedef eclass_alias<int> ectest0;
typedef eclass_alias<int> ectest1;
static_assert (same_type<ectest0, ectest1>::value, "");
template<typename T>
enum_alias<T> efoo(T f) { return enum_alias<T>::zero; }
template<typename T>
constexpr enum_alias<T> cefoo(T f) { return enum_alias<T>::zero; }
static_assert ( cefoo(1) == e::zero, "");
template<typename T>
eclass_alias<T> ecfoo(T f) { return eclass_alias<T>::one; }
template<typename T>
constexpr eclass_alias<T> cecfoo(T f) { return eclass_alias<T>::one; }
static_assert ( cecfoo(1) == eclass::one, "");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment