From a0d260fcc5f6fe1a246e8ee40235a825369f3627 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Mon, 25 Apr 2011 22:27:19 +0000 Subject: [PATCH] c-common.c (struct c_common_resword): Add __underlying_type. /gcc 2011-04-25 Paolo Carlini * 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 * 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 * 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 --- gcc/ChangeLog | 6 +++ gcc/c-family/c-common.c | 1 + gcc/c-family/c-common.h | 1 + gcc/cp/ChangeLog | 20 +++++++++ gcc/cp/cp-objcp-common.c | 1 + gcc/cp/cp-tree.def | 6 ++- gcc/cp/cp-tree.h | 10 ++++- gcc/cp/cxx-pretty-print.c | 3 +- gcc/cp/error.c | 13 +++++- gcc/cp/mangle.c | 4 ++ gcc/cp/parser.c | 30 ++++++++++--- gcc/cp/pt.c | 22 +++++++--- gcc/cp/semantics.c | 38 ++++++++++++++++ gcc/cp/tree.c | 1 + gcc/cp/typeck.c | 4 ++ gcc/testsuite/ChangeLog | 13 ++++++ gcc/testsuite/g++.dg/ext/underlying_type1.C | 18 ++++++++ gcc/testsuite/g++.dg/ext/underlying_type10.C | 32 ++++++++++++++ gcc/testsuite/g++.dg/ext/underlying_type2.C | 9 ++++ gcc/testsuite/g++.dg/ext/underlying_type3.C | 33 ++++++++++++++ gcc/testsuite/g++.dg/ext/underlying_type4.C | 25 +++++++++++ gcc/testsuite/g++.dg/ext/underlying_type5.C | 43 ++++++++++++++++++ gcc/testsuite/g++.dg/ext/underlying_type6.C | 31 +++++++++++++ gcc/testsuite/g++.dg/ext/underlying_type7.C | 24 ++++++++++ gcc/testsuite/g++.dg/ext/underlying_type8.C | 46 ++++++++++++++++++++ gcc/testsuite/g++.dg/ext/underlying_type9.C | 30 +++++++++++++ 26 files changed, 448 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/underlying_type1.C create mode 100644 gcc/testsuite/g++.dg/ext/underlying_type10.C create mode 100644 gcc/testsuite/g++.dg/ext/underlying_type2.C create mode 100644 gcc/testsuite/g++.dg/ext/underlying_type3.C create mode 100644 gcc/testsuite/g++.dg/ext/underlying_type4.C create mode 100644 gcc/testsuite/g++.dg/ext/underlying_type5.C create mode 100644 gcc/testsuite/g++.dg/ext/underlying_type6.C create mode 100644 gcc/testsuite/g++.dg/ext/underlying_type7.C create mode 100644 gcc/testsuite/g++.dg/ext/underlying_type8.C create mode 100644 gcc/testsuite/g++.dg/ext/underlying_type9.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 26b8cb9f1b2..334ee8f6b86 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2011-04-25 Paolo Carlini + + * 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 * config/rs6000/titan.md (automata_option "progress"): Remove. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 752806e275b..63277ca76af 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -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 }, diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index da9dad5c781..09aa6000689 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -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, diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d2dbe4ea2e8..303a4c9dd1f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,23 @@ +2011-04-25 Paolo Carlini + + * 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 PR c++/48707 diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c index 6421f6f2656..d15aed0c2c2 100644 --- a/gcc/cp/cp-objcp-common.c +++ b/gcc/cp/cp-objcp-common.c @@ -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); diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index 42840a81c10..7bd35e0d6b2 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -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: diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 66ac4e8d26d..1c7a4e66f61 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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); diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c index d8bf9126e5b..bd0381bf438 100644 --- a/gcc/cp/cxx-pretty-print.c +++ b/gcc/cp/cxx-pretty-print.c @@ -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 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); diff --git a/gcc/cp/error.c b/gcc/cp/error.c index ec9b9fe85af..fce74036b02 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -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: diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index b33f31723c7..3dbc3b7782a 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -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. */ diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 7d3121c1b57..bb97700fe62 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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 . 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; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 70fcbba7395..654289a9e6d 100644 --- a/gcc/cp/pt.c +++ b/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 diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 7763ae00bf3..62272aaccfa 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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. */ diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 23daa6c45e0..fd5c55e4da3 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -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; diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index dcdc79084d0..afe0dbcf2b2 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cd361e7e18c..f464fa41619 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,16 @@ +2011-04-25 Paolo Carlini + + * 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 * g++.dg/cpp0x/regress/template-const2.C: New. diff --git a/gcc/testsuite/g++.dg/ext/underlying_type1.C b/gcc/testsuite/g++.dg/ext/underlying_type1.C new file mode 100644 index 00000000000..a8f68d3d60a --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/underlying_type1.C @@ -0,0 +1,18 @@ +// { dg-do compile } + +struct B { }; +union U { }; + +template + 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::type i5; +underlying_type::type i6; // { dg-error "not declared|template|expected" } +underlying_type::type i7; +underlying_type::type i8; diff --git a/gcc/testsuite/g++.dg/ext/underlying_type10.C b/gcc/testsuite/g++.dg/ext/underlying_type10.C new file mode 100644 index 00000000000..cb57407fe88 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/underlying_type10.C @@ -0,0 +1,32 @@ +// { dg-do run } +// { dg-options "-std=c++0x" } + +#include + +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 + struct underlying_type + { typedef __underlying_type(T) type; }; + +template + void + test(T t, typename underlying_type::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__); +} diff --git a/gcc/testsuite/g++.dg/ext/underlying_type2.C b/gcc/testsuite/g++.dg/ext/underlying_type2.C new file mode 100644 index 00000000000..0e4519876d2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/underlying_type2.C @@ -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__; diff --git a/gcc/testsuite/g++.dg/ext/underlying_type3.C b/gcc/testsuite/g++.dg/ext/underlying_type3.C new file mode 100644 index 00000000000..b78cc7dd3f6 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/underlying_type3.C @@ -0,0 +1,33 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +template + struct is_same + { static const bool value = false; }; + +template + struct is_same + { 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"); diff --git a/gcc/testsuite/g++.dg/ext/underlying_type4.C b/gcc/testsuite/g++.dg/ext/underlying_type4.C new file mode 100644 index 00000000000..b80ed57694b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/underlying_type4.C @@ -0,0 +1,25 @@ +// { dg-do compile } + +#include + +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 + struct underlying_type + { typedef __underlying_type(T) type; }; + +int test1[is_same::type, UTE1>::value ? 1 : -1]; +int test2[is_same::type, UTE2>::value ? 1 : -1]; +int test3[is_same::type, UTE3>::value ? 1 : -1]; + +int test4[is_integral::type>::value ? 1 : -1]; +int test5[is_integral::type>::value ? 1 : -1]; +int test6[is_integral::type>::value ? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/ext/underlying_type5.C b/gcc/testsuite/g++.dg/ext/underlying_type5.C new file mode 100644 index 00000000000..a9c19924b95 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/underlying_type5.C @@ -0,0 +1,43 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +template + struct is_same + { static const bool value = false; }; + +template + struct is_same + { 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 + struct underlying_type + { typedef __underlying_type(T) type; }; + +static_assert(is_same::type, UTE1>::value, "Error"); +static_assert(is_same::type, UTE2>::value, "Error"); +static_assert(is_same::type, UTE3>::value, "Error"); +static_assert(is_same::type, UTE4>::value, "Error"); +static_assert(is_same::type, UTE5>::value, "Error"); +static_assert(is_same::type, UTE6>::value, "Error"); + +static_assert(is_same::type, unsigned>::value, "Error"); +static_assert(is_same::type, char>::value, "Error"); +static_assert(is_same::type, int>::value, "Error"); +static_assert(is_same::type, + unsigned char>::value, "Error"); +static_assert(is_same::type, int>::value, "Error"); +static_assert(is_same::type, long>::value, "Error"); diff --git a/gcc/testsuite/g++.dg/ext/underlying_type6.C b/gcc/testsuite/g++.dg/ext/underlying_type6.C new file mode 100644 index 00000000000..50f528856d7 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/underlying_type6.C @@ -0,0 +1,31 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +template + struct is_same + { static const bool value = false; }; + +template + struct is_same + { 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 + struct test + { + static_assert(is_same::value, "Error"); + }; + +template class test; +template class test; +template class test; +template class test; +template class test; +template class test; diff --git a/gcc/testsuite/g++.dg/ext/underlying_type7.C b/gcc/testsuite/g++.dg/ext/underlying_type7.C new file mode 100644 index 00000000000..872fe52b00e --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/underlying_type7.C @@ -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 + 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__); +} diff --git a/gcc/testsuite/g++.dg/ext/underlying_type8.C b/gcc/testsuite/g++.dg/ext/underlying_type8.C new file mode 100644 index 00000000000..0bbed2b489c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/underlying_type8.C @@ -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 + struct is_same + { static const bool value = false; }; + +template + struct is_same + { static const bool value = true; }; + +template + struct underlying_type; + +template + void + test(T, U, typename underlying_type::type); + +template + struct underlying_type + { typedef __underlying_type(T) type; }; + +template + void + test(T, U, typename underlying_type::type) + { + static_assert(is_same::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__); +} diff --git a/gcc/testsuite/g++.dg/ext/underlying_type9.C b/gcc/testsuite/g++.dg/ext/underlying_type9.C new file mode 100644 index 00000000000..9ffd24439a4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/underlying_type9.C @@ -0,0 +1,30 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +template + struct is_same + { static const bool value = false; }; + +template + struct is_same + { 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 + struct test + { + static_assert(is_same::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; -- 2.30.2