c-common.c (struct c_common_resword): Add __underlying_type.

/gcc
2011-04-25  Paolo Carlini  <paolo.carlini@oracle.com>

	* c-family/c-common.c (struct c_common_resword): Add
	__underlying_type.
	* c-family/c-common.h (enum rid): Add RID_UNDERLYING_TYPE.

/cp
2011-04-25  Paolo Carlini  <paolo.carlini@oracle.com>

	* cp-tree.def: Add a new UNDERLYING_TYPE tree code.
	* cp-tree.h (enum cp_trait_kind): Add CPTK_UNDERLYING_TYPE, tidy.
	(UNDERLYING_TYPE_TYPE): Add.
	* cp-objcp-common.c (cp_common_init_ts): Mark UNDERLYING_TYPE
	as TS_COMMON.
	* parser.c (cp_lexer_next_token_is_decl_specifier_keyword,
	cp_parser_simple_type_specifier): Handle UNDERLYING_TYPE.
	(cp_parser_trait_expr): Deal with RID_UNDERLYING_TYPE; tidy.
	* semantics.c (finish_underlying_type): New.
	* typeck.c (structural_comptypes): Handle UNDERLYING_TYPE.
	* error.c (dump_type, dump_type_prefix, dump_type_suffix): Likewise.
	* cxx-pretty-print.c (p_cxx_type_id): Likewise.
	* tree.c (cp_walk_subtrees): Likewise.
	* pt.c (for_each_template_parm_r, tsubst, unify,
	dependent_type_p_r): Likewise.
	* mangle.c (write_type): Sorry for __underlying_type.
	* doc/extend.texi: Document __underlying_type.

/testsuite
2011-04-25  Paolo Carlini  <paolo.carlini@oracle.com>

	* g++.dg/ext/underlying_type1.C: New.
	* g++.dg/ext/underlying_type2.C: Likewise.
	* g++.dg/ext/underlying_type3.C: Likewise.
	* g++.dg/ext/underlying_type4.C: Likewise.
	* g++.dg/ext/underlying_type5.C: Likewise.
	* g++.dg/ext/underlying_type6.C: Likewise.
	* g++.dg/ext/underlying_type7.C: Likewise.
	* g++.dg/ext/underlying_type8.C: Likewise.
	* g++.dg/ext/underlying_type9.C: Likewise.
	* g++.dg/ext/underlying_type10.C: Likewise.

From-SVN: r172943
This commit is contained in:
Paolo Carlini 2011-04-25 22:27:19 +00:00 committed by Paolo Carlini
parent d95f258e90
commit a0d260fcc5
26 changed files with 448 additions and 16 deletions

View File

@ -1,3 +1,9 @@
2011-04-25 Paolo Carlini <paolo.carlini@oracle.com>
* c-family/c-common.c (struct c_common_resword): Add
__underlying_type.
* c-family/c-common.h (enum rid): Add RID_UNDERLYING_TYPE.
2011-04-25 Segher Boessenkool <segher@kernel.crashing.org>
* config/rs6000/titan.md (automata_option "progress"): Remove.

View File

@ -450,6 +450,7 @@ const struct c_common_resword c_common_reswords[] =
{ "__is_trivial", RID_IS_TRIVIAL, D_CXXONLY },
{ "__is_union", RID_IS_UNION, D_CXXONLY },
{ "__is_literal_type", RID_IS_LITERAL_TYPE, D_CXXONLY },
{ "__underlying_type", RID_UNDERLYING_TYPE, D_CXXONLY },
{ "__imag", RID_IMAGPART, 0 },
{ "__imag__", RID_IMAGPART, 0 },
{ "__inline", RID_INLINE, 0 },

View File

@ -138,6 +138,7 @@ enum rid
RID_IS_POD, RID_IS_POLYMORPHIC,
RID_IS_STD_LAYOUT, RID_IS_TRIVIAL,
RID_IS_UNION, RID_IS_LITERAL_TYPE,
RID_UNDERLYING_TYPE,
/* C++0x */
RID_CONSTEXPR, RID_DECLTYPE, RID_NOEXCEPT, RID_NULLPTR, RID_STATIC_ASSERT,

View File

@ -1,3 +1,23 @@
2011-04-25 Paolo Carlini <paolo.carlini@oracle.com>
* cp-tree.def: Add a new UNDERLYING_TYPE tree code.
* cp-tree.h (enum cp_trait_kind): Add CPTK_UNDERLYING_TYPE, tidy.
(UNDERLYING_TYPE_TYPE): Add.
* cp-objcp-common.c (cp_common_init_ts): Mark UNDERLYING_TYPE
as TS_COMMON.
* parser.c (cp_lexer_next_token_is_decl_specifier_keyword,
cp_parser_simple_type_specifier): Handle UNDERLYING_TYPE.
(cp_parser_trait_expr): Deal with RID_UNDERLYING_TYPE; tidy.
* semantics.c (finish_underlying_type): New.
* typeck.c (structural_comptypes): Handle UNDERLYING_TYPE.
* error.c (dump_type, dump_type_prefix, dump_type_suffix): Likewise.
* cxx-pretty-print.c (p_cxx_type_id): Likewise.
* tree.c (cp_walk_subtrees): Likewise.
* pt.c (for_each_template_parm_r, tsubst, unify,
dependent_type_p_r): Likewise.
* mangle.c (write_type): Sorry for __underlying_type.
* doc/extend.texi: Document __underlying_type.
2011-04-25 Jason Merrill <jason@redhat.com>
PR c++/48707

View File

@ -238,6 +238,7 @@ cp_common_init_ts (void)
MARK_TS_COMMON (TEMPLATE_INFO);
MARK_TS_COMMON (TYPENAME_TYPE);
MARK_TS_COMMON (TYPEOF_TYPE);
MARK_TS_COMMON (UNDERLYING_TYPE);
MARK_TS_COMMON (BASELINK);
MARK_TS_COMMON (TYPE_PACK_EXPANSION);
MARK_TS_COMMON (EXPR_PACK_EXPANSION);

View File

@ -2,7 +2,7 @@
additional tree codes used in the GNU C++ compiler (see tree.def
for the standard codes).
Copyright (C) 1987, 1988, 1990, 1993, 1997, 1998, 2003, 2004, 2005,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2010
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2010, 2011
Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
@ -450,6 +450,10 @@ DEFTREECODE (LAMBDA_EXPR, "lambda_expr", tcc_exceptional, 0)
DECLTYPE_FOR_LAMBDA_RETURN is set if we want lambda return deduction. */
DEFTREECODE (DECLTYPE_TYPE, "decltype_type", tcc_type, 0)
/* A type designated by `__underlying_type (type)'.
UNDERLYING_TYPE_TYPE is the type in question. */
DEFTREECODE (UNDERLYING_TYPE, "underlying_type", tcc_type, 0)
/* Used to represent the template information stored by template
specializations.
The accessors are:

View File

@ -556,12 +556,13 @@ typedef enum cp_trait_kind
CPTK_IS_CONVERTIBLE_TO,
CPTK_IS_EMPTY,
CPTK_IS_ENUM,
CPTK_IS_LITERAL_TYPE,
CPTK_IS_POD,
CPTK_IS_POLYMORPHIC,
CPTK_IS_STD_LAYOUT,
CPTK_IS_TRIVIAL,
CPTK_IS_LITERAL_TYPE,
CPTK_IS_UNION
CPTK_IS_UNION,
CPTK_UNDERLYING_TYPE
} cp_trait_kind;
/* The types that we are processing. */
@ -3360,6 +3361,10 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
/* The expression in question for a TYPEOF_TYPE. */
#define TYPEOF_TYPE_EXPR(NODE) (TYPEOF_TYPE_CHECK (NODE))->type.values
/* The type in question for an UNDERLYING_TYPE. */
#define UNDERLYING_TYPE_TYPE(NODE) \
(UNDERLYING_TYPE_CHECK (NODE))->type.values
/* The expression in question for a DECLTYPE_TYPE. */
#define DECLTYPE_TYPE_EXPR(NODE) (DECLTYPE_TYPE_CHECK (NODE))->type.values
@ -5321,6 +5326,7 @@ extern tree finish_id_expression (tree, tree, tree,
const char **,
location_t);
extern tree finish_typeof (tree);
extern tree finish_underlying_type (tree);
extern tree finish_offsetof (tree);
extern void finish_decl_cleanup (tree, tree);
extern void finish_eh_cleanup (tree);

View File

@ -1,6 +1,6 @@
/* Implementation of subroutines for the GNU C++ pretty-printer.
Copyright (C) 2003, 2004, 2005, 2007, 2008,
2009, 2010 Free Software Foundation, Inc.
2009, 2010, 2011 Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
This file is part of GCC.
@ -1694,6 +1694,7 @@ pp_cxx_type_id (cxx_pretty_printer *pp, tree t)
case TEMPLATE_PARM_INDEX:
case TEMPLATE_DECL:
case TYPEOF_TYPE:
case UNDERLYING_TYPE:
case DECLTYPE_TYPE:
case TEMPLATE_ID_EXPR:
pp_cxx_type_specifier_seq (pp, t);

View File

@ -1,7 +1,8 @@
/* Call-backs for C++ error reporting.
This code is non-reentrant.
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003,
2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
@ -483,6 +484,14 @@ dump_type (tree t, int flags)
pp_cxx_right_paren (cxx_pp);
break;
case UNDERLYING_TYPE:
pp_cxx_ws_string (cxx_pp, "__underlying_type");
pp_cxx_whitespace (cxx_pp);
pp_cxx_left_paren (cxx_pp);
dump_expr (UNDERLYING_TYPE_TYPE (t), flags & ~TFF_EXPR_IN_PARENS);
pp_cxx_right_paren (cxx_pp);
break;
case TYPE_PACK_EXPANSION:
dump_type (PACK_EXPANSION_PATTERN (t), flags);
pp_cxx_ws_string (cxx_pp, "...");
@ -731,6 +740,7 @@ dump_type_prefix (tree t, int flags)
case COMPLEX_TYPE:
case VECTOR_TYPE:
case TYPEOF_TYPE:
case UNDERLYING_TYPE:
case DECLTYPE_TYPE:
case TYPE_PACK_EXPANSION:
case FIXED_POINT_TYPE:
@ -834,6 +844,7 @@ dump_type_suffix (tree t, int flags)
case COMPLEX_TYPE:
case VECTOR_TYPE:
case TYPEOF_TYPE:
case UNDERLYING_TYPE:
case DECLTYPE_TYPE:
case TYPE_PACK_EXPANSION:
case FIXED_POINT_TYPE:

View File

@ -1991,6 +1991,10 @@ write_type (tree type)
sorry ("mangling typeof, use decltype instead");
break;
case UNDERLYING_TYPE:
sorry ("mangling __underlying_type");
break;
case LANG_TYPE:
/* fall through. */

View File

@ -1,6 +1,6 @@
/* C++ Parser.
Copyright (C) 2000, 2001, 2002, 2003, 2004,
2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
2005, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
Written by Mark Mitchell <mark@codesourcery.com>.
This file is part of GCC.
@ -654,6 +654,7 @@ cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer)
case RID_TYPEOF:
/* C++0x extensions. */
case RID_DECLTYPE:
case RID_UNDERLYING_TYPE:
return true;
default:
@ -7129,7 +7130,10 @@ cp_parser_builtin_offsetof (cp_parser *parser)
return expr;
}
/* Parse a trait expression. */
/* Parse a trait expression.
Returns a representation of the expression, the underlying type
of the type at issue when KEYWORD is RID_UNDERLYING_TYPE. */
static tree
cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
@ -7185,6 +7189,9 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
case RID_IS_ENUM:
kind = CPTK_IS_ENUM;
break;
case RID_IS_LITERAL_TYPE:
kind = CPTK_IS_LITERAL_TYPE;
break;
case RID_IS_POD:
kind = CPTK_IS_POD;
break;
@ -7200,8 +7207,8 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
case RID_IS_UNION:
kind = CPTK_IS_UNION;
break;
case RID_IS_LITERAL_TYPE:
kind = CPTK_IS_LITERAL_TYPE;
case RID_UNDERLYING_TYPE:
kind = CPTK_UNDERLYING_TYPE;
break;
default:
gcc_unreachable ();
@ -7247,7 +7254,9 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
/* Complete the trait expression, which may mean either processing
the trait expr now or saving it for template instantiation. */
return finish_trait_expr (kind, type1, type2);
return kind != CPTK_UNDERLYING_TYPE
? finish_trait_expr (kind, type1, type2)
: finish_underlying_type (type1);
}
/* Lambdas that appear in variable initializer or default argument scope
@ -12505,6 +12514,7 @@ cp_parser_type_specifier (cp_parser* parser,
decltype ( expression )
char16_t
char32_t
__underlying_type ( type-id )
GNU Extension:
@ -12621,6 +12631,16 @@ cp_parser_simple_type_specifier (cp_parser* parser,
return type;
case RID_UNDERLYING_TYPE:
type = cp_parser_trait_expr (parser, RID_UNDERLYING_TYPE);
if (decl_specs)
cp_parser_set_decl_spec_type (decl_specs, type,
token->location,
/*user_defined_p=*/true);
return type;
default:
break;
}

View File

@ -7255,6 +7255,7 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
break;
case TYPEOF_TYPE:
case UNDERLYING_TYPE:
if (pfd->include_nondeduced_p
&& for_each_template_parm (TYPE_FIELDS (t), fn, data,
pfd->visited,
@ -11032,6 +11033,13 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
complain);
}
case UNDERLYING_TYPE:
{
tree type = tsubst (UNDERLYING_TYPE_TYPE (t), args,
complain, in_decl);
return finish_underlying_type (type);
}
case TYPE_ARGUMENT_PACK:
case NONTYPE_ARGUMENT_PACK:
{
@ -15692,8 +15700,9 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
case TYPEOF_TYPE:
case DECLTYPE_TYPE:
/* Cannot deduce anything from TYPEOF_TYPE or DECLTYPE_TYPE
nodes. */
case UNDERLYING_TYPE:
/* Cannot deduce anything from TYPEOF_TYPE, DECLTYPE_TYPE,
or UNDERLYING_TYPE nodes. */
return 0;
case ERROR_MARK:
@ -17952,11 +17961,12 @@ dependent_type_p_r (tree type)
(INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type)))))
return true;
/* All TYPEOF_TYPEs and DECLTYPE_TYPEs are dependent; if the
argument of the `typeof' expression is not type-dependent, then
it should already been have resolved. */
/* All TYPEOF_TYPEs, DECLTYPE_TYPEs, and UNDERLYING_TYPEs are
dependent; if the argument of the `typeof' expression is not
type-dependent, then it should already been have resolved. */
if (TREE_CODE (type) == TYPEOF_TYPE
|| TREE_CODE (type) == DECLTYPE_TYPE)
|| TREE_CODE (type) == DECLTYPE_TYPE
|| TREE_CODE (type) == UNDERLYING_TYPE)
return true;
/* A template argument pack is dependent if any of its packed

View File

@ -3366,6 +3366,44 @@ finish_typeof (tree expr)
return type;
}
/* Implement the __underlying_type keyword: Return the underlying
type of TYPE, suitable for use as a type-specifier. */
tree
finish_underlying_type (tree type)
{
tree underlying_type;
if (processing_template_decl)
{
underlying_type = cxx_make_type (UNDERLYING_TYPE);
UNDERLYING_TYPE_TYPE (underlying_type) = type;
SET_TYPE_STRUCTURAL_EQUALITY (underlying_type);
return underlying_type;
}
complete_type (type);
if (TREE_CODE (type) != ENUMERAL_TYPE)
{
error ("%qE is not an enumeration type", type);
return error_mark_node;
}
underlying_type = ENUM_UNDERLYING_TYPE (type);
/* Fixup necessary in this case because ENUM_UNDERLYING_TYPE
includes TYPE_MIN_VALUE and TYPE_MAX_VALUE information.
See finish_enum_value_list for details. */
if (!ENUM_FIXED_UNDERLYING_TYPE_P (type))
underlying_type
= c_common_type_for_mode (TYPE_MODE (underlying_type),
TYPE_UNSIGNED (underlying_type));
return underlying_type;
}
/* Perform C++-specific checks for __builtin_offsetof before calling
fold_offsetof. */

View File

@ -2831,6 +2831,7 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
case TEMPLATE_TYPE_PARM:
case TYPENAME_TYPE:
case TYPEOF_TYPE:
case UNDERLYING_TYPE:
/* None of these have subtrees other than those already walked
above. */
*walk_subtrees_p = 0;

View File

@ -1331,6 +1331,10 @@ structural_comptypes (tree t1, tree t2, int strict)
return false;
break;
case UNDERLYING_TYPE:
return same_type_p (UNDERLYING_TYPE_TYPE (t1),
UNDERLYING_TYPE_TYPE (t2));
default:
return false;
}

View File

@ -1,3 +1,16 @@
2011-04-25 Paolo Carlini <paolo.carlini@oracle.com>
* g++.dg/ext/underlying_type1.C: New.
* g++.dg/ext/underlying_type2.C: Likewise.
* g++.dg/ext/underlying_type3.C: Likewise.
* g++.dg/ext/underlying_type4.C: Likewise.
* g++.dg/ext/underlying_type5.C: Likewise.
* g++.dg/ext/underlying_type6.C: Likewise.
* g++.dg/ext/underlying_type7.C: Likewise.
* g++.dg/ext/underlying_type8.C: Likewise.
* g++.dg/ext/underlying_type9.C: Likewise.
* g++.dg/ext/underlying_type10.C: Likewise.
2011-04-25 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/regress/template-const2.C: New.

View File

@ -0,0 +1,18 @@
// { dg-do compile }
struct B { };
union U { };
template<typename T>
struct underlying_type
{ typedef __underlying_type(T) type; }; // { dg-error "not an enumeration" }
__underlying_type(int) i1; // { dg-error "not an enumeration|invalid" }
__underlying_type(A) i2; // { dg-error "expected" }
__underlying_type(B) i3; // { dg-error "not an enumeration|invalid" }
__underlying_type(U) i4; // { dg-error "not an enumeration|invalid" }
underlying_type<int>::type i5;
underlying_type<A>::type i6; // { dg-error "not declared|template|expected" }
underlying_type<B>::type i7;
underlying_type<U>::type i8;

View File

@ -0,0 +1,32 @@
// { dg-do run }
// { dg-options "-std=c++0x" }
#include <cassert>
enum E1 : unsigned { E1_en = 1 };
enum E2 : char { E2_en = 1 };
enum class E3 { a = -1 };
enum class E4 : unsigned char { c = 1 };
enum class E5 : int { a = -1, b = 1 };
enum class E6 : long { c = __LONG_MAX__ };
template<typename T>
struct underlying_type
{ typedef __underlying_type(T) type; };
template<typename T>
void
test(T t, typename underlying_type<T>::type v)
{
assert( t == T(v) );
}
int main()
{
test(E1::E1_en, 1);
test(E2::E2_en, 1);
test(E3::a, -1);
test(E4::c, 1);
test(E5::a, -1);
test(E6::c, __LONG_MAX__);
}

View File

@ -0,0 +1,9 @@
// { dg-do compile }
enum E1 { };
enum E2 { a = -1, b = 1 };
enum E3 { c = __LONG_MAX__ };
__underlying_type(E1) e1 = 0;
__underlying_type(E2) e2 = b;
__underlying_type(E3) e3 = __LONG_MAX__;

View File

@ -0,0 +1,33 @@
// { dg-do compile }
// { dg-options "-std=c++0x" }
template<typename T1, typename T2>
struct is_same
{ static const bool value = false; };
template<typename T>
struct is_same<T, T>
{ static const bool value = true; };
enum E1 : unsigned { };
enum E2 : char { };
enum class E3 { };
enum class E4 : unsigned char { c = 1 };
enum class E5 : int { a = -1, b = 1 };
enum class E6 : long { c = __LONG_MAX__ };
__underlying_type(E1) i1 = __INT_MAX__ * 2U + 1;
__underlying_type(E2) i2 = (char(-1) < 0
? __SCHAR_MAX__
: __SCHAR_MAX__ * 2U + 1);
__underlying_type(E3) i3 = __INT_MAX__;
__underlying_type(E4) i4 = __SCHAR_MAX__ * 2U + 1;
__underlying_type(E5) i5 = int(E5::b);
__underlying_type(E6) i6 = __LONG_MAX__;
static_assert(is_same<__underlying_type(E1), unsigned>::value, "Error");
static_assert(is_same<__underlying_type(E2), char>::value, "Error");
static_assert(is_same<__underlying_type(E3), int>::value, "Error");
static_assert(is_same<__underlying_type(E4), unsigned char>::value, "Error");
static_assert(is_same<__underlying_type(E5), int>::value, "Error");
static_assert(is_same<__underlying_type(E6), long>::value, "Error");

View File

@ -0,0 +1,25 @@
// { dg-do compile }
#include <tr1/type_traits>
using namespace std::tr1;
enum E1 { };
enum E2 { a = -1, b = 1 };
enum E3 { c = __LONG_MAX__ };
typedef __underlying_type(E1) UTE1;
typedef __underlying_type(E2) UTE2;
typedef __underlying_type(E3) UTE3;
template<typename T>
struct underlying_type
{ typedef __underlying_type(T) type; };
int test1[is_same<underlying_type<E1>::type, UTE1>::value ? 1 : -1];
int test2[is_same<underlying_type<E2>::type, UTE2>::value ? 1 : -1];
int test3[is_same<underlying_type<E3>::type, UTE3>::value ? 1 : -1];
int test4[is_integral<underlying_type<E1>::type>::value ? 1 : -1];
int test5[is_integral<underlying_type<E2>::type>::value ? 1 : -1];
int test6[is_integral<underlying_type<E3>::type>::value ? 1 : -1];

View File

@ -0,0 +1,43 @@
// { dg-do compile }
// { dg-options "-std=c++0x" }
template<typename T1, typename T2>
struct is_same
{ static const bool value = false; };
template<typename T>
struct is_same<T, T>
{ static const bool value = true; };
enum E1 : unsigned { };
enum E2 : char { };
enum class E3 { };
enum class E4 : unsigned char { c = 1 };
enum class E5 : int { a = -1, b = 1 };
enum class E6 : long { c = __LONG_MAX__ };
typedef __underlying_type(E1) UTE1;
typedef __underlying_type(E2) UTE2;
typedef __underlying_type(E3) UTE3;
typedef __underlying_type(E4) UTE4;
typedef __underlying_type(E5) UTE5;
typedef __underlying_type(E6) UTE6;
template<typename T>
struct underlying_type
{ typedef __underlying_type(T) type; };
static_assert(is_same<underlying_type<E1>::type, UTE1>::value, "Error");
static_assert(is_same<underlying_type<E2>::type, UTE2>::value, "Error");
static_assert(is_same<underlying_type<E3>::type, UTE3>::value, "Error");
static_assert(is_same<underlying_type<E4>::type, UTE4>::value, "Error");
static_assert(is_same<underlying_type<E5>::type, UTE5>::value, "Error");
static_assert(is_same<underlying_type<E6>::type, UTE6>::value, "Error");
static_assert(is_same<underlying_type<E1>::type, unsigned>::value, "Error");
static_assert(is_same<underlying_type<E2>::type, char>::value, "Error");
static_assert(is_same<underlying_type<E3>::type, int>::value, "Error");
static_assert(is_same<underlying_type<E4>::type,
unsigned char>::value, "Error");
static_assert(is_same<underlying_type<E5>::type, int>::value, "Error");
static_assert(is_same<underlying_type<E6>::type, long>::value, "Error");

View File

@ -0,0 +1,31 @@
// { dg-do compile }
// { dg-options "-std=c++0x" }
template<typename T1, typename T2>
struct is_same
{ static const bool value = false; };
template<typename T>
struct is_same<T, T>
{ static const bool value = true; };
enum E1 : unsigned { };
enum E2 : char { };
enum class E3 { };
enum class E4 : unsigned char { c = 1 };
enum class E5 : int { a = -1, b = 1 };
enum class E6 : long { c = __LONG_MAX__ };
template<typename T, typename U,
typename V = __underlying_type(T)>
struct test
{
static_assert(is_same<U, V>::value, "Error");
};
template class test<E1, unsigned>;
template class test<E2, char>;
template class test<E3, int>;
template class test<E4, unsigned char>;
template class test<E5, int>;
template class test<E6, long>;

View File

@ -0,0 +1,24 @@
// { dg-do compile }
// { dg-options "-std=c++0x" }
enum E1 : unsigned { E1_en = 1 };
enum E2 : char { E2_en = 1 };
enum class E3 { a = -1 };
enum class E4 : unsigned char { c = 1 };
enum class E5 : int { a = -1, b = 1 };
enum class E6 : long { c = __LONG_MAX__ };
template<typename T>
void
test(T, __underlying_type(T)) // { dg-message "sorry, unimplemented: mangling" }
{ }
int main()
{
test(E1::E1_en, 1);
test(E2::E2_en, 1);
test(E3::a, -1);
test(E4::c, 1);
test(E5::a, -1);
test(E6::c, __LONG_MAX__);
}

View File

@ -0,0 +1,46 @@
// { dg-do compile }
// { dg-options "-std=c++0x" }
enum E1 : unsigned { E1_en = 1 };
enum E2 : char { E2_en = 1 };
enum class E3 { a = -1 };
enum class E4 : unsigned char { c = 1 };
enum class E5 : int { a = -1, b = 1 };
enum class E6 : long { c = __LONG_MAX__ };
template<typename T1, typename T2>
struct is_same
{ static const bool value = false; };
template<typename T>
struct is_same<T, T>
{ static const bool value = true; };
template<typename>
struct underlying_type;
template<typename T, typename U>
void
test(T, U, typename underlying_type<T>::type);
template<typename T>
struct underlying_type
{ typedef __underlying_type(T) type; };
template<typename T, typename U>
void
test(T, U, typename underlying_type<T>::type)
{
static_assert(is_same<typename underlying_type<T>::type, U>::value,
"Error");
}
int main()
{
test(E1::E1_en, unsigned(), 1);
test(E2::E2_en, char(), 1);
test(E3::a, int(), -1);
test(E4::c, (unsigned char)(1), 1);
test(E5::a, int(), -1);
test(E6::c, long(), __LONG_MAX__);
}

View File

@ -0,0 +1,30 @@
// { dg-do compile }
// { dg-options "-std=c++0x" }
template<typename T1, typename T2>
struct is_same
{ static const bool value = false; };
template<typename T>
struct is_same<T, T>
{ static const bool value = true; };
enum E1 : unsigned { };
enum E2 : char { };
enum class E3 { };
enum class E4 : unsigned char { c = 1 };
enum class E5 : int { a = -1, b = 1 };
enum class E6 : long { c = __LONG_MAX__ };
template<typename T, typename U>
struct test
{
static_assert(is_same<T, U>::value, "Error");
};
test<__underlying_type(E1), unsigned> t1;
test<__underlying_type(E2), char> t2;
test<__underlying_type(E3), int> t3;
test<__underlying_type(E4), unsigned char> t4;
test<__underlying_type(E5), int> t5;
test<__underlying_type(E6), long> t6;