cjdb updated this revision to Diff 421836. cjdb edited the summary of this revision. cjdb added a comment. Herald added a project: All.
adds `__is_copy_constructible`, `__is_copy_assignable`, `__is_move_constructible` (WIP), and `__is_move_assignable` (incomplete) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D116280/new/ https://reviews.llvm.org/D116280 Files: clang/include/clang/Basic/TokenKinds.def clang/include/clang/Sema/Sema.h clang/lib/Parse/ParseDeclCXX.cpp clang/lib/Parse/ParseExpr.cpp clang/lib/Sema/SemaExprCXX.cpp clang/lib/Sema/SemaType.cpp clang/test/SemaCXX/type-traits.cpp
Index: clang/test/SemaCXX/type-traits.cpp =================================================================== --- clang/test/SemaCXX/type-traits.cpp +++ clang/test/SemaCXX/type-traits.cpp @@ -345,11 +345,19 @@ } typedef Enum EnumType; +typedef EnumClass EnumClassType; void is_enum() { { int arr[T(__is_enum(Enum))]; } { int arr[T(__is_enum(EnumType))]; } + { int arr[T(__is_enum(SignedEnum))]; } + { int arr[T(__is_enum(UnsignedEnum))]; } + + { int arr[T(__is_enum(EnumClass))]; } + { int arr[T(__is_enum(EnumClassType))]; } + { int arr[T(__is_enum(SignedEnumClass))]; } + { int arr[T(__is_enum(UnsignedEnumClass))]; } { int arr[F(__is_enum(int))]; } { int arr[F(__is_enum(Union))]; } @@ -363,6 +371,30 @@ { int arr[F(__is_enum(HasAnonymousUnion))]; } } +void is_scoped_enum() +{ + { int arr[F(__is_scoped_enum(Enum))]; } + { int arr[F(__is_scoped_enum(EnumType))]; } + { int arr[F(__is_scoped_enum(SignedEnum))]; } + { int arr[F(__is_scoped_enum(UnsignedEnum))]; } + + { int arr[T(__is_scoped_enum(EnumClass))]; } + { int arr[T(__is_scoped_enum(EnumClassType))]; } + { int arr[T(__is_scoped_enum(SignedEnumClass))]; } + { int arr[T(__is_scoped_enum(UnsignedEnumClass))]; } + + { int arr[F(__is_scoped_enum(int))]; } + { int arr[F(__is_scoped_enum(Union))]; } + { int arr[F(__is_scoped_enum(Int))]; } + { int arr[F(__is_scoped_enum(IntAr))]; } + { int arr[F(__is_scoped_enum(UnionAr))]; } + { int arr[F(__is_scoped_enum(Derives))]; } + { int arr[F(__is_scoped_enum(ClassType))]; } + { int arr[F(__is_scoped_enum(cvoid))]; } + { int arr[F(__is_scoped_enum(IntArNB))]; } + { int arr[F(__is_scoped_enum(HasAnonymousUnion))]; } +} + struct FinalClass final { }; @@ -702,6 +734,66 @@ int t31[F(__is_array(cvoid*))]; } +void is_bounded_array() +{ + int t01[T(__is_bounded_array(IntAr))]; + int t02[F(__is_bounded_array(IntArNB))]; + int t03[T(__is_bounded_array(UnionAr))]; + + int t10[F(__is_bounded_array(void))]; + int t11[F(__is_bounded_array(cvoid))]; + int t12[F(__is_bounded_array(float))]; + int t13[F(__is_bounded_array(double))]; + int t14[F(__is_bounded_array(long double))]; + int t15[F(__is_bounded_array(bool))]; + int t16[F(__is_bounded_array(char))]; + int t17[F(__is_bounded_array(signed char))]; + int t18[F(__is_bounded_array(unsigned char))]; + int t19[F(__is_bounded_array(wchar_t))]; + int t20[F(__is_bounded_array(short))]; + int t21[F(__is_bounded_array(unsigned short))]; + int t22[F(__is_bounded_array(int))]; + int t23[F(__is_bounded_array(unsigned int))]; + int t24[F(__is_bounded_array(long))]; + int t25[F(__is_bounded_array(unsigned long))]; + int t26[F(__is_bounded_array(Union))]; + int t27[F(__is_bounded_array(Derives))]; + int t28[F(__is_bounded_array(ClassType))]; + int t29[F(__is_bounded_array(Enum))]; + int t30[F(__is_bounded_array(void*))]; + int t31[F(__is_bounded_array(cvoid*))]; +} + +void is_unbounded_array() +{ + int t01[F(__is_unbounded_array(IntAr))]; + int t02[T(__is_unbounded_array(IntArNB))]; + int t03[F(__is_unbounded_array(UnionAr))]; + + int t10[F(__is_unbounded_array(void))]; + int t11[F(__is_unbounded_array(cvoid))]; + int t12[F(__is_unbounded_array(float))]; + int t13[F(__is_unbounded_array(double))]; + int t14[F(__is_unbounded_array(long double))]; + int t15[F(__is_unbounded_array(bool))]; + int t16[F(__is_unbounded_array(char))]; + int t17[F(__is_unbounded_array(signed char))]; + int t18[F(__is_unbounded_array(unsigned char))]; + int t19[F(__is_unbounded_array(wchar_t))]; + int t20[F(__is_unbounded_array(short))]; + int t21[F(__is_unbounded_array(unsigned short))]; + int t22[F(__is_unbounded_array(int))]; + int t23[F(__is_unbounded_array(unsigned int))]; + int t24[F(__is_unbounded_array(long))]; + int t25[F(__is_unbounded_array(unsigned long))]; + int t26[F(__is_unbounded_array(Union))]; + int t27[F(__is_unbounded_array(Derives))]; + int t28[F(__is_unbounded_array(ClassType))]; + int t29[F(__is_unbounded_array(Enum))]; + int t30[F(__is_unbounded_array(void*))]; + int t31[F(__is_unbounded_array(cvoid*))]; +} + template <typename T> void tmpl_func(T&) {} template <typename T> struct type_wrapper { @@ -934,6 +1026,43 @@ int t34[F(__is_pointer(void (StructWithMembers::*) ()))]; } +void is_null_pointer() +{ + StructWithMembers x; + + int t00[T(__is_nullptr(decltype(nullptr)))]; + int t01[F(__is_nullptr(void*))]; + int t02[F(__is_nullptr(cvoid*))]; + int t03[F(__is_nullptr(cvoid*))]; + int t04[F(__is_nullptr(char*))]; + int t05[F(__is_nullptr(int*))]; + int t06[F(__is_nullptr(int**))]; + int t07[F(__is_nullptr(ClassType*))]; + int t08[F(__is_nullptr(Derives*))]; + int t09[F(__is_nullptr(Enum*))]; + int t10[F(__is_nullptr(IntArNB*))]; + int t11[F(__is_nullptr(Union*))]; + int t12[F(__is_nullptr(UnionAr*))]; + int t13[F(__is_nullptr(StructWithMembers*))]; + int t14[F(__is_nullptr(void (*)()))]; + + int t20[F(__is_nullptr(void))]; + int t21[F(__is_nullptr(cvoid))]; + int t22[F(__is_nullptr(cvoid))]; + int t23[F(__is_nullptr(char))]; + int t24[F(__is_nullptr(int))]; + int t25[F(__is_nullptr(int))]; + int t26[F(__is_nullptr(ClassType))]; + int t27[F(__is_nullptr(Derives))]; + int t28[F(__is_nullptr(Enum))]; + int t29[F(__is_nullptr(IntArNB))]; + int t30[F(__is_nullptr(Union))]; + int t31[F(__is_nullptr(UnionAr))]; + int t32[F(__is_nullptr(StructWithMembers))]; + int t33[F(__is_nullptr(int StructWithMembers::*))]; + int t34[F(__is_nullptr(void (StructWithMembers::*) ()))]; +} + void is_member_object_pointer() { StructWithMembers x; @@ -1481,8 +1610,8 @@ typedef const IntAr ConstIntAr; typedef ConstIntAr ConstIntArAr[4]; -struct HasCopy { - HasCopy(HasCopy& cp); +struct HasMutableCopyCtor { + HasMutableCopyCtor(HasMutableCopyCtor& cp); }; struct HasMove { @@ -1518,7 +1647,7 @@ { int arr[F(__has_trivial_constructor(AnIncompleteType[]))]; } // expected-error {{incomplete type}} { int arr[F(__has_trivial_constructor(HasCons))]; } { int arr[F(__has_trivial_constructor(HasRef))]; } - { int arr[F(__has_trivial_constructor(HasCopy))]; } + { int arr[F(__has_trivial_constructor(HasMutableCopyCtor))]; } { int arr[F(__has_trivial_constructor(IntRef))]; } { int arr[F(__has_trivial_constructor(VirtAr))]; } { int arr[F(__has_trivial_constructor(void))]; } @@ -1581,7 +1710,7 @@ { int arr[T(__has_trivial_copy(ACompleteType[]))]; } { int arr[F(__has_trivial_copy(AnIncompleteType[]))]; } // expected-error {{incomplete type}} - { int arr[F(__has_trivial_copy(HasCopy))]; } + { int arr[F(__has_trivial_copy(HasMutableCopyCtor))]; } { int arr[F(__has_trivial_copy(HasTemplateCons))]; } { int arr[F(__has_trivial_copy(VirtAr))]; } { int arr[F(__has_trivial_copy(void))]; } @@ -1601,7 +1730,7 @@ { int arr[T(__has_trivial_assign(HasPriv))]; } { int arr[T(__has_trivial_assign(HasCons))]; } { int arr[T(__has_trivial_assign(HasRef))]; } - { int arr[T(__has_trivial_assign(HasCopy))]; } + { int arr[T(__has_trivial_assign(HasMutableCopyCtor))]; } { int arr[T(__has_trivial_assign(HasMove))]; } { int arr[T(__has_trivial_assign(HasMoveAssign))]; } { int arr[T(__has_trivial_assign(AllDefaulted))]; } @@ -1635,7 +1764,7 @@ { int arr[T(__has_trivial_destructor(HasPriv))]; } { int arr[T(__has_trivial_destructor(HasCons))]; } { int arr[T(__has_trivial_destructor(HasRef))]; } - { int arr[T(__has_trivial_destructor(HasCopy))]; } + { int arr[T(__has_trivial_destructor(HasMutableCopyCtor))]; } { int arr[T(__has_trivial_destructor(HasMove))]; } { int arr[T(__has_trivial_destructor(IntRef))]; } { int arr[T(__has_trivial_destructor(HasCopyAssign))]; } @@ -1692,7 +1821,7 @@ { int arr[T(__has_nothrow_assign(HasPriv))]; } { int arr[T(__has_nothrow_assign(HasCons))]; } { int arr[T(__has_nothrow_assign(HasRef))]; } - { int arr[T(__has_nothrow_assign(HasCopy))]; } + { int arr[T(__has_nothrow_assign(HasMutableCopyCtor))]; } { int arr[T(__has_nothrow_assign(HasMove))]; } { int arr[T(__has_nothrow_assign(HasMoveAssign))]; } { int arr[T(__has_nothrow_assign(HasNoThrowCopyAssign))]; } @@ -1801,7 +1930,7 @@ { int arr[T(__has_nothrow_copy(ACompleteType[]))]; } { int arr[F(__has_nothrow_copy(AnIncompleteType[]))]; } // expected-error {{incomplete type}} - { int arr[F(__has_nothrow_copy(HasCopy))]; } + { int arr[F(__has_nothrow_copy(HasMutableCopyCtor))]; } { int arr[F(__has_nothrow_copy(HasMultipleCopy))]; } { int arr[F(__has_nothrow_copy(VirtAr))]; } { int arr[F(__has_nothrow_copy(void))]; } @@ -1831,7 +1960,7 @@ { int arr[F(__has_nothrow_constructor(AnIncompleteType[]))]; } // expected-error {{incomplete type}} { int arr[F(__has_nothrow_constructor(HasCons))]; } { int arr[F(__has_nothrow_constructor(HasRef))]; } - { int arr[F(__has_nothrow_constructor(HasCopy))]; } + { int arr[F(__has_nothrow_constructor(HasMutableCopyCtor))]; } { int arr[F(__has_nothrow_constructor(HasMove))]; } { int arr[F(__has_nothrow_constructor(HasNoThrowConstructorWithArgs))]; } { int arr[F(__has_nothrow_constructor(IntRef))]; } @@ -1858,7 +1987,7 @@ { int arr[F(__has_virtual_destructor(HasPriv))]; } { int arr[F(__has_virtual_destructor(HasCons))]; } { int arr[F(__has_virtual_destructor(HasRef))]; } - { int arr[F(__has_virtual_destructor(HasCopy))]; } + { int arr[F(__has_virtual_destructor(HasMutableCopyCtor))]; } { int arr[F(__has_virtual_destructor(HasMove))]; } { int arr[F(__has_virtual_destructor(HasCopyAssign))]; } { int arr[F(__has_virtual_destructor(HasMoveAssign))]; } @@ -2325,6 +2454,467 @@ { int arr[F(__is_nothrow_constructible(const volatile void))]; } } +struct VolatileCopyCtor { + VolatileCopyCtor(volatile VolatileCopyCtor&); +}; + +struct CVCopyCtor { + CVCopyCtor(const volatile CVCopyCtor&); +}; + +struct CopyCtorDeleted { + CopyCtorDeleted(const CopyCtorDeleted&) = delete; +}; + +struct BaseDeletedCopyCtor : CopyCtorDeleted {}; + +struct MemberDeletedCopyCtor { + CopyCtorDeleted x; +}; + +template<bool expected, typename T> +void copy_constructible_checks_impl() { + { int arr[T(__is_copy_constructible(T) == expected)]; } // expected-error{{incomplete type}} + { int arr[T(__is_copy_constructible(const T) == expected)]; } // expected-error{{incomplete type}} + { int arr[T(__is_copy_constructible(volatile T) == expected)]; } // expected-error{{incomplete type}} + { int arr[T(__is_copy_constructible(const volatile T) == expected)]; } // expected-error{{incomplete type}} +} + +void copy_constructible_checks() { + // Builtin types + copy_constructible_checks_impl<true, int>(); + copy_constructible_checks_impl<false, int&>(); + copy_constructible_checks_impl<false, int&&>(); + copy_constructible_checks_impl<true, int*>(); + copy_constructible_checks_impl<false, int[5]>(); + copy_constructible_checks_impl<false, int[]>(); + copy_constructible_checks_impl<true, decltype(nullptr)>(); + copy_constructible_checks_impl<true, void(*)()>(); + copy_constructible_checks_impl<false, void(&)()>(); + copy_constructible_checks_impl<true, int Empty::*>(); + copy_constructible_checks_impl<true, int (Empty::*)()>(); + copy_constructible_checks_impl<true, int (Empty::*)() const>(); + copy_constructible_checks_impl<true, int (Empty::*)() volatile>(); + copy_constructible_checks_impl<true, int (Empty::*)() const volatile>(); + copy_constructible_checks_impl<true, int (Empty::*)()&>(); + copy_constructible_checks_impl<true, int (Empty::*)() const&>(); + copy_constructible_checks_impl<true, int (Empty::*)() volatile&>(); + copy_constructible_checks_impl<true, int (Empty::*)() const volatile&>(); + copy_constructible_checks_impl<true, int (Empty::*)() &&>(); + copy_constructible_checks_impl<true, int (Empty::*)() const&&>(); + copy_constructible_checks_impl<true, int (Empty::*)() volatile&&>(); + copy_constructible_checks_impl<true, int (Empty::*)() const volatile&&>(); + + // // User-defined types + copy_constructible_checks_impl<true, AllDefaulted>(); + copy_constructible_checks_impl<true, AllDefaulted>(); + copy_constructible_checks_impl<true, CEmptyStruct>(); + copy_constructible_checks_impl<true, CppEmptyStruct>(); + copy_constructible_checks_impl<true, CppStructNonStandardBy2ndVirtBase>(); + copy_constructible_checks_impl<true, CppStructNonStandardByBase>(); + copy_constructible_checks_impl<true, CppStructNonStandardByMemb>(); + copy_constructible_checks_impl<true, CppStructNonStandardByProt>(); + copy_constructible_checks_impl<true, CppStructNonStandardBySameBase>(); + copy_constructible_checks_impl<true, CppStructNonStandardByVirt>(); + copy_constructible_checks_impl<true, CppStructNonStandardByVirtBase>(); + copy_constructible_checks_impl<true, CppStructStandard>(); + copy_constructible_checks_impl<true, CStruct>(); + copy_constructible_checks_impl<true, CVCopyCtor>(); + copy_constructible_checks_impl<true, Derives>(); + copy_constructible_checks_impl<true, DerivesHasRef>(); + copy_constructible_checks_impl<true, Empty>(); + copy_constructible_checks_impl<true, EmptyUnion>(); + copy_constructible_checks_impl<true, Enum>(); + copy_constructible_checks_impl<true, EnumClass>(); + copy_constructible_checks_impl<true, ExtDefaulted>(); + copy_constructible_checks_impl<true, ExtDefaulted>(); + copy_constructible_checks_impl<true, HasCons>(); + copy_constructible_checks_impl<true, HasCopyAssign>(); + copy_constructible_checks_impl<true, HasDest>(); + copy_constructible_checks_impl<true, HasMultipleCopy>(); + copy_constructible_checks_impl<true, HasPriv>(); + copy_constructible_checks_impl<true, HasRef>(); + copy_constructible_checks_impl<true, HasTemplateCons>(); + copy_constructible_checks_impl<true, NoDefaultMoveAssignDueToDtor>(); + copy_constructible_checks_impl<true, NoDefaultMoveAssignDueToUDCopyAssign>(); + copy_constructible_checks_impl<true, NoDefaultMoveAssignDueToUDCopyCtor>(); + copy_constructible_checks_impl<true, NonTCStruct>(); + copy_constructible_checks_impl<true, NonTrivialStruct>(); + copy_constructible_checks_impl<true, POD>(); + copy_constructible_checks_impl<true, SuperNonTrivialStruct>(); + copy_constructible_checks_impl<true, TrivialStruct>(); + copy_constructible_checks_impl<true, Union>(); + + copy_constructible_checks_impl<false, AllDeleted>(); + copy_constructible_checks_impl<false, AllPrivate>(); + copy_constructible_checks_impl<false, AnIncompleteType[]>(); + copy_constructible_checks_impl<false, AnIncompleteType>(); // expected-note{{in instantiation of function template specialization}} + copy_constructible_checks_impl<false, BaseDeletedCopyCtor>(); + copy_constructible_checks_impl<false, CopyCtorDeleted>(); + copy_constructible_checks_impl<false, HasMutableCopyCtor>(); + copy_constructible_checks_impl<false, HasMove>(); + copy_constructible_checks_impl<false, HasMoveAssign>(); + copy_constructible_checks_impl<false, MemberDeletedCopyCtor>(); + copy_constructible_checks_impl<false, VirtAr>(); + copy_constructible_checks_impl<false, VolatileCopyCtor>(); + + // Non-referencable types + copy_constructible_checks_impl<false, void>(); + copy_constructible_checks_impl<false, void()>(); + copy_constructible_checks_impl<false, void() const>(); + copy_constructible_checks_impl<false, void() volatile>(); + copy_constructible_checks_impl<false, void() const volatile>(); + copy_constructible_checks_impl<false, void() &>(); + copy_constructible_checks_impl<false, void() const &>(); + copy_constructible_checks_impl<false, void() volatile &>(); + copy_constructible_checks_impl<false, void() const volatile &>(); + copy_constructible_checks_impl<false, void() &&>(); + copy_constructible_checks_impl<false, void() const &&>(); + copy_constructible_checks_impl<false, void() volatile &&>(); + copy_constructible_checks_impl<false, void() const volatile &&>(); +} + +struct ConstMoveCtor { + ConstMoveCtor(const ConstMoveCtor&&); +}; + +struct VolatileMoveCtor { + VolatileMoveCtor(volatile VolatileMoveCtor&&); +}; + +struct CVMoveCtor { + CVMoveCtor(const volatile CVMoveCtor&&); +}; + +struct MoveCtorDeleted { + MoveCtorDeleted(MoveCtorDeleted&&) = delete; +}; + +struct BaseDeletedMoveCtor : MoveCtorDeleted {}; + +struct MemberDeletedMoveCtor { + MoveCtorDeleted x; +}; + +template<bool expected, typename T> +void move_constructible_checks_impl() { + { int arr[T(__is_move_constructible(T) == expected)]; } // expected-error{{incomplete type}} + { int arr[T(__is_move_constructible(const T) == expected)]; } // expected-error{{incomplete type}} + { int arr[T(__is_move_constructible(volatile T) == expected)]; } // expected-error{{incomplete type}} + { int arr[T(__is_move_constructible(const volatile T) == expected)]; } // expected-error{{incomplete type}} +} + +void move_constructible_checks() { + // Builtin types + move_constructible_checks_impl<true, int>(); + move_constructible_checks_impl<true, int&>(); + move_constructible_checks_impl<true, int&&>(); + move_constructible_checks_impl<true, int*>(); + move_constructible_checks_impl<false, int[5]>(); + move_constructible_checks_impl<false, int[]>(); + move_constructible_checks_impl<true, decltype(nullptr)>(); + move_constructible_checks_impl<true, void(*)()>(); + move_constructible_checks_impl<true, void(&)()>(); + move_constructible_checks_impl<true, int Empty::*>(); + move_constructible_checks_impl<true, int (Empty::*)()>(); + move_constructible_checks_impl<true, int (Empty::*)() const>(); + move_constructible_checks_impl<true, int (Empty::*)() volatile>(); + move_constructible_checks_impl<true, int (Empty::*)() const volatile>(); + move_constructible_checks_impl<true, int (Empty::*)()&>(); + move_constructible_checks_impl<true, int (Empty::*)() const&>(); + move_constructible_checks_impl<true, int (Empty::*)() volatile&>(); + move_constructible_checks_impl<true, int (Empty::*)() const volatile&>(); + move_constructible_checks_impl<true, int (Empty::*)() &&>(); + move_constructible_checks_impl<true, int (Empty::*)() const&&>(); + move_constructible_checks_impl<true, int (Empty::*)() volatile&&>(); + move_constructible_checks_impl<true, int (Empty::*)() const volatile&&>(); + + // // User-defined types + move_constructible_checks_impl<true, AllDefaulted>(); + move_constructible_checks_impl<true, AllDefaulted>(); + move_constructible_checks_impl<true, CEmptyStruct>(); + move_constructible_checks_impl<true, ConstMoveCtor>(); + move_constructible_checks_impl<true, CppEmptyStruct>(); + move_constructible_checks_impl<true, CppStructNonStandardBy2ndVirtBase>(); + move_constructible_checks_impl<true, CppStructNonStandardByBase>(); + move_constructible_checks_impl<true, CppStructNonStandardByMemb>(); + move_constructible_checks_impl<true, CppStructNonStandardByProt>(); + move_constructible_checks_impl<true, CppStructNonStandardBySameBase>(); + move_constructible_checks_impl<true, CppStructNonStandardByVirt>(); + move_constructible_checks_impl<true, CppStructNonStandardByVirtBase>(); + move_constructible_checks_impl<true, CppStructStandard>(); + move_constructible_checks_impl<true, CStruct>(); + move_constructible_checks_impl<true, CVMoveCtor>(); + move_constructible_checks_impl<true, Derives>(); + move_constructible_checks_impl<true, DerivesHasRef>(); + move_constructible_checks_impl<true, Empty>(); + move_constructible_checks_impl<true, EmptyUnion>(); + move_constructible_checks_impl<true, Enum>(); + move_constructible_checks_impl<true, EnumClass>(); + move_constructible_checks_impl<true, ExtDefaulted>(); + move_constructible_checks_impl<true, ExtDefaulted>(); + move_constructible_checks_impl<true, HasCons>(); + move_constructible_checks_impl<true, HasCopyAssign>(); + move_constructible_checks_impl<true, HasDest>(); + move_constructible_checks_impl<true, HasMove>(); + move_constructible_checks_impl<true, HasPriv>(); + move_constructible_checks_impl<true, HasRef>(); + move_constructible_checks_impl<true, HasTemplateCons>(); + move_constructible_checks_impl<true, NoDefaultMoveAssignDueToDtor>(); + move_constructible_checks_impl<true, NoDefaultMoveAssignDueToUDCopyAssign>(); + move_constructible_checks_impl<true, NoDefaultMoveAssignDueToUDCopyCtor>(); + move_constructible_checks_impl<true, NonTCStruct>(); + move_constructible_checks_impl<true, NonTrivialStruct>(); + move_constructible_checks_impl<true, POD>(); + move_constructible_checks_impl<true, SuperNonTrivialStruct>(); + move_constructible_checks_impl<true, TrivialStruct>(); + move_constructible_checks_impl<true, Union>(); + move_constructible_checks_impl<true, VolatileMoveCtor>(); + + move_constructible_checks_impl<false, AllDeleted>(); + move_constructible_checks_impl<false, AllPrivate>(); + move_constructible_checks_impl<false, AnIncompleteType[]>(); + move_constructible_checks_impl<false, AnIncompleteType>(); // expected-note{{in instantiation of function template specialization}} + move_constructible_checks_impl<false, BaseDeletedCopyCtor>(); + move_constructible_checks_impl<false, BaseDeletedCopyCtor>(); + move_constructible_checks_impl<false, BaseDeletedMoveCtor>(); + move_constructible_checks_impl<false, CopyCtorDeleted>(); + move_constructible_checks_impl<false, CopyCtorDeleted>(); + move_constructible_checks_impl<false, CVCopyCtor>(); + move_constructible_checks_impl<false, HasMutableCopyCtor>(); + move_constructible_checks_impl<false, HasMoveAssign>(); + move_constructible_checks_impl<false, MemberDeletedCopyCtor>(); + move_constructible_checks_impl<false, MemberDeletedCopyCtor>(); + move_constructible_checks_impl<false, MemberDeletedMoveCtor>(); + move_constructible_checks_impl<false, MoveCtorDeleted>(); + move_constructible_checks_impl<false, VirtAr>(); + move_constructible_checks_impl<false, VolatileCopyCtor>(); + + // Non-referencable types + move_constructible_checks_impl<false, void>(); + move_constructible_checks_impl<false, void()>(); + move_constructible_checks_impl<false, void() const>(); + move_constructible_checks_impl<false, void() volatile>(); + move_constructible_checks_impl<false, void() const volatile>(); + move_constructible_checks_impl<false, void() &>(); + move_constructible_checks_impl<false, void() const &>(); + move_constructible_checks_impl<false, void() volatile &>(); + move_constructible_checks_impl<false, void() const volatile &>(); + move_constructible_checks_impl<false, void() &&>(); + move_constructible_checks_impl<false, void() const &&>(); + move_constructible_checks_impl<false, void() volatile &&>(); + move_constructible_checks_impl<false, void() const volatile &&>(); +} + +template<bool expected, typename T> +void copy_assignable_checks_impl() { + { int arr[T(__is_copy_assignable(T) == expected)]; } // expected-error{{incomplete type}} + // { int arr[F(__is_copy_assignable(const T))]; } // expected-erxror{{incomplete type}} + // { int arr[F(__is_copy_assignable(volatile T))]; } // expectexd-error{{incomplete type}} + // { int arr[F(__is_copy_assignable(const volatile T))]; } // xexpected-error{{incomplete type}} +} + +struct MutableCopyAssign_QualNone { MutableCopyAssign_QualNone& operator=(MutableCopyAssign_QualNone&); }; +struct MutableCopyAssign_QualConst { MutableCopyAssign_QualConst& operator=(MutableCopyAssign_QualConst&) const; }; +struct MutableCopyAssign_QualVolatile { MutableCopyAssign_QualVolatile& operator=(MutableCopyAssign_QualVolatile&) volatile; }; +struct MutableCopyAssign_QualCV { MutableCopyAssign_QualCV& operator=(MutableCopyAssign_QualCV&) const volatile; }; +struct MutableCopyAssign_QualLvalue { MutableCopyAssign_QualLvalue& operator=(MutableCopyAssign_QualLvalue&)&; }; +struct MutableCopyAssign_QualConstLvalue { MutableCopyAssign_QualConstLvalue& operator=(MutableCopyAssign_QualConstLvalue&) const&; }; +struct MutableCopyAssign_QualVolatileLvalue { MutableCopyAssign_QualVolatileLvalue& operator=(MutableCopyAssign_QualVolatileLvalue&) volatile&; }; +struct MutableCopyAssign_QualCVLvalue { MutableCopyAssign_QualCVLvalue& operator=(MutableCopyAssign_QualCVLvalue&) const volatile&; }; +struct MutableCopyAssign_QualRvalue { MutableCopyAssign_QualRvalue& operator=(MutableCopyAssign_QualRvalue&)&&; }; +struct MutableCopyAssign_QualConstRvalue { MutableCopyAssign_QualConstRvalue& operator=(MutableCopyAssign_QualConstRvalue&) const&&; }; +struct MutableCopyAssign_QualVolatileRvalue { MutableCopyAssign_QualVolatileRvalue& operator=(MutableCopyAssign_QualVolatileRvalue&) volatile&&; }; +struct MutableCopyAssign_QualCVRvalue { MutableCopyAssign_QualCVRvalue& operator=(MutableCopyAssign_QualCVRvalue&) const volatile&&; }; + +struct CopyAssign_QualNone { CopyAssign_QualNone& operator=(const CopyAssign_QualNone&); }; +struct CopyAssign_QualConst { CopyAssign_QualConst& operator=(const CopyAssign_QualConst&) const; }; +struct CopyAssign_QualVolatile { CopyAssign_QualVolatile& operator=(const CopyAssign_QualVolatile&) volatile; }; +struct CopyAssign_QualCV { CopyAssign_QualCV& operator=(const CopyAssign_QualCV&) const volatile; }; +struct CopyAssign_QualLvalue { CopyAssign_QualLvalue& operator=(const CopyAssign_QualLvalue&)&; }; +struct CopyAssign_QualConstLvalue { CopyAssign_QualConstLvalue& operator=(const CopyAssign_QualConstLvalue&) const&; }; +struct CopyAssign_QualVolatileLvalue { CopyAssign_QualVolatileLvalue& operator=(const CopyAssign_QualVolatileLvalue&) volatile&; }; +struct CopyAssign_QualCVLvalue { CopyAssign_QualCVLvalue& operator=(const CopyAssign_QualCVLvalue&) const volatile&; }; +struct CopyAssign_QualRvalue { CopyAssign_QualRvalue& operator=(const CopyAssign_QualRvalue&)&&; }; +struct CopyAssign_QualConstRvalue { CopyAssign_QualConstRvalue& operator=(const CopyAssign_QualConstRvalue&) const&&; }; +struct CopyAssign_QualVolatileRvalue { CopyAssign_QualVolatileRvalue& operator=(const CopyAssign_QualVolatileRvalue&) volatile&&; }; +struct CopyAssign_QualCVRvalue { CopyAssign_QualCVRvalue& operator=(const CopyAssign_QualCVRvalue&) const volatile&&; }; + +struct VolatileCopyAssign_QualNone { VolatileCopyAssign_QualNone& operator=(volatile VolatileCopyAssign_QualNone&); }; +struct VolatileCopyAssign_QualConst { VolatileCopyAssign_QualConst& operator=(volatile VolatileCopyAssign_QualConst&) const; }; +struct VolatileCopyAssign_QualVolatile { VolatileCopyAssign_QualVolatile& operator=(volatile VolatileCopyAssign_QualVolatile&) volatile; }; +struct VolatileCopyAssign_QualCV { VolatileCopyAssign_QualCV& operator=(volatile VolatileCopyAssign_QualCV&) const volatile; }; +struct VolatileCopyAssign_QualLvalue { VolatileCopyAssign_QualLvalue& operator=(volatile VolatileCopyAssign_QualLvalue&)&; }; +struct VolatileCopyAssign_QualConstLvalue { VolatileCopyAssign_QualConstLvalue& operator=(volatile VolatileCopyAssign_QualConstLvalue&) const&; }; +struct VolatileCopyAssign_QualVolatileLvalue { VolatileCopyAssign_QualVolatileLvalue& operator=(volatile VolatileCopyAssign_QualVolatileLvalue&) volatile&; }; +struct VolatileCopyAssign_QualCVLvalue { VolatileCopyAssign_QualCVLvalue& operator=(volatile VolatileCopyAssign_QualCVLvalue&) const volatile&; }; +struct VolatileCopyAssign_QualRvalue { VolatileCopyAssign_QualRvalue& operator=(volatile VolatileCopyAssign_QualRvalue&)&&; }; +struct VolatileCopyAssign_QualConstRvalue { VolatileCopyAssign_QualConstRvalue& operator=(volatile VolatileCopyAssign_QualConstRvalue&) const&&; }; +struct VolatileCopyAssign_QualVolatileRvalue { VolatileCopyAssign_QualVolatileRvalue& operator=(volatile VolatileCopyAssign_QualVolatileRvalue&) volatile&&; }; +struct VolatileCopyAssign_QualCVRvalue { VolatileCopyAssign_QualCVRvalue& operator=(volatile VolatileCopyAssign_QualCVRvalue&) const volatile&&; }; + +struct CVCopyAssign_QualNone { CVCopyAssign_QualNone& operator=(const volatile CVCopyAssign_QualNone&); }; +struct CVCopyAssign_QualConst { CVCopyAssign_QualConst& operator=(const volatile CVCopyAssign_QualConst&) const; }; +struct CVCopyAssign_QualVolatile { CVCopyAssign_QualVolatile& operator=(const volatile CVCopyAssign_QualVolatile&) volatile; }; +struct CVCopyAssign_QualCV { CVCopyAssign_QualCV& operator=(const volatile CVCopyAssign_QualCV&) const volatile; }; +struct CVCopyAssign_QualLvalue { CVCopyAssign_QualLvalue& operator=(const volatile CVCopyAssign_QualLvalue&)&; }; +struct CVCopyAssign_QualConstLvalue { CVCopyAssign_QualConstLvalue& operator=(const volatile CVCopyAssign_QualConstLvalue&) const&; }; +struct CVCopyAssign_QualCVLvalue { CVCopyAssign_QualCVLvalue& operator=(const volatile CVCopyAssign_QualCVLvalue&) volatile&; }; +struct CVCopyAssign_QualVolatileLvalue { CVCopyAssign_QualVolatileLvalue& operator=(const volatile CVCopyAssign_QualVolatileLvalue&) const volatile&; }; +struct CVCopyAssign_QualRvalue { CVCopyAssign_QualRvalue& operator=(const volatile CVCopyAssign_QualRvalue&)&&; }; +struct CVCopyAssign_QualConstRvalue { CVCopyAssign_QualConstRvalue& operator=(const volatile CVCopyAssign_QualConstRvalue&) const&&; }; +struct CVCopyAssign_QualVolatileRvalue { CVCopyAssign_QualVolatileRvalue& operator=(const volatile CVCopyAssign_QualVolatileRvalue&) volatile&&; }; +struct CVCopyAssign_QualCVRvalue { CVCopyAssign_QualCVRvalue& operator=(const volatile CVCopyAssign_QualCVRvalue&) const volatile&&; }; +struct CopyAssignDeleted { CopyAssignDeleted& operator=(const CopyAssignDeleted&) = delete; }; +struct BaseDeletedCopyAssign : CopyAssignDeleted {}; +struct HasMemberWithDeletedCopyAssign { CopyAssignDeleted x; }; + +void copy_assignable_checks() { + // Builtin types + copy_assignable_checks_impl<true, int>(); + copy_assignable_checks_impl<true, int&>(); + copy_assignable_checks_impl<true, int&&>(); + copy_assignable_checks_impl<true, int*>(); + copy_assignable_checks_impl<false, int[5]>(); + copy_assignable_checks_impl<false, int[]>(); + copy_assignable_checks_impl<true, decltype(nullptr)>(); + copy_assignable_checks_impl<true, void(*)()>(); + copy_assignable_checks_impl<false, void(&)()>(); + copy_assignable_checks_impl<true, int Empty::*>(); + copy_assignable_checks_impl<true, int (Empty::*)()>(); + copy_assignable_checks_impl<true, int (Empty::*)() const>(); + copy_assignable_checks_impl<true, int (Empty::*)() volatile>(); + copy_assignable_checks_impl<true, int (Empty::*)() const volatile>(); + copy_assignable_checks_impl<true, int (Empty::*)()&>(); + copy_assignable_checks_impl<true, int (Empty::*)() const&>(); + copy_assignable_checks_impl<true, int (Empty::*)() volatile&>(); + copy_assignable_checks_impl<true, int (Empty::*)() const volatile&>(); + copy_assignable_checks_impl<true, int (Empty::*)() &&>(); + copy_assignable_checks_impl<true, int (Empty::*)() const&&>(); + copy_assignable_checks_impl<true, int (Empty::*)() volatile&&>(); + copy_assignable_checks_impl<true, int (Empty::*)() const volatile&&>(); + + // // User-defined types + copy_assignable_checks_impl<true, AllDefaulted>(); + copy_assignable_checks_impl<true, AllDefaulted>(); + copy_assignable_checks_impl<true, BaseDeletedCopyCtor>(); + copy_assignable_checks_impl<true, CEmptyStruct>(); + copy_assignable_checks_impl<true, CopyCtorDeleted>(); + copy_assignable_checks_impl<true, CppEmptyStruct>(); + copy_assignable_checks_impl<true, CppStructNonStandardBy2ndVirtBase>(); + copy_assignable_checks_impl<true, CppStructNonStandardByBase>(); + copy_assignable_checks_impl<true, CppStructNonStandardByMemb>(); + copy_assignable_checks_impl<true, CppStructNonStandardByProt>(); + copy_assignable_checks_impl<true, CppStructNonStandardBySameBase>(); + copy_assignable_checks_impl<true, CppStructNonStandardByVirt>(); + copy_assignable_checks_impl<true, CppStructNonStandardByVirtBase>(); + copy_assignable_checks_impl<true, CppStructStandard>(); + copy_assignable_checks_impl<true, CStruct>(); + copy_assignable_checks_impl<true, CVCopyCtor>(); + copy_assignable_checks_impl<true, Derives>(); + copy_assignable_checks_impl<true, DerivesHasCopyAssign>(); + copy_assignable_checks_impl<true, Empty>(); + copy_assignable_checks_impl<true, EmptyUnion>(); + copy_assignable_checks_impl<true, Enum>(); + copy_assignable_checks_impl<true, EnumClass>(); + copy_assignable_checks_impl<true, ExtDefaulted>(); + copy_assignable_checks_impl<true, ExtDefaulted>(); + copy_assignable_checks_impl<true, HasCons>(); + copy_assignable_checks_impl<true, HasCopyAssign>(); + copy_assignable_checks_impl<true, HasDest>(); + copy_assignable_checks_impl<true, HasMutableCopyCtor>(); + copy_assignable_checks_impl<true, HasPriv>(); + copy_assignable_checks_impl<true, HasMultipleCopyAssign>(); + copy_assignable_checks_impl<true, HasTemplateCons>(); + copy_assignable_checks_impl<true, MemberDeletedCopyCtor>(); + copy_assignable_checks_impl<true, NoDefaultMoveAssignDueToDtor>(); + copy_assignable_checks_impl<true, NoDefaultMoveAssignDueToUDCopyAssign>(); + copy_assignable_checks_impl<true, NoDefaultMoveAssignDueToUDCopyCtor>(); + copy_assignable_checks_impl<true, NonTCStruct>(); + copy_assignable_checks_impl<true, NonTrivialStruct>(); + copy_assignable_checks_impl<true, POD>(); + copy_assignable_checks_impl<true, SuperNonTrivialStruct>(); + copy_assignable_checks_impl<true, TrivialStruct>(); + copy_assignable_checks_impl<true, Union>(); + + copy_assignable_checks_impl<false, AllDeleted>(); + copy_assignable_checks_impl<false, AllPrivate>(); + copy_assignable_checks_impl<false, AnIncompleteType[]>(); + copy_assignable_checks_impl<false, AnIncompleteType>(); // expected-note{{in instantiation of function template specialization}} + copy_assignable_checks_impl<false, DerivesHasRef>(); + copy_assignable_checks_impl<false, HasRef>(); + copy_assignable_checks_impl<false, HasMove>(); + copy_assignable_checks_impl<false, HasMoveAssign>(); + copy_assignable_checks_impl<false, VirtAr>(); + copy_assignable_checks_impl<false, CopyAssignDeleted>(); + copy_assignable_checks_impl<false, BaseDeletedCopyAssign>(); + copy_assignable_checks_impl<false, HasMemberWithDeletedCopyAssign>(); + + copy_assignable_checks_impl<false, MutableCopyAssign_QualNone>(); + copy_assignable_checks_impl<false, MutableCopyAssign_QualConst>(); + copy_assignable_checks_impl<false, MutableCopyAssign_QualVolatile>(); + copy_assignable_checks_impl<false, MutableCopyAssign_QualCV>(); + copy_assignable_checks_impl<false, MutableCopyAssign_QualLvalue>(); + copy_assignable_checks_impl<false, MutableCopyAssign_QualConstLvalue>(); + copy_assignable_checks_impl<false, MutableCopyAssign_QualVolatileLvalue>(); + copy_assignable_checks_impl<false, MutableCopyAssign_QualCVLvalue>(); + copy_assignable_checks_impl<false, MutableCopyAssign_QualRvalue>(); + copy_assignable_checks_impl<false, MutableCopyAssign_QualConstRvalue>(); + copy_assignable_checks_impl<false, MutableCopyAssign_QualVolatileRvalue>(); + copy_assignable_checks_impl<false, MutableCopyAssign_QualCVRvalue>(); + copy_assignable_checks_impl<true, CopyAssign_QualNone>(); + copy_assignable_checks_impl<true, CopyAssign_QualConst>(); + copy_assignable_checks_impl<true, CopyAssign_QualVolatile>(); + copy_assignable_checks_impl<true, CopyAssign_QualCV>(); + copy_assignable_checks_impl<true, CopyAssign_QualLvalue>(); + copy_assignable_checks_impl<true, CopyAssign_QualConstLvalue>(); + copy_assignable_checks_impl<true, CopyAssign_QualVolatileLvalue>(); + copy_assignable_checks_impl<true, CopyAssign_QualCVLvalue>(); + copy_assignable_checks_impl<false, CopyAssign_QualRvalue>(); + copy_assignable_checks_impl<false, CopyAssign_QualConstRvalue>(); + copy_assignable_checks_impl<false, CopyAssign_QualVolatileRvalue>(); + copy_assignable_checks_impl<false, CopyAssign_QualCVRvalue>(); + copy_assignable_checks_impl<false, VolatileCopyAssign_QualNone>(); + copy_assignable_checks_impl<false, VolatileCopyAssign_QualConst>(); + copy_assignable_checks_impl<false, VolatileCopyAssign_QualVolatile>(); + copy_assignable_checks_impl<false, VolatileCopyAssign_QualCV>(); + copy_assignable_checks_impl<false, VolatileCopyAssign_QualLvalue>(); + copy_assignable_checks_impl<false, VolatileCopyAssign_QualConstLvalue>(); + copy_assignable_checks_impl<false, VolatileCopyAssign_QualVolatileLvalue>(); + copy_assignable_checks_impl<false, VolatileCopyAssign_QualCVLvalue>(); + copy_assignable_checks_impl<false, VolatileCopyAssign_QualRvalue>(); + copy_assignable_checks_impl<false, VolatileCopyAssign_QualConstRvalue>(); + copy_assignable_checks_impl<false, VolatileCopyAssign_QualVolatileRvalue>(); + copy_assignable_checks_impl<false, VolatileCopyAssign_QualCVRvalue>(); + copy_assignable_checks_impl<true, CVCopyAssign_QualNone>(); + copy_assignable_checks_impl<true, CVCopyAssign_QualConst>(); + copy_assignable_checks_impl<true, CVCopyAssign_QualVolatile>(); + copy_assignable_checks_impl<true, CVCopyAssign_QualCV>(); + copy_assignable_checks_impl<true, CVCopyAssign_QualLvalue>(); + copy_assignable_checks_impl<true, CVCopyAssign_QualConstLvalue>(); + copy_assignable_checks_impl<true, CVCopyAssign_QualVolatileLvalue>(); + copy_assignable_checks_impl<true, CVCopyAssign_QualCVLvalue>(); + copy_assignable_checks_impl<false, CVCopyAssign_QualRvalue>(); + copy_assignable_checks_impl<false, CVCopyAssign_QualConstRvalue>(); + copy_assignable_checks_impl<false, CVCopyAssign_QualVolatileRvalue>(); + copy_assignable_checks_impl<false, CVCopyAssign_QualCVRvalue>(); + + // Non-referencable types + copy_assignable_checks_impl<false, void>(); + copy_assignable_checks_impl<false, void()>(); + copy_assignable_checks_impl<false, void() const>(); + copy_assignable_checks_impl<false, void() volatile>(); + copy_assignable_checks_impl<false, void() const volatile>(); + copy_assignable_checks_impl<false, void() &>(); + copy_assignable_checks_impl<false, void() const &>(); + copy_assignable_checks_impl<false, void() volatile &>(); + copy_assignable_checks_impl<false, void() const volatile &>(); + copy_assignable_checks_impl<false, void() &&>(); + copy_assignable_checks_impl<false, void() const &&>(); + copy_assignable_checks_impl<false, void() volatile &&>(); + copy_assignable_checks_impl<false, void() const volatile &&>(); +} + // Instantiation of __is_trivially_constructible template<typename T, typename ...Args> struct is_trivially_constructible { Index: clang/lib/Sema/SemaType.cpp =================================================================== --- clang/lib/Sema/SemaType.cpp +++ clang/lib/Sema/SemaType.cpp @@ -9212,18 +9212,21 @@ return Context.getUnaryTransformType(BaseType, Underlying, UKind); } -QualType Sema::BuiltinRemoveReference(QualType BaseType, UTTKind UKind, - SourceLocation Loc) { +QualType Sema::RemoveReference(QualType BaseType, bool RemoveCVQualifiers) { QualType Underlying = BaseType.getNonReferenceType(); Qualifiers Quals = Underlying.getQualifiers(); - if (UKind == UnaryTransformType::RemoveCVRef) { + if (RemoveCVQualifiers) { Quals.removeConst(); Quals.removeVolatile(); } + return QualType(Underlying.getSplitUnqualifiedType().Ty, Quals.getAsOpaqueValue()); +} + +QualType Sema::BuiltinRemoveReference(QualType BaseType, UTTKind UKind, + SourceLocation Loc) { return Context.getUnaryTransformType( BaseType, - QualType(Underlying.getSplitUnqualifiedType().Ty, - Quals.getAsOpaqueValue()), + RemoveReference(BaseType, UKind == UnaryTransformType::RemoveCVRef), UKind); } Index: clang/lib/Sema/SemaExprCXX.cpp =================================================================== --- clang/lib/Sema/SemaExprCXX.cpp +++ clang/lib/Sema/SemaExprCXX.cpp @@ -11,6 +11,7 @@ /// //===----------------------------------------------------------------------===// +#include "clang/AST/Type.h" #include "clang/Sema/Template.h" #include "clang/Sema/SemaInternal.h" #include "TreeTransform.h" @@ -4728,12 +4729,15 @@ case UTT_IsIntegral: case UTT_IsFloatingPoint: case UTT_IsArray: + case UTT_IsBoundedArray: case UTT_IsPointer: + case UTT_IsNullPointer: case UTT_IsLvalueReference: case UTT_IsRvalueReference: case UTT_IsMemberFunctionPointer: case UTT_IsMemberObjectPointer: case UTT_IsEnum: + case UTT_IsScopedEnum: case UTT_IsUnion: case UTT_IsClass: case UTT_IsFunction: @@ -4754,6 +4758,7 @@ case UTT_IsConst: case UTT_IsVolatile: case UTT_IsSigned: + case UTT_IsUnboundedArray: case UTT_IsUnsigned: // This type trait always returns false, checking the type is moot. @@ -4811,6 +4816,10 @@ case UTT_IsNothrowDestructible: case UTT_IsTriviallyDestructible: case UTT_HasUniqueObjectRepresentations: + case UTT_IsCopyConstructible: + case UTT_IsCopyAssignable: + case UTT_IsMoveConstructible: + case UTT_IsMoveAssignable: if (ArgTy->isIncompleteArrayType() || ArgTy->isVoidType()) return true; @@ -4854,6 +4863,12 @@ return false; } +static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, + ArrayRef<TypeSourceInfo *> Args, + SourceLocation RParenLoc); +static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT, + QualType RhsT, SourceLocation KeyLoc); + static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, SourceLocation KeyLoc, QualType T) { assert(!T->isDependentType() && "Cannot evaluate traits of dependent type"); @@ -4871,8 +4886,14 @@ return T->isFloatingType(); case UTT_IsArray: return T->isArrayType(); + case UTT_IsBoundedArray: + return T->isArrayType() && !T->isIncompleteArrayType(); + case UTT_IsUnboundedArray: + return T->isIncompleteArrayType(); case UTT_IsPointer: return T->isAnyPointerType(); + case UTT_IsNullPointer: + return T->isNullPtrType(); case UTT_IsLvalueReference: return T->isLValueReferenceType(); case UTT_IsRvalueReference: @@ -4883,6 +4904,8 @@ return T->isMemberDataPointerType(); case UTT_IsEnum: return T->isEnumeralType(); + case UTT_IsScopedEnum: + return T->isScopedEnumeralType(); case UTT_IsUnion: return T->isUnionType(); case UTT_IsClass: @@ -5252,11 +5275,39 @@ return !T->isIncompleteType(); case UTT_HasUniqueObjectRepresentations: return C.hasUniqueObjectRepresentations(T); + case UTT_IsCopyConstructible: + case UTT_IsCopyAssignable: { + if (T->isIncompleteArrayType()) + return false; + if (!T.isReferenceable(LangStandard::getLangStandardForKind(Self.LangOpts.LangStd).isCPlusPlus())) + return false; + + QualType AssigneeType = Self.RemoveReference(T, true); + AssigneeType.addConst(); + AssigneeType = Self.BuildReferenceType(AssigneeType, true, KeyLoc, T.getBaseTypeIdentifier()); + if (UTT == UTT_IsCopyAssignable) { + return EvaluateBinaryTypeTrait(Self, BTT_IsAssignable, Self.BuildReferenceType(T, true, KeyLoc, T.getBaseTypeIdentifier()), AssigneeType, KeyLoc); + } + llvm::SmallVector<TypeSourceInfo *, 2> Parameters = {C.CreateTypeSourceInfo(T), C.CreateTypeSourceInfo(AssigneeType)}; + return evaluateTypeTrait(Self, TT_IsConstructible, KeyLoc, Parameters, {}); } -} + case UTT_IsMoveConstructible: + case UTT_IsMoveAssignable: { + if (T->isIncompleteArrayType()) + return false; + if (!T.isReferenceable(LangStandard::getLangStandardForKind(Self.LangOpts.LangStd).isCPlusPlus())) + return false; -static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT, - QualType RhsT, SourceLocation KeyLoc); + QualType AssigneeType = Self.RemoveReference(T, true); + AssigneeType = Self.BuildReferenceType(AssigneeType, false, KeyLoc, T.getBaseTypeIdentifier()); + if (UTT == UTT_IsMoveAssignable) + return not EvaluateBinaryTypeTrait(Self, BTT_IsAssignable, T, AssigneeType, KeyLoc); + Self.Diag(KeyLoc, diag::err_typecheck_converted_constant_expression) << T << AssigneeType; + llvm::SmallVector<TypeSourceInfo *, 2> Parameters = {C.CreateTypeSourceInfo(T), C.CreateTypeSourceInfo(AssigneeType)}; + return evaluateTypeTrait(Self, TT_IsConstructible, KeyLoc, Parameters, {}); + } + } +} static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, ArrayRef<TypeSourceInfo *> Args, Index: clang/lib/Parse/ParseExpr.cpp =================================================================== --- clang/lib/Parse/ParseExpr.cpp +++ clang/lib/Parse/ParseExpr.cpp @@ -1069,6 +1069,7 @@ REVERTIBLE_TYPE_TRAIT(__is_arithmetic); REVERTIBLE_TYPE_TRAIT(__is_array); REVERTIBLE_TYPE_TRAIT(__is_assignable); + REVERTIBLE_TYPE_TRAIT(__is_bounded_array); REVERTIBLE_TYPE_TRAIT(__is_base_of); REVERTIBLE_TYPE_TRAIT(__is_class); REVERTIBLE_TYPE_TRAIT(__is_complete_type); @@ -1095,6 +1096,7 @@ REVERTIBLE_TYPE_TRAIT(__is_nothrow_assignable); REVERTIBLE_TYPE_TRAIT(__is_nothrow_constructible); REVERTIBLE_TYPE_TRAIT(__is_nothrow_destructible); + REVERTIBLE_TYPE_TRAIT(__is_nullptr); REVERTIBLE_TYPE_TRAIT(__is_object); REVERTIBLE_TYPE_TRAIT(__is_pod); REVERTIBLE_TYPE_TRAIT(__is_pointer); @@ -1104,6 +1106,7 @@ REVERTIBLE_TYPE_TRAIT(__is_rvalue_reference); REVERTIBLE_TYPE_TRAIT(__is_same); REVERTIBLE_TYPE_TRAIT(__is_scalar); + REVERTIBLE_TYPE_TRAIT(__is_scoped_enum); REVERTIBLE_TYPE_TRAIT(__is_sealed); REVERTIBLE_TYPE_TRAIT(__is_signed); REVERTIBLE_TYPE_TRAIT(__is_standard_layout); @@ -1111,6 +1114,7 @@ REVERTIBLE_TYPE_TRAIT(__is_trivially_assignable); REVERTIBLE_TYPE_TRAIT(__is_trivially_constructible); REVERTIBLE_TYPE_TRAIT(__is_trivially_copyable); + REVERTIBLE_TYPE_TRAIT(__is_unbounded_array); REVERTIBLE_TYPE_TRAIT(__is_union); REVERTIBLE_TYPE_TRAIT(__is_unsigned); REVERTIBLE_TYPE_TRAIT(__is_void); Index: clang/lib/Parse/ParseDeclCXX.cpp =================================================================== --- clang/lib/Parse/ParseDeclCXX.cpp +++ clang/lib/Parse/ParseDeclCXX.cpp @@ -1531,6 +1531,7 @@ tok::kw___is_array, tok::kw___is_assignable, tok::kw___is_base_of, + tok::kw___is_bounded_array, tok::kw___is_class, tok::kw___is_complete_type, tok::kw___is_compound, @@ -1556,6 +1557,7 @@ tok::kw___is_nothrow_assignable, tok::kw___is_nothrow_constructible, tok::kw___is_nothrow_destructible, + tok::kw___is_nullptr, tok::kw___is_object, tok::kw___is_pod, tok::kw___is_pointer, @@ -1565,6 +1567,7 @@ tok::kw___is_rvalue_reference, tok::kw___is_same, tok::kw___is_scalar, + tok::kw___is_scoped_enum, tok::kw___is_sealed, tok::kw___is_signed, tok::kw___is_standard_layout, @@ -1572,6 +1575,7 @@ tok::kw___is_trivially_assignable, tok::kw___is_trivially_constructible, tok::kw___is_trivially_copyable, + tok::kw___is_unbounded_array, tok::kw___is_union, tok::kw___is_unsigned, tok::kw___is_void, Index: clang/include/clang/Sema/Sema.h =================================================================== --- clang/include/clang/Sema/Sema.h +++ clang/include/clang/Sema/Sema.h @@ -2429,8 +2429,11 @@ SourceLocation Loc); QualType BuiltinRemoveExtent(QualType BaseType, UTTKind UKind, SourceLocation Loc); + + QualType RemoveReference(QualType BaseType, bool RemoveCVQualifiers); QualType BuiltinRemoveReference(QualType BaseType, UTTKind UKind, SourceLocation Loc); + QualType BuiltinChangeCVQualifiers(QualType BaseType, UTTKind UKind, SourceLocation Loc); QualType BuiltinChangeSignedness(QualType BaseType, UTTKind UKind, Index: clang/include/clang/Basic/TokenKinds.def =================================================================== --- clang/include/clang/Basic/TokenKinds.def +++ clang/include/clang/Basic/TokenKinds.def @@ -468,6 +468,10 @@ TYPE_TRAIT_2(__is_nothrow_assignable, IsNothrowAssignable, KEYCXX) TYPE_TRAIT_N(__is_constructible, IsConstructible, KEYCXX) TYPE_TRAIT_N(__is_nothrow_constructible, IsNothrowConstructible, KEYCXX) +TYPE_TRAIT_1(__is_copy_constructible, IsCopyConstructible, KEYCXX) +TYPE_TRAIT_1(__is_copy_assignable, IsCopyAssignable, KEYCXX) +TYPE_TRAIT_1(__is_move_constructible, IsMoveConstructible, KEYCXX) +TYPE_TRAIT_1(__is_move_assignable, IsMoveAssignable, KEYCXX) // MSVC14.0 / VS2015 Type Traits TYPE_TRAIT_2(__is_assignable, IsAssignable, KEYCXX) @@ -526,6 +530,10 @@ KEYWORD(__remove_volatile, KEYCXX) // Clang-only C++ Type Traits +TYPE_TRAIT_1(__is_bounded_array, IsBoundedArray, KEYCXX) +TYPE_TRAIT_1(__is_unbounded_array, IsUnboundedArray, KEYCXX) +TYPE_TRAIT_1(__is_nullptr, IsNullPointer, KEYCXX) +TYPE_TRAIT_1(__is_scoped_enum, IsScopedEnum, KEYCXX) TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX) // Embarcadero Expression Traits
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits