From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7069 invoked by alias); 9 Oct 2011 19:13:38 -0000 Received: (qmail 7044 invoked by uid 22791); 9 Oct 2011 19:13:34 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL,BAYES_00,TW_CX,TW_NV X-Spam-Check-By: sourceware.org Received: from mail87.messagelabs.com (HELO mail87.messagelabs.com) (216.82.250.19) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 09 Oct 2011 19:13:18 +0000 X-Env-Sender: mike_spertus@symantec.com X-Msg-Ref: server-12.tower-87.messagelabs.com!1318187596!33883729!1 X-StarScan-Version: 6.3.6; banners=-,-,- X-VirusChecked: Checked Received: (qmail 25836 invoked from network); 9 Oct 2011 19:13:17 -0000 Received: from tus1smtoutpex02.symantec.com (HELO tus1smtoutpex02.symantec.com) (216.10.195.242) by server-12.tower-87.messagelabs.com with DHE-RSA-AES256-SHA encrypted SMTP; 9 Oct 2011 19:13:17 -0000 Received: from ecl1mtahubpin02.ges.symantec.com (ECL1MTAHUBPIN02.ges.symantec.com [10.48.69.202]) by tus1smtoutpex02.symantec.com (Symantec Brightmail Gateway out) with SMTP id 64.CD.31812.C42F19E4; Sun, 9 Oct 2011 12:13:16 -0700 (MST) Received: from [155.64.220.137] (helo=TUS1XCHHUBPIN01.SYMC.SYMANTEC.COM) by ecl1mtahubpin02.ges.symantec.com with esmtp (Exim 4.76) (envelope-from ) id 1RCyoF-0008ST-SM; Sun, 09 Oct 2011 15:13:16 -0400 Received: from TUS1XCHEVSPIN34.SYMC.SYMANTEC.COM ([155.64.220.149]) by TUS1XCHHUBPIN01.SYMC.SYMANTEC.COM ([155.64.220.137]) with mapi; Sun, 9 Oct 2011 12:13:15 -0700 From: Michael Spertus To: Benjamin Kosnik CC: Jonathan Wakely , "gcc-patches@gcc.gnu.org" , Jason Merrill , "libstdc++@gcc.gnu.org" , Michael Spertus Date: Sun, 09 Oct 2011 19:31:00 -0000 Subject: RE: Intrinsics for N2965: Type traits and base classes Message-ID: References: <20110913154324.4be22faf@shotwell> <4E809F45.2010908@symantec.com> <20110927195930.54e0d0df@shotwell> <4E830B10.8020802@symantec.com> <4E831DF8.9080700@symantec.com> <20110929102215.33af0ba9@shotwell> <20111003214035.2cbbcaf8@shotwell> <20111003220353.7d511557@shotwell> In-Reply-To: <20111003220353.7d511557@shotwell> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-RouteViaML: true Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2011-10/txt/msg00692.txt.bz2 Here is a new diff that works for non-class types (fixing Benjamin's failin= g test), fixes some spacing and alphabetization, and doesn't inadvertently = break the __underlying_type trait. Index: libstdc++-v3/include/tr2/type_traits =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- libstdc++-v3/include/tr2/type_traits (revision 0) +++ libstdc++-v3/include/tr2/type_traits (revision 0) @@ -0,0 +1,96 @@ +// TR2 type_traits -*- C++ -*- + +// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +/** @file tr2/type_traits + * This is a TR2 C++ Library header.=20 + */ + +#ifndef _GLIBCXX_TR2_TYPE_TRAITS +#define _GLIBCXX_TR2_TYPE_TRAITS 1 + +#pragma GCC system_header +#include +#include + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr2 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @defgroup metaprogramming Type Traits + * @ingroup utilities + * + * Compile time type transformation and information. + * @{ + */ + + template struct typelist; + template<> + struct typelist<> + { + typedef std::true_type empty; + }; + + template + struct typelist<_First, _Rest...> + { + struct first + { + typedef _First type; + }; + + struct rest + { + typedef typelist<_Rest...> type; + }; + + typedef std::false_type empty; + }; + + // Sequence abstraction metafunctions default to looking in the type + template struct first : public T::first {}; + template struct rest : public T::rest {}; + template struct empty : public T::empty {}; + + + template + struct bases + { + typedef typelist<__bases(T)...> type; + }; + + template + struct direct_bases + { + typedef typelist<__direct_bases(T)...> type; + }; +=09 +_GLIBCXX_END_NAMESPACE_VERSION +} +} + +#endif // _GLIBCXX_TR2_TYPE_TRAITS Index: gcc/c-family/c-common.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc/c-family/c-common.c (revision 178892) +++ gcc/c-family/c-common.c (working copy) @@ -423,6 +423,7 @@ { "__asm__", RID_ASM, 0 }, { "__attribute", RID_ATTRIBUTE, 0 }, { "__attribute__", RID_ATTRIBUTE, 0 }, + { "__bases", RID_BASES, D_CXXONLY }, { "__builtin_choose_expr", RID_CHOOSE_EXPR, D_CONLY }, { "__builtin_complex", RID_BUILTIN_COMPLEX, D_CONLY }, { "__builtin_offsetof", RID_OFFSETOF, 0 }, @@ -433,6 +434,7 @@ { "__const", RID_CONST, 0 }, { "__const__", RID_CONST, 0 }, { "__decltype", RID_DECLTYPE, D_CXXONLY }, + { "__direct_bases", RID_DIRECT_BASES, D_CXXONLY }, { "__extension__", RID_EXTENSION, 0 }, { "__func__", RID_C99_FUNCTION_NAME, 0 }, { "__has_nothrow_assign", RID_HAS_NOTHROW_ASSIGN, D_CXXONLY }, Index: gcc/c-family/c-common.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc/c-family/c-common.h (revision 178892) +++ gcc/c-family/c-common.h (working copy) @@ -129,12 +129,13 @@ RID_CONSTCAST, RID_DYNCAST, RID_REINTCAST, RID_STATCAST, =20 /* C++ extensions */ + RID_BASES, RID_DIRECT_BASES, RID_HAS_NOTHROW_ASSIGN, RID_HAS_NOTHROW_CONSTRUCTOR, RID_HAS_NOTHROW_COPY, RID_HAS_TRIVIAL_ASSIGN, RID_HAS_TRIVIAL_CONSTRUCTOR, RID_HAS_TRIVIAL_COPY, RID_HAS_TRIVIAL_DESTRUCTOR, RID_HAS_VIRTUAL_DESTRUCTOR, RID_IS_ABSTRACT, RID_IS_BASE_OF, - RID_IS_CONVERTIBLE_TO, RID_IS_CLASS, + RID_IS_CLASS, RID_IS_CONVERTIBLE_TO,=20=20=20=20=20=20 RID_IS_EMPTY, RID_IS_ENUM, RID_IS_LITERAL_TYPE, RID_IS_POD, RID_IS_POLYMORPHIC, RID_IS_STD_LAYOUT, Index: gcc/cp/pt.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc/cp/pt.c (revision 178892) +++ gcc/cp/pt.c (working copy) @@ -2976,6 +2976,9 @@ } break; =20 + case BASES: + parameter_pack_p =3D true; + break; default: /* Not a parameter pack. */ break; @@ -9123,6 +9126,15 @@ tree arg_pack =3D NULL_TREE; tree orig_arg =3D NULL_TREE; =20 + if (TREE_CODE (parm_pack) =3D=3D BASES) + { + if (BASES_DIRECT (parm_pack)) + return calculate_direct_bases (tsubst_expr (BASES_TYPE (parm_pack), + args, complain, in= _decl, false)); + else + return calculate_bases (tsubst_expr (BASES_TYPE (parm_pack), + args, complain, in_decl, = false)); + } if (TREE_CODE (parm_pack) =3D=3D PARM_DECL) { if (!cp_unevaluated_operand) Index: gcc/cp/semantics.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc/cp/semantics.c (revision 178892) +++ gcc/cp/semantics.c (working copy) @@ -3407,6 +3407,150 @@ return underlying_type; } =20 +/* Implement the __direct_bases keyword: Return the direct base classes + of type */ + +tree +calculate_direct_bases (tree type) +{ + VEC(tree, gc) *vector =3D make_tree_vector(); + tree bases_vec =3D NULL_TREE; + VEC(tree, none) *base_binfos; + tree binfo; + unsigned i; + + complete_type (type); + + if (!NON_UNION_CLASS_TYPE_P (type)) + return make_tree_vec (0); + + base_binfos =3D BINFO_BASE_BINFOS (TYPE_BINFO (type)); + + /* Virtual bases are initialized first */ + for (i =3D 0; VEC_iterate (tree, base_binfos, i, binfo); i++) + { + if (BINFO_VIRTUAL_P (binfo)) + { + VEC_safe_push (tree, gc, vector, binfo); + } + } + + /* Now non-virtuals */ + for (i =3D 0; VEC_iterate (tree, base_binfos, i, binfo); i++) + { + if (!BINFO_VIRTUAL_P (binfo)) + { + VEC_safe_push (tree, gc, vector, binfo); + } + } + + + bases_vec =3D make_tree_vec (VEC_length (tree, vector)); + + for (i =3D 0; i < VEC_length (tree, vector); ++i) + { + TREE_VEC_ELT (bases_vec, i) =3D BINFO_TYPE (VEC_index (tree, vector,= i)); + }=20 + return bases_vec; +} + +/* Implement the __bases keyword: Return the base classes + of type */ + +/* Find morally non-virtual base classes by walking binfo hierarchy */ +/* Virtual base classes are handled separately in finish_bases */ + +static tree +dfs_calculate_bases_pre (tree binfo, void *data_) +{ + (void)data_; + /* Don't walk bases of virtual bases */ + return BINFO_VIRTUAL_P (binfo) ? dfs_skip_bases : NULL_TREE; +} + +static tree +dfs_calculate_bases_post (tree binfo, void *data_) +{ + VEC(tree, gc) **data =3D (VEC(tree, gc) **) data_; + if (!BINFO_VIRTUAL_P (binfo)) + { + VEC_safe_push (tree, gc, *data, BINFO_TYPE (binfo)); + } + return NULL_TREE; +} +=20=20 +/* Calculates the morally non-virtual base classes of a class */ +static VEC(tree, gc) * +calculate_bases_helper (tree type) +{ + VEC(tree, gc) *vector =3D make_tree_vector(); + + /* Now add non-virtual base classes in order of construction */ + dfs_walk_all (TYPE_BINFO (type), + dfs_calculate_bases_pre, dfs_calculate_bases_post, &vector= ); + return vector; +} + +tree +calculate_bases (tree type) +{ + VEC(tree, gc) *vector =3D make_tree_vector(); + tree bases_vec =3D NULL_TREE; + unsigned i; + VEC(tree, gc) *vbases; + VEC(tree, gc) *nonvbases; + tree binfo; + + complete_type (type); + + if (!NON_UNION_CLASS_TYPE_P (type)) + return make_tree_vec (0); + + /* First go through virtual base classes */ + for (vbases =3D CLASSTYPE_VBASECLASSES (type), i =3D 0; + VEC_iterate (tree, vbases, i, binfo); i++) + { + VEC(tree, gc) *vbase_bases =3D calculate_bases_helper (BINFO_TYPE (b= info)); + VEC_safe_splice (tree, gc, vector, vbase_bases); + release_tree_vector (vbase_bases); + } + + /* Now for the non-virtual bases */ + nonvbases =3D calculate_bases_helper (type); + VEC_safe_splice (tree, gc, vector, nonvbases); + release_tree_vector (nonvbases); + + /* Last element is entire class, so don't copy */ + bases_vec =3D make_tree_vec (VEC_length (tree, vector) - 1); + + for (i =3D 0; i < VEC_length (tree, vector) - 1; ++i) + { + TREE_VEC_ELT (bases_vec, i) =3D VEC_index (tree, vector, i); + }=20 + release_tree_vector (vector); + return bases_vec; +} + +tree +finish_bases (tree type, bool direct) +{ + tree bases =3D NULL_TREE; + + if (!processing_template_decl) + { + /* Parameter packs can only be used in templates */ + error ("Parameter pack __bases only valid in template declaration"); + return error_mark_node; + } + + bases =3D cxx_make_type (BASES); + BASES_TYPE (bases) =3D type; + BASES_DIRECT (bases) =3D direct; + SET_TYPE_STRUCTURAL_EQUALITY (bases); + + return bases; +} + /* Perform C++-specific checks for __builtin_offsetof before calling fold_offsetof. */ =20 Index: gcc/cp/parser.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc/cp/parser.c (revision 178892) +++ gcc/cp/parser.c (working copy) @@ -7295,6 +7295,12 @@ case RID_UNDERLYING_TYPE: kind =3D CPTK_UNDERLYING_TYPE; break; + case RID_BASES: + kind =3D CPTK_BASES; + break; + case RID_DIRECT_BASES: + kind =3D CPTK_DIRECT_BASES; + break; default: gcc_unreachable (); } @@ -7339,9 +7345,17 @@ =20 /* Complete the trait expression, which may mean either processing the trait expr now or saving it for template instantiation. */ - return kind !=3D CPTK_UNDERLYING_TYPE - ? finish_trait_expr (kind, type1, type2) - : finish_underlying_type (type1); + switch(kind) + { + case CPTK_UNDERLYING_TYPE: + return finish_underlying_type (type1); + case CPTK_BASES: + return finish_bases (type1, false); + case CPTK_DIRECT_BASES: + return finish_bases (type1, true); + default: + return finish_trait_expr (kind, type1, type2); + } } =20 /* Lambdas that appear in variable initializer or default argument scope @@ -12010,6 +12024,7 @@ parser->integral_constant_expression_p =3D false; saved_non_ice_p =3D parser->non_integral_constant_expression_p; parser->non_integral_constant_expression_p =3D false; + /* Parse the arguments. */ do { @@ -12827,7 +12842,6 @@ =20 case RID_UNDERLYING_TYPE: type =3D cp_parser_trait_expr (parser, RID_UNDERLYING_TYPE); - if (decl_specs) cp_parser_set_decl_spec_type (decl_specs, type, token->location, @@ -12835,6 +12849,14 @@ =20 return type; =20 + case RID_BASES: + case RID_DIRECT_BASES: + type =3D cp_parser_trait_expr (parser, token->keyword); + if (decl_specs) + cp_parser_set_decl_spec_type (decl_specs, type, + token->location, + /*type_definition_p=3D*/false); + return type; default: break; } @@ -20534,7 +20556,7 @@ } =20 /* Parse a template-argument-list, as well as the trailing ">" (but - not the opening ">"). See cp_parser_template_argument_list for the + not the opening "<"). See cp_parser_template_argument_list for the return value. */ =20 static tree Index: gcc/cp/cp-tree.def =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc/cp/cp-tree.def (revision 178892) +++ gcc/cp/cp-tree.def (working copy) @@ -461,6 +461,10 @@ UNDERLYING_TYPE_TYPE is the type in question. */ DEFTREECODE (UNDERLYING_TYPE, "underlying_type", tcc_type, 0) =20 +/* A type designated by one of the bases type traits. + BASES_TYPE is the type in question. */ +DEFTREECODE (BASES, "bases", tcc_type, 0) + /* Used to represent the template information stored by template specializations. The accessors are: Index: gcc/cp/cp-tree.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- gcc/cp/cp-tree.h (revision 178892) +++ gcc/cp/cp-tree.h (working copy) @@ -558,6 +558,8 @@ =20 typedef enum cp_trait_kind { + CPTK_BASES, + CPTK_DIRECT_BASES, CPTK_HAS_NOTHROW_ASSIGN, CPTK_HAS_NOTHROW_CONSTRUCTOR, CPTK_HAS_NOTHROW_COPY, @@ -3416,6 +3418,13 @@ #define UNDERLYING_TYPE_TYPE(NODE) \ (TYPE_VALUES_RAW (UNDERLYING_TYPE_CHECK (NODE))) =20 +/* The type in question for BASES. */ +#define BASES_TYPE(NODE) \ + (TYPE_VALUES_RAW (BASES_CHECK (NODE))) + +#define BASES_DIRECT(NODE) \ + TREE_LANG_FLAG_0 (BASES_CHECK (NODE)) + /* The expression in question for a DECLTYPE_TYPE. */ #define DECLTYPE_TYPE_EXPR(NODE) (TYPE_VALUES_RAW (DECLTYPE_TYPE_CHECK (NO= DE))) =20 @@ -5430,6 +5439,9 @@ location_t); extern tree finish_typeof (tree); extern tree finish_underlying_type (tree); +extern tree calculate_bases (tree); +extern tree finish_bases (tree, bool); +extern tree calculate_direct_bases (tree); extern tree finish_offsetof (tree); extern void finish_decl_cleanup (tree, tree); extern void finish_eh_cleanup (tree);