diff options
author | Jason Merrill <jason@redhat.com> | 2009-07-16 16:36:10 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2009-07-16 16:36:10 -0400 |
commit | c32097d8b4fb21997c571cf6520431fa7d06090f (patch) | |
tree | 100c59a1743caa8ea59faa87406fd5f529be94f4 /gcc/cp/tree.c | |
parent | b3c5a40978985447d8ccf7d583929a4e8a78a91d (diff) | |
download | gcc-c32097d8b4fb21997c571cf6520431fa7d06090f.zip gcc-c32097d8b4fb21997c571cf6520431fa7d06090f.tar.gz gcc-c32097d8b4fb21997c571cf6520431fa7d06090f.tar.bz2 |
re PR libstdc++/37907 ([c++0x] support for std::is_standard_layout)
PR libstdc++/37907
Support std::is_standard_layout and std::is_trivial traits,
change POD to C++0x version (except for layout).
* gcc/c-common.c (c_common_reswords): Add __is_standard_layout
and __is_trivial.
* gcc/c-common.h (enum rid): Add RID_IS_STD_LAYOUT and RID_IS_TRIVIAL.
* gcc/cp/cp-tree.h (enum cp_trait_kind): Add CPTK_IS_STD_LAYOUT,
CPTK_IS_TRIVIAL.
(struct lang_type_class): Add non_std_layout.
(CLASSTYPE_NON_STD_LAYOUT): New.
* gcc/cp/class.c (check_bases): Set it.
(check_field_decls): Likewise.
(check_bases_and_members): Likewise.
* gcc/cp/parser.c (cp_parser_primary_expression): Handle RID_IS_STD_LAYOUT,
RID_IS_TRIVIAL.
(cp_parser_trait_expr): Likewise.
* gcc/cp/semantics.c (trait_expr_value): Handle CPTK_IS_STD_LAYOUT,
CPTK_IS_TRIVIAL.
(finish_trait_expr): Likewise.
* gcc/cp/tree.c (scalarish_type_p, trivial_type_p, std_layout_type_p): New.
(pod_type_p): Use them.
* gcc/cp/typeck.c (build_class_member_access_expr): Check
CLASSTYPE_NON_STD_LAYOUT rather than CLASSTYPE_NON_POD_P.
* libstdc++-v3/include/std/type_traits: Add is_standard_layout, is_trivial.
From-SVN: r149721
Diffstat (limited to 'gcc/cp/tree.c')
-rw-r--r-- | gcc/cp/tree.c | 116 |
1 files changed, 94 insertions, 22 deletions
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index a003b44..255a297 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -2238,36 +2238,108 @@ is_dummy_object (const_tree ob) && TREE_OPERAND (ob, 0) == void_zero_node); } +/* Returns 1 iff type T is something we want to treat as a scalar type for + the purpose of deciding whether it is trivial/POD/standard-layout. */ + +static bool +scalarish_type_p (const_tree t) +{ + if (t == error_mark_node) + return 1; + + return (SCALAR_TYPE_P (t) + || TREE_CODE (t) == VECTOR_TYPE); +} + +/* Returns true iff T requires non-trivial default initialization. */ + +bool +type_has_nontrivial_default_init (const_tree t) +{ + t = strip_array_types (CONST_CAST_TREE (t)); + + if (CLASS_TYPE_P (t)) + return TYPE_HAS_COMPLEX_DFLT (t); + else + return 0; +} + +/* Returns true iff copying an object of type T is non-trivial. */ + +bool +type_has_nontrivial_copy_init (const_tree t) +{ + t = strip_array_types (CONST_CAST_TREE (t)); + + if (CLASS_TYPE_P (t)) + return TYPE_HAS_COMPLEX_INIT_REF (t); + else + return 0; +} + +/* Returns 1 iff type T is a trivial type, as defined in [basic.types]. */ + +bool +trivial_type_p (const_tree t) +{ + t = strip_array_types (CONST_CAST_TREE (t)); + + if (CLASS_TYPE_P (t)) + return !(TYPE_HAS_COMPLEX_DFLT (t) + || TYPE_HAS_COMPLEX_INIT_REF (t) + || TYPE_HAS_COMPLEX_ASSIGN_REF (t) + || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)); + else + return scalarish_type_p (t); +} + /* Returns 1 iff type T is a POD type, as defined in [basic.types]. */ -int +bool pod_type_p (const_tree t) { /* This CONST_CAST is okay because strip_array_types returns its argument unmodified and we assign it to a const_tree. */ t = strip_array_types (CONST_CAST_TREE(t)); - if (t == error_mark_node) - return 1; - if (INTEGRAL_OR_ENUMERATION_TYPE_P (t)) - return 1; /* integral, character or enumeral type */ - if (FLOAT_TYPE_P (t)) - return 1; - if (TYPE_PTR_P (t)) - return 1; /* pointer to non-member */ - if (TYPE_PTR_TO_MEMBER_P (t)) - return 1; /* pointer to member */ - - if (TREE_CODE (t) == VECTOR_TYPE) - return 1; /* vectors are (small) arrays of scalars */ - - if (! RECORD_OR_UNION_CODE_P (TREE_CODE (t))) - return 0; /* other non-class type (reference or function) */ - if (! CLASS_TYPE_P (t)) - return 1; /* struct created by the back end */ - if (CLASSTYPE_NON_POD_P (t)) - return 0; - return 1; + if (CLASS_TYPE_P (t)) + /* [class]/10: A POD struct is a class that is both a trivial class and a + standard-layout class, and has no non-static data members of type + non-POD struct, non-POD union (or array of such types). + + We don't need to check individual members because if a member is + non-std-layout or non-trivial, the class will be too. */ + return (std_layout_type_p (t) && trivial_type_p (t)); + else + return scalarish_type_p (t); +} + +/* Returns true iff T is POD for the purpose of layout, as defined in the + C++ ABI. */ + +bool +layout_pod_type_p (const_tree t) +{ + t = strip_array_types (CONST_CAST_TREE (t)); + + if (CLASS_TYPE_P (t)) + return !CLASSTYPE_NON_LAYOUT_POD_P (t); + else + return scalarish_type_p (t); +} + +/* Returns true iff T is a standard-layout type, as defined in + [basic.types]. */ + +bool +std_layout_type_p (const_tree t) +{ + t = strip_array_types (CONST_CAST_TREE (t)); + + if (CLASS_TYPE_P (t)) + return !CLASSTYPE_NON_STD_LAYOUT (t); + else + return scalarish_type_p (t); } /* Nonzero iff type T is a class template implicit specialization. */ |