[clang] [libcxx] [Clang] Add __is_invocable_r and __is_nothrow_invocable_r (PR #81213)

2024-02-12 Thread Nikolas Klauser via cfe-commits

https://github.com/philnik777 converted_to_draft 
https://github.com/llvm/llvm-project/pull/81213
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [Clang] Add __is_invocable_r and __is_nothrow_invocable_r (PR #81213)

2024-02-09 Thread Nikolas Klauser via cfe-commits

https://github.com/philnik777 updated 
https://github.com/llvm/llvm-project/pull/81213

>From a6ef9191b3a68e68e7dd225bfb1e802f7542ccd9 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser 
Date: Mon, 11 Sep 2023 04:31:02 +0200
Subject: [PATCH] [Clang] Add __is_invocable_r and __is_nothrow_invocable_r

This patch also uses the new builtins in libc++.
---
 clang/docs/LanguageExtensions.rst|   2 +
 clang/docs/ReleaseNotes.rst  |   4 +
 clang/include/clang/Basic/TokenKinds.def |   2 +
 clang/lib/Sema/SemaExprCXX.cpp   | 395 +--
 clang/test/SemaCXX/type-traits-invocable.cpp | 312 +++
 libcxx/include/__type_traits/invoke.h|  40 +-
 6 files changed, 634 insertions(+), 121 deletions(-)
 create mode 100644 clang/test/SemaCXX/type-traits-invocable.cpp

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index e91156837290f7..bf061590e5ca0b 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -1582,6 +1582,7 @@ The following type trait primitives are supported by 
Clang. Those traits marked
 * ``__is_integral`` (C++, Embarcadero)
 * ``__is_interface_class`` (Microsoft):
   Returns ``false``, even for types defined with ``__interface``.
+* ``__is_invocable_r`` (Clang)
 * ``__is_literal`` (Clang):
   Synonym for ``__is_literal_type``.
 * ``__is_literal_type`` (C++, GNU, Microsoft):
@@ -1594,6 +1595,7 @@ The following type trait primitives are supported by 
Clang. Those traits marked
 * ``__is_nothrow_assignable`` (C++, MSVC 2013)
 * ``__is_nothrow_constructible`` (C++, MSVC 2013)
 * ``__is_nothrow_destructible`` (C++, MSVC 2013)
+* ``__is_nothrow_invocable_r`` (Clang)
 * ``__is_nullptr`` (C++, GNU, Microsoft, Embarcadero):
   Returns true for ``std::nullptr_t`` and false for everything else. The
   corresponding standard library feature is ``std::is_null_pointer``, but
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index cd8a82f281f52a..8a4ae646c008f6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -78,6 +78,10 @@ here. Generic improvements to Clang as a whole or to its 
underlying
 infrastructure are described first, followed by language-specific
 sections with improvements to Clang's support for those languages.
 
+- The builtins `__is_invocable_r` and `__is_nothrow_invocable_r` have been 
added.
+  These are equivalent to the standard library builtins `std::is_invocable_r`
+  and `std::is_nothrow_invocable_r`.
+
 C++ Language Changes
 
 
diff --git a/clang/include/clang/Basic/TokenKinds.def 
b/clang/include/clang/Basic/TokenKinds.def
index 23817cde7a9354..6467a52c82cb5b 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -532,6 +532,8 @@ 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_N(__is_invocable_r, IsInvocableR, KEYCXX)
+TYPE_TRAIT_N(__is_nothrow_invocable_r, IsNothrowInvocableR, KEYCXX)
 TYPE_TRAIT_1(__can_pass_in_regs, CanPassInRegs, KEYCXX)
 TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)
 TYPE_TRAIT_2(__reference_constructs_from_temporary, 
ReferenceConstructsFromTemporary, KEYCXX)
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 246d2313e089f3..6fca4b0edda1e7 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5468,6 +5468,271 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, 
TypeTrait UTT,
 static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
 QualType RhsT, SourceLocation KeyLoc);
 
+static bool IsBaseOf(Sema &Self, QualType LhsT, QualType RhsT,
+ SourceLocation KeyLoc) {
+  // C++0x [meta.rel]p2
+  // Base is a base class of Derived without regard to cv-qualifiers or
+  // Base and Derived are not unions and name the same class type without
+  // regard to cv-qualifiers.
+
+  const RecordType *lhsRecord = LhsT->getAs();
+  const RecordType *rhsRecord = RhsT->getAs();
+  if (!rhsRecord || !lhsRecord) {
+const ObjCObjectType *LHSObjTy = LhsT->getAs();
+const ObjCObjectType *RHSObjTy = RhsT->getAs();
+if (!LHSObjTy || !RHSObjTy)
+  return false;
+
+ObjCInterfaceDecl *BaseInterface = LHSObjTy->getInterface();
+ObjCInterfaceDecl *DerivedInterface = RHSObjTy->getInterface();
+if (!BaseInterface || !DerivedInterface)
+  return false;
+
+if (Self.RequireCompleteType(
+KeyLoc, RhsT, diag::err_incomplete_type_used_in_type_trait_expr))
+  return false;
+
+return BaseInterface->isSuperClassOf(DerivedInterface);
+  }
+
+  assert(Self.Context.hasSameUnqualifiedType(LhsT, RhsT) ==
+ (lhsRecord == rhsRecord));
+
+  // Unions ar

[clang] [libcxx] [Clang] Add __is_invocable_r and __is_nothrow_invocable_r (PR #81213)

2024-02-09 Thread Nikolas Klauser via cfe-commits

https://github.com/philnik777 updated 
https://github.com/llvm/llvm-project/pull/81213

>From b0b0072067c650e0eb1f4a556301cbc5b873935d Mon Sep 17 00:00:00 2001
From: Nikolas Klauser 
Date: Mon, 11 Sep 2023 04:31:02 +0200
Subject: [PATCH] [Clang] Add __is_invocable_r and __is_nothrow_invocable_r

This patch also uses the new builtins in libc++.
---
 clang/docs/LanguageExtensions.rst|   2 +
 clang/docs/ReleaseNotes.rst  |   4 +
 clang/include/clang/AST/Type.h   |   4 +
 clang/include/clang/Basic/TokenKinds.def |   2 +
 clang/lib/Sema/SemaExprCXX.cpp   | 395 +--
 clang/test/SemaCXX/type-traits-invocable.cpp | 308 +++
 libcxx/include/__type_traits/invoke.h|  40 +-
 7 files changed, 634 insertions(+), 121 deletions(-)
 create mode 100644 clang/test/SemaCXX/type-traits-invocable.cpp

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index e91156837290f7..bf061590e5ca0b 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -1582,6 +1582,7 @@ The following type trait primitives are supported by 
Clang. Those traits marked
 * ``__is_integral`` (C++, Embarcadero)
 * ``__is_interface_class`` (Microsoft):
   Returns ``false``, even for types defined with ``__interface``.
+* ``__is_invocable_r`` (Clang)
 * ``__is_literal`` (Clang):
   Synonym for ``__is_literal_type``.
 * ``__is_literal_type`` (C++, GNU, Microsoft):
@@ -1594,6 +1595,7 @@ The following type trait primitives are supported by 
Clang. Those traits marked
 * ``__is_nothrow_assignable`` (C++, MSVC 2013)
 * ``__is_nothrow_constructible`` (C++, MSVC 2013)
 * ``__is_nothrow_destructible`` (C++, MSVC 2013)
+* ``__is_nothrow_invocable_r`` (Clang)
 * ``__is_nullptr`` (C++, GNU, Microsoft, Embarcadero):
   Returns true for ``std::nullptr_t`` and false for everything else. The
   corresponding standard library feature is ``std::is_null_pointer``, but
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index cd8a82f281f52a..8a4ae646c008f6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -78,6 +78,10 @@ here. Generic improvements to Clang as a whole or to its 
underlying
 infrastructure are described first, followed by language-specific
 sections with improvements to Clang's support for those languages.
 
+- The builtins `__is_invocable_r` and `__is_nothrow_invocable_r` have been 
added.
+  These are equivalent to the standard library builtins `std::is_invocable_r`
+  and `std::is_nothrow_invocable_r`.
+
 C++ Language Changes
 
 
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index d6a55f39a4bede..a3ab09db7fad6a 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -4578,6 +4578,10 @@ class FunctionProtoType final
 return static_cast(FunctionTypeBits.RefQualifier);
   }
 
+  bool isAbominable() const {
+return !getMethodQuals().empty() || getRefQualifier() != RQ_None;
+  }
+
   using param_type_iterator = const QualType *;
 
   ArrayRef param_types() const {
diff --git a/clang/include/clang/Basic/TokenKinds.def 
b/clang/include/clang/Basic/TokenKinds.def
index 23817cde7a9354..6467a52c82cb5b 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -532,6 +532,8 @@ 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_N(__is_invocable_r, IsInvocableR, KEYCXX)
+TYPE_TRAIT_N(__is_nothrow_invocable_r, IsNothrowInvocableR, KEYCXX)
 TYPE_TRAIT_1(__can_pass_in_regs, CanPassInRegs, KEYCXX)
 TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)
 TYPE_TRAIT_2(__reference_constructs_from_temporary, 
ReferenceConstructsFromTemporary, KEYCXX)
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 246d2313e089f3..e18b6fdc99e919 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5468,6 +5468,271 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, 
TypeTrait UTT,
 static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
 QualType RhsT, SourceLocation KeyLoc);
 
+static bool IsBaseOf(Sema &Self, QualType LhsT, QualType RhsT,
+ SourceLocation KeyLoc) {
+  // C++0x [meta.rel]p2
+  // Base is a base class of Derived without regard to cv-qualifiers or
+  // Base and Derived are not unions and name the same class type without
+  // regard to cv-qualifiers.
+
+  const RecordType *lhsRecord = LhsT->getAs();
+  const RecordType *rhsRecord = RhsT->getAs();
+  if (!rhsRecord || !lhsRecord) {
+const ObjCObjectType *LHSObjTy = LhsT->getAs();
+const ObjCObjectType *RHSObjTy = RhsT->getAs();
+if (!LHSObjTy ||

[clang] [libcxx] [Clang] Add __is_invocable_r and __is_nothrow_invocable_r (PR #81213)

2024-02-08 Thread Nikolas Klauser via cfe-commits

https://github.com/philnik777 updated 
https://github.com/llvm/llvm-project/pull/81213

>From 8657d0de76373665c55b774b9cdffe9707288efc Mon Sep 17 00:00:00 2001
From: Nikolas Klauser 
Date: Mon, 11 Sep 2023 04:31:02 +0200
Subject: [PATCH] [Clang] Add __is_invocable_r and __is_nothrow_invocable_r

This patch also uses the new builtins in libc++.
---
 clang/docs/LanguageExtensions.rst|   2 +
 clang/docs/ReleaseNotes.rst  |   4 +
 clang/include/clang/Basic/TokenKinds.def |   2 +
 clang/lib/Sema/SemaExprCXX.cpp   | 390 +--
 clang/test/SemaCXX/type-traits-invocable.cpp | 288 ++
 libcxx/include/__type_traits/invoke.h|  40 +-
 6 files changed, 605 insertions(+), 121 deletions(-)
 create mode 100644 clang/test/SemaCXX/type-traits-invocable.cpp

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index e91156837290f..bf061590e5ca0 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -1582,6 +1582,7 @@ The following type trait primitives are supported by 
Clang. Those traits marked
 * ``__is_integral`` (C++, Embarcadero)
 * ``__is_interface_class`` (Microsoft):
   Returns ``false``, even for types defined with ``__interface``.
+* ``__is_invocable_r`` (Clang)
 * ``__is_literal`` (Clang):
   Synonym for ``__is_literal_type``.
 * ``__is_literal_type`` (C++, GNU, Microsoft):
@@ -1594,6 +1595,7 @@ The following type trait primitives are supported by 
Clang. Those traits marked
 * ``__is_nothrow_assignable`` (C++, MSVC 2013)
 * ``__is_nothrow_constructible`` (C++, MSVC 2013)
 * ``__is_nothrow_destructible`` (C++, MSVC 2013)
+* ``__is_nothrow_invocable_r`` (Clang)
 * ``__is_nullptr`` (C++, GNU, Microsoft, Embarcadero):
   Returns true for ``std::nullptr_t`` and false for everything else. The
   corresponding standard library feature is ``std::is_null_pointer``, but
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index cd8a82f281f52..8a4ae646c008f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -78,6 +78,10 @@ here. Generic improvements to Clang as a whole or to its 
underlying
 infrastructure are described first, followed by language-specific
 sections with improvements to Clang's support for those languages.
 
+- The builtins `__is_invocable_r` and `__is_nothrow_invocable_r` have been 
added.
+  These are equivalent to the standard library builtins `std::is_invocable_r`
+  and `std::is_nothrow_invocable_r`.
+
 C++ Language Changes
 
 
diff --git a/clang/include/clang/Basic/TokenKinds.def 
b/clang/include/clang/Basic/TokenKinds.def
index 23817cde7a935..6467a52c82cb5 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -532,6 +532,8 @@ 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_N(__is_invocable_r, IsInvocableR, KEYCXX)
+TYPE_TRAIT_N(__is_nothrow_invocable_r, IsNothrowInvocableR, KEYCXX)
 TYPE_TRAIT_1(__can_pass_in_regs, CanPassInRegs, KEYCXX)
 TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)
 TYPE_TRAIT_2(__reference_constructs_from_temporary, 
ReferenceConstructsFromTemporary, KEYCXX)
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 246d2313e089f..5b82de9a51323 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5468,6 +5468,266 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, 
TypeTrait UTT,
 static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
 QualType RhsT, SourceLocation KeyLoc);
 
+static bool IsBaseOf(Sema &Self, QualType LhsT, QualType RhsT,
+ SourceLocation KeyLoc) {
+  // C++0x [meta.rel]p2
+  // Base is a base class of Derived without regard to cv-qualifiers or
+  // Base and Derived are not unions and name the same class type without
+  // regard to cv-qualifiers.
+
+  const RecordType *lhsRecord = LhsT->getAs();
+  const RecordType *rhsRecord = RhsT->getAs();
+  if (!rhsRecord || !lhsRecord) {
+const ObjCObjectType *LHSObjTy = LhsT->getAs();
+const ObjCObjectType *RHSObjTy = RhsT->getAs();
+if (!LHSObjTy || !RHSObjTy)
+  return false;
+
+ObjCInterfaceDecl *BaseInterface = LHSObjTy->getInterface();
+ObjCInterfaceDecl *DerivedInterface = RHSObjTy->getInterface();
+if (!BaseInterface || !DerivedInterface)
+  return false;
+
+if (Self.RequireCompleteType(
+KeyLoc, RhsT, diag::err_incomplete_type_used_in_type_trait_expr))
+  return false;
+
+return BaseInterface->isSuperClassOf(DerivedInterface);
+  }
+
+  assert(Self.Context.hasSameUnqualifiedType(LhsT, RhsT) ==
+ (lhsRecord == rhsRecord));
+
+  // Unions are never b

[clang] [libcxx] [Clang] Add __is_invocable_r and __is_nothrow_invocable_r (PR #81213)

2024-02-08 Thread Nikolas Klauser via cfe-commits

https://github.com/philnik777 updated 
https://github.com/llvm/llvm-project/pull/81213

>From f2394044b0397cbe3bd15f96f43fbf0e50def206 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser 
Date: Mon, 11 Sep 2023 04:31:02 +0200
Subject: [PATCH] [Clang] Add __is_invocable_r and __is_nothrow_invocable_r

This patch also uses the new builtins in libc++.
---
 clang/docs/LanguageExtensions.rst|   2 +
 clang/docs/ReleaseNotes.rst  |   4 +
 clang/include/clang/Basic/TokenKinds.def |   2 +
 clang/lib/Sema/SemaExprCXX.cpp   | 390 +--
 clang/test/SemaCXX/type-traits-invocable.cpp | 288 ++
 libcxx/include/__type_traits/invoke.h|  36 ++
 6 files changed, 603 insertions(+), 119 deletions(-)
 create mode 100644 clang/test/SemaCXX/type-traits-invocable.cpp

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index e91156837290f7..bf061590e5ca0b 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -1582,6 +1582,7 @@ The following type trait primitives are supported by 
Clang. Those traits marked
 * ``__is_integral`` (C++, Embarcadero)
 * ``__is_interface_class`` (Microsoft):
   Returns ``false``, even for types defined with ``__interface``.
+* ``__is_invocable_r`` (Clang)
 * ``__is_literal`` (Clang):
   Synonym for ``__is_literal_type``.
 * ``__is_literal_type`` (C++, GNU, Microsoft):
@@ -1594,6 +1595,7 @@ The following type trait primitives are supported by 
Clang. Those traits marked
 * ``__is_nothrow_assignable`` (C++, MSVC 2013)
 * ``__is_nothrow_constructible`` (C++, MSVC 2013)
 * ``__is_nothrow_destructible`` (C++, MSVC 2013)
+* ``__is_nothrow_invocable_r`` (Clang)
 * ``__is_nullptr`` (C++, GNU, Microsoft, Embarcadero):
   Returns true for ``std::nullptr_t`` and false for everything else. The
   corresponding standard library feature is ``std::is_null_pointer``, but
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index cd8a82f281f52a..8a4ae646c008f6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -78,6 +78,10 @@ here. Generic improvements to Clang as a whole or to its 
underlying
 infrastructure are described first, followed by language-specific
 sections with improvements to Clang's support for those languages.
 
+- The builtins `__is_invocable_r` and `__is_nothrow_invocable_r` have been 
added.
+  These are equivalent to the standard library builtins `std::is_invocable_r`
+  and `std::is_nothrow_invocable_r`.
+
 C++ Language Changes
 
 
diff --git a/clang/include/clang/Basic/TokenKinds.def 
b/clang/include/clang/Basic/TokenKinds.def
index 23817cde7a9354..6467a52c82cb5b 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -532,6 +532,8 @@ 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_N(__is_invocable_r, IsInvocableR, KEYCXX)
+TYPE_TRAIT_N(__is_nothrow_invocable_r, IsNothrowInvocableR, KEYCXX)
 TYPE_TRAIT_1(__can_pass_in_regs, CanPassInRegs, KEYCXX)
 TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)
 TYPE_TRAIT_2(__reference_constructs_from_temporary, 
ReferenceConstructsFromTemporary, KEYCXX)
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 246d2313e089f3..5b82de9a51323f 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5468,6 +5468,266 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, 
TypeTrait UTT,
 static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
 QualType RhsT, SourceLocation KeyLoc);
 
+static bool IsBaseOf(Sema &Self, QualType LhsT, QualType RhsT,
+ SourceLocation KeyLoc) {
+  // C++0x [meta.rel]p2
+  // Base is a base class of Derived without regard to cv-qualifiers or
+  // Base and Derived are not unions and name the same class type without
+  // regard to cv-qualifiers.
+
+  const RecordType *lhsRecord = LhsT->getAs();
+  const RecordType *rhsRecord = RhsT->getAs();
+  if (!rhsRecord || !lhsRecord) {
+const ObjCObjectType *LHSObjTy = LhsT->getAs();
+const ObjCObjectType *RHSObjTy = RhsT->getAs();
+if (!LHSObjTy || !RHSObjTy)
+  return false;
+
+ObjCInterfaceDecl *BaseInterface = LHSObjTy->getInterface();
+ObjCInterfaceDecl *DerivedInterface = RHSObjTy->getInterface();
+if (!BaseInterface || !DerivedInterface)
+  return false;
+
+if (Self.RequireCompleteType(
+KeyLoc, RhsT, diag::err_incomplete_type_used_in_type_trait_expr))
+  return false;
+
+return BaseInterface->isSuperClassOf(DerivedInterface);
+  }
+
+  assert(Self.Context.hasSameUnqualifiedType(LhsT, RhsT) ==
+ (lhsRecord == rhsRecord));
+
+  // Unions are

[clang] [libcxx] [Clang] Add __is_invocable_r and __is_nothrow_invocable_r (PR #81213)

2024-02-08 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 9cc2122bf5a81f7063c2a32b2cb78c8d615578a1 
6c74eb263dd889858f3f7be328d85fe354f71835 -- 
clang/test/SemaCXX/type-traits-invocable.cpp clang/include/clang/AST/Type.h 
clang/lib/Sema/SemaExprCXX.cpp libcxx/include/__type_traits/invoke.h
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 4f4b6492e5..d033113805 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5520,7 +5520,8 @@ static bool IsBaseOf(Sema &Self, QualType LhsT, QualType 
RhsT,
   ->isDerivedFrom(cast(lhsRecord->getDecl()));
 }
 
-static bool IsConvertible(Sema& Self, QualType LhsT, QualType RhsT, 
SourceLocation KeyLoc, bool CheckNothrow) {
+static bool IsConvertible(Sema &Self, QualType LhsT, QualType RhsT,
+  SourceLocation KeyLoc, bool CheckNothrow) {
   // C++0x [meta.rel]p4:
   //   Given the following function prototype:
   //
@@ -5667,7 +5668,7 @@ static bool IsInvocable(Sema &S, SourceLocation KWLoc,
 if (Object->isPointerType())
   Object = Object->getPointeeType();
 // bullets 2, 5 - ignore reference_wrapper
-else if (auto* RD = Object->getAsCXXRecordDecl()) {
+else if (auto *RD = Object->getAsCXXRecordDecl()) {
   if (auto *TS = dyn_cast(RD)) {
 if (TS->isInStdNamespace() && TS->getName() == "reference_wrapper")
   Object = TS->getTemplateArgs().get(0).getAsType();
@@ -5865,7 +5866,8 @@ static bool EvaluateBooleanTypeTrait(Sema &S, TypeTrait 
Kind,
 return IsInvocable(S, KWLoc, Args, RParenLoc,
Kind == TT_IsNothrowInvocableR);
 
-  default: llvm_unreachable("not a TT");
+  default:
+llvm_unreachable("not a TT");
   }
 
   return false;
diff --git a/libcxx/include/__type_traits/invoke.h 
b/libcxx/include/__type_traits/invoke.h
index 5286d78bf6..0920539c71 100644
--- a/libcxx/include/__type_traits/invoke.h
+++ b/libcxx/include/__type_traits/invoke.h
@@ -424,7 +424,7 @@ struct __invoke_void_return_wrapper<_Ret, true> {
 
 // is_invocable
 
-#if __has_builtin(__is_invocable_r)
+#  if __has_builtin(__is_invocable_r)
 
 template 
 struct _LIBCPP_TEMPLATE_VIS is_invocable : 
bool_constant<__is_invocable_r(void, _Fn, _Args...)> {};
@@ -438,7 +438,7 @@ inline constexpr bool is_invocable_v = 
__is_invocable_r(void, _Fn, _Args...);
 template 
 inline constexpr bool is_invocable_r_v = __is_invocable_r(_Ret, _Fn, _Args...);
 
-#else
+#  else
 
 template 
 struct _LIBCPP_TEMPLATE_VIS is_invocable : integral_constant::value> {};
@@ -452,11 +452,11 @@ inline constexpr bool is_invocable_v = is_invocable<_Fn, 
_Args...>::value;
 template 
 inline constexpr bool is_invocable_r_v = is_invocable_r<_Ret, _Fn, 
_Args...>::value;
 
-#endif // __has_builtin(__is_invocable_r)
+#  endif // __has_builtin(__is_invocable_r)
 
 // is_nothrow_invocable
 
-#if __has_builtin(__is_nothrow_invocable_r)
+#  if __has_builtin(__is_nothrow_invocable_r)
 
 template 
 struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable : 
bool_constant<__is_nothrow_invocable_r(void, _Fn, _Args...)> {};
@@ -470,7 +470,7 @@ inline constexpr bool is_nothrow_invocable_v = 
__is_nothrow_invocable_r(void, _F
 template 
 inline constexpr bool is_nothrow_invocable_r_v = 
__is_nothrow_invocable_r(_Ret, _Fn, _Args...);
 
-#else
+#  else
 
 template 
 struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable : integral_constant::value> {
@@ -486,7 +486,7 @@ inline constexpr bool is_nothrow_invocable_v = 
is_nothrow_invocable<_Fn, _Args..
 template 
 inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<_Ret, 
_Fn, _Args...>::value;
 
-#endif // __has_builtin(__is_nothrow_invocable_r)
+#  endif // __has_builtin(__is_nothrow_invocable_r)
 
 template 
 struct _LIBCPP_TEMPLATE_VIS invoke_result : __invoke_of<_Fn, _Args...> {};

``




https://github.com/llvm/llvm-project/pull/81213
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [Clang] Add __is_invocable_r and __is_nothrow_invocable_r (PR #81213)

2024-02-08 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-libcxx

@llvm/pr-subscribers-clang

Author: Nikolas Klauser (philnik777)


Changes

This patch also uses the new builtins in libc++.


---

Patch is 37.90 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/81213.diff


7 Files Affected:

- (modified) clang/docs/LanguageExtensions.rst (+2) 
- (modified) clang/docs/ReleaseNotes.rst (+4) 
- (modified) clang/include/clang/AST/Type.h (+3) 
- (modified) clang/include/clang/Basic/TokenKinds.def (+2) 
- (modified) clang/lib/Sema/SemaExprCXX.cpp (+271-119) 
- (added) clang/test/SemaCXX/type-traits-invocable.cpp (+288) 
- (modified) libcxx/include/__type_traits/invoke.h (+36) 


``diff
diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index e91156837290f7..bf061590e5ca0b 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -1582,6 +1582,7 @@ The following type trait primitives are supported by 
Clang. Those traits marked
 * ``__is_integral`` (C++, Embarcadero)
 * ``__is_interface_class`` (Microsoft):
   Returns ``false``, even for types defined with ``__interface``.
+* ``__is_invocable_r`` (Clang)
 * ``__is_literal`` (Clang):
   Synonym for ``__is_literal_type``.
 * ``__is_literal_type`` (C++, GNU, Microsoft):
@@ -1594,6 +1595,7 @@ The following type trait primitives are supported by 
Clang. Those traits marked
 * ``__is_nothrow_assignable`` (C++, MSVC 2013)
 * ``__is_nothrow_constructible`` (C++, MSVC 2013)
 * ``__is_nothrow_destructible`` (C++, MSVC 2013)
+* ``__is_nothrow_invocable_r`` (Clang)
 * ``__is_nullptr`` (C++, GNU, Microsoft, Embarcadero):
   Returns true for ``std::nullptr_t`` and false for everything else. The
   corresponding standard library feature is ``std::is_null_pointer``, but
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index cd8a82f281f52a..8a4ae646c008f6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -78,6 +78,10 @@ here. Generic improvements to Clang as a whole or to its 
underlying
 infrastructure are described first, followed by language-specific
 sections with improvements to Clang's support for those languages.
 
+- The builtins `__is_invocable_r` and `__is_nothrow_invocable_r` have been 
added.
+  These are equivalent to the standard library builtins `std::is_invocable_r`
+  and `std::is_nothrow_invocable_r`.
+
 C++ Language Changes
 
 
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index d6a55f39a4bede..fe10391ac7057c 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -926,6 +926,9 @@ class QualType {
   /// Return true if this is a trivially equality comparable type.
   bool isTriviallyEqualityComparableType(const ASTContext &Context) const;
 
+  /// Returns true if this is an invocable type.
+  bool isInvocableType() const;
+
   /// Returns true if it is a class and it might be dynamic.
   bool mayBeDynamicClass() const;
 
diff --git a/clang/include/clang/Basic/TokenKinds.def 
b/clang/include/clang/Basic/TokenKinds.def
index 23817cde7a9354..6467a52c82cb5b 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -532,6 +532,8 @@ 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_N(__is_invocable_r, IsInvocableR, KEYCXX)
+TYPE_TRAIT_N(__is_nothrow_invocable_r, IsNothrowInvocableR, KEYCXX)
 TYPE_TRAIT_1(__can_pass_in_regs, CanPassInRegs, KEYCXX)
 TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)
 TYPE_TRAIT_2(__reference_constructs_from_temporary, 
ReferenceConstructsFromTemporary, KEYCXX)
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 246d2313e089f3..4f4b6492e58880 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5468,6 +5468,266 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, 
TypeTrait UTT,
 static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
 QualType RhsT, SourceLocation KeyLoc);
 
+static bool IsBaseOf(Sema &Self, QualType LhsT, QualType RhsT,
+ SourceLocation KeyLoc) {
+  // C++0x [meta.rel]p2
+  // Base is a base class of Derived without regard to cv-qualifiers or
+  // Base and Derived are not unions and name the same class type without
+  // regard to cv-qualifiers.
+
+  const RecordType *lhsRecord = LhsT->getAs();
+  const RecordType *rhsRecord = RhsT->getAs();
+  if (!rhsRecord || !lhsRecord) {
+const ObjCObjectType *LHSObjTy = LhsT->getAs();
+const ObjCObjectType *RHSObjTy = RhsT->getAs();
+if (!LHSObjTy || !RHSObjTy)
+  return false;
+
+ObjCInterfaceDecl *BaseInterface = LHSObjTy->getInterface();
+

[clang] [libcxx] [Clang] Add __is_invocable_r and __is_nothrow_invocable_r (PR #81213)

2024-02-08 Thread Nikolas Klauser via cfe-commits

https://github.com/philnik777 created 
https://github.com/llvm/llvm-project/pull/81213

This patch also uses the new builtins in libc++.


>From 6c74eb263dd889858f3f7be328d85fe354f71835 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser 
Date: Mon, 11 Sep 2023 04:31:02 +0200
Subject: [PATCH] [Clang] Add __is_invocable_r and __is_nothrow_invocable_r

This patch also uses the new builtins in libc++.
---
 clang/docs/LanguageExtensions.rst|   2 +
 clang/docs/ReleaseNotes.rst  |   4 +
 clang/include/clang/AST/Type.h   |   3 +
 clang/include/clang/Basic/TokenKinds.def |   2 +
 clang/lib/Sema/SemaExprCXX.cpp   | 390 +--
 clang/test/SemaCXX/type-traits-invocable.cpp | 288 ++
 libcxx/include/__type_traits/invoke.h|  36 ++
 7 files changed, 606 insertions(+), 119 deletions(-)
 create mode 100644 clang/test/SemaCXX/type-traits-invocable.cpp

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index e91156837290f7..bf061590e5ca0b 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -1582,6 +1582,7 @@ The following type trait primitives are supported by 
Clang. Those traits marked
 * ``__is_integral`` (C++, Embarcadero)
 * ``__is_interface_class`` (Microsoft):
   Returns ``false``, even for types defined with ``__interface``.
+* ``__is_invocable_r`` (Clang)
 * ``__is_literal`` (Clang):
   Synonym for ``__is_literal_type``.
 * ``__is_literal_type`` (C++, GNU, Microsoft):
@@ -1594,6 +1595,7 @@ The following type trait primitives are supported by 
Clang. Those traits marked
 * ``__is_nothrow_assignable`` (C++, MSVC 2013)
 * ``__is_nothrow_constructible`` (C++, MSVC 2013)
 * ``__is_nothrow_destructible`` (C++, MSVC 2013)
+* ``__is_nothrow_invocable_r`` (Clang)
 * ``__is_nullptr`` (C++, GNU, Microsoft, Embarcadero):
   Returns true for ``std::nullptr_t`` and false for everything else. The
   corresponding standard library feature is ``std::is_null_pointer``, but
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index cd8a82f281f52a..8a4ae646c008f6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -78,6 +78,10 @@ here. Generic improvements to Clang as a whole or to its 
underlying
 infrastructure are described first, followed by language-specific
 sections with improvements to Clang's support for those languages.
 
+- The builtins `__is_invocable_r` and `__is_nothrow_invocable_r` have been 
added.
+  These are equivalent to the standard library builtins `std::is_invocable_r`
+  and `std::is_nothrow_invocable_r`.
+
 C++ Language Changes
 
 
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index d6a55f39a4bede..fe10391ac7057c 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -926,6 +926,9 @@ class QualType {
   /// Return true if this is a trivially equality comparable type.
   bool isTriviallyEqualityComparableType(const ASTContext &Context) const;
 
+  /// Returns true if this is an invocable type.
+  bool isInvocableType() const;
+
   /// Returns true if it is a class and it might be dynamic.
   bool mayBeDynamicClass() const;
 
diff --git a/clang/include/clang/Basic/TokenKinds.def 
b/clang/include/clang/Basic/TokenKinds.def
index 23817cde7a9354..6467a52c82cb5b 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -532,6 +532,8 @@ 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_N(__is_invocable_r, IsInvocableR, KEYCXX)
+TYPE_TRAIT_N(__is_nothrow_invocable_r, IsNothrowInvocableR, KEYCXX)
 TYPE_TRAIT_1(__can_pass_in_regs, CanPassInRegs, KEYCXX)
 TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)
 TYPE_TRAIT_2(__reference_constructs_from_temporary, 
ReferenceConstructsFromTemporary, KEYCXX)
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 246d2313e089f3..4f4b6492e58880 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5468,6 +5468,266 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, 
TypeTrait UTT,
 static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
 QualType RhsT, SourceLocation KeyLoc);
 
+static bool IsBaseOf(Sema &Self, QualType LhsT, QualType RhsT,
+ SourceLocation KeyLoc) {
+  // C++0x [meta.rel]p2
+  // Base is a base class of Derived without regard to cv-qualifiers or
+  // Base and Derived are not unions and name the same class type without
+  // regard to cv-qualifiers.
+
+  const RecordType *lhsRecord = LhsT->getAs();
+  const RecordType *rhsRecord = RhsT->getAs();
+  if (!rhsRecord || !lhsRecord) {
+const ObjCObjec