cjdb created this revision. cjdb added a reviewer: aaron.ballman. Herald added a project: All. cjdb requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
... as builtins. 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. This was originally a part of D116280 <https://reviews.llvm.org/D116280>. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D135177 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 @@ -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,29 @@ { 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 { }; @@ -766,6 +797,42 @@ (void)__is_unbounded_array(decltype(t32)); // expected-error{{variable length arrays are not supported for '__is_unbounded_array'}} } +void is_referenceable() { + { int a[T(__is_referenceable(int))]; } + { int a[T(__is_referenceable(const int))]; } + { int a[T(__is_referenceable(volatile int))]; } + { int a[T(__is_referenceable(const volatile int))]; } + { int a[T(__is_referenceable(int *))]; } + { int a[T(__is_referenceable(int &))]; } + { int a[T(__is_referenceable(int &&))]; } + { int a[T(__is_referenceable(int (*)()))]; } + { int a[T(__is_referenceable(int (&)()))]; } + { int a[T(__is_referenceable(int(&&)()))]; } + { int a[T(__is_referenceable(IntAr))]; } + { int a[T(__is_referenceable(IntArNB))]; } + { int a[T(__is_referenceable(decltype(nullptr)))]; } + { int a[T(__is_referenceable(Empty))]; } + { int a[T(__is_referenceable(Union))]; } + { int a[T(__is_referenceable(Derives))]; } + { int a[T(__is_referenceable(Enum))]; } + { int a[T(__is_referenceable(EnumClass))]; } + { int a[T(__is_referenceable(int Empty::*))]; } + { int a[T(__is_referenceable(int(Empty::*)()))]; } + { int a[T(__is_referenceable(int(Empty::*)() const))]; } + { int a[T(__is_referenceable(int(Empty::*)() volatile))]; } + { int a[T(__is_referenceable(int(Empty::*)() const volatile))]; } + { int a[T(__is_referenceable(int(Empty::*)() &))]; } + { int a[T(__is_referenceable(int(Empty::*)() const &))]; } + { int a[T(__is_referenceable(int(Empty::*)() volatile &))]; } + { int a[T(__is_referenceable(int(Empty::*)() const volatile &))]; } + { int a[T(__is_referenceable(int(Empty::*)() &&))]; } + { int a[T(__is_referenceable(int(Empty::*)() const &&))]; } + { int a[T(__is_referenceable(int(Empty::*)() volatile &&))]; } + { int a[T(__is_referenceable(int(Empty::*)() const volatile &&))]; } + + { int a[F(__is_referenceable(void))]; } +} + template <typename T> void tmpl_func(T&) {} template <typename T> struct type_wrapper { @@ -998,6 +1065,42 @@ 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; @@ -3359,6 +3462,8 @@ static_assert(__is_same(remove_cvref_t<M>, M), ""); static_assert(__is_same(remove_pointer_t<M>, M), ""); static_assert(__is_same(remove_reference_t<M>, M), ""); + + static_assert(!__is_referenceable(M), ""); } }; Index: clang/lib/Sema/SemaExprCXX.cpp =================================================================== --- clang/lib/Sema/SemaExprCXX.cpp +++ clang/lib/Sema/SemaExprCXX.cpp @@ -4760,11 +4760,14 @@ case UTT_IsArray: case UTT_IsBoundedArray: case UTT_IsPointer: + case UTT_IsNullPointer: + case UTT_IsReferenceable: 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: @@ -4917,6 +4920,8 @@ return T->isIncompleteArrayType(); case UTT_IsPointer: return T->isAnyPointerType(); + case UTT_IsNullPointer: + return T->isNullPtrType(); case UTT_IsLvalueReference: return T->isLValueReferenceType(); case UTT_IsRvalueReference: @@ -4927,6 +4932,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: @@ -5298,6 +5305,8 @@ return C.hasUniqueObjectRepresentations(T); case UTT_IsTriviallyRelocatable: return T.isTriviallyRelocatableType(C); + case UTT_IsReferenceable: + return T.isReferenceable(); } } Index: clang/lib/Parse/ParseExpr.cpp =================================================================== --- clang/lib/Parse/ParseExpr.cpp +++ clang/lib/Parse/ParseExpr.cpp @@ -1067,20 +1067,20 @@ 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_bounded_array); REVERTIBLE_TYPE_TRAIT(__is_class); REVERTIBLE_TYPE_TRAIT(__is_complete_type); REVERTIBLE_TYPE_TRAIT(__is_compound); REVERTIBLE_TYPE_TRAIT(__is_const); REVERTIBLE_TYPE_TRAIT(__is_constructible); - REVERTIBLE_TYPE_TRAIT(__is_convertible); REVERTIBLE_TYPE_TRAIT(__is_convertible_to); + REVERTIBLE_TYPE_TRAIT(__is_convertible); REVERTIBLE_TYPE_TRAIT(__is_destructible); REVERTIBLE_TYPE_TRAIT(__is_empty); REVERTIBLE_TYPE_TRAIT(__is_enum); - REVERTIBLE_TYPE_TRAIT(__is_floating_point); REVERTIBLE_TYPE_TRAIT(__is_final); + REVERTIBLE_TYPE_TRAIT(__is_floating_point); REVERTIBLE_TYPE_TRAIT(__is_function); REVERTIBLE_TYPE_TRAIT(__is_fundamental); REVERTIBLE_TYPE_TRAIT(__is_integral); @@ -1094,15 +1094,18 @@ 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); REVERTIBLE_TYPE_TRAIT(__is_polymorphic); REVERTIBLE_TYPE_TRAIT(__is_reference); + REVERTIBLE_TYPE_TRAIT(__is_referenceable); REVERTIBLE_TYPE_TRAIT(__is_rvalue_expr); 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 @@ -1605,15 +1605,18 @@ 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, tok::kw___is_polymorphic, tok::kw___is_reference, + tok::kw___is_referenceable, tok::kw___is_rvalue_expr, 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 @@ -520,6 +520,9 @@ TYPE_TRAIT_1(__is_trivially_relocatable, IsTriviallyRelocatable, KEYCXX) 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_1(__is_referenceable, IsReferenceable, 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