Re: Intrinsics for N2965: Type traits and base classes
Please post a ChangeLog entry with a patch. Someone added one for you: 2011-10-17 Michael Spertus mike_sper...@symantec.com * gcc/c-family/c-common.c (c_common_reswords): Add __bases, __direct_bases. * gcc/c-family/c-common.h: Add RID_BASES and RID_DIRECT_BASES. but it is in the wrong file (c-family has its own ChangeLog) and shouldn't contain the gcc/c-family prefix (paths are relative to the directory). Sorry Eric, this was my fault. I see that Paolo has already fixed this up. Thanks Paolo! best, benjamin
Re: Intrinsics for N2965: Type traits and base classes
This patch consists intrinsics to properly create the bases and direct_bases of a class in the correct order (including multiple nested ambiguous virtual and non-virtual classes) for N2965 (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2965.html). This allows you to create type traits for giving the base classes of the class: Please post a ChangeLog entry with a patch. Someone added one for you: 2011-10-17 Michael Spertus mike_sper...@symantec.com * gcc/c-family/c-common.c (c_common_reswords): Add __bases, __direct_bases. * gcc/c-family/c-common.h: Add RID_BASES and RID_DIRECT_BASES. but it is in the wrong file (c-family has its own ChangeLog) and shouldn't contain the gcc/c-family prefix (paths are relative to the directory). -- Eric Botcazou
Re: Intrinsics for N2965: Type traits and base classes
This is now in, thanks everybody for playing! Attached is the final diff. tested x86_64/linux -benjamindiff --git a/gcc/ChangeLog b/gcc/ChangeLog index ddc5149..6c73404 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2011-10-17 Michael Spertus mike_sper...@symantec.com + + * gcc/c-family/c-common.c (c_common_reswords): Add __bases, + __direct_bases. + * gcc/c-family/c-common.h: Add RID_BASES and RID_DIRECT_BASES. + 2011-10-17 Simon Baldwin sim...@google.com Ian Lance Taylor i...@google.com diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 0aa0fef..9d20d80 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -423,6 +423,7 @@ const struct c_common_resword c_common_reswords[] = { __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_shuffle, RID_BUILTIN_SHUFFLE, D_CONLY }, @@ -434,6 +435,7 @@ const struct c_common_resword c_common_reswords[] = { __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 }, diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 8996eef..9818c9c 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -128,12 +128,13 @@ enum rid RID_CONSTCAST, RID_DYNCAST, RID_REINTCAST, RID_STATCAST, /* 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, RID_IS_EMPTY,RID_IS_ENUM, RID_IS_LITERAL_TYPE, RID_IS_POD, RID_IS_POLYMORPHIC, RID_IS_STD_LAYOUT, diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ed7d832..2a4bdbb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +2011-10-17 Michael Spertus mike_sper...@symantec.com + + * cp-tree.def: Add BASES as a new tree code. + * cp-tree.h (enum cp_trait_kind): Add CPTK_BASES, CPTK_DIRECT_BASES. + (BASES_TYPE, BASES_DIRECT): Define. + (calculate_bases, finish_bases, calculate_direct_bases): Declare. + * parser.c (cp_parser_trait_expr, cp_parser_template_argument_list, + (cp_parser_simple_type_specifier, cp_parser_save_nsdmi): Use them. + * pt.c (find_parameter_packs_r, tsubst_pack_expansion): Likewise. + * semantics.c (calculate_bases, finish_bases, calculate_direct_bases, + dfs_calculate_bases_pre, dfs_calculate_bases_post, + calculate_bases_helper): Define. + 2011-10-17 Jason Merrill ja...@redhat.com PR c++/50736 diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index be29870..4eec9f9 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -462,6 +462,10 @@ DEFTREECODE (DECLTYPE_TYPE, decltype_type, tcc_type, 0) UNDERLYING_TYPE_TYPE is the type in question. */ DEFTREECODE (UNDERLYING_TYPE, underlying_type, tcc_type, 0) +/* 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: diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 88f7fbd..bda18d9 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -564,6 +564,8 @@ struct GTY (()) tree_argument_pack_select { typedef enum cp_trait_kind { + CPTK_BASES, + CPTK_DIRECT_BASES, CPTK_HAS_NOTHROW_ASSIGN, CPTK_HAS_NOTHROW_CONSTRUCTOR, CPTK_HAS_NOTHROW_COPY, @@ -3433,6 +3435,13 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) #define UNDERLYING_TYPE_TYPE(NODE) \ (TYPE_VALUES_RAW (UNDERLYING_TYPE_CHECK (NODE))) +/* 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 (NODE))) @@ -5462,6 +5471,9 @@ extern tree finish_id_expression (tree, tree, tree, 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);
Re: Intrinsics for N2965: Type traits and base classes
On 10/13/2011 01:35 PM, Michael Spertus wrote: +int main() { + assert(typeid(bF::type) + == typeid(typesA,C,D,A,C,D,B,C,C,D,B,E)); + assert(typeid(dbF::type) == typeid(typesA,B,E)); + assert(typeid(dbint::type) == typeid(types)); + return 0; +} Let's make this a compile-time test using something like template class,class struct assert_same_type; template class T struct assert_same_typeT,T {}; Jason
RE: Intrinsics for N2965: Type traits and base classes
Redo test to run at compile-time per Jason's suggestion Index: libstdc++-v3/include/tr2/type_traits === --- 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 +// http://www.gnu.org/licenses/. + +/** @file tr2/type_traits + * This is a TR2 C++ Library header. + */ + +#ifndef _GLIBCXX_TR2_TYPE_TRAITS +#define _GLIBCXX_TR2_TYPE_TRAITS 1 + +#pragma GCC system_header +#include type_traits +#include bits/c++config.h + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr2 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @defgroup metaprogramming Type Traits + * @ingroup utilities + * + * Compile time type transformation and information. + * @{ + */ + + templatetypename... _Elements struct typelist; + template +struct typelist +{ + typedef std::true_type empty; +}; + + templatetypename _First, typename... _Rest +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 + templatetypename T struct first : public T::first {}; + templatetypename T struct rest : public T::rest {}; + templatetypename T struct empty : public T::empty {}; + + + templatetypename T +struct bases +{ + typedef typelist__bases(T)... type; +}; + + templatetypename T +struct direct_bases +{ + typedef typelist__direct_bases(T)... type; +}; + +_GLIBCXX_END_NAMESPACE_VERSION +} +} + +#endif // _GLIBCXX_TR2_TYPE_TRAITS Index: gcc/c-family/c-common.c === --- 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 === --- 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, /* 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, RID_IS_EMPTY,RID_IS_ENUM, RID_IS_LITERAL_TYPE, RID_IS_POD, RID_IS_POLYMORPHIC, RID_IS_STD_LAYOUT, Index: gcc/testsuite/g++.dg/ext/bases.C === --- gcc/testsuite/g++.dg/ext/bases.C(revision 0) +++ gcc/testsuite/g++.dg/ext/bases.C(revision 0) @@ -0,0 +1,32 @@ +// { dg-do run } +#includetypeinfo +#includecassert +// A simple typelist
Re: Intrinsics for N2965: Type traits and base classes
Looks good, thanks. I'll let Benjamin check this in. Jason
RE: Intrinsics for N2965: Type traits and base classes
:) -Original Message- From: Jason Merrill [mailto:ja...@redhat.com] Sent: Friday, October 14, 2011 2:41 PM To: Michael Spertus Cc: Benjamin Kosnik; Jonathan Wakely; gcc-patches@gcc.gnu.org; libstd...@gcc.gnu.org Subject: Re: Intrinsics for N2965: Type traits and base classes Looks good, thanks. I'll let Benjamin check this in. Jason
RE: Intrinsics for N2965: Type traits and base classes
Addressing Jason's comments: Index: libstdc++-v3/include/tr2/type_traits === --- 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 +// http://www.gnu.org/licenses/. + +/** @file tr2/type_traits + * This is a TR2 C++ Library header. + */ + +#ifndef _GLIBCXX_TR2_TYPE_TRAITS +#define _GLIBCXX_TR2_TYPE_TRAITS 1 + +#pragma GCC system_header +#include type_traits +#include bits/c++config.h + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr2 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @defgroup metaprogramming Type Traits + * @ingroup utilities + * + * Compile time type transformation and information. + * @{ + */ + + templatetypename... _Elements struct typelist; + template +struct typelist +{ + typedef std::true_type empty; +}; + + templatetypename _First, typename... _Rest +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 + templatetypename T struct first : public T::first {}; + templatetypename T struct rest : public T::rest {}; + templatetypename T struct empty : public T::empty {}; + + + templatetypename T +struct bases +{ + typedef typelist__bases(T)... type; +}; + + templatetypename T +struct direct_bases +{ + typedef typelist__direct_bases(T)... type; +}; + +_GLIBCXX_END_NAMESPACE_VERSION +} +} + +#endif // _GLIBCXX_TR2_TYPE_TRAITS Index: gcc/c-family/c-common.c === --- 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 === --- 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, /* 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, RID_IS_EMPTY,RID_IS_ENUM, RID_IS_LITERAL_TYPE, RID_IS_POD, RID_IS_POLYMORPHIC, RID_IS_STD_LAYOUT, Index: gcc/testsuite/g++.dg/ext/bases.C === --- gcc/testsuite/g++.dg/ext/bases.C(revision 0) +++ gcc/testsuite/g++.dg/ext/bases.C(revision 0) @@ -0,0 +1,29 @@ +// { dg-do run } +#includetypeinfo +#includecassert +// A simple typelist +templatetypename... _Elements
Re: Intrinsics for N2965: Type traits and base classes
This is looking pretty good, from the libstdc++ side. This latest round of gcc hacking fixes the previous testsuite fixes, so once you get the gcc bits OK'd by Jason you can check in. I'd still like to see some testcases for the intrinsic, independent of the library. Seems like some simple test case along the lines of gcc/testsuite/g++.dg/ext/is_base_of.C will suffice. -benjamin
RE: Intrinsics for N2965: Type traits and base classes
Here is a new diff that works for non-class types (fixing Benjamin's failing test), fixes some spacing and alphabetization, and doesn't inadvertently break the __underlying_type trait. Index: libstdc++-v3/include/tr2/type_traits === --- 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 +// http://www.gnu.org/licenses/. + +/** @file tr2/type_traits + * This is a TR2 C++ Library header. + */ + +#ifndef _GLIBCXX_TR2_TYPE_TRAITS +#define _GLIBCXX_TR2_TYPE_TRAITS 1 + +#pragma GCC system_header +#include type_traits +#include bits/c++config.h + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr2 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @defgroup metaprogramming Type Traits + * @ingroup utilities + * + * Compile time type transformation and information. + * @{ + */ + + templatetypename... _Elements struct typelist; + template +struct typelist +{ + typedef std::true_type empty; +}; + + templatetypename _First, typename... _Rest +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 + templatetypename T struct first : public T::first {}; + templatetypename T struct rest : public T::rest {}; + templatetypename T struct empty : public T::empty {}; + + + templatetypename T +struct bases +{ + typedef typelist__bases(T)... type; +}; + + templatetypename T +struct direct_bases +{ + typedef typelist__direct_bases(T)... type; +}; + +_GLIBCXX_END_NAMESPACE_VERSION +} +} + +#endif // _GLIBCXX_TR2_TYPE_TRAITS Index: gcc/c-family/c-common.c === --- 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 === --- 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, /* 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, 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 === --- gcc/cp/pt.c (revision 178892) +++ gcc/cp/pt.c (working copy) @@ -2976,6
Re: Intrinsics for N2965: Type traits and base classes
On 10/09/2011 08:13 PM, Michael Spertus wrote: +dfs_calculate_bases_pre (tree binfo, void *data_) +{ + (void)data_; You can use ATTRIBUTE_UNUSED to mark an unused parameter. I'd still like to see some testcases for the intrinsic, independent of the library. Jason
Re: Intrinsics for N2965: Type traits and base classes
The code looks good, though you are still missing some spaces before '('. The main thing left is some testcases. Jason
Re: Intrinsics for N2965: Type traits and base classes
On 3 October 2011 02:55, Michael Spertus wrote: Index: gcc/c-family/c-common.h === --- gcc/c-family/c-common.h (revision 178892) +++ gcc/c-family/c-common.h (working copy) @@ -139,7 +139,8 @@ RID_IS_LITERAL_TYPE, RID_IS_POD, RID_IS_POLYMORPHIC, RID_IS_STD_LAYOUT, RID_IS_TRIVIAL, RID_IS_UNION, - RID_UNDERLYING_TYPE, + RID_UNDERLYING_TYPE, RID_BASES, + RID_DIRECT_BASES, Should that be kept in alphabetical order?
Re: Intrinsics for N2965: Type traits and base classes
OK. Here is a new diff that hopefully takes into account all of Jason's and Benjamin's comments. Benjamin's TR2 build patch is not repeated (or tested!) here. Benjamin, I'd really appreciate if you wouldn't mind confirming I handled that correctly in tr2/type_traits (Including the inclusion of std/type_traits). Hey! Here is a preliminary test suite. Just the basics on this one. There's a bit of an issue with fundamental types, ICEs, but seems fixable. From here on in, just populate the testsuite/tr2/* directories with .cc files. They will be tested by the testsuite machinery. Your typelist interface looks pretty good. We should start here for the interface, and can embellish it after it goes in. -benjamin diff --git a/libstdc++-v3/include/tr2/type_traits b/libstdc++-v3/include/tr2/type_traits new file mode 100644 index 000..94aebf0 --- /dev/null +++ b/libstdc++-v3/include/tr2/type_traits @@ -0,0 +1,102 @@ +// TR2 type_traits -*- C++ -*- + +// Copyright (C) 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 +// http://www.gnu.org/licenses/. + +/** @file tr2/type_traits + * This is a TR2 C++ Library header. + */ + +#ifndef _GLIBCXX_TR2_TYPE_TRAITS +#define _GLIBCXX_TR2_TYPE_TRAITS 1 + +#pragma GCC system_header +#include type_traits +#include bits/c++config.h + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr2 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @defgroup metaprogramming Type Traits + * @ingroup utilities + * + * Compile time type transformation and information. + * @{ + */ + + templatetypename... _Elements +struct typelist; + + template +struct typelist +{ + typedef std::true_type empty; +}; + + templatetypename _First, typename... _Rest +struct typelist_First, _Rest... +{ + typedef std::false_type empty; + + struct first + { + typedef _First type; + }; + + struct rest + { + typedef typelist_Rest... type; + }; +}; + + // Sequence abstraction metafunctions default to looking in the type + templatetypename _Tp +struct first : public _Tp::first { }; + + templatetypename _Tp +struct rest : public _Tp::rest { }; + + templatetypename _Tp +struct empty : public _Tp::empty { }; + + + templatetypename _Tp +struct bases +{ + typedef typelist__bases(_Tp)... type; +}; + + templatetypename _Tp +struct direct_bases +{ + typedef typelist__direct_bases(_Tp)... type; +}; + +_GLIBCXX_END_NAMESPACE_VERSION +} +} + +#endif // _GLIBCXX_TR2_TYPE_TRAITS diff --git a/libstdc++-v3/scripts/create_testsuite_files b/libstdc++-v3/scripts/create_testsuite_files index f4a0bcd..a427eef 100755 --- a/libstdc++-v3/scripts/create_testsuite_files +++ b/libstdc++-v3/scripts/create_testsuite_files @@ -32,7 +32,7 @@ cd $srcdir # This is the ugly version of everything but the current directory. It's # what has to happen when find(1) doesn't support -mindepth, or -xtype. dlist=`echo [0-9][0-9]*` -dlist=$dlist abi backward ext performance tr1 decimal +dlist=$dlist abi backward ext performance tr1 tr2 decimal find $dlist ( -type f -o -type l ) -name *.cc -print $tmp.01 find $dlist ( -type f -o -type l ) -name *.c -print $tmp.02 cat $tmp.01 $tmp.02 | sort $tmp.1 diff --git a/libstdc++-v3/testsuite/libstdc++-dg/conformance.exp b/libstdc++-v3/testsuite/libstdc++-dg/conformance.exp index 8642eb7..19fa0e2 100644 --- a/libstdc++-v3/testsuite/libstdc++-dg/conformance.exp +++ b/libstdc++-v3/testsuite/libstdc++-dg/conformance.exp @@ -58,6 +58,7 @@ if {[info exists tests_file] [file exists $tests_file]} { lappend subdirs $srcdir/ext lappend subdirs $srcdir/performance lappend subdirs $srcdir/tr1 +lappend subdirs $srcdir/tr2 lappend subdirs $srcdir/decimal verbose subdirs are $subdirs diff --git a/libstdc++-v3/testsuite/tr2/bases/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/tr2/bases/requirements/explicit_instantiation.cc new file mode 100644 index 000..ddd6d6f --- /dev/null
RE: Intrinsics for N2965: Type traits and base classes
OK. Here is a new diff that hopefully takes into account all of Jason's and Benjamin's comments. Benjamin's TR2 build patch is not repeated (or tested!) here. Benjamin, I'd really appreciate if you wouldn't mind confirming I handled that correctly in tr2/type_traits (Including the inclusion of std/type_traits). Thanks, Mike Index: libstdc++-v3/include/tr2/type_traits === --- 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 +// http://www.gnu.org/licenses/. + +/** @file tr2/type_traits + * This is a TR2 C++ Library header. + */ + +#ifndef _GLIBCXX_TR2_TYPE_TRAITS +#define _GLIBCXX_TR2_TYPE_TRAITS 1 + +#pragma GCC system_header +#include type_traits +#include bits/c++config.h + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace tr2 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @defgroup metaprogramming Type Traits + * @ingroup utilities + * + * Compile time type transformation and information. + * @{ + */ + + templatetypename... _Elements struct typelist; + template +struct typelist +{ + typedef std::true_type empty; +}; + + templatetypename _First, typename... _Rest +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 + templatetypename T struct first : public T::first {}; + templatetypename T struct rest : public T::rest {}; + templatetypename T struct empty : public T::empty {}; + + + templatetypename T +struct bases +{ + typedef typelist__bases(T)... type; +}; + + templatetypename T +struct direct_bases +{ + typedef typelist__direct_bases(T)... type; +}; + +_GLIBCXX_END_NAMESPACE_VERSION +} +} + +#endif // _GLIBCXX_TR2_TYPE_TRAITS Index: gcc/c-family/c-common.c === --- 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 === --- gcc/c-family/c-common.h (revision 178892) +++ gcc/c-family/c-common.h (working copy) @@ -139,7 +139,8 @@ RID_IS_LITERAL_TYPE, RID_IS_POD, RID_IS_POLYMORPHIC, RID_IS_STD_LAYOUT, RID_IS_TRIVIAL, RID_IS_UNION, - RID_UNDERLYING_TYPE, + RID_UNDERLYING_TYPE, RID_BASES, + RID_DIRECT_BASES, /* C++0x */ RID_CONSTEXPR, RID_DECLTYPE, RID_NOEXCEPT, RID_NULLPTR, RID_STATIC_ASSERT, Index: gcc/cp/pt.c === --- gcc/cp/pt.c (revision 178892) +++ gcc/cp/pt.c (working copy) @@ -2976,6 +2976,9 @@ } break; +case BASES: + parameter_pack_p = true; + break; default: /* Not a parameter pack. */ break; @@ -9123,6 +9126,15 @@ tree
Re: Intrinsics for N2965: Type traits and base classes
OK. Here are some simple benchmarks. I simulated heavy use of reflection with 1000 classes that each had about a thousand base classes. I also created a super-simple typelist class templatetypename... T struct typelist {}; // Variadic templates rock If bases returns a typelist, the program takes about 4 sec. If bases returns a tuple, the program takes about 4 min. If I make the program any bigger, the tuple case fails to compile with spurious error messages, while the typelist version stays quick. Given that metaprograms typically create large class hierarchies (look at Alexandrescu's CreateScatterHierarchy that he uses to implement factory in the Modern C++ design book) and that compile times are an enormous obstacle to metaprogramming, I don't think these tests are at all ridiculous. I think this shows we need to return a typelist instead of a tuple. Yes, compelling. As I mentioned earlier, I could just return the typelist, or hide it by returning an unspecified type (which would actually be a typelist) that you would apply a first and a rest template to walk through. The interface is still simple, I like it. This would give us more flexibility for the future (e.g., if a standard typelist type is adopted. Likewise, we would be covered if wanted to change bases implementation in the future to return an associative container. For example, if using sizegrepA, basesE::type::value to count the number of occurrences of A as a base class of E turns out to be useful). This plan sounds excellent to me. -benjamin
Re: Intrinsics for N2965: Type traits and base classes
On 28 September 2011 04:22, Michael Spertus wrote: Benjamin, I think tuple is wrong both for performance reasons (I believe these are likely to be serious enough to depress use due to inordinately long compiles) and because it prematurely locks us into a rigid choice of how our typelists are implemented. My inclination is to make it type-independent by returning an unspecified type that can have a sequence of types extracted from it (this is the approach taken by boost::mpl and has loads of experience that shows it is a good approach to metaprogramming). In other words, firstbasesA::type would be the first base of A, etc. Citing Boost MPL as a good way to avoid inordinately long compiles ... interesting! Have you ever tried to reduce a GCC bug report from 20k lines to 20, because most Boost libs include every MPL header?! I hope we can get a simple typelist _without_ needing everything else in MPL, such as the apply and lambda metafunctions (and maybe a lot of that could be massively simplified using variadic templates anyway.)
Re: Intrinsics for N2965: Type traits and base classes
Don't worry, I'm not suggesting including boost::mpl at all, just leaving the return type of the bases trait unspecified. IMO, your example illustrates my point that without performance tuning, compiling metaprograms can be prohibitively expensive, so I want to avoid running the tuple metaprogram that creates the fields when we never need to instantiate the type. Benchmarks soon. Mike On 9/28/2011 2:53 AM, Jonathan Wakely wrote: On 28 September 2011 04:22, Michael Spertus wrote: Benjamin, I think tuple is wrong both for performance reasons (I believe these are likely to be serious enough to depress use due to inordinately long compiles) and because it prematurely locks us into a rigid choice of how our typelists are implemented. My inclination is to make it type-independent by returning an unspecified type that can have a sequence of types extracted from it (this is the approach taken by boost::mpl and has loads of experience that shows it is a good approach to metaprogramming). In other words, firstbasesA::type would be the first base of A, etc. Citing Boost MPL as a good way to avoid inordinately long compiles ... interesting! Have you ever tried to reduce a GCC bug report from 20k lines to 20, because most Boost libs include every MPL header?! I hope we can get a simple typelist _without_ needing everything else in MPL, such as the apply and lambda metafunctions (and maybe a lot of that could be massively simplified using variadic templates anyway.) .
Re: Intrinsics for N2965: Type traits and base classes
OK. Here are some simple benchmarks. I simulated heavy use of reflection with 1000 classes that each had about a thousand base classes. I also created a super-simple typelist class templatetypename... T struct typelist {}; // Variadic templates rock If bases returns a typelist, the program takes about 4 sec. If bases returns a tuple, the program takes about 4 min. If I make the program any bigger, the tuple case fails to compile with spurious error messages, while the typelist version stays quick. Given that metaprograms typically create large class hierarchies (look at Alexandrescu's CreateScatterHierarchy that he uses to implement factory in the Modern C++ design book) and that compile times are an enormous obstacle to metaprogramming, I don't think these tests are at all ridiculous. I think this shows we need to return a typelist instead of a tuple. As I mentioned earlier, I could just return the typelist, or hide it by returning an unspecified type (which would actually be a typelist) that you would apply a first and a rest template to walk through. This would give us more flexibility for the future (e.g., if a standard typelist type is adopted. Likewise, we would be covered if wanted to change bases implementation in the future to return an associative container. For example, if using sizegrepA, basesE::type::value to count the number of occurrences of A as a base class of E turns out to be useful). Thanks, Mike On 9/28/2011 6:54 AM, Mike Spertus wrote: Don't worry, I'm not suggesting including boost::mpl at all, just leaving the return type of the bases trait unspecified. IMO, your example illustrates my point that without performance tuning, compiling metaprograms can be prohibitively expensive, so I want to avoid running the tuple metaprogram that creates the fields when we never need to instantiate the type. Benchmarks soon. Mike On 9/28/2011 2:53 AM, Jonathan Wakely wrote: On 28 September 2011 04:22, Michael Spertus wrote: Benjamin, I think tuple is wrong both for performance reasons (I believe these are likely to be serious enough to depress use due to inordinately long compiles) and because it prematurely locks us into a rigid choice of how our typelists are implemented. My inclination is to make it type-independent by returning an unspecified type that can have a sequence of types extracted from it (this is the approach taken by boost::mpl and has loads of experience that shows it is a good approach to metaprogramming). In other words, firstbasesA::type would be the first base of A, etc. Citing Boost MPL as a good way to avoid inordinately long compiles ... interesting! Have you ever tried to reduce a GCC bug report from 20k lines to 20, because most Boost libs include every MPL header?! I hope we can get a simple typelist _without_ needing everything else in MPL, such as the apply and lambda metafunctions (and maybe a lot of that could be massively simplified using variadic templates anyway.) .
Re: Intrinsics for N2965: Type traits and base classes
Oops, this is the right patch. -benjamindiff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index a59a0b6..e1176ee 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,14 @@ 2011-09-27 Benjamin Kosnik b...@redhat.com + * doc/Makefile.am: Add tr2 support. + * doc/Makefile.in: Regenerate. + +2011-09-27 Mike Spertus mike_sper...@symantec.com + + * include/tr2/type_traits (bases, direct_bases): New. + +2011-09-27 Benjamin Kosnik b...@redhat.com + * doc/html/*: Regenerate. * doc/Makefile.am: Un-nest the ext output directory. diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 4016882..9fdaa8d 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -604,6 +604,11 @@ tr1_headers = \ ${tr1_srcdir}/wchar.h \ ${tr1_srcdir}/wctype.h +tr2_srcdir = ${glibcxx_srcdir}/include/tr2 +tr2_builddir = ./tr2 +tr2_headers = \ + ${tr2_srcdir}/type_traits + decimal_srcdir = ${glibcxx_srcdir}/include/decimal decimal_builddir = ./decimal decimal_headers = \ @@ -887,7 +892,7 @@ endif # CLEANFILES and all-local are kept up-to-date. allstamped = \ stamp-std stamp-bits stamp-bits-sup stamp-c_base stamp-c_compatibility \ - stamp-backward stamp-ext stamp-pb stamp-tr1 stamp-decimal \ + stamp-backward stamp-ext stamp-pb stamp-tr1 stamp-tr2 stamp-decimal \ stamp-debug stamp-parallel stamp-profile stamp-profile-impl \ stamp-host @@ -1002,6 +1007,11 @@ stamp-tr1: ${tr1_headers} @-cd ${tr1_builddir} $(LN_S) $? . 2/dev/null @$(STAMP) stamp-tr1 +stamp-tr2: ${tr2_headers} + @-mkdir -p ${tr2_builddir} + @-cd ${tr2_builddir} $(LN_S) $? . 2/dev/null + @$(STAMP) stamp-tr2 + stamp-decimal: ${decimal_headers} @-mkdir -p ${decimal_builddir} @-cd ${decimal_builddir} $(LN_S) $? . 2/dev/null @@ -1245,6 +1255,9 @@ install-headers: $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${tr1_builddir} for file in ${tr1_headers}; do \ $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${tr1_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${tr2_builddir} + for file in ${tr2_headers}; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${tr2_builddir}; done $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${decimal_builddir} for file in ${decimal_headers}; do \ $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${decimal_builddir}; done @@ -1291,7 +1304,7 @@ clean-local: # developer tries to create them via make in the include build # directory. (This is more of an example of how this kind of rule can # be made.) -.PRECIOUS: $(std_headers) $(c_base_headers) $(tr1_headers) +.PRECIOUS: $(std_headers) $(c_base_headers) $(tr1_headers) $(tr2_headers) $(decimal_headers) $(ext_headers) $(std_headers): ; @: $(c_base_headers): ; @: diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 58dbfc4..5ad5932 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -854,6 +854,11 @@ tr1_headers = \ ${tr1_srcdir}/wchar.h \ ${tr1_srcdir}/wctype.h +tr2_srcdir = ${glibcxx_srcdir}/include/tr2 +tr2_builddir = ./tr2 +tr2_headers = \ + ${tr2_srcdir}/type_traits + decimal_srcdir = ${glibcxx_srcdir}/include/decimal decimal_builddir = ./decimal decimal_headers = \ @@ -1125,7 +1130,7 @@ PCHFLAGS = -x c++-header -nostdinc++ $(CXXFLAGS) # CLEANFILES and all-local are kept up-to-date. allstamped = \ stamp-std stamp-bits stamp-bits-sup stamp-c_base stamp-c_compatibility \ - stamp-backward stamp-ext stamp-pb stamp-tr1 stamp-decimal \ + stamp-backward stamp-ext stamp-pb stamp-tr1 stamp-tr2 stamp-decimal \ stamp-debug stamp-parallel stamp-profile stamp-profile-impl \ stamp-host @@ -1402,6 +1407,11 @@ stamp-tr1: ${tr1_headers} @-cd ${tr1_builddir} $(LN_S) $? . 2/dev/null @$(STAMP) stamp-tr1 +stamp-tr2: ${tr2_headers} + @-mkdir -p ${tr2_builddir} + @-cd ${tr2_builddir} $(LN_S) $? . 2/dev/null + @$(STAMP) stamp-tr2 + stamp-decimal: ${decimal_headers} @-mkdir -p ${decimal_builddir} @-cd ${decimal_builddir} $(LN_S) $? . 2/dev/null @@ -1630,6 +1640,9 @@ install-headers: $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${tr1_builddir} for file in ${tr1_headers}; do \ $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${tr1_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${tr2_builddir} + for file in ${tr2_headers}; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${tr2_builddir}; done $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${decimal_builddir} for file in ${decimal_headers}; do \ $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${decimal_builddir}; done @@ -1673,7 +1686,7 @@ clean-local: # developer tries to create them via make in the include build # directory. (This is more of an example of how this kind of rule can # be made.) -.PRECIOUS: $(std_headers) $(c_base_headers) $(tr1_headers) +.PRECIOUS: $(std_headers) $(c_base_headers) $(tr1_headers)
Re: Intrinsics for N2965: Type traits and base classes
Benjamin, I think tuple is wrong both for performance reasons (I believe these are likely to be serious enough to depress use due to inordinately long compiles) and because it prematurely locks us into a rigid choice of how our typelists are implemented. My inclination is to make it type-independent by returning an unspecified type that can have a sequence of types extracted from it (this is the approach taken by boost::mpl and has loads of experience that shows it is a good approach to metaprogramming). In other words, firstbasesA::type would be the first base of A, etc. I've coded this up, and it seems to work very well without committing us to any particular typelist implementation. I don't think it has any downsides relative to tuple. I'll do a little benchmarking to compare it to tuple (I suspect it will be far faster) and then send to the library list, Mike Sent from my iPhone On Sep 27, 2011, at 9:59 PM, Benjamin Kosnik b...@redhat.com wrote: This patch consists intrinsics to properly create the bases and direct_bases of a class in the correct order (including multiple nested ambiguous virtual and non-virtual classes) for N2965 (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2965.html). This allows you to create type traits for giving the base classes of the class: templatetypename _Tp struct bases { typedef tuple__bases(_Tp)... type; }; Cool! So glad to see this. I didn't modify the standard library to include the above type trait in the patch because it is not yet clear what type it should return (e.g., a tuple, a typelist, something satisfying the requirements of a boost::mpl sequence, or a generalization of parameter packs). I have (cursorily) tested it with the above type trait and the corresponding direct_bases trait. OK. Here's a patch for the above. What's wrong with tuple? I kind of like it seems simple. It's what's in N2965, so let's start there. Since it's the first TR2 header, I did the build bits for you. Also, I cc'd the library list. best, benjamin 20110927-4.patch
Intrinsics for N2965: Type traits and base classes
This patch consists intrinsics to properly create the bases and direct_bases of a class in the correct order (including multiple nested ambiguous virtual and non-virtual classes) for N2965 (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2965.html). This allows you to create type traits for giving the base classes of the class: templatetypename _Tp struct bases { typedef tuple__bases(_Tp)... type; }; I didn't modify the standard library to include the above type trait in the patch because it is not yet clear what type it should return (e.g., a tuple, a typelist, something satisfying the requirements of a boost::mpl sequence, or a generalization of parameter packs). I have (cursorily) tested it with the above type trait and the corresponding direct_bases trait. Thanks to Jason Merrill and Benjamin Kosnik for all their help, Mike Index: gcc/c-family/c-common.c === --- 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 === --- gcc/c-family/c-common.h(revision 178892) +++ gcc/c-family/c-common.h(working copy) @@ -139,7 +139,8 @@ RID_IS_LITERAL_TYPE, RID_IS_POD, RID_IS_POLYMORPHIC, RID_IS_STD_LAYOUT, RID_IS_TRIVIAL, RID_IS_UNION, - RID_UNDERLYING_TYPE, + RID_UNDERLYING_TYPE, RID_BASES, + RID_DIRECT_BASES, /* C++0x */ RID_CONSTEXPR, RID_DECLTYPE, RID_NOEXCEPT, RID_NULLPTR, RID_STATIC_ASSERT, Index: gcc/tree.h === --- gcc/tree.h(revision 178892) +++ gcc/tree.h(working copy) @@ -21,7 +21,6 @@ #ifndef GCC_TREE_H #define GCC_TREE_H - #include hashtab.h #include machmode.h #include input.h Index: gcc/cp/pt.c === --- gcc/cp/pt.c(revision 178892) +++ gcc/cp/pt.c(working copy) @@ -2976,6 +2976,10 @@ } break; +case BASES: +case DIRECT_BASES: + parameter_pack_p = true; + break; default: /* Not a parameter pack. */ break; @@ -9123,6 +9127,16 @@ tree arg_pack = NULL_TREE; tree orig_arg = NULL_TREE; + if (TREE_CODE (parm_pack) == BASES) +{ + return calculate_bases(tsubst_expr(BASES_TYPE(parm_pack), + args, complain, in_decl, false)); +} + if (TREE_CODE (parm_pack) == DIRECT_BASES) +{ + return calculate_direct_bases(tsubst_expr(DIRECT_BASES_TYPE(parm_pack), +args, complain, in_decl, false)); +} if (TREE_CODE (parm_pack) == PARM_DECL) { if (!cp_unevaluated_operand) Index: gcc/cp/semantics.c === --- gcc/cp/semantics.c(revision 178892) +++ gcc/cp/semantics.c(working copy) @@ -3407,6 +3407,155 @@ return underlying_type; } +/* Implement the __direct_bases keyword: Return the direct base classes + of type */ +tree +calculate_direct_bases (tree type) +{ + VEC(tree, gc) *vector; + tree bases_vec = NULL_TREE; + VEC(tree, none) *base_binfos; + tree binfo; + unsigned i; + + complete_type (type); + + if (!NON_UNION_CLASS_TYPE_P (type)) +{ + return bases_vec; +} + /* Virtual bases are initialized first */ + vector = VEC_copy (tree, gc, CLASSTYPE_VBASECLASSES (type)); + + base_binfos = BINFO_BASE_BINFOS(TYPE_BINFO (complete_type (TYPE_MAIN_VARIANT (type; + for (i = 0; VEC_iterate (tree, base_binfos, i, binfo); i++) +{ + /* Now the non-virtual bases */ + if (!BINFO_VIRTUAL_P (binfo)) +{ + VEC_safe_push (tree, gc, vector, binfo); +} +} + + bases_vec = make_tree_vec (VEC_length (tree, vector)); + + for (i = 0; i VEC_length (tree, vector); ++i) +{ + TREE_VEC_ELT (bases_vec, i) = BINFO_TYPE (VEC_index (tree, vector, i)); +} + return bases_vec; +} + +tree +finish_direct_bases (tree type) +{ + tree direct_bases = NULL_TREE; + + if (!processing_template_decl) +{ + /* Parameter packs can only be used in templates */ +
Re: Intrinsics for N2965: Type traits and base classes
On 09/26/2011 11:50 AM, Mike Spertus wrote: This patch consists intrinsics to properly create the bases and direct_bases of a class Looks pretty good. Some comments: #define GCC_TREE_H - #include hashtab.h I don't see any reason to remove this blank line. + if (TREE_CODE (parm_pack) == BASES) +{ + return calculate_bases(tsubst_expr(BASES_TYPE(parm_pack), + args, complain, in_decl, false)); +} + if (TREE_CODE (parm_pack) == DIRECT_BASES) +{ + return calculate_direct_bases(tsubst_expr(DIRECT_BASES_TYPE(parm_pack), +args, complain, in_decl, false)); +} Need spaces before '(' in C code. And we usually don't put braces around a single statement. +/* Implement the __direct_bases keyword: Return the direct base classes + of type */ +tree Add a blank line between comment and return type. + if (!NON_UNION_CLASS_TYPE_P (type)) +{ + return bases_vec; +} More braces. + /* Virtual bases are initialized first */ + vector = VEC_copy (tree, gc, CLASSTYPE_VBASECLASSES (type)); This will get you indirect virtual bases as well as direct. + base_binfos = BINFO_BASE_BINFOS(TYPE_BINFO (complete_type (TYPE_MAIN_VARIANT (type; Another missing space. And you don't need either complete_type or TYPE_MAIN_VARIANT here; all variants get completed together by the complete_type earlier in the function, and TYPE_BINFO is the same for all variants. + /* First go through virtual base classes */ + for (vbases = CLASSTYPE_VBASECLASSES (type), i = 0; + VEC_iterate (tree, vbases, i, binfo); i++) +{ + VEC_safe_splice (tree, gc, vector, calculate_bases_helper (BINFO_TYPE (binfo))); +} Looks like you'll get duplicates if a virtual base itself has virtual bases. Let's release_tree_vector the returned vector after we've spliced it on. + dfs_walk_all (TYPE_BINFO (complete_type (TYPE_MAIN_VARIANT (type))), Again, TYPE_BINFO (type) should be enough. +DEFTREECODE (BASES, bases, tcc_type, 0) +DEFTREECODE (DIRECT_BASES, direct_bases, tcc_type, 0) Instead of two tree codes, let's use one and a flag. Also combine finish_bases and finish_direct_bases. Jason