diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -527,6 +527,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_null_pointer, IsNullPointer, KEYCXX) +TYPE_TRAIT_1(__is_scoped_enum, IsScopedEnum, KEYCXX) TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX) // Embarcadero Expression Traits diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -1524,6 +1524,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, @@ -1549,6 +1550,7 @@ tok::kw___is_nothrow_assignable, tok::kw___is_nothrow_constructible, tok::kw___is_nothrow_destructible, + tok::kw___is_null_pointer, tok::kw___is_object, tok::kw___is_pod, tok::kw___is_pointer, @@ -1558,6 +1560,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, @@ -1565,6 +1568,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, diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1066,6 +1066,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); @@ -1092,6 +1093,7 @@ REVERTIBLE_TYPE_TRAIT(__is_nothrow_assignable); REVERTIBLE_TYPE_TRAIT(__is_nothrow_constructible); REVERTIBLE_TYPE_TRAIT(__is_nothrow_destructible); + REVERTIBLE_TYPE_TRAIT(__is_null_pointer); REVERTIBLE_TYPE_TRAIT(__is_object); REVERTIBLE_TYPE_TRAIT(__is_pod); REVERTIBLE_TYPE_TRAIT(__is_pointer); @@ -1101,6 +1103,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); @@ -1108,6 +1111,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); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -4686,12 +4686,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: @@ -4712,6 +4715,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. @@ -4829,8 +4833,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: @@ -4841,6 +4851,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: diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp --- a/clang/test/SemaCXX/type-traits.cpp +++ b/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 void tmpl_func(T&) {} template struct type_wrapper { @@ -934,6 +1026,43 @@ int t34[F(__is_pointer(void (StructWithMembers::*) ()))]; } +void is_null_pointer() +{ + StructWithMembers x; + + int t00[T(__is_null_pointer(decltype(nullptr)))]; + int t01[F(__is_null_pointer(void*))]; + int t02[F(__is_null_pointer(cvoid*))]; + int t03[F(__is_null_pointer(cvoid*))]; + int t04[F(__is_null_pointer(char*))]; + int t05[F(__is_null_pointer(int*))]; + int t06[F(__is_null_pointer(int**))]; + int t07[F(__is_null_pointer(ClassType*))]; + int t08[F(__is_null_pointer(Derives*))]; + int t09[F(__is_null_pointer(Enum*))]; + int t10[F(__is_null_pointer(IntArNB*))]; + int t11[F(__is_null_pointer(Union*))]; + int t12[F(__is_null_pointer(UnionAr*))]; + int t13[F(__is_null_pointer(StructWithMembers*))]; + int t14[F(__is_null_pointer(void (*)()))]; + + int t20[F(__is_null_pointer(void))]; + int t21[F(__is_null_pointer(cvoid))]; + int t22[F(__is_null_pointer(cvoid))]; + int t23[F(__is_null_pointer(char))]; + int t24[F(__is_null_pointer(int))]; + int t25[F(__is_null_pointer(int))]; + int t26[F(__is_null_pointer(ClassType))]; + int t27[F(__is_null_pointer(Derives))]; + int t28[F(__is_null_pointer(Enum))]; + int t29[F(__is_null_pointer(IntArNB))]; + int t30[F(__is_null_pointer(Union))]; + int t31[F(__is_null_pointer(UnionAr))]; + int t32[F(__is_null_pointer(StructWithMembers))]; + int t33[F(__is_null_pointer(int StructWithMembers::*))]; + int t34[F(__is_null_pointer(void (StructWithMembers::*) ()))]; +} + void is_member_object_pointer() { StructWithMembers x;