[clang] [clang] __is_trivially_equality_comparable for types containing lambdas (PR #68506)

Amirreza Ashouri via cfe-commits cfe-commits at lists.llvm.org
Sun Oct 8 06:10:32 PDT 2023


https://github.com/AMP999 updated https://github.com/llvm/llvm-project/pull/68506

>From ae2cd56b1c68353aae6c74524e71973ce6ca6904 Mon Sep 17 00:00:00 2001
From: Amirreza Ashouri <ar.ashouri999 at gmail.com>
Date: Sat, 7 Oct 2023 19:02:34 +0330
Subject: [PATCH 1/2] [clang] Rename some misleading names (Non-functional)
 These names could be misleading; should we change them to
 `NonTriviallyComparable` instead?

---
 clang/test/SemaCXX/type-traits.cpp | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp
index a35689d52978fcc..a1315f1966a6dd4 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -3160,11 +3160,18 @@ static_assert(!__is_trivially_equality_comparable(float), "");
 static_assert(!__is_trivially_equality_comparable(double), "");
 static_assert(!__is_trivially_equality_comparable(long double), "");
 
-struct TriviallyEqualityComparableNoDefaultedComparator {
+struct NonTriviallyEqualityComparableNoComparator {
   int i;
   int j;
 };
-static_assert(!__is_trivially_equality_comparable(TriviallyEqualityComparableNoDefaultedComparator), "");
+static_assert(!__is_trivially_equality_comparable(NonTriviallyEqualityComparableNoComparator), "");
+
+struct NonTriviallyEqualityComparableNonDefaultedComparator {
+  int i;
+  int j;
+  bool operator==(const NonTriviallyEqualityComparableNonDefaultedComparator&);
+};
+static_assert(!__is_trivially_equality_comparable(NonTriviallyEqualityComparableNonDefaultedComparator), "");
 
 #if __cplusplus >= 202002L
 
@@ -3177,7 +3184,7 @@ struct TriviallyEqualityComparable {
 
   bool operator==(const TriviallyEqualityComparable&) const = default;
 };
-static_assert(__is_trivially_equality_comparable(TriviallyEqualityComparable), "");
+static_assert(__is_trivially_equality_comparable(TriviallyEqualityComparable));
 
 struct TriviallyEqualityComparableContainsArray {
   int a[4];

>From a584b4bdd6bad3a8c8db3249b096e18c5e955839 Mon Sep 17 00:00:00 2001
From: Amirreza Ashouri <ar.ashouri999 at gmail.com>
Date: Sat, 7 Oct 2023 19:07:32 +0330
Subject: [PATCH 2/2] [clang] __is_trivially_equality_comparable for types
 containing lambdas

Lambdas (closure types) are trivially equality-comparable iff they are
non-capturing, because non-capturing lambdas are convertible to function
pointers: if (lam1 == lam2) compiles, then lam1 and lam2 must have
the same type, and be always-equal, and be empty.
---
 clang/lib/AST/Type.cpp             | 828 +++++++++++++++--------------
 clang/test/SemaCXX/type-traits.cpp |  11 +
 2 files changed, 452 insertions(+), 387 deletions(-)

diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 4c433f7fe9daca0..324f5321e631b52 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -59,21 +59,21 @@ using namespace clang;
 
 bool Qualifiers::isStrictSupersetOf(Qualifiers Other) const {
   return (*this != Other) &&
-    // CVR qualifiers superset
-    (((Mask & CVRMask) | (Other.Mask & CVRMask)) == (Mask & CVRMask)) &&
-    // ObjC GC qualifiers superset
-    ((getObjCGCAttr() == Other.getObjCGCAttr()) ||
-     (hasObjCGCAttr() && !Other.hasObjCGCAttr())) &&
-    // Address space superset.
-    ((getAddressSpace() == Other.getAddressSpace()) ||
-     (hasAddressSpace()&& !Other.hasAddressSpace())) &&
-    // Lifetime qualifier superset.
-    ((getObjCLifetime() == Other.getObjCLifetime()) ||
-     (hasObjCLifetime() && !Other.hasObjCLifetime()));
-}
-
-const IdentifierInfo* QualType::getBaseTypeIdentifier() const {
-  const Type* ty = getTypePtr();
+         // CVR qualifiers superset
+         (((Mask & CVRMask) | (Other.Mask & CVRMask)) == (Mask & CVRMask)) &&
+         // ObjC GC qualifiers superset
+         ((getObjCGCAttr() == Other.getObjCGCAttr()) ||
+          (hasObjCGCAttr() && !Other.hasObjCGCAttr())) &&
+         // Address space superset.
+         ((getAddressSpace() == Other.getAddressSpace()) ||
+          (hasAddressSpace() && !Other.hasAddressSpace())) &&
+         // Lifetime qualifier superset.
+         ((getObjCLifetime() == Other.getObjCLifetime()) ||
+          (hasObjCLifetime() && !Other.hasObjCLifetime()));
+}
+
+const IdentifierInfo *QualType::getBaseTypeIdentifier() const {
+  const Type *ty = getTypePtr();
   NamedDecl *ND = nullptr;
   if (ty->isPointerType() || ty->isReferenceType())
     return ty->getPointeeType().getBaseTypeIdentifier();
@@ -84,8 +84,9 @@ const IdentifierInfo* QualType::getBaseTypeIdentifier() const {
   else if (ty->getTypeClass() == Type::Typedef)
     ND = ty->castAs<TypedefType>()->getDecl();
   else if (ty->isArrayType())
-    return ty->castAsArrayTypeUnsafe()->
-        getElementType().getBaseTypeIdentifier();
+    return ty->castAsArrayTypeUnsafe()
+        ->getElementType()
+        .getBaseTypeIdentifier();
 
   if (ND)
     return ND->getIdentifier();
@@ -114,7 +115,7 @@ bool QualType::isConstant(QualType T, const ASTContext &Ctx) {
 
 std::optional<QualType::NonConstantStorageReason>
 QualType::isNonConstantStorage(const ASTContext &Ctx, bool ExcludeCtor,
-                            bool ExcludeDtor) {
+                               bool ExcludeDtor) {
   if (!isConstant(Ctx) && !(*this)->isReferenceType())
     return NonConstantStorageReason::NonConstNonReferenceType;
   if (!Ctx.getLangOpts().CPlusPlus)
@@ -159,9 +160,10 @@ ArrayType::ArrayType(TypeClass tc, QualType et, QualType can,
   ArrayTypeBits.SizeModifier = sm;
 }
 
-unsigned ConstantArrayType::getNumAddressingBits(const ASTContext &Context,
-                                                 QualType ElementType,
-                                               const llvm::APInt &NumElements) {
+unsigned
+ConstantArrayType::getNumAddressingBits(const ASTContext &Context,
+                                        QualType ElementType,
+                                        const llvm::APInt &NumElements) {
   uint64_t ElementSize = Context.getTypeSizeInChars(ElementType).getQuantity();
 
   // Fast path the common cases so we can avoid the conservative computation
@@ -185,8 +187,8 @@ unsigned ConstantArrayType::getNumAddressingBits(const ASTContext &Context,
   // Otherwise, use APSInt to handle arbitrary sized values.
   llvm::APSInt SizeExtended(NumElements, true);
   unsigned SizeTypeBits = Context.getTypeSize(Context.getSizeType());
-  SizeExtended = SizeExtended.extend(std::max(SizeTypeBits,
-                                              SizeExtended.getBitWidth()) * 2);
+  SizeExtended = SizeExtended.extend(
+      std::max(SizeTypeBits, SizeExtended.getBitWidth()) * 2);
 
   llvm::APSInt TotalSize(llvm::APInt(SizeExtended.getBitWidth(), ElementSize));
   TotalSize *= SizeExtended;
@@ -233,11 +235,9 @@ DependentSizedArrayType::DependentSizedArrayType(QualType et, QualType can,
       Brackets(brackets) {}
 
 void DependentSizedArrayType::Profile(llvm::FoldingSetNodeID &ID,
-                                      const ASTContext &Context,
-                                      QualType ET,
+                                      const ASTContext &Context, QualType ET,
                                       ArraySizeModifier SizeMod,
-                                      unsigned TypeQuals,
-                                      Expr *E) {
+                                      unsigned TypeQuals, Expr *E) {
   ID.AddPointer(ET.getAsOpaquePtr());
   ID.AddInteger(SizeMod);
   ID.AddInteger(TypeQuals);
@@ -277,10 +277,10 @@ DependentSizedExtVectorType::DependentSizedExtVectorType(QualType ElementType,
                          : TypeDependence::None)),
       SizeExpr(SizeExpr), ElementType(ElementType), loc(loc) {}
 
-void
-DependentSizedExtVectorType::Profile(llvm::FoldingSetNodeID &ID,
-                                     const ASTContext &Context,
-                                     QualType ElementType, Expr *SizeExpr) {
+void DependentSizedExtVectorType::Profile(llvm::FoldingSetNodeID &ID,
+                                          const ASTContext &Context,
+                                          QualType ElementType,
+                                          Expr *SizeExpr) {
   ID.AddPointer(ElementType.getAsOpaquePtr());
   SizeExpr->Profile(ID, Context, true);
 }
@@ -401,7 +401,8 @@ const Type *Type::getArrayElementTypeNoTypeQual() const {
   // If this is a typedef for an array type, strip the typedef off without
   // losing all typedef information.
   return cast<ArrayType>(getUnqualifiedDesugaredType())
-    ->getElementType().getTypePtr();
+      ->getElementType()
+      .getTypePtr();
 }
 
 /// getDesugaredType - Return the specified type with any "sugar" removed from
@@ -425,8 +426,8 @@ QualType QualType::getSingleStepDesugaredTypeImpl(QualType type,
 // Check that no type class is polymorphic. LLVM style RTTI should be used
 // instead. If absolutely needed an exception can still be added here by
 // defining the appropriate macro (but please don't do this).
-#define TYPE(CLASS, BASE) \
-  static_assert(!std::is_polymorphic<CLASS##Type>::value, \
+#define TYPE(CLASS, BASE)                                                      \
+  static_assert(!std::is_polymorphic<CLASS##Type>::value,                      \
                 #CLASS "Type should not be polymorphic!");
 #include "clang/AST/TypeNodes.inc"
 
@@ -445,11 +446,12 @@ QualType QualType::getSingleStepDesugaredTypeImpl(QualType type,
 QualType Type::getLocallyUnqualifiedSingleStepDesugaredType() const {
   switch (getTypeClass()) {
 #define ABSTRACT_TYPE(Class, Parent)
-#define TYPE(Class, Parent) \
-  case Type::Class: { \
-    const auto *ty = cast<Class##Type>(this); \
-    if (!ty->isSugared()) return QualType(ty, 0); \
-    return ty->desugar(); \
+#define TYPE(Class, Parent)                                                    \
+  case Type::Class: {                                                          \
+    const auto *ty = cast<Class##Type>(this);                                  \
+    if (!ty->isSugared())                                                      \
+      return QualType(ty, 0);                                                  \
+    return ty->desugar();                                                      \
   }
 #include "clang/AST/TypeNodes.inc"
   }
@@ -464,14 +466,14 @@ SplitQualType QualType::getSplitDesugaredType(QualType T) {
     const Type *CurTy = Qs.strip(Cur);
     switch (CurTy->getTypeClass()) {
 #define ABSTRACT_TYPE(Class, Parent)
-#define TYPE(Class, Parent) \
-    case Type::Class: { \
-      const auto *Ty = cast<Class##Type>(CurTy); \
-      if (!Ty->isSugared()) \
-        return SplitQualType(Ty, Qs); \
-      Cur = Ty->desugar(); \
-      break; \
-    }
+#define TYPE(Class, Parent)                                                    \
+  case Type::Class: {                                                          \
+    const auto *Ty = cast<Class##Type>(CurTy);                                 \
+    if (!Ty->isSugared())                                                      \
+      return SplitQualType(Ty, Qs);                                            \
+    Cur = Ty->desugar();                                                       \
+    break;                                                                     \
+  }
 #include "clang/AST/TypeNodes.inc"
     }
   }
@@ -493,13 +495,14 @@ SplitQualType QualType::getSplitUnqualifiedTypeImpl(QualType type) {
     // sugared.
     switch (split.Ty->getTypeClass()) {
 #define ABSTRACT_TYPE(Class, Parent)
-#define TYPE(Class, Parent) \
-    case Type::Class: { \
-      const auto *ty = cast<Class##Type>(split.Ty); \
-      if (!ty->isSugared()) goto done; \
-      next = ty->desugar(); \
-      break; \
-    }
+#define TYPE(Class, Parent)                                                    \
+  case Type::Class: {                                                          \
+    const auto *ty = cast<Class##Type>(split.Ty);                              \
+    if (!ty->isSugared())                                                      \
+      goto done;                                                               \
+    next = ty->desugar();                                                      \
+    break;                                                                     \
+  }
 #include "clang/AST/TypeNodes.inc"
     }
 
@@ -512,7 +515,7 @@ SplitQualType QualType::getSplitUnqualifiedTypeImpl(QualType type) {
     }
   }
 
- done:
+done:
   return SplitQualType(lastTypeWithQuals, quals);
 }
 
@@ -526,19 +529,20 @@ QualType QualType::IgnoreParens(QualType T) {
 /// This will check for a T (which should be a Type which can act as
 /// sugar, such as a TypedefType) by removing any existing sugar until it
 /// reaches a T or a non-sugared type.
-template<typename T> static const T *getAsSugar(const Type *Cur) {
+template <typename T> static const T *getAsSugar(const Type *Cur) {
   while (true) {
     if (const auto *Sugar = dyn_cast<T>(Cur))
       return Sugar;
     switch (Cur->getTypeClass()) {
 #define ABSTRACT_TYPE(Class, Parent)
-#define TYPE(Class, Parent) \
-    case Type::Class: { \
-      const auto *Ty = cast<Class##Type>(Cur); \
-      if (!Ty->isSugared()) return 0; \
-      Cur = Ty->desugar().getTypePtr(); \
-      break; \
-    }
+#define TYPE(Class, Parent)                                                    \
+  case Type::Class: {                                                          \
+    const auto *Ty = cast<Class##Type>(Cur);                                   \
+    if (!Ty->isSugared())                                                      \
+      return 0;                                                                \
+    Cur = Ty->desugar().getTypePtr();                                          \
+    break;                                                                     \
+  }
 #include "clang/AST/TypeNodes.inc"
     }
   }
@@ -569,13 +573,14 @@ const Type *Type::getUnqualifiedDesugaredType() const {
   while (true) {
     switch (Cur->getTypeClass()) {
 #define ABSTRACT_TYPE(Class, Parent)
-#define TYPE(Class, Parent) \
-    case Class: { \
-      const auto *Ty = cast<Class##Type>(Cur); \
-      if (!Ty->isSugared()) return Cur; \
-      Cur = Ty->desugar().getTypePtr(); \
-      break; \
-    }
+#define TYPE(Class, Parent)                                                    \
+  case Class: {                                                                \
+    const auto *Ty = cast<Class##Type>(Cur);                                   \
+    if (!Ty->isSugared())                                                      \
+      return Cur;                                                              \
+    Cur = Ty->desugar().getTypePtr();                                          \
+    break;                                                                     \
+  }
 #include "clang/AST/TypeNodes.inc"
     }
   }
@@ -725,8 +730,9 @@ bool Type::isObjCIdOrObjectKindOfType(const ASTContext &ctx,
     return false;
 
   // Figure out the type bound for the __kindof type.
-  bound = OPT->getObjectType()->stripObjCKindOfTypeAndQuals(ctx)
-            ->getAs<ObjCObjectType>();
+  bound = OPT->getObjectType()
+              ->stripObjCKindOfTypeAndQuals(ctx)
+              ->getAs<ObjCObjectType>();
   return true;
 }
 
@@ -829,8 +835,8 @@ bool ObjCObjectType::isKindOfType() const {
   return false;
 }
 
-QualType ObjCObjectType::stripObjCKindOfTypeAndQuals(
-           const ASTContext &ctx) const {
+QualType
+ObjCObjectType::stripObjCKindOfTypeAndQuals(const ASTContext &ctx) const {
   if (!isKindOfType() && qual_empty())
     return QualType(this, 0);
 
@@ -840,11 +846,11 @@ QualType ObjCObjectType::stripObjCKindOfTypeAndQuals(
   if (const auto *baseObj = splitBaseType.Ty->getAs<ObjCObjectType>())
     baseType = baseObj->stripObjCKindOfTypeAndQuals(ctx);
 
-  return ctx.getObjCObjectType(ctx.getQualifiedType(baseType,
-                                                    splitBaseType.Quals),
-                               getTypeArgsAsWritten(),
-                               /*protocols=*/{},
-                               /*isKindOf=*/false);
+  return ctx.getObjCObjectType(
+      ctx.getQualifiedType(baseType, splitBaseType.Quals),
+      getTypeArgsAsWritten(),
+      /*protocols=*/{},
+      /*isKindOf=*/false);
 }
 
 ObjCInterfaceDecl *ObjCInterfaceType::getDecl() const {
@@ -855,7 +861,7 @@ ObjCInterfaceDecl *ObjCInterfaceType::getDecl() const {
 }
 
 const ObjCObjectPointerType *ObjCObjectPointerType::stripObjCKindOfTypeAndQuals(
-                               const ASTContext &ctx) const {
+    const ASTContext &ctx) const {
   if (!isKindOfType() && qual_empty())
     return this;
 
@@ -891,22 +897,22 @@ struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> {
   // None of the clients of this transformation can occur where
   // there are dependent types, so skip dependent types.
 #define TYPE(Class, Base)
-#define DEPENDENT_TYPE(Class, Base) \
+#define DEPENDENT_TYPE(Class, Base)                                            \
   QualType Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); }
 #include "clang/AST/TypeNodes.inc"
 
-#define TRIVIAL_TYPE_CLASS(Class) \
+#define TRIVIAL_TYPE_CLASS(Class)                                              \
   QualType Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); }
-#define SUGARED_TYPE_CLASS(Class) \
-  QualType Visit##Class##Type(const Class##Type *T) { \
-    if (!T->isSugared()) \
-      return QualType(T, 0); \
-    QualType desugaredType = recurse(T->desugar()); \
-    if (desugaredType.isNull()) \
-      return {}; \
-    if (desugaredType.getAsOpaquePtr() == T->desugar().getAsOpaquePtr()) \
-      return QualType(T, 0); \
-    return desugaredType; \
+#define SUGARED_TYPE_CLASS(Class)                                              \
+  QualType Visit##Class##Type(const Class##Type *T) {                          \
+    if (!T->isSugared())                                                       \
+      return QualType(T, 0);                                                   \
+    QualType desugaredType = recurse(T->desugar());                            \
+    if (desugaredType.isNull())                                                \
+      return {};                                                               \
+    if (desugaredType.getAsOpaquePtr() == T->desugar().getAsOpaquePtr())       \
+      return QualType(T, 0);                                                   \
+    return desugaredType;                                                      \
   }
 
   TRIVIAL_TYPE_CLASS(Builtin)
@@ -949,8 +955,8 @@ struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> {
     if (pointeeType.isNull())
       return {};
 
-    if (pointeeType.getAsOpaquePtr()
-          == T->getPointeeTypeAsWritten().getAsOpaquePtr())
+    if (pointeeType.getAsOpaquePtr() ==
+        T->getPointeeTypeAsWritten().getAsOpaquePtr())
       return QualType(T, 0);
 
     return Ctx.getLValueReferenceType(pointeeType, T->isSpelledAsLValue());
@@ -961,8 +967,8 @@ struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> {
     if (pointeeType.isNull())
       return {};
 
-    if (pointeeType.getAsOpaquePtr()
-          == T->getPointeeTypeAsWritten().getAsOpaquePtr())
+    if (pointeeType.getAsOpaquePtr() ==
+        T->getPointeeTypeAsWritten().getAsOpaquePtr())
       return QualType(T, 0);
 
     return Ctx.getRValueReferenceType(pointeeType);
@@ -1000,10 +1006,9 @@ struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> {
     if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())
       return QualType(T, 0);
 
-    return Ctx.getVariableArrayType(elementType, T->getSizeExpr(),
-                                    T->getSizeModifier(),
-                                    T->getIndexTypeCVRQualifiers(),
-                                    T->getBracketsRange());
+    return Ctx.getVariableArrayType(
+        elementType, T->getSizeExpr(), T->getSizeModifier(),
+        T->getIndexTypeCVRQualifiers(), T->getBracketsRange());
   }
 
   QualType VisitIncompleteArrayType(const IncompleteArrayType *T) {
@@ -1135,8 +1140,8 @@ struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> {
     if (adjustedType.isNull())
       return {};
 
-    if (originalType.getAsOpaquePtr()
-          == T->getOriginalType().getAsOpaquePtr() &&
+    if (originalType.getAsOpaquePtr() ==
+            T->getOriginalType().getAsOpaquePtr() &&
         adjustedType.getAsOpaquePtr() == T->getAdjustedType().getAsOpaquePtr())
       return QualType(T, 0);
 
@@ -1148,8 +1153,7 @@ struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> {
     if (originalType.isNull())
       return {};
 
-    if (originalType.getAsOpaquePtr()
-          == T->getOriginalType().getAsOpaquePtr())
+    if (originalType.getAsOpaquePtr() == T->getOriginalType().getAsOpaquePtr())
       return QualType(T, 0);
 
     return Ctx.getDecayedType(originalType);
@@ -1174,10 +1178,10 @@ struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> {
     if (equivalentType.isNull())
       return {};
 
-    if (modifiedType.getAsOpaquePtr()
-          == T->getModifiedType().getAsOpaquePtr() &&
-        equivalentType.getAsOpaquePtr()
-          == T->getEquivalentType().getAsOpaquePtr())
+    if (modifiedType.getAsOpaquePtr() ==
+            T->getModifiedType().getAsOpaquePtr() &&
+        equivalentType.getAsOpaquePtr() ==
+            T->getEquivalentType().getAsOpaquePtr())
       return QualType(T, 0);
 
     return Ctx.getAttributedType(T->getAttrKind(), modifiedType,
@@ -1189,8 +1193,8 @@ struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> {
     if (replacementType.isNull())
       return {};
 
-    if (replacementType.getAsOpaquePtr()
-          == T->getReplacementType().getAsOpaquePtr())
+    if (replacementType.getAsOpaquePtr() ==
+        T->getReplacementType().getAsOpaquePtr())
       return QualType(T, 0);
 
     return Ctx.getSubstTemplateTypeParmType(replacementType,
@@ -1209,13 +1213,11 @@ struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> {
     if (deducedType.isNull())
       return {};
 
-    if (deducedType.getAsOpaquePtr()
-          == T->getDeducedType().getAsOpaquePtr())
+    if (deducedType.getAsOpaquePtr() == T->getDeducedType().getAsOpaquePtr())
       return QualType(T, 0);
 
-    return Ctx.getAutoType(deducedType, T->getKeyword(),
-                           T->isDependentType(), /*IsPack=*/false,
-                           T->getTypeConstraintConcept(),
+    return Ctx.getAutoType(deducedType, T->getKeyword(), T->isDependentType(),
+                           /*IsPack=*/false, T->getTypeConstraintConcept(),
                            T->getTypeConstraintArguments());
   }
 
@@ -1255,8 +1257,7 @@ struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> {
     if (pointeeType.isNull())
       return {};
 
-    if (pointeeType.getAsOpaquePtr()
-          == T->getPointeeType().getAsOpaquePtr())
+    if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr())
       return QualType(T, 0);
 
     return Ctx.getObjCObjectPointerType(pointeeType);
@@ -1267,8 +1268,7 @@ struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> {
     if (valueType.isNull())
       return {};
 
-    if (valueType.getAsOpaquePtr()
-          == T->getValueType().getAsOpaquePtr())
+    if (valueType.getAsOpaquePtr() == T->getValueType().getAsOpaquePtr())
       return QualType(T, 0);
 
     return Ctx.getAtomicType(valueType);
@@ -1305,7 +1305,7 @@ struct SubstObjCTypeArgsVisitor
       protocolsVec.append(OTPTy->qual_begin(), OTPTy->qual_end());
       ArrayRef<ObjCProtocolDecl *> protocolsToApply = protocolsVec;
       return Ctx.applyObjCProtocolQualifiers(
-          argType, protocolsToApply, hasError, true/*allowOnPointerType*/);
+          argType, protocolsToApply, hasError, true /*allowOnPointerType*/);
     }
 
     switch (SubstContext) {
@@ -1343,7 +1343,7 @@ struct SubstObjCTypeArgsVisitor
     // If we have a function type, update the substitution context
     // appropriately.
 
-    //Substitute result type.
+    // Substitute result type.
     QualType returnType = funcType->getReturnType().substObjCTypeArgs(
         Ctx, TypeArgs, ObjCSubstitutionContext::Result);
     if (returnType.isNull())
@@ -1615,14 +1615,14 @@ Type::getObjCSubstitutions(const DeclContext *dc) const {
   } else if (getAs<BlockPointerType>()) {
     ASTContext &ctx = dc->getParentASTContext();
     objectType = ctx.getObjCObjectType(ctx.ObjCBuiltinIdTy, {}, {})
-                   ->castAs<ObjCObjectType>();
+                     ->castAs<ObjCObjectType>();
   } else {
     objectType = getAs<ObjCObjectType>();
   }
 
   /// Extract the class from the receiver object type.
-  ObjCInterfaceDecl *curClassDecl = objectType ? objectType->getInterface()
-                                               : nullptr;
+  ObjCInterfaceDecl *curClassDecl =
+      objectType ? objectType->getInterface() : nullptr;
   if (!curClassDecl) {
     // If we don't have a context type (e.g., this is "id" or some
     // variant thereof), substitute the bounds.
@@ -1693,7 +1693,7 @@ void ObjCObjectType::computeSuperClassTypeSlow() const {
   ObjCTypeParamList *superClassTypeParams = superClassDecl->getTypeParamList();
   if (!superClassTypeParams) {
     CachedSuperClassType.setPointerAndInt(
-      superClassType->castAs<ObjCObjectType>(), true);
+        superClassType->castAs<ObjCObjectType>(), true);
     return;
   }
 
@@ -1708,19 +1708,18 @@ void ObjCObjectType::computeSuperClassTypeSlow() const {
   ObjCTypeParamList *typeParams = classDecl->getTypeParamList();
   if (!typeParams) {
     CachedSuperClassType.setPointerAndInt(
-      superClassType->castAs<ObjCObjectType>(), true);
+        superClassType->castAs<ObjCObjectType>(), true);
     return;
   }
 
   // If the subclass type isn't specialized, return the unspecialized
   // superclass.
   if (isUnspecialized()) {
-    QualType unspecializedSuper
-      = classDecl->getASTContext().getObjCInterfaceType(
-          superClassObjTy->getInterface());
+    QualType unspecializedSuper =
+        classDecl->getASTContext().getObjCInterfaceType(
+            superClassObjTy->getInterface());
     CachedSuperClassType.setPointerAndInt(
-      unspecializedSuper->castAs<ObjCObjectType>(),
-      true);
+        unspecializedSuper->castAs<ObjCObjectType>(), true);
     return;
   }
 
@@ -1728,16 +1727,18 @@ void ObjCObjectType::computeSuperClassTypeSlow() const {
   ArrayRef<QualType> typeArgs = getTypeArgs();
   assert(typeArgs.size() == typeParams->size());
   CachedSuperClassType.setPointerAndInt(
-    superClassType.substObjCTypeArgs(classDecl->getASTContext(), typeArgs,
-                                     ObjCSubstitutionContext::Superclass)
-      ->castAs<ObjCObjectType>(),
-    true);
+      superClassType
+          .substObjCTypeArgs(classDecl->getASTContext(), typeArgs,
+                             ObjCSubstitutionContext::Superclass)
+          ->castAs<ObjCObjectType>(),
+      true);
 }
 
 const ObjCInterfaceType *ObjCObjectPointerType::getInterfaceType() const {
   if (auto interfaceDecl = getObjectType()->getInterface()) {
-    return interfaceDecl->getASTContext().getObjCInterfaceType(interfaceDecl)
-             ->castAs<ObjCInterfaceType>();
+    return interfaceDecl->getASTContext()
+        .getObjCInterfaceType(interfaceDecl)
+        ->castAs<ObjCInterfaceType>();
   }
 
   return nullptr;
@@ -1846,103 +1847,100 @@ bool Type::hasAttr(attr::Kind AK) const {
 
 namespace {
 
-  class GetContainedDeducedTypeVisitor :
-    public TypeVisitor<GetContainedDeducedTypeVisitor, Type*> {
-    bool Syntactic;
+class GetContainedDeducedTypeVisitor
+    : public TypeVisitor<GetContainedDeducedTypeVisitor, Type *> {
+  bool Syntactic;
 
-  public:
-    GetContainedDeducedTypeVisitor(bool Syntactic = false)
-        : Syntactic(Syntactic) {}
+public:
+  GetContainedDeducedTypeVisitor(bool Syntactic = false)
+      : Syntactic(Syntactic) {}
 
-    using TypeVisitor<GetContainedDeducedTypeVisitor, Type*>::Visit;
+  using TypeVisitor<GetContainedDeducedTypeVisitor, Type *>::Visit;
 
-    Type *Visit(QualType T) {
-      if (T.isNull())
-        return nullptr;
-      return Visit(T.getTypePtr());
-    }
+  Type *Visit(QualType T) {
+    if (T.isNull())
+      return nullptr;
+    return Visit(T.getTypePtr());
+  }
 
-    // The deduced type itself.
-    Type *VisitDeducedType(const DeducedType *AT) {
-      return const_cast<DeducedType*>(AT);
-    }
+  // The deduced type itself.
+  Type *VisitDeducedType(const DeducedType *AT) {
+    return const_cast<DeducedType *>(AT);
+  }
 
-    // Only these types can contain the desired 'auto' type.
-    Type *VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
-      return Visit(T->getReplacementType());
-    }
+  // Only these types can contain the desired 'auto' type.
+  Type *VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
+    return Visit(T->getReplacementType());
+  }
 
-    Type *VisitElaboratedType(const ElaboratedType *T) {
-      return Visit(T->getNamedType());
-    }
+  Type *VisitElaboratedType(const ElaboratedType *T) {
+    return Visit(T->getNamedType());
+  }
 
-    Type *VisitPointerType(const PointerType *T) {
-      return Visit(T->getPointeeType());
-    }
+  Type *VisitPointerType(const PointerType *T) {
+    return Visit(T->getPointeeType());
+  }
 
-    Type *VisitBlockPointerType(const BlockPointerType *T) {
-      return Visit(T->getPointeeType());
-    }
+  Type *VisitBlockPointerType(const BlockPointerType *T) {
+    return Visit(T->getPointeeType());
+  }
 
-    Type *VisitReferenceType(const ReferenceType *T) {
-      return Visit(T->getPointeeTypeAsWritten());
-    }
+  Type *VisitReferenceType(const ReferenceType *T) {
+    return Visit(T->getPointeeTypeAsWritten());
+  }
 
-    Type *VisitMemberPointerType(const MemberPointerType *T) {
-      return Visit(T->getPointeeType());
-    }
+  Type *VisitMemberPointerType(const MemberPointerType *T) {
+    return Visit(T->getPointeeType());
+  }
 
-    Type *VisitArrayType(const ArrayType *T) {
-      return Visit(T->getElementType());
-    }
+  Type *VisitArrayType(const ArrayType *T) {
+    return Visit(T->getElementType());
+  }
 
-    Type *VisitDependentSizedExtVectorType(
-      const DependentSizedExtVectorType *T) {
-      return Visit(T->getElementType());
-    }
+  Type *VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T) {
+    return Visit(T->getElementType());
+  }
 
-    Type *VisitVectorType(const VectorType *T) {
-      return Visit(T->getElementType());
-    }
+  Type *VisitVectorType(const VectorType *T) {
+    return Visit(T->getElementType());
+  }
 
-    Type *VisitDependentSizedMatrixType(const DependentSizedMatrixType *T) {
-      return Visit(T->getElementType());
-    }
+  Type *VisitDependentSizedMatrixType(const DependentSizedMatrixType *T) {
+    return Visit(T->getElementType());
+  }
 
-    Type *VisitConstantMatrixType(const ConstantMatrixType *T) {
-      return Visit(T->getElementType());
-    }
+  Type *VisitConstantMatrixType(const ConstantMatrixType *T) {
+    return Visit(T->getElementType());
+  }
 
-    Type *VisitFunctionProtoType(const FunctionProtoType *T) {
-      if (Syntactic && T->hasTrailingReturn())
-        return const_cast<FunctionProtoType*>(T);
-      return VisitFunctionType(T);
-    }
+  Type *VisitFunctionProtoType(const FunctionProtoType *T) {
+    if (Syntactic && T->hasTrailingReturn())
+      return const_cast<FunctionProtoType *>(T);
+    return VisitFunctionType(T);
+  }
 
-    Type *VisitFunctionType(const FunctionType *T) {
-      return Visit(T->getReturnType());
-    }
+  Type *VisitFunctionType(const FunctionType *T) {
+    return Visit(T->getReturnType());
+  }
 
-    Type *VisitParenType(const ParenType *T) {
-      return Visit(T->getInnerType());
-    }
+  Type *VisitParenType(const ParenType *T) { return Visit(T->getInnerType()); }
 
-    Type *VisitAttributedType(const AttributedType *T) {
-      return Visit(T->getModifiedType());
-    }
+  Type *VisitAttributedType(const AttributedType *T) {
+    return Visit(T->getModifiedType());
+  }
 
-    Type *VisitMacroQualifiedType(const MacroQualifiedType *T) {
-      return Visit(T->getUnderlyingType());
-    }
+  Type *VisitMacroQualifiedType(const MacroQualifiedType *T) {
+    return Visit(T->getUnderlyingType());
+  }
 
-    Type *VisitAdjustedType(const AdjustedType *T) {
-      return Visit(T->getOriginalType());
-    }
+  Type *VisitAdjustedType(const AdjustedType *T) {
+    return Visit(T->getOriginalType());
+  }
 
-    Type *VisitPackExpansionType(const PackExpansionType *T) {
-      return Visit(T->getPattern());
-    }
-  };
+  Type *VisitPackExpansionType(const PackExpansionType *T) {
+    return Visit(T->getPattern());
+  }
+};
 
 } // namespace
 
@@ -2062,9 +2060,11 @@ bool Type::isChar32Type() const {
 /// types.
 bool Type::isAnyCharacterType() const {
   const auto *BT = dyn_cast<BuiltinType>(CanonicalType);
-  if (!BT) return false;
+  if (!BT)
+    return false;
   switch (BT->getKind()) {
-  default: return false;
+  default:
+    return false;
   case BuiltinType::Char_U:
   case BuiltinType::UChar:
   case BuiltinType::WChar_U:
@@ -2155,7 +2155,7 @@ bool Type::isUnsignedIntegerType() const {
 bool Type::isUnsignedIntegerOrEnumerationType() const {
   if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) {
     return BT->getKind() >= BuiltinType::Bool &&
-    BT->getKind() <= BuiltinType::UInt128;
+           BT->getKind() <= BuiltinType::UInt128;
   }
 
   if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) {
@@ -2212,7 +2212,7 @@ bool Type::isRealType() const {
     return BT->getKind() >= BuiltinType::Bool &&
            BT->getKind() <= BuiltinType::Ibm128;
   if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
-      return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped();
+    return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped();
   return isBitIntType();
 }
 
@@ -2236,11 +2236,16 @@ Type::ScalarTypeKind Type::getScalarTypeKind() const {
 
   const Type *T = CanonicalType.getTypePtr();
   if (const auto *BT = dyn_cast<BuiltinType>(T)) {
-    if (BT->getKind() == BuiltinType::Bool) return STK_Bool;
-    if (BT->getKind() == BuiltinType::NullPtr) return STK_CPointer;
-    if (BT->isInteger()) return STK_Integral;
-    if (BT->isFloatingPoint()) return STK_Floating;
-    if (BT->isFixedPointType()) return STK_FixedPoint;
+    if (BT->getKind() == BuiltinType::Bool)
+      return STK_Bool;
+    if (BT->getKind() == BuiltinType::NullPtr)
+      return STK_CPointer;
+    if (BT->isInteger())
+      return STK_Integral;
+    if (BT->isFloatingPoint())
+      return STK_Floating;
+    if (BT->isFixedPointType())
+      return STK_FixedPoint;
     llvm_unreachable("unknown scalar builtin type");
   } else if (isa<PointerType>(T)) {
     return STK_CPointer;
@@ -2302,7 +2307,8 @@ bool Type::isIncompleteType(NamedDecl **Def) const {
     *Def = nullptr;
 
   switch (CanonicalType->getTypeClass()) {
-  default: return false;
+  default:
+    return false;
   case Builtin:
     // Void is the only incomplete builtin type.  Per C99 6.2.5p19, it can never
     // be completed.
@@ -2327,8 +2333,9 @@ bool Type::isIncompleteType(NamedDecl **Def) const {
     // (C++ [dcl.array]p1).
     // We don't handle dependent-sized arrays (dependent types are never treated
     // as incomplete).
-    return cast<ArrayType>(CanonicalType)->getElementType()
-             ->isIncompleteType(Def);
+    return cast<ArrayType>(CanonicalType)
+        ->getElementType()
+        ->isIncompleteType(Def);
   case IncompleteArray:
     // An array of unknown size is an incomplete type (C99 6.2.5p22).
     return true;
@@ -2355,12 +2362,13 @@ bool Type::isIncompleteType(NamedDecl **Def) const {
     return true;
   }
   case ObjCObject:
-    return cast<ObjCObjectType>(CanonicalType)->getBaseType()
-             ->isIncompleteType(Def);
+    return cast<ObjCObjectType>(CanonicalType)
+        ->getBaseType()
+        ->isIncompleteType(Def);
   case ObjCInterface: {
     // ObjC interfaces are incomplete if they are @class, not @interface.
-    ObjCInterfaceDecl *Interface
-      = cast<ObjCInterfaceType>(CanonicalType)->getDecl();
+    ObjCInterfaceDecl *Interface =
+        cast<ObjCInterfaceType>(CanonicalType)->getDecl();
     if (Def)
       *Def = Interface;
     return !Interface->hasDefinition();
@@ -2472,9 +2480,10 @@ QualType Type::getSveEltType(const ASTContext &Ctx) const {
 bool Type::isRVVVLSBuiltinType() const {
   if (const BuiltinType *BT = getAs<BuiltinType>()) {
     switch (BT->getKind()) {
-#define RVV_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, NF, IsSigned, IsFP) \
-    case BuiltinType::Id: \
-      return NF == 1;
+#define RVV_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, NF, IsSigned,   \
+                        IsFP)                                                  \
+  case BuiltinType::Id:                                                        \
+    return NF == 1;
 #include "clang/Basic/RISCVVTypes.def"
     default:
       return false;
@@ -2517,7 +2526,8 @@ bool QualType::isCXX98PODType(const ASTContext &Context) const {
   QualType CanonicalType = getTypePtr()->CanonicalType;
   switch (CanonicalType->getTypeClass()) {
     // Everything not explicitly mentioned is not POD.
-  default: return false;
+  default:
+    return false;
   case Type::VariableArray:
   case Type::ConstantArray:
     // IncompleteArray is handled above.
@@ -2630,7 +2640,8 @@ bool QualType::isTriviallyCopyableType(const ASTContext &Context) const {
 
   if (const auto *RT = CanonicalType->getAs<RecordType>()) {
     if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
-      if (!ClassDecl->isTriviallyCopyable()) return false;
+      if (!ClassDecl->isTriviallyCopyable())
+        return false;
     }
 
     return true;
@@ -2663,6 +2674,9 @@ static bool
 HasNonDeletedDefaultedEqualityComparison(const CXXRecordDecl *Decl) {
   if (Decl->isUnion())
     return false;
+  if (Decl->isLambda())
+    return Decl->captures().empty() &&
+           (Decl->getLambdaCaptureDefault() == LCD_None);
 
   auto IsDefaultedOperatorEqualEqual = [&](const FunctionDecl *Function) {
     return Function->getOverloadedOperator() ==
@@ -2691,7 +2705,8 @@ HasNonDeletedDefaultedEqualityComparison(const CXXRecordDecl *Decl) {
          llvm::all_of(Decl->fields(), [](const FieldDecl *FD) {
            auto Type = FD->getType();
            if (Type->isArrayType())
-             Type = Type->getBaseElementTypeUnsafe()->getCanonicalTypeUnqualified();
+             Type = Type->getBaseElementTypeUnsafe()
+                        ->getCanonicalTypeUnqualified();
 
            if (Type->isReferenceType() || Type->isEnumeralType())
              return false;
@@ -2723,7 +2738,8 @@ bool QualType::isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const {
          getObjCLifetime() != Qualifiers::OCL_Weak;
 }
 
-bool QualType::hasNonTrivialToPrimitiveDefaultInitializeCUnion(const RecordDecl *RD) {
+bool QualType::hasNonTrivialToPrimitiveDefaultInitializeCUnion(
+    const RecordDecl *RD) {
   return RD->hasNonTrivialToPrimitiveDefaultInitializeCUnion();
 }
 
@@ -2885,7 +2901,8 @@ bool Type::isStandardLayoutType() const {
     return false;
 
   // As an extension, Clang treats vector types as Scalar types.
-  if (BaseTy->isScalarType() || BaseTy->isVectorType()) return true;
+  if (BaseTy->isScalarType() || BaseTy->isVectorType())
+    return true;
   if (const auto *RT = BaseTy->getAs<RecordType>()) {
     if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl()))
       if (!ClassDecl->isStandardLayout())
@@ -2927,17 +2944,20 @@ bool QualType::isCXX11PODType(const ASTContext &Context) const {
     return false;
 
   // As an extension, Clang treats vector types as Scalar types.
-  if (BaseTy->isScalarType() || BaseTy->isVectorType()) return true;
+  if (BaseTy->isScalarType() || BaseTy->isVectorType())
+    return true;
   if (const auto *RT = BaseTy->getAs<RecordType>()) {
     if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
       // C++11 [class]p10:
       //   A POD struct is a non-union class that is both a trivial class [...]
-      if (!ClassDecl->isTrivial()) return false;
+      if (!ClassDecl->isTrivial())
+        return false;
 
       // C++11 [class]p10:
       //   A POD struct is a non-union class that is both a trivial class and
       //   a standard-layout class [...]
-      if (!ClassDecl->isStandardLayout()) return false;
+      if (!ClassDecl->isStandardLayout())
+        return false;
 
       // C++11 [class]p10:
       //   A POD struct is a non-union class that is both a trivial class and
@@ -3010,24 +3030,35 @@ bool Type::isSpecifierType() const {
 ElaboratedTypeKeyword
 TypeWithKeyword::getKeywordForTypeSpec(unsigned TypeSpec) {
   switch (TypeSpec) {
-  default: return ETK_None;
-  case TST_typename: return ETK_Typename;
-  case TST_class: return ETK_Class;
-  case TST_struct: return ETK_Struct;
-  case TST_interface: return ETK_Interface;
-  case TST_union: return ETK_Union;
-  case TST_enum: return ETK_Enum;
-  }
-}
-
-TagTypeKind
-TypeWithKeyword::getTagTypeKindForTypeSpec(unsigned TypeSpec) {
-  switch(TypeSpec) {
-  case TST_class: return TTK_Class;
-  case TST_struct: return TTK_Struct;
-  case TST_interface: return TTK_Interface;
-  case TST_union: return TTK_Union;
-  case TST_enum: return TTK_Enum;
+  default:
+    return ETK_None;
+  case TST_typename:
+    return ETK_Typename;
+  case TST_class:
+    return ETK_Class;
+  case TST_struct:
+    return ETK_Struct;
+  case TST_interface:
+    return ETK_Interface;
+  case TST_union:
+    return ETK_Union;
+  case TST_enum:
+    return ETK_Enum;
+  }
+}
+
+TagTypeKind TypeWithKeyword::getTagTypeKindForTypeSpec(unsigned TypeSpec) {
+  switch (TypeSpec) {
+  case TST_class:
+    return TTK_Class;
+  case TST_struct:
+    return TTK_Struct;
+  case TST_interface:
+    return TTK_Interface;
+  case TST_union:
+    return TTK_Union;
+  case TST_enum:
+    return TTK_Enum;
   }
 
   llvm_unreachable("Type specifier is not a tag type kind.");
@@ -3036,11 +3067,16 @@ TypeWithKeyword::getTagTypeKindForTypeSpec(unsigned TypeSpec) {
 ElaboratedTypeKeyword
 TypeWithKeyword::getKeywordForTagTypeKind(TagTypeKind Kind) {
   switch (Kind) {
-  case TTK_Class: return ETK_Class;
-  case TTK_Struct: return ETK_Struct;
-  case TTK_Interface: return ETK_Interface;
-  case TTK_Union: return ETK_Union;
-  case TTK_Enum: return ETK_Enum;
+  case TTK_Class:
+    return ETK_Class;
+  case TTK_Struct:
+    return ETK_Struct;
+  case TTK_Interface:
+    return ETK_Interface;
+  case TTK_Union:
+    return ETK_Union;
+  case TTK_Enum:
+    return ETK_Enum;
   }
   llvm_unreachable("Unknown tag type kind.");
 }
@@ -3048,11 +3084,16 @@ TypeWithKeyword::getKeywordForTagTypeKind(TagTypeKind Kind) {
 TagTypeKind
 TypeWithKeyword::getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword) {
   switch (Keyword) {
-  case ETK_Class: return TTK_Class;
-  case ETK_Struct: return TTK_Struct;
-  case ETK_Interface: return TTK_Interface;
-  case ETK_Union: return TTK_Union;
-  case ETK_Enum: return TTK_Enum;
+  case ETK_Class:
+    return TTK_Class;
+  case ETK_Struct:
+    return TTK_Struct;
+  case ETK_Interface:
+    return TTK_Interface;
+  case ETK_Union:
+    return TTK_Union;
+  case ETK_Enum:
+    return TTK_Enum;
   case ETK_None: // Fall through.
   case ETK_Typename:
     llvm_unreachable("Elaborated type keyword is not a tag type kind.");
@@ -3060,8 +3101,7 @@ TypeWithKeyword::getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword) {
   llvm_unreachable("Unknown elaborated type keyword.");
 }
 
-bool
-TypeWithKeyword::KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword) {
+bool TypeWithKeyword::KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword) {
   switch (Keyword) {
   case ETK_None:
   case ETK_Typename:
@@ -3078,13 +3118,20 @@ TypeWithKeyword::KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword) {
 
 StringRef TypeWithKeyword::getKeywordName(ElaboratedTypeKeyword Keyword) {
   switch (Keyword) {
-  case ETK_None: return {};
-  case ETK_Typename: return "typename";
-  case ETK_Class:  return "class";
-  case ETK_Struct: return "struct";
-  case ETK_Interface: return "__interface";
-  case ETK_Union:  return "union";
-  case ETK_Enum:   return "enum";
+  case ETK_None:
+    return {};
+  case ETK_Typename:
+    return "typename";
+  case ETK_Class:
+    return "class";
+  case ETK_Struct:
+    return "struct";
+  case ETK_Interface:
+    return "__interface";
+  case ETK_Union:
+    return "union";
+  case ETK_Enum:
+    return "enum";
   }
 
   llvm_unreachable("Unknown elaborated type keyword.");
@@ -3110,13 +3157,10 @@ DependentTemplateSpecializationType::DependentTemplateSpecializationType(
   }
 }
 
-void
-DependentTemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
-                                             const ASTContext &Context,
-                                             ElaboratedTypeKeyword Keyword,
-                                             NestedNameSpecifier *Qualifier,
-                                             const IdentifierInfo *Name,
-                                             ArrayRef<TemplateArgument> Args) {
+void DependentTemplateSpecializationType::Profile(
+    llvm::FoldingSetNodeID &ID, const ASTContext &Context,
+    ElaboratedTypeKeyword Keyword, NestedNameSpecifier *Qualifier,
+    const IdentifierInfo *Name, ArrayRef<TemplateArgument> Args) {
   ID.AddInteger(Keyword);
   ID.AddPointer(Qualifier);
   ID.AddPointer(Name);
@@ -3142,7 +3186,9 @@ bool Type::isElaboratedTypeSpecifier() const {
 const char *Type::getTypeClassName() const {
   switch (TypeBits.TC) {
 #define ABSTRACT_TYPE(Derived, Base)
-#define TYPE(Derived, Base) case Derived: return #Derived;
+#define TYPE(Derived, Base)                                                    \
+  case Derived:                                                                \
+    return #Derived;
 #include "clang/AST/TypeNodes.inc"
   }
 
@@ -3278,8 +3324,8 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
     return "Class";
   case ObjCSel:
     return "SEL";
-#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
-  case Id: \
+#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix)                   \
+  case Id:                                                                     \
     return "__" #Access " " #ImgType "_t";
 #include "clang/Basic/OpenCLImageTypes.def"
   case OCLSampler:
@@ -3300,16 +3346,16 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
     return "<OpenMP array shaping type>";
   case OMPIterator:
     return "<OpenMP iterator type>";
-#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
-  case Id: \
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext)                                      \
+  case Id:                                                                     \
     return #ExtType;
 #include "clang/Basic/OpenCLExtensionTypes.def"
-#define SVE_TYPE(Name, Id, SingletonId) \
-  case Id: \
+#define SVE_TYPE(Name, Id, SingletonId)                                        \
+  case Id:                                                                     \
     return Name;
 #include "clang/Basic/AArch64SVEACLETypes.def"
-#define PPC_VECTOR_TYPE(Name, Id, Size) \
-  case Id: \
+#define PPC_VECTOR_TYPE(Name, Id, Size)                                        \
+  case Id:                                                                     \
     return #Name;
 #include "clang/Basic/PPCTypes.def"
 #define RVV_TYPE(Name, Id, SingletonId)                                        \
@@ -3350,27 +3396,48 @@ QualType QualType::getNonLValueExprType(const ASTContext &Context) const {
 
 StringRef FunctionType::getNameForCallConv(CallingConv CC) {
   switch (CC) {
-  case CC_C: return "cdecl";
-  case CC_X86StdCall: return "stdcall";
-  case CC_X86FastCall: return "fastcall";
-  case CC_X86ThisCall: return "thiscall";
-  case CC_X86Pascal: return "pascal";
-  case CC_X86VectorCall: return "vectorcall";
-  case CC_Win64: return "ms_abi";
-  case CC_X86_64SysV: return "sysv_abi";
-  case CC_X86RegCall : return "regcall";
-  case CC_AAPCS: return "aapcs";
-  case CC_AAPCS_VFP: return "aapcs-vfp";
-  case CC_AArch64VectorCall: return "aarch64_vector_pcs";
-  case CC_AArch64SVEPCS: return "aarch64_sve_pcs";
-  case CC_AMDGPUKernelCall: return "amdgpu_kernel";
-  case CC_IntelOclBicc: return "intel_ocl_bicc";
-  case CC_SpirFunction: return "spir_function";
-  case CC_OpenCLKernel: return "opencl_kernel";
-  case CC_Swift: return "swiftcall";
-  case CC_SwiftAsync: return "swiftasynccall";
-  case CC_PreserveMost: return "preserve_most";
-  case CC_PreserveAll: return "preserve_all";
+  case CC_C:
+    return "cdecl";
+  case CC_X86StdCall:
+    return "stdcall";
+  case CC_X86FastCall:
+    return "fastcall";
+  case CC_X86ThisCall:
+    return "thiscall";
+  case CC_X86Pascal:
+    return "pascal";
+  case CC_X86VectorCall:
+    return "vectorcall";
+  case CC_Win64:
+    return "ms_abi";
+  case CC_X86_64SysV:
+    return "sysv_abi";
+  case CC_X86RegCall:
+    return "regcall";
+  case CC_AAPCS:
+    return "aapcs";
+  case CC_AAPCS_VFP:
+    return "aapcs-vfp";
+  case CC_AArch64VectorCall:
+    return "aarch64_vector_pcs";
+  case CC_AArch64SVEPCS:
+    return "aarch64_sve_pcs";
+  case CC_AMDGPUKernelCall:
+    return "amdgpu_kernel";
+  case CC_IntelOclBicc:
+    return "intel_ocl_bicc";
+  case CC_SpirFunction:
+    return "spir_function";
+  case CC_OpenCLKernel:
+    return "opencl_kernel";
+  case CC_Swift:
+    return "swiftcall";
+  case CC_SwiftAsync:
+    return "swiftasynccall";
+  case CC_PreserveMost:
+    return "preserve_most";
+  case CC_PreserveAll:
+    return "preserve_all";
   }
 
   llvm_unreachable("Invalid calling convention.");
@@ -3398,7 +3465,6 @@ FunctionProtoType::FunctionProtoType(QualType result, ArrayRef<QualType> params,
     FunctionTypeBits.HasExtraBitfields = false;
   }
 
-
   // Fill in the trailing argument array.
   auto *argSlot = getTrailingObjects<QualType>();
   for (unsigned i = 0; i != getNumParams(); ++i) {
@@ -3592,12 +3658,10 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
   // This method is relatively performance sensitive, so as a performance
   // shortcut, use one AddInteger call instead of four for the next four
   // fields.
-  assert(!(unsigned(epi.Variadic) & ~1) &&
-         !(unsigned(epi.RefQualifier) & ~3) &&
+  assert(!(unsigned(epi.Variadic) & ~1) && !(unsigned(epi.RefQualifier) & ~3) &&
          !(unsigned(epi.ExceptionSpec.Type) & ~15) &&
          "Values larger than expected.");
-  ID.AddInteger(unsigned(epi.Variadic) +
-                (epi.RefQualifier << 1) +
+  ID.AddInteger(unsigned(epi.Variadic) + (epi.RefQualifier << 1) +
                 (epi.ExceptionSpec.Type << 3));
   ID.Add(epi.TypeQuals);
   if (epi.ExceptionSpec.Type == EST_Dynamic) {
@@ -3683,9 +3747,7 @@ TypeOfExprType::TypeOfExprType(Expr *E, TypeOfKind Kind, QualType Can)
   TypeOfBits.IsUnqual = Kind == TypeOfKind::Unqualified;
 }
 
-bool TypeOfExprType::isSugared() const {
-  return !TOExpr->isTypeDependent();
-}
+bool TypeOfExprType::isSugared() const { return !TOExpr->isTypeDependent(); }
 
 QualType TypeOfExprType::desugar() const {
   if (isSugared()) {
@@ -3740,7 +3802,7 @@ UnaryTransformType::UnaryTransformType(QualType BaseType,
 DependentUnaryTransformType::DependentUnaryTransformType(const ASTContext &C,
                                                          QualType BaseType,
                                                          UTTKind UKind)
-     : UnaryTransformType(BaseType, C.DependentTy, UKind, QualType()) {}
+    : UnaryTransformType(BaseType, C.DependentTy, UKind, QualType()) {}
 
 TagType::TagType(TypeClass TC, const TagDecl *D, QualType can)
     : Type(TC, can,
@@ -3757,16 +3819,12 @@ static TagDecl *getInterestingTagDecl(TagDecl *decl) {
   return decl;
 }
 
-TagDecl *TagType::getDecl() const {
-  return getInterestingTagDecl(decl);
-}
+TagDecl *TagType::getDecl() const { return getInterestingTagDecl(decl); }
 
-bool TagType::isBeingDefined() const {
-  return getDecl()->isBeingDefined();
-}
+bool TagType::isBeingDefined() const { return getDecl()->isBeingDefined(); }
 
 bool RecordType::hasConstFields() const {
-  std::vector<const RecordType*> RecordTypeList;
+  std::vector<const RecordType *> RecordTypeList;
   RecordTypeList.push_back(this);
   unsigned NextToCheckIndex = 0;
 
@@ -3814,7 +3872,8 @@ bool AttributedType::isQualifier() const {
 bool AttributedType::isMSTypeSpec() const {
   // FIXME: Generate this with TableGen?
   switch (getAttrKind()) {
-  default: return false;
+  default:
+    return false;
   case attr::Ptr32:
   case attr::Ptr64:
   case attr::SPtr:
@@ -3831,7 +3890,8 @@ bool AttributedType::isWebAssemblyFuncrefSpec() const {
 bool AttributedType::isCallingConv() const {
   // FIXME: Generate this with TableGen.
   switch (getAttrKind()) {
-  default: return false;
+  default:
+    return false;
   case attr::Pcs:
   case attr::CDecl:
   case attr::FastCall:
@@ -3943,7 +4003,8 @@ void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID,
 }
 
 bool TemplateSpecializationType::anyDependentTemplateArguments(
-    const TemplateArgumentListInfo &Args, ArrayRef<TemplateArgument> Converted) {
+    const TemplateArgumentListInfo &Args,
+    ArrayRef<TemplateArgument> Converted) {
   return anyDependentTemplateArguments(Args.arguments(), Converted);
 }
 
@@ -3956,7 +4017,7 @@ bool TemplateSpecializationType::anyDependentTemplateArguments(
 }
 
 bool TemplateSpecializationType::anyInstantiationDependentTemplateArguments(
-      ArrayRef<TemplateArgumentLoc> Args) {
+    ArrayRef<TemplateArgumentLoc> Args) {
   for (const TemplateArgumentLoc &ArgLoc : Args) {
     if (ArgLoc.getArgument().isInstantiationDependent())
       return true;
@@ -3968,9 +4029,8 @@ TemplateSpecializationType::TemplateSpecializationType(
     TemplateName T, ArrayRef<TemplateArgument> Args, QualType Canon,
     QualType AliasedType)
     : Type(TemplateSpecialization, Canon.isNull() ? QualType(this, 0) : Canon,
-           (Canon.isNull()
-                ? TypeDependence::DependentInstantiation
-                : toSemanticDependence(Canon->getDependence())) |
+           (Canon.isNull() ? TypeDependence::DependentInstantiation
+                           : toSemanticDependence(Canon->getDependence())) |
                (toTypeDependence(T.getDependence()) &
                 TypeDependence::UnexpandedPack)),
       Template(T) {
@@ -4022,34 +4082,32 @@ void TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
     getAliasedType().Profile(ID);
 }
 
-void
-TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
-                                    TemplateName T,
-                                    ArrayRef<TemplateArgument> Args,
-                                    const ASTContext &Context) {
+void TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
+                                         TemplateName T,
+                                         ArrayRef<TemplateArgument> Args,
+                                         const ASTContext &Context) {
   T.Profile(ID);
   for (const TemplateArgument &Arg : Args)
     Arg.Profile(ID, Context);
 }
 
-QualType
-QualifierCollector::apply(const ASTContext &Context, QualType QT) const {
+QualType QualifierCollector::apply(const ASTContext &Context,
+                                   QualType QT) const {
   if (!hasNonFastQualifiers())
     return QT.withFastQualifiers(getFastQualifiers());
 
   return Context.getQualifiedType(QT, *this);
 }
 
-QualType
-QualifierCollector::apply(const ASTContext &Context, const Type *T) const {
+QualType QualifierCollector::apply(const ASTContext &Context,
+                                   const Type *T) const {
   if (!hasNonFastQualifiers())
     return QualType(T, getFastQualifiers());
 
   return Context.getQualifiedType(T, *this);
 }
 
-void ObjCObjectTypeImpl::Profile(llvm::FoldingSetNodeID &ID,
-                                 QualType BaseType,
+void ObjCObjectTypeImpl::Profile(llvm::FoldingSetNodeID &ID, QualType BaseType,
                                  ArrayRef<QualType> typeArgs,
                                  ArrayRef<ObjCProtocolDecl *> protocols,
                                  bool isKindOf) {
@@ -4116,9 +4174,7 @@ namespace clang {
 /// leakage.
 template <class Private> class TypePropertyCache {
 public:
-  static CachedProperties get(QualType T) {
-    return get(T.getTypePtr());
-  }
+  static CachedProperties get(QualType T) { return get(T.getTypePtr()); }
 
   static CachedProperties get(const Type *T) {
     ensure(T);
@@ -4128,7 +4184,8 @@ template <class Private> class TypePropertyCache {
 
   static void ensure(const Type *T) {
     // If the cache is valid, we're okay.
-    if (T->TypeBits.isCacheValid()) return;
+    if (T->TypeBits.isCacheValid())
+      return;
 
     // If this type is non-canonical, ask its canonical type for the
     // relevant information.
@@ -4164,17 +4221,18 @@ using Cache = TypePropertyCache<Private>;
 
 static CachedProperties computeCachedProperties(const Type *T) {
   switch (T->getTypeClass()) {
-#define TYPE(Class,Base)
-#define NON_CANONICAL_TYPE(Class,Base) case Type::Class:
+#define TYPE(Class, Base)
+#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
 #include "clang/AST/TypeNodes.inc"
     llvm_unreachable("didn't expect a non-canonical type here");
 
-#define TYPE(Class,Base)
-#define DEPENDENT_TYPE(Class,Base) case Type::Class:
-#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class,Base) case Type::Class:
+#define TYPE(Class, Base)
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
 #include "clang/AST/TypeNodes.inc"
     // Treat instantiation-dependent types as external.
-    if (!T->isInstantiationDependentType()) T->dump();
+    if (!T->isInstantiationDependentType())
+      T->dump();
     assert(T->isInstantiationDependentType());
     return CachedProperties(ExternalLinkage, false);
 
@@ -4200,9 +4258,8 @@ static CachedProperties computeCachedProperties(const Type *T) {
     //       for linkage purposes (7.1.3)) and the name has linkage; or
     //     -  it is a specialization of a class template (14); or
     Linkage L = Tag->getLinkageInternal();
-    bool IsLocalOrUnnamed =
-      Tag->getDeclContext()->isFunctionOrMethod() ||
-      !Tag->hasNameForLinkage();
+    bool IsLocalOrUnnamed = Tag->getDeclContext()->isFunctionOrMethod() ||
+                            !Tag->hasNameForLinkage();
     return CachedProperties(L, IsLocalOrUnnamed);
   }
 
@@ -4271,14 +4328,14 @@ bool Type::hasUnnamedOrLocalType() const {
 
 LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) {
   switch (T->getTypeClass()) {
-#define TYPE(Class,Base)
-#define NON_CANONICAL_TYPE(Class,Base) case Type::Class:
+#define TYPE(Class, Base)
+#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
 #include "clang/AST/TypeNodes.inc"
     llvm_unreachable("didn't expect a non-canonical type here");
 
-#define TYPE(Class,Base)
-#define DEPENDENT_TYPE(Class,Base) case Type::Class:
-#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class,Base) case Type::Class:
+#define TYPE(Class, Base)
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
 #include "clang/AST/TypeNodes.inc"
     // Treat instantiation-dependent types as external.
     assert(T->isInstantiationDependentType());
@@ -4386,9 +4443,9 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
   QualType type = getCanonicalTypeInternal();
 
   switch (type->getTypeClass()) {
-  // We'll only see canonical types here.
-#define NON_CANONICAL_TYPE(Class, Parent)       \
-  case Type::Class:                             \
+    // We'll only see canonical types here.
+#define NON_CANONICAL_TYPE(Class, Parent)                                      \
+  case Type::Class:                                                            \
     llvm_unreachable("non-canonical type");
 #define TYPE(Class, Parent)
 #include "clang/AST/TypeNodes.inc"
@@ -4417,9 +4474,10 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
   // types unless they're known to be specializations of a class
   // template.
   case Type::TemplateSpecialization:
-    if (TemplateDecl *templateDecl
-          = cast<TemplateSpecializationType>(type.getTypePtr())
-              ->getTemplateName().getAsTemplateDecl()) {
+    if (TemplateDecl *templateDecl =
+            cast<TemplateSpecializationType>(type.getTypePtr())
+                ->getTemplateName()
+                .getAsTemplateDecl()) {
       if (isa<ClassTemplateDecl>(templateDecl))
         return false;
     }
@@ -4448,22 +4506,19 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
     case BuiltinType::ObjCId:
     case BuiltinType::ObjCClass:
     case BuiltinType::ObjCSel:
-#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
-    case BuiltinType::Id:
+#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix)                   \
+  case BuiltinType::Id:
 #include "clang/Basic/OpenCLImageTypes.def"
-#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
-    case BuiltinType::Id:
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) case BuiltinType::Id:
 #include "clang/Basic/OpenCLExtensionTypes.def"
     case BuiltinType::OCLSampler:
     case BuiltinType::OCLEvent:
     case BuiltinType::OCLClkEvent:
     case BuiltinType::OCLQueue:
     case BuiltinType::OCLReserveID:
-#define SVE_TYPE(Name, Id, SingletonId) \
-    case BuiltinType::Id:
+#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
 #include "clang/Basic/AArch64SVEACLETypes.def"
-#define PPC_VECTOR_TYPE(Name, Id, Size) \
-    case BuiltinType::Id:
+#define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:
 #include "clang/Basic/PPCTypes.def"
 #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
 #include "clang/Basic/RISCVVTypes.def"
@@ -4611,8 +4666,7 @@ bool Type::isObjCIndependentClassType() const {
 }
 
 bool Type::isObjCRetainableType() const {
-  return isObjCObjectPointerType() ||
-         isBlockPointerType() ||
+  return isObjCObjectPointerType() || isBlockPointerType() ||
          isObjCNSObjectType();
 }
 
@@ -4668,7 +4722,8 @@ bool Type::isCUDADeviceBuiltinTextureType() const {
 }
 
 bool Type::hasSizedVLAType() const {
-  if (!isVariablyModifiedType()) return false;
+  if (!isVariablyModifiedType())
+    return false;
 
   if (const auto *ptr = getAs<PointerType>())
     return ptr->getPointeeType()->hasSizedVLAType();
@@ -4698,8 +4753,7 @@ QualType::DestructionKind QualType::isDestructedTypeImpl(QualType type) {
     return DK_objc_weak_lifetime;
   }
 
-  if (const auto *RT =
-          type->getBaseElementTypeUnsafe()->getAs<RecordType>()) {
+  if (const auto *RT = type->getBaseElementTypeUnsafe()->getAs<RecordType>()) {
     const RecordDecl *RD = RT->getDecl();
     if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
       /// Check if this is a C++ object with a non-trivial destructor.
@@ -4752,9 +4806,9 @@ AutoType::AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword,
 }
 
 void AutoType::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
-                      QualType Deduced, AutoTypeKeyword Keyword,
-                      bool IsDependent, ConceptDecl *CD,
-                      ArrayRef<TemplateArgument> Arguments) {
+                       QualType Deduced, AutoTypeKeyword Keyword,
+                       bool IsDependent, ConceptDecl *CD,
+                       ArrayRef<TemplateArgument> Arguments) {
   ID.AddPointer(Deduced.getAsOpaquePtr());
   ID.AddInteger((unsigned)Keyword);
   ID.AddBoolean(IsDependent);
diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp
index a1315f1966a6dd4..275ddcbae73930d 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -3200,6 +3200,17 @@ struct TriviallyEqualityComparableContainsMultiDimensionArray {
 };
 static_assert(__is_trivially_equality_comparable(TriviallyEqualityComparableContainsMultiDimensionArray));
 
+auto GetNonCapturingLambda() { return [](){ return 42; }; }
+
+struct TriviallyEqualityComparableContainsLambda {
+  [[no_unique_address]] decltype(GetNonCapturingLambda()) l;
+  int i;
+
+  bool operator==(const TriviallyEqualityComparableContainsLambda&) const = default;
+};
+static_assert(!__is_trivially_equality_comparable(decltype(GetNonCapturingLambda()))); // padding
+static_assert(__is_trivially_equality_comparable(TriviallyEqualityComparableContainsLambda));
+
 struct TriviallyEqualityComparableNonTriviallyCopyable {
   TriviallyEqualityComparableNonTriviallyCopyable(const TriviallyEqualityComparableNonTriviallyCopyable&);
   ~TriviallyEqualityComparableNonTriviallyCopyable();



More information about the cfe-commits mailing list