cjdb created this revision. Herald added a subscriber: dexonsmith. cjdb requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This is information that the compiler already has, and should be exposed so that the library doesn't need to reimplement the exact same functionality. - `__is_null_pointer` - `__is_bounded_array` - `__is_scoped_enum` Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D116280 Files: clang/include/clang/Basic/TokenKinds.def clang/lib/Parse/ParseDeclCXX.cpp clang/lib/Parse/ParseExpr.cpp clang/lib/Sema/SemaExprCXX.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 @@ -14,6 +14,9 @@ enum Enum { EV }; enum SignedEnum : signed int { }; enum UnsignedEnum : unsigned int { }; +enum class EnumClass { EV }; +enum class SignedEnumClass : signed int {}; +enum class UnsignedEnumClass : unsigned int {}; struct POD { Enum e; int i; float f; NonPOD* p; }; struct Empty {}; struct IncompleteStruct; @@ -342,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))]; } @@ -360,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 { }; @@ -699,6 +734,36 @@ 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*))]; +} + template <typename T> void tmpl_func(T&) {} template <typename T> struct type_wrapper { @@ -931,6 +996,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; Index: clang/lib/Sema/SemaExprCXX.cpp =================================================================== --- clang/lib/Sema/SemaExprCXX.cpp +++ 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: @@ -4829,8 +4832,12 @@ return T->isFloatingType(); case UTT_IsArray: return T->isArrayType(); + case UTT_IsBoundedArray: + return T->isArrayType() && !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 +4848,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: Index: clang/lib/Parse/ParseExpr.cpp =================================================================== --- clang/lib/Parse/ParseExpr.cpp +++ 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); Index: clang/lib/Parse/ParseDeclCXX.cpp =================================================================== --- clang/lib/Parse/ParseDeclCXX.cpp +++ clang/lib/Parse/ParseDeclCXX.cpp @@ -1520,6 +1520,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, @@ -1545,6 +1546,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, @@ -1554,6 +1556,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, Index: clang/include/clang/Basic/TokenKinds.def =================================================================== --- clang/include/clang/Basic/TokenKinds.def +++ clang/include/clang/Basic/TokenKinds.def @@ -518,6 +518,9 @@ KEYWORD(__remove_volatile, KEYCXX) // Clang-only C++ Type Traits +TYPE_TRAIT_1(__is_bounded_array, IsBoundedArray, 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
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits