diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -1398,6 +1398,10 @@ * ``__array_extent(type, dim)`` (Embarcadero): The ``dim``'th array bound in the type ``type``, or ``0`` if ``dim >= __array_rank(type)``. +* ``__can_pass_in_regs`` (C++) + Returns whether a class can be passed in registers under the current + ABI. Returns ``true`` for non-class types like builtins or references. + This is not a portable type trait. * ``__has_nothrow_assign`` (GNU, Microsoft, Embarcadero): Deprecated, use ``__is_nothrow_assignable`` instead. * ``__has_nothrow_move_assign`` (GNU, Microsoft): 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 @@ -523,6 +523,7 @@ TYPE_TRAIT_1(__is_nullptr, IsNullPointer, KEYCXX) TYPE_TRAIT_1(__is_scoped_enum, IsScopedEnum, KEYCXX) TYPE_TRAIT_1(__is_referenceable, IsReferenceable, KEYCXX) +TYPE_TRAIT_1(__can_pass_in_regs, CanPassInRegs, KEYCXX) TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX) // Embarcadero Expression Traits 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 @@ -4892,6 +4892,7 @@ case UTT_IsLiteral: // By analogy, is_trivially_relocatable imposes the same constraints. case UTT_IsTriviallyRelocatable: + case UTT_CanPassInRegs: // Per the GCC type traits documentation, T shall be a complete type, cv void, // or an array of unknown bound. But GCC actually imposes the same constraints // as above. @@ -5380,6 +5381,10 @@ return T.isTriviallyRelocatableType(C); case UTT_IsReferenceable: return T.isReferenceable(); + case UTT_CanPassInRegs: + if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) + return RD->canPassInRegisters(); + return true; } } 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 @@ -3055,6 +3055,23 @@ } // namespace is_trivially_relocatable +namespace can_pass_in_regs { + +struct A { }; + +struct B { + ~B(); +}; + +static_assert(__can_pass_in_regs(A), ""); +static_assert(__can_pass_in_regs(A&), ""); +static_assert(!__can_pass_in_regs(B), ""); +static_assert(__can_pass_in_regs(B&), ""); +static_assert(__can_pass_in_regs(int), ""); +static_assert(__can_pass_in_regs(int&), ""); + +} + struct S {}; template using remove_const_t = __remove_const(T);