mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-28 16:01:00 +08:00
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:
parent
d95f258e90
commit
a0d260fcc5
@ -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.
|
||||
|
@ -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 },
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
22
gcc/cp/pt.c
22
gcc/cp/pt.c
@ -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
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
18
gcc/testsuite/g++.dg/ext/underlying_type1.C
Normal file
18
gcc/testsuite/g++.dg/ext/underlying_type1.C
Normal 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;
|
32
gcc/testsuite/g++.dg/ext/underlying_type10.C
Normal file
32
gcc/testsuite/g++.dg/ext/underlying_type10.C
Normal 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__);
|
||||
}
|
9
gcc/testsuite/g++.dg/ext/underlying_type2.C
Normal file
9
gcc/testsuite/g++.dg/ext/underlying_type2.C
Normal 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__;
|
33
gcc/testsuite/g++.dg/ext/underlying_type3.C
Normal file
33
gcc/testsuite/g++.dg/ext/underlying_type3.C
Normal 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");
|
25
gcc/testsuite/g++.dg/ext/underlying_type4.C
Normal file
25
gcc/testsuite/g++.dg/ext/underlying_type4.C
Normal 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];
|
43
gcc/testsuite/g++.dg/ext/underlying_type5.C
Normal file
43
gcc/testsuite/g++.dg/ext/underlying_type5.C
Normal 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");
|
31
gcc/testsuite/g++.dg/ext/underlying_type6.C
Normal file
31
gcc/testsuite/g++.dg/ext/underlying_type6.C
Normal 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>;
|
24
gcc/testsuite/g++.dg/ext/underlying_type7.C
Normal file
24
gcc/testsuite/g++.dg/ext/underlying_type7.C
Normal 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__);
|
||||
}
|
46
gcc/testsuite/g++.dg/ext/underlying_type8.C
Normal file
46
gcc/testsuite/g++.dg/ext/underlying_type8.C
Normal 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__);
|
||||
}
|
30
gcc/testsuite/g++.dg/ext/underlying_type9.C
Normal file
30
gcc/testsuite/g++.dg/ext/underlying_type9.C
Normal 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;
|
Loading…
x
Reference in New Issue
Block a user