brintos

brintos / llvm-project-archived public Read only

0
0
Text · 103.5 KiB · 3802da8 Raw
2829 lines · cpp
1//===----- SemaTypeTraits.cpp - Semantic Analysis for C++ Type Traits -----===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9//  This file implements semantic analysis for C++ type traits.10//11//===----------------------------------------------------------------------===//12 13#include "clang/AST/DeclCXX.h"14#include "clang/AST/TemplateBase.h"15#include "clang/AST/Type.h"16#include "clang/Basic/DiagnosticIDs.h"17#include "clang/Basic/DiagnosticParse.h"18#include "clang/Basic/DiagnosticSema.h"19#include "clang/Basic/Specifiers.h"20#include "clang/Basic/TypeTraits.h"21#include "clang/Sema/EnterExpressionEvaluationContext.h"22#include "clang/Sema/Initialization.h"23#include "clang/Sema/Lookup.h"24#include "clang/Sema/Overload.h"25#include "clang/Sema/Sema.h"26#include "clang/Sema/SemaHLSL.h"27#include "llvm/ADT/STLExtras.h"28 29using namespace clang;30 31static CXXMethodDecl *LookupSpecialMemberFromXValue(Sema &SemaRef,32                                                    const CXXRecordDecl *RD,33                                                    bool Assign) {34  RD = RD->getDefinition();35  SourceLocation LookupLoc = RD->getLocation();36 37  CanQualType CanTy = SemaRef.getASTContext().getCanonicalTagType(RD);38  DeclarationName Name;39  Expr *Arg = nullptr;40  unsigned NumArgs;41 42  QualType ArgType = CanTy;43  ExprValueKind VK = clang::VK_XValue;44 45  if (Assign)46    Name =47        SemaRef.getASTContext().DeclarationNames.getCXXOperatorName(OO_Equal);48  else49    Name =50        SemaRef.getASTContext().DeclarationNames.getCXXConstructorName(CanTy);51 52  OpaqueValueExpr FakeArg(LookupLoc, ArgType, VK);53  NumArgs = 1;54  Arg = &FakeArg;55 56  // Create the object argument57  QualType ThisTy = CanTy;58  Expr::Classification Classification =59      OpaqueValueExpr(LookupLoc, ThisTy, VK_LValue)60          .Classify(SemaRef.getASTContext());61 62  // Now we perform lookup on the name we computed earlier and do overload63  // resolution. Lookup is only performed directly into the class since there64  // will always be a (possibly implicit) declaration to shadow any others.65  OverloadCandidateSet OCS(LookupLoc, OverloadCandidateSet::CSK_Normal);66  DeclContext::lookup_result R = RD->lookup(Name);67 68  if (R.empty())69    return nullptr;70 71  // Copy the candidates as our processing of them may load new declarations72  // from an external source and invalidate lookup_result.73  SmallVector<NamedDecl *, 8> Candidates(R.begin(), R.end());74 75  for (NamedDecl *CandDecl : Candidates) {76    if (CandDecl->isInvalidDecl())77      continue;78 79    DeclAccessPair Cand = DeclAccessPair::make(CandDecl, clang::AS_none);80    auto CtorInfo = getConstructorInfo(Cand);81    if (CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(Cand->getUnderlyingDecl())) {82      if (Assign)83        SemaRef.AddMethodCandidate(M, Cand, const_cast<CXXRecordDecl *>(RD),84                                   ThisTy, Classification,85                                   llvm::ArrayRef(&Arg, NumArgs), OCS, true);86      else {87        assert(CtorInfo);88        SemaRef.AddOverloadCandidate(CtorInfo.Constructor, CtorInfo.FoundDecl,89                                     llvm::ArrayRef(&Arg, NumArgs), OCS,90                                     /*SuppressUserConversions*/ true);91      }92    } else if (FunctionTemplateDecl *Tmpl =93                   dyn_cast<FunctionTemplateDecl>(Cand->getUnderlyingDecl())) {94      if (Assign)95        SemaRef.AddMethodTemplateCandidate(96            Tmpl, Cand, const_cast<CXXRecordDecl *>(RD), nullptr, ThisTy,97            Classification, llvm::ArrayRef(&Arg, NumArgs), OCS, true);98      else {99        assert(CtorInfo);100        SemaRef.AddTemplateOverloadCandidate(101            CtorInfo.ConstructorTmpl, CtorInfo.FoundDecl, nullptr,102            llvm::ArrayRef(&Arg, NumArgs), OCS, true);103      }104    }105  }106 107  OverloadCandidateSet::iterator Best;108  switch (OCS.BestViableFunction(SemaRef, LookupLoc, Best)) {109  case OR_Success:110  case OR_Deleted:111    return cast<CXXMethodDecl>(Best->Function)->getCanonicalDecl();112  default:113    return nullptr;114  }115}116 117static bool hasSuitableConstructorForRelocation(Sema &SemaRef,118                                                const CXXRecordDecl *D,119                                                bool AllowUserDefined) {120  assert(D->hasDefinition() && !D->isInvalidDecl());121 122  if (D->hasSimpleMoveConstructor() || D->hasSimpleCopyConstructor())123    return true;124 125  CXXMethodDecl *Decl =126      LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/false);127  return Decl && (AllowUserDefined || !Decl->isUserProvided()) &&128         !Decl->isDeleted();129}130 131static bool hasSuitableMoveAssignmentOperatorForRelocation(132    Sema &SemaRef, const CXXRecordDecl *D, bool AllowUserDefined) {133  assert(D->hasDefinition() && !D->isInvalidDecl());134 135  if (D->hasSimpleMoveAssignment() || D->hasSimpleCopyAssignment())136    return true;137 138  CXXMethodDecl *Decl =139      LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/true);140  if (!Decl)141    return false;142 143  return Decl && (AllowUserDefined || !Decl->isUserProvided()) &&144         !Decl->isDeleted();145}146 147// [C++26][class.prop]148// A class C is default-movable if149// - overload resolution for direct-initializing an object of type C150// from an xvalue of type C selects a constructor that is a direct member of C151// and is neither user-provided nor deleted,152// - overload resolution for assigning to an lvalue of type C from an xvalue of153// type C selects an assignment operator function that is a direct member of C154// and is neither user-provided nor deleted, and C has a destructor that is155// neither user-provided nor deleted.156static bool IsDefaultMovable(Sema &SemaRef, const CXXRecordDecl *D) {157  if (!hasSuitableConstructorForRelocation(SemaRef, D,158                                           /*AllowUserDefined=*/false))159    return false;160 161  if (!hasSuitableMoveAssignmentOperatorForRelocation(162          SemaRef, D, /*AllowUserDefined=*/false))163    return false;164 165  CXXDestructorDecl *Dtr = D->getDestructor();166 167  if (!Dtr)168    return true;169 170  Dtr = Dtr->getCanonicalDecl();171 172  if (Dtr->isUserProvided() && (!Dtr->isDefaulted() || Dtr->isDeleted()))173    return false;174 175  return !Dtr->isDeleted();176}177 178// [C++26][class.prop]179// A class is eligible for trivial relocation unless it...180static bool IsEligibleForTrivialRelocation(Sema &SemaRef,181                                           const CXXRecordDecl *D) {182 183  for (const CXXBaseSpecifier &B : D->bases()) {184    const auto *BaseDecl = B.getType()->getAsCXXRecordDecl();185    if (!BaseDecl)186      continue;187    // ... has any virtual base classes188    // ... has a base class that is not a trivially relocatable class189    if (B.isVirtual() || (!BaseDecl->isDependentType() &&190                          !SemaRef.IsCXXTriviallyRelocatableType(B.getType())))191      return false;192  }193 194  bool IsUnion = D->isUnion();195  for (const FieldDecl *Field : D->fields()) {196    if (Field->getType()->isDependentType())197      continue;198    if (Field->getType()->isReferenceType())199      continue;200    // ... has a non-static data member of an object type that is not201    // of a trivially relocatable type202    if (!SemaRef.IsCXXTriviallyRelocatableType(Field->getType()))203      return false;204 205    // A union contains values with address discriminated pointer auth206    // cannot be relocated.207    if (IsUnion && SemaRef.Context.containsAddressDiscriminatedPointerAuth(208                       Field->getType()))209      return false;210  }211  return !D->hasDeletedDestructor();212}213 214// [C++26][class.prop]215// A class C is eligible for replacement unless216static bool IsEligibleForReplacement(Sema &SemaRef, const CXXRecordDecl *D) {217 218  for (const CXXBaseSpecifier &B : D->bases()) {219    const auto *BaseDecl = B.getType()->getAsCXXRecordDecl();220    if (!BaseDecl)221      continue;222    // it has a base class that is not a replaceable class223    if (!BaseDecl->isDependentType() &&224        !SemaRef.IsCXXReplaceableType(B.getType()))225      return false;226  }227 228  for (const FieldDecl *Field : D->fields()) {229    if (Field->getType()->isDependentType())230      continue;231 232    // it has a non-static data member that is not of a replaceable type,233    if (!SemaRef.IsCXXReplaceableType(Field->getType()))234      return false;235  }236  return !D->hasDeletedDestructor();237}238 239ASTContext::CXXRecordDeclRelocationInfo240Sema::CheckCXX2CRelocatableAndReplaceable(const CXXRecordDecl *D) {241  ASTContext::CXXRecordDeclRelocationInfo Info{false, false};242 243  if (!getLangOpts().CPlusPlus || D->isInvalidDecl())244    return Info;245 246  assert(D->hasDefinition());247 248  // This is part of "eligible for replacement", however we defer it249  // to avoid extraneous computations.250  auto HasSuitableSMP = [&] {251    return hasSuitableConstructorForRelocation(*this, D,252                                               /*AllowUserDefined=*/true) &&253           hasSuitableMoveAssignmentOperatorForRelocation(254               *this, D, /*AllowUserDefined=*/true);255  };256 257  auto IsUnion = [&, Is = std::optional<bool>{}]() mutable {258    if (!Is.has_value())259      Is = D->isUnion() && !D->hasUserDeclaredCopyConstructor() &&260           !D->hasUserDeclaredCopyAssignment() &&261           !D->hasUserDeclaredMoveOperation() &&262           !D->hasUserDeclaredDestructor();263    return *Is;264  };265 266  auto IsDefaultMovable = [&, Is = std::optional<bool>{}]() mutable {267    if (!Is.has_value())268      Is = ::IsDefaultMovable(*this, D);269    return *Is;270  };271 272  Info.IsRelocatable = [&] {273    if (D->isDependentType())274      return false;275 276    // if it is eligible for trivial relocation277    if (!IsEligibleForTrivialRelocation(*this, D))278      return false;279 280    // has the trivially_relocatable_if_eligible class-property-specifier,281    if (D->hasAttr<TriviallyRelocatableAttr>())282      return true;283 284    // is a union with no user-declared special member functions, or285    if (IsUnion())286      return true;287 288    // is default-movable.289    return IsDefaultMovable();290  }();291 292  Info.IsReplaceable = [&] {293    if (D->isDependentType())294      return false;295 296    // A class C is a replaceable class if it is eligible for replacement297    if (!IsEligibleForReplacement(*this, D))298      return false;299 300    // has the replaceable_if_eligible class-property-specifier301    if (D->hasAttr<ReplaceableAttr>())302      return HasSuitableSMP();303 304    // is a union with no user-declared special member functions, or305    if (IsUnion())306      return HasSuitableSMP();307 308    // is default-movable.309    return IsDefaultMovable();310  }();311 312  return Info;313}314 315bool Sema::IsCXXTriviallyRelocatableType(const CXXRecordDecl &RD) {316  if (std::optional<ASTContext::CXXRecordDeclRelocationInfo> Info =317          getASTContext().getRelocationInfoForCXXRecord(&RD))318    return Info->IsRelocatable;319  ASTContext::CXXRecordDeclRelocationInfo Info =320      CheckCXX2CRelocatableAndReplaceable(&RD);321  getASTContext().setRelocationInfoForCXXRecord(&RD, Info);322  return Info.IsRelocatable;323}324 325bool Sema::IsCXXTriviallyRelocatableType(QualType Type) {326  QualType BaseElementType = getASTContext().getBaseElementType(Type);327 328  if (Type->isVariableArrayType())329    return false;330 331  if (BaseElementType.hasNonTrivialObjCLifetime())332    return false;333 334  if (BaseElementType->isIncompleteType())335    return false;336 337  if (Context.containsNonRelocatablePointerAuth(Type))338    return false;339 340  if (BaseElementType->isScalarType() || BaseElementType->isVectorType())341    return true;342 343  if (const auto *RD = BaseElementType->getAsCXXRecordDecl())344    return IsCXXTriviallyRelocatableType(*RD);345 346  return false;347}348 349static bool IsCXXReplaceableType(Sema &S, const CXXRecordDecl *RD) {350  if (std::optional<ASTContext::CXXRecordDeclRelocationInfo> Info =351          S.getASTContext().getRelocationInfoForCXXRecord(RD))352    return Info->IsReplaceable;353  ASTContext::CXXRecordDeclRelocationInfo Info =354      S.CheckCXX2CRelocatableAndReplaceable(RD);355  S.getASTContext().setRelocationInfoForCXXRecord(RD, Info);356  return Info.IsReplaceable;357}358 359bool Sema::IsCXXReplaceableType(QualType Type) {360  if (Type.isConstQualified() || Type.isVolatileQualified())361    return false;362 363  if (Type->isVariableArrayType())364    return false;365 366  QualType BaseElementType =367      getASTContext().getBaseElementType(Type.getUnqualifiedType());368  if (BaseElementType->isIncompleteType())369    return false;370  if (BaseElementType->isScalarType())371    return true;372  if (const auto *RD = BaseElementType->getAsCXXRecordDecl())373    return ::IsCXXReplaceableType(*this, RD);374  return false;375}376 377/// Checks that type T is not a VLA.378///379/// @returns @c true if @p T is VLA and a diagnostic was emitted,380/// @c false otherwise.381static bool DiagnoseVLAInCXXTypeTrait(Sema &S, const TypeSourceInfo *T,382                                      clang::tok::TokenKind TypeTraitID) {383  if (!T->getType()->isVariableArrayType())384    return false;385 386  S.Diag(T->getTypeLoc().getBeginLoc(), diag::err_vla_unsupported)387      << 1 << TypeTraitID;388  return true;389}390 391/// Checks that type T is not an atomic type (_Atomic).392///393/// @returns @c true if @p T is VLA and a diagnostic was emitted,394/// @c false otherwise.395static bool DiagnoseAtomicInCXXTypeTrait(Sema &S, const TypeSourceInfo *T,396                                         clang::tok::TokenKind TypeTraitID) {397  if (!T->getType()->isAtomicType())398    return false;399 400  S.Diag(T->getTypeLoc().getBeginLoc(), diag::err_atomic_unsupported)401      << TypeTraitID;402  return true;403}404 405/// Check the completeness of a type in a unary type trait.406///407/// If the particular type trait requires a complete type, tries to complete408/// it. If completing the type fails, a diagnostic is emitted and false409/// returned. If completing the type succeeds or no completion was required,410/// returns true.411static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT,412                                                SourceLocation Loc,413                                                QualType ArgTy) {414  // C++0x [meta.unary.prop]p3:415  //   For all of the class templates X declared in this Clause, instantiating416  //   that template with a template argument that is a class template417  //   specialization may result in the implicit instantiation of the template418  //   argument if and only if the semantics of X require that the argument419  //   must be a complete type.420  // We apply this rule to all the type trait expressions used to implement421  // these class templates. We also try to follow any GCC documented behavior422  // in these expressions to ensure portability of standard libraries.423  switch (UTT) {424  default:425    llvm_unreachable("not a UTT");426    // is_complete_type somewhat obviously cannot require a complete type.427  case UTT_IsCompleteType:428    // Fall-through429 430    // These traits are modeled on the type predicates in C++0x431    // [meta.unary.cat] and [meta.unary.comp]. They are not specified as432    // requiring a complete type, as whether or not they return true cannot be433    // impacted by the completeness of the type.434  case UTT_IsVoid:435  case UTT_IsIntegral:436  case UTT_IsFloatingPoint:437  case UTT_IsArray:438  case UTT_IsBoundedArray:439  case UTT_IsPointer:440  case UTT_IsLvalueReference:441  case UTT_IsRvalueReference:442  case UTT_IsMemberFunctionPointer:443  case UTT_IsMemberObjectPointer:444  case UTT_IsEnum:445  case UTT_IsScopedEnum:446  case UTT_IsUnion:447  case UTT_IsClass:448  case UTT_IsFunction:449  case UTT_IsReference:450  case UTT_IsArithmetic:451  case UTT_IsFundamental:452  case UTT_IsObject:453  case UTT_IsScalar:454  case UTT_IsCompound:455  case UTT_IsMemberPointer:456  case UTT_IsTypedResourceElementCompatible:457    // Fall-through458 459    // These traits are modeled on type predicates in C++0x [meta.unary.prop]460    // which requires some of its traits to have the complete type. However,461    // the completeness of the type cannot impact these traits' semantics, and462    // so they don't require it. This matches the comments on these traits in463    // Table 49.464  case UTT_IsConst:465  case UTT_IsVolatile:466  case UTT_IsSigned:467  case UTT_IsUnboundedArray:468  case UTT_IsUnsigned:469 470    // This type trait always returns false, checking the type is moot.471  case UTT_IsInterfaceClass:472    return true;473 474    // We diagnose incomplete class types later.475  case UTT_StructuredBindingSize:476    return true;477 478    // C++14 [meta.unary.prop]:479    //   If T is a non-union class type, T shall be a complete type.480  case UTT_IsEmpty:481  case UTT_IsPolymorphic:482  case UTT_IsAbstract:483    if (const auto *RD = ArgTy->getAsCXXRecordDecl())484      if (!RD->isUnion())485        return !S.RequireCompleteType(486            Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);487    return true;488 489    // C++14 [meta.unary.prop]:490    //   If T is a class type, T shall be a complete type.491  case UTT_IsFinal:492  case UTT_IsSealed:493    if (ArgTy->getAsCXXRecordDecl())494      return !S.RequireCompleteType(495          Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);496    return true;497 498    // LWG3823: T shall be an array type, a complete type, or cv void.499  case UTT_IsAggregate:500  case UTT_IsImplicitLifetime:501    if (ArgTy->isArrayType() || ArgTy->isVoidType())502      return true;503 504    return !S.RequireCompleteType(505        Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);506 507    // has_unique_object_representations<T>508    // remove_all_extents_t<T> shall be a complete type or cv void (LWG4113).509  case UTT_HasUniqueObjectRepresentations:510    ArgTy = QualType(ArgTy->getBaseElementTypeUnsafe(), 0);511    if (ArgTy->isVoidType())512      return true;513    return !S.RequireCompleteType(514        Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);515 516    // C++1z [meta.unary.prop]:517    //   remove_all_extents_t<T> shall be a complete type or cv void.518  case UTT_IsTrivial:519  case UTT_IsTriviallyCopyable:520  case UTT_IsStandardLayout:521  case UTT_IsPOD:522  case UTT_IsLiteral:523  case UTT_IsBitwiseCloneable:524  // By analogy, is_trivially_relocatable and is_trivially_equality_comparable525  // impose the same constraints.526  case UTT_IsTriviallyRelocatable:527  case UTT_IsTriviallyEqualityComparable:528  case UTT_IsCppTriviallyRelocatable:529  case UTT_IsReplaceable:530  case UTT_CanPassInRegs:531  // Per the GCC type traits documentation, T shall be a complete type, cv void,532  // or an array of unknown bound. But GCC actually imposes the same constraints533  // as above.534  case UTT_HasNothrowAssign:535  case UTT_HasNothrowMoveAssign:536  case UTT_HasNothrowConstructor:537  case UTT_HasNothrowCopy:538  case UTT_HasTrivialAssign:539  case UTT_HasTrivialMoveAssign:540  case UTT_HasTrivialDefaultConstructor:541  case UTT_HasTrivialMoveConstructor:542  case UTT_HasTrivialCopy:543  case UTT_HasTrivialDestructor:544  case UTT_HasVirtualDestructor:545    ArgTy = QualType(ArgTy->getBaseElementTypeUnsafe(), 0);546    [[fallthrough]];547  // C++1z [meta.unary.prop]:548  //   T shall be a complete type, cv void, or an array of unknown bound.549  case UTT_IsDestructible:550  case UTT_IsNothrowDestructible:551  case UTT_IsTriviallyDestructible:552  case UTT_IsIntangibleType:553    if (ArgTy->isIncompleteArrayType() || ArgTy->isVoidType())554      return true;555 556    return !S.RequireCompleteType(557        Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);558  }559}560 561static bool HasNoThrowOperator(CXXRecordDecl *RD, OverloadedOperatorKind Op,562                               Sema &Self, SourceLocation KeyLoc, ASTContext &C,563                               bool (CXXRecordDecl::*HasTrivial)() const,564                               bool (CXXRecordDecl::*HasNonTrivial)() const,565                               bool (CXXMethodDecl::*IsDesiredOp)() const) {566  if ((RD->*HasTrivial)() && !(RD->*HasNonTrivial)())567    return true;568 569  DeclarationName Name = C.DeclarationNames.getCXXOperatorName(Op);570  DeclarationNameInfo NameInfo(Name, KeyLoc);571  LookupResult Res(Self, NameInfo, Sema::LookupOrdinaryName);572  if (Self.LookupQualifiedName(Res, RD)) {573    bool FoundOperator = false;574    Res.suppressDiagnostics();575    for (LookupResult::iterator Op = Res.begin(), OpEnd = Res.end();576         Op != OpEnd; ++Op) {577      if (isa<FunctionTemplateDecl>(*Op))578        continue;579 580      CXXMethodDecl *Operator = cast<CXXMethodDecl>(*Op);581      if ((Operator->*IsDesiredOp)()) {582        FoundOperator = true;583        auto *CPT = Operator->getType()->castAs<FunctionProtoType>();584        CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);585        if (!CPT || !CPT->isNothrow())586          return false;587      }588    }589    return FoundOperator;590  }591  return false;592}593 594static bool HasNonDeletedDefaultedEqualityComparison(Sema &S,595                                                     const CXXRecordDecl *Decl,596                                                     SourceLocation KeyLoc) {597  if (Decl->isUnion())598    return false;599  if (Decl->isLambda())600    return Decl->isCapturelessLambda();601 602  CanQualType T = S.Context.getCanonicalTagType(Decl);603  {604    EnterExpressionEvaluationContext UnevaluatedContext(605        S, Sema::ExpressionEvaluationContext::Unevaluated);606    Sema::SFINAETrap SFINAE(S, /*ForValidityCheck=*/true);607    Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl());608 609    // const ClassT& obj;610    OpaqueValueExpr Operand(KeyLoc, T.withConst(), ExprValueKind::VK_LValue);611    UnresolvedSet<16> Functions;612    // obj == obj;613    S.LookupBinOp(S.TUScope, {}, BinaryOperatorKind::BO_EQ, Functions);614 615    auto Result = S.CreateOverloadedBinOp(KeyLoc, BinaryOperatorKind::BO_EQ,616                                          Functions, &Operand, &Operand);617    if (Result.isInvalid() || SFINAE.hasErrorOccurred())618      return false;619 620    const auto *CallExpr = dyn_cast<CXXOperatorCallExpr>(Result.get());621    if (!CallExpr)622      return false;623    const auto *Callee = CallExpr->getDirectCallee();624    auto ParamT = Callee->getParamDecl(0)->getType();625    if (!Callee->isDefaulted())626      return false;627    if (!ParamT->isReferenceType() && !Decl->isTriviallyCopyable())628      return false;629    if (!S.Context.hasSameUnqualifiedType(ParamT.getNonReferenceType(), T))630      return false;631  }632 633  return llvm::all_of(Decl->bases(),634                      [&](const CXXBaseSpecifier &BS) {635                        if (const auto *RD = BS.getType()->getAsCXXRecordDecl())636                          return HasNonDeletedDefaultedEqualityComparison(637                              S, RD, KeyLoc);638                        return true;639                      }) &&640         llvm::all_of(Decl->fields(), [&](const FieldDecl *FD) {641           auto Type = FD->getType();642           if (Type->isArrayType())643             Type = Type->getBaseElementTypeUnsafe()644                        ->getCanonicalTypeUnqualified();645 646           if (Type->isReferenceType() || Type->isEnumeralType())647             return false;648           if (const auto *RD = Type->getAsCXXRecordDecl())649             return HasNonDeletedDefaultedEqualityComparison(S, RD, KeyLoc);650           return true;651         });652}653 654static bool isTriviallyEqualityComparableType(Sema &S, QualType Type,655                                              SourceLocation KeyLoc) {656  QualType CanonicalType = Type.getCanonicalType();657  if (CanonicalType->isIncompleteType() || CanonicalType->isDependentType() ||658      CanonicalType->isEnumeralType() || CanonicalType->isArrayType())659    return false;660 661  if (const auto *RD = CanonicalType->getAsCXXRecordDecl()) {662    if (!HasNonDeletedDefaultedEqualityComparison(S, RD, KeyLoc))663      return false;664  }665 666  return S.getASTContext().hasUniqueObjectRepresentations(667      CanonicalType, /*CheckIfTriviallyCopyable=*/false);668}669 670static bool IsTriviallyRelocatableType(Sema &SemaRef, QualType T) {671  QualType BaseElementType = SemaRef.getASTContext().getBaseElementType(T);672 673  if (BaseElementType->isIncompleteType())674    return false;675  if (!BaseElementType->isObjectType())676    return false;677 678  // The deprecated __builtin_is_trivially_relocatable does not have679  // an equivalent to __builtin_trivially_relocate, so there is no680  // safe way to use it if there are any address discriminated values.681  if (SemaRef.getASTContext().containsAddressDiscriminatedPointerAuth(T))682    return false;683 684  if (const auto *RD = BaseElementType->getAsCXXRecordDecl();685      RD && !RD->isPolymorphic() && SemaRef.IsCXXTriviallyRelocatableType(*RD))686    return true;687 688  if (const auto *RD = BaseElementType->getAsRecordDecl())689    return RD->canPassInRegisters();690 691  if (BaseElementType.isTriviallyCopyableType(SemaRef.getASTContext()))692    return true;693 694  switch (T.isNonTrivialToPrimitiveDestructiveMove()) {695  case QualType::PCK_Trivial:696    return !T.isDestructedType();697  case QualType::PCK_ARCStrong:698    return true;699  default:700    return false;701  }702}703 704static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,705                                   SourceLocation KeyLoc,706                                   TypeSourceInfo *TInfo) {707  QualType T = TInfo->getType();708  assert(!T->isDependentType() && "Cannot evaluate traits of dependent type");709 710  ASTContext &C = Self.Context;711  switch (UTT) {712  default:713    llvm_unreachable("not a UTT");714    // Type trait expressions corresponding to the primary type category715    // predicates in C++0x [meta.unary.cat].716  case UTT_IsVoid:717    return T->isVoidType();718  case UTT_IsIntegral:719    return T->isIntegralType(C);720  case UTT_IsFloatingPoint:721    return T->isFloatingType();722  case UTT_IsArray:723    // Zero-sized arrays aren't considered arrays in partial specializations,724    // so __is_array shouldn't consider them arrays either.725    if (const auto *CAT = C.getAsConstantArrayType(T))726      return CAT->getSize() != 0;727    return T->isArrayType();728  case UTT_IsBoundedArray:729    if (DiagnoseVLAInCXXTypeTrait(Self, TInfo, tok::kw___is_bounded_array))730      return false;731    // Zero-sized arrays aren't considered arrays in partial specializations,732    // so __is_bounded_array shouldn't consider them arrays either.733    if (const auto *CAT = C.getAsConstantArrayType(T))734      return CAT->getSize() != 0;735    return T->isArrayType() && !T->isIncompleteArrayType();736  case UTT_IsUnboundedArray:737    if (DiagnoseVLAInCXXTypeTrait(Self, TInfo, tok::kw___is_unbounded_array))738      return false;739    return T->isIncompleteArrayType();740  case UTT_IsPointer:741    return T->isAnyPointerType();742  case UTT_IsLvalueReference:743    return T->isLValueReferenceType();744  case UTT_IsRvalueReference:745    return T->isRValueReferenceType();746  case UTT_IsMemberFunctionPointer:747    return T->isMemberFunctionPointerType();748  case UTT_IsMemberObjectPointer:749    return T->isMemberDataPointerType();750  case UTT_IsEnum:751    return T->isEnumeralType();752  case UTT_IsScopedEnum:753    return T->isScopedEnumeralType();754  case UTT_IsUnion:755    return T->isUnionType();756  case UTT_IsClass:757    return T->isClassType() || T->isStructureType() || T->isInterfaceType();758  case UTT_IsFunction:759    return T->isFunctionType();760 761    // Type trait expressions which correspond to the convenient composition762    // predicates in C++0x [meta.unary.comp].763  case UTT_IsReference:764    return T->isReferenceType();765  case UTT_IsArithmetic:766    return T->isArithmeticType() && !T->isEnumeralType();767  case UTT_IsFundamental:768    return T->isFundamentalType();769  case UTT_IsObject:770    return T->isObjectType();771  case UTT_IsScalar:772    // Note: semantic analysis depends on Objective-C lifetime types to be773    // considered scalar types. However, such types do not actually behave774    // like scalar types at run time (since they may require retain/release775    // operations), so we report them as non-scalar.776    if (T->isObjCLifetimeType()) {777      switch (T.getObjCLifetime()) {778      case Qualifiers::OCL_None:779      case Qualifiers::OCL_ExplicitNone:780        return true;781 782      case Qualifiers::OCL_Strong:783      case Qualifiers::OCL_Weak:784      case Qualifiers::OCL_Autoreleasing:785        return false;786      }787    }788 789    return T->isScalarType();790  case UTT_IsCompound:791    return T->isCompoundType();792  case UTT_IsMemberPointer:793    return T->isMemberPointerType();794 795    // Type trait expressions which correspond to the type property predicates796    // in C++0x [meta.unary.prop].797  case UTT_IsConst:798    return T.isConstQualified();799  case UTT_IsVolatile:800    return T.isVolatileQualified();801  case UTT_IsTrivial:802    return T.isTrivialType(C);803  case UTT_IsTriviallyCopyable:804    return T.isTriviallyCopyableType(C);805  case UTT_IsStandardLayout:806    return T->isStandardLayoutType();807  case UTT_IsPOD:808    return T.isPODType(C);809  case UTT_IsLiteral:810    return T->isLiteralType(C);811  case UTT_IsEmpty:812    if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())813      return !RD->isUnion() && RD->isEmpty();814    return false;815  case UTT_IsPolymorphic:816    if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())817      return !RD->isUnion() && RD->isPolymorphic();818    return false;819  case UTT_IsAbstract:820    if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())821      return !RD->isUnion() && RD->isAbstract();822    return false;823  case UTT_IsAggregate:824    // Report vector extensions and complex types as aggregates because they825    // support aggregate initialization. GCC mirrors this behavior for vectors826    // but not _Complex.827    return T->isAggregateType() || T->isVectorType() || T->isExtVectorType() ||828           T->isAnyComplexType();829  // __is_interface_class only returns true when CL is invoked in /CLR mode and830  // even then only when it is used with the 'interface struct ...' syntax831  // Clang doesn't support /CLR which makes this type trait moot.832  case UTT_IsInterfaceClass:833    return false;834  case UTT_IsFinal:835  case UTT_IsSealed:836    if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())837      return RD->hasAttr<FinalAttr>();838    return false;839  case UTT_IsSigned:840    // Enum types should always return false.841    // Floating points should always return true.842    return T->isFloatingType() ||843           (T->isSignedIntegerType() && !T->isEnumeralType());844  case UTT_IsUnsigned:845    // Enum types should always return false.846    return T->isUnsignedIntegerType() && !T->isEnumeralType();847 848    // Type trait expressions which query classes regarding their construction,849    // destruction, and copying. Rather than being based directly on the850    // related type predicates in the standard, they are specified by both851    // GCC[1] and the Embarcadero C++ compiler[2], and Clang implements those852    // specifications.853    //854    //   1: http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html855    //   2:856    //   http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index857    //858    // Note that these builtins do not behave as documented in g++: if a class859    // has both a trivial and a non-trivial special member of a particular kind,860    // they return false! For now, we emulate this behavior.861    // FIXME: This appears to be a g++ bug: more complex cases reveal that it862    // does not correctly compute triviality in the presence of multiple special863    // members of the same kind. Revisit this once the g++ bug is fixed.864  case UTT_HasTrivialDefaultConstructor:865    // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:866    //   If __is_pod (type) is true then the trait is true, else if type is867    //   a cv class or union type (or array thereof) with a trivial default868    //   constructor ([class.ctor]) then the trait is true, else it is false.869    if (T.isPODType(C))870      return true;871    if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())872      return RD->hasTrivialDefaultConstructor() &&873             !RD->hasNonTrivialDefaultConstructor();874    return false;875  case UTT_HasTrivialMoveConstructor:876    //  This trait is implemented by MSVC 2012 and needed to parse the877    //  standard library headers. Specifically this is used as the logic878    //  behind std::is_trivially_move_constructible (20.9.4.3).879    if (T.isPODType(C))880      return true;881    if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())882      return RD->hasTrivialMoveConstructor() &&883             !RD->hasNonTrivialMoveConstructor();884    return false;885  case UTT_HasTrivialCopy:886    // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:887    //   If __is_pod (type) is true or type is a reference type then888    //   the trait is true, else if type is a cv class or union type889    //   with a trivial copy constructor ([class.copy]) then the trait890    //   is true, else it is false.891    if (T.isPODType(C) || T->isReferenceType())892      return true;893    if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())894      return RD->hasTrivialCopyConstructor() &&895             !RD->hasNonTrivialCopyConstructor();896    return false;897  case UTT_HasTrivialMoveAssign:898    //  This trait is implemented by MSVC 2012 and needed to parse the899    //  standard library headers. Specifically it is used as the logic900    //  behind std::is_trivially_move_assignable (20.9.4.3)901    if (T.isPODType(C))902      return true;903    if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())904      return RD->hasTrivialMoveAssignment() &&905             !RD->hasNonTrivialMoveAssignment();906    return false;907  case UTT_HasTrivialAssign:908    // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:909    //   If type is const qualified or is a reference type then the910    //   trait is false. Otherwise if __is_pod (type) is true then the911    //   trait is true, else if type is a cv class or union type with912    //   a trivial copy assignment ([class.copy]) then the trait is913    //   true, else it is false.914    // Note: the const and reference restrictions are interesting,915    // given that const and reference members don't prevent a class916    // from having a trivial copy assignment operator (but do cause917    // errors if the copy assignment operator is actually used, q.v.918    // [class.copy]p12).919 920    if (T.isConstQualified())921      return false;922    if (T.isPODType(C))923      return true;924    if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())925      return RD->hasTrivialCopyAssignment() &&926             !RD->hasNonTrivialCopyAssignment();927    return false;928  case UTT_IsDestructible:929  case UTT_IsTriviallyDestructible:930  case UTT_IsNothrowDestructible:931    // C++14 [meta.unary.prop]:932    //   For reference types, is_destructible<T>::value is true.933    if (T->isReferenceType())934      return true;935 936    // Objective-C++ ARC: autorelease types don't require destruction.937    if (T->isObjCLifetimeType() &&938        T.getObjCLifetime() == Qualifiers::OCL_Autoreleasing)939      return true;940 941    // C++14 [meta.unary.prop]:942    //   For incomplete types and function types, is_destructible<T>::value is943    //   false.944    if (T->isIncompleteType() || T->isFunctionType())945      return false;946 947    // A type that requires destruction (via a non-trivial destructor or ARC948    // lifetime semantics) is not trivially-destructible.949    if (UTT == UTT_IsTriviallyDestructible && T.isDestructedType())950      return false;951 952    // C++14 [meta.unary.prop]:953    //   For object types and given U equal to remove_all_extents_t<T>, if the954    //   expression std::declval<U&>().~U() is well-formed when treated as an955    //   unevaluated operand (Clause 5), then is_destructible<T>::value is true956    if (auto *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) {957      CXXDestructorDecl *Destructor = Self.LookupDestructor(RD);958      if (!Destructor)959        return false;960      //  C++14 [dcl.fct.def.delete]p2:961      //    A program that refers to a deleted function implicitly or962      //    explicitly, other than to declare it, is ill-formed.963      if (Destructor->isDeleted())964        return false;965      if (C.getLangOpts().AccessControl && Destructor->getAccess() != AS_public)966        return false;967      if (UTT == UTT_IsNothrowDestructible) {968        auto *CPT = Destructor->getType()->castAs<FunctionProtoType>();969        CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);970        if (!CPT || !CPT->isNothrow())971          return false;972      }973    }974    return true;975 976  case UTT_HasTrivialDestructor:977    // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html978    //   If __is_pod (type) is true or type is a reference type979    //   then the trait is true, else if type is a cv class or union980    //   type (or array thereof) with a trivial destructor981    //   ([class.dtor]) then the trait is true, else it is982    //   false.983    if (T.isPODType(C) || T->isReferenceType())984      return true;985 986    // Objective-C++ ARC: autorelease types don't require destruction.987    if (T->isObjCLifetimeType() &&988        T.getObjCLifetime() == Qualifiers::OCL_Autoreleasing)989      return true;990 991    if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())992      return RD->hasTrivialDestructor();993    return false;994  // TODO: Propagate nothrowness for implicitly declared special members.995  case UTT_HasNothrowAssign:996    // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:997    //   If type is const qualified or is a reference type then the998    //   trait is false. Otherwise if __has_trivial_assign (type)999    //   is true then the trait is true, else if type is a cv class1000    //   or union type with copy assignment operators that are known1001    //   not to throw an exception then the trait is true, else it is1002    //   false.1003    if (C.getBaseElementType(T).isConstQualified())1004      return false;1005    if (T->isReferenceType())1006      return false;1007    if (T.isPODType(C) || T->isObjCLifetimeType())1008      return true;1009 1010    if (auto *RD = T->getAsCXXRecordDecl())1011      return HasNoThrowOperator(RD, OO_Equal, Self, KeyLoc, C,1012                                &CXXRecordDecl::hasTrivialCopyAssignment,1013                                &CXXRecordDecl::hasNonTrivialCopyAssignment,1014                                &CXXMethodDecl::isCopyAssignmentOperator);1015    return false;1016  case UTT_HasNothrowMoveAssign:1017    //  This trait is implemented by MSVC 2012 and needed to parse the1018    //  standard library headers. Specifically this is used as the logic1019    //  behind std::is_nothrow_move_assignable (20.9.4.3).1020    if (T.isPODType(C))1021      return true;1022 1023    if (auto *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())1024      return HasNoThrowOperator(RD, OO_Equal, Self, KeyLoc, C,1025                                &CXXRecordDecl::hasTrivialMoveAssignment,1026                                &CXXRecordDecl::hasNonTrivialMoveAssignment,1027                                &CXXMethodDecl::isMoveAssignmentOperator);1028    return false;1029  case UTT_HasNothrowCopy:1030    // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:1031    //   If __has_trivial_copy (type) is true then the trait is true, else1032    //   if type is a cv class or union type with copy constructors that are1033    //   known not to throw an exception then the trait is true, else it is1034    //   false.1035    if (T.isPODType(C) || T->isReferenceType() || T->isObjCLifetimeType())1036      return true;1037    if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) {1038      if (RD->hasTrivialCopyConstructor() &&1039          !RD->hasNonTrivialCopyConstructor())1040        return true;1041 1042      bool FoundConstructor = false;1043      unsigned FoundTQs;1044      for (const auto *ND : Self.LookupConstructors(RD)) {1045        // A template constructor is never a copy constructor.1046        // FIXME: However, it may actually be selected at the actual overload1047        // resolution point.1048        if (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl()))1049          continue;1050        // UsingDecl itself is not a constructor1051        if (isa<UsingDecl>(ND))1052          continue;1053        auto *Constructor = cast<CXXConstructorDecl>(ND->getUnderlyingDecl());1054        if (Constructor->isCopyConstructor(FoundTQs)) {1055          FoundConstructor = true;1056          auto *CPT = Constructor->getType()->castAs<FunctionProtoType>();1057          CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);1058          if (!CPT)1059            return false;1060          // TODO: check whether evaluating default arguments can throw.1061          // For now, we'll be conservative and assume that they can throw.1062          if (!CPT->isNothrow() || CPT->getNumParams() > 1)1063            return false;1064        }1065      }1066 1067      return FoundConstructor;1068    }1069    return false;1070  case UTT_HasNothrowConstructor:1071    // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html1072    //   If __has_trivial_constructor (type) is true then the trait is1073    //   true, else if type is a cv class or union type (or array1074    //   thereof) with a default constructor that is known not to1075    //   throw an exception then the trait is true, else it is false.1076    if (T.isPODType(C) || T->isObjCLifetimeType())1077      return true;1078    if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) {1079      if (RD->hasTrivialDefaultConstructor())1080        return true;1081 1082      bool FoundConstructor = false;1083      for (const auto *ND : Self.LookupConstructors(RD)) {1084        // FIXME: In C++0x, a constructor template can be a default constructor.1085        if (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl()))1086          continue;1087        // UsingDecl itself is not a constructor1088        if (isa<UsingDecl>(ND))1089          continue;1090        auto *Constructor = cast<CXXConstructorDecl>(ND->getUnderlyingDecl());1091        if (Constructor->isDefaultConstructor()) {1092          FoundConstructor = true;1093          auto *CPT = Constructor->getType()->castAs<FunctionProtoType>();1094          CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);1095          if (!CPT)1096            return false;1097          // FIXME: check whether evaluating default arguments can throw.1098          // For now, we'll be conservative and assume that they can throw.1099          if (!CPT->isNothrow() || CPT->getNumParams() > 0)1100            return false;1101        }1102      }1103      return FoundConstructor;1104    }1105    return false;1106  case UTT_HasVirtualDestructor:1107    // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:1108    //   If type is a class type with a virtual destructor ([class.dtor])1109    //   then the trait is true, else it is false.1110    if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())1111      if (CXXDestructorDecl *Destructor = Self.LookupDestructor(RD))1112        return Destructor->isVirtual();1113    return false;1114 1115    // These type trait expressions are modeled on the specifications for the1116    // Embarcadero C++0x type trait functions:1117    //   http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index1118  case UTT_IsCompleteType:1119    // http://docwiki.embarcadero.com/RADStudio/XE/en/Is_complete_type_(typename_T_):1120    //   Returns True if and only if T is a complete type at the point of the1121    //   function call.1122    return !T->isIncompleteType();1123  case UTT_HasUniqueObjectRepresentations:1124    return C.hasUniqueObjectRepresentations(T);1125  case UTT_IsTriviallyRelocatable:1126    return IsTriviallyRelocatableType(Self, T);1127  case UTT_IsBitwiseCloneable:1128    return T.isBitwiseCloneableType(C);1129  case UTT_IsCppTriviallyRelocatable:1130    return Self.IsCXXTriviallyRelocatableType(T);1131  case UTT_IsReplaceable:1132    return Self.IsCXXReplaceableType(T);1133  case UTT_CanPassInRegs:1134    if (CXXRecordDecl *RD = T->getAsCXXRecordDecl(); RD && !T.hasQualifiers())1135      return RD->canPassInRegisters();1136    Self.Diag(KeyLoc, diag::err_builtin_pass_in_regs_non_class) << T;1137    return false;1138  case UTT_IsTriviallyEqualityComparable:1139    return isTriviallyEqualityComparableType(Self, T, KeyLoc);1140  case UTT_IsImplicitLifetime: {1141    DiagnoseVLAInCXXTypeTrait(Self, TInfo,1142                              tok::kw___builtin_is_implicit_lifetime);1143    DiagnoseAtomicInCXXTypeTrait(Self, TInfo,1144                                 tok::kw___builtin_is_implicit_lifetime);1145 1146    // [basic.types.general] p91147    // Scalar types, implicit-lifetime class types ([class.prop]),1148    // array types, and cv-qualified versions of these types1149    // are collectively called implicit-lifetime types.1150    QualType UnqualT = T->getCanonicalTypeUnqualified();1151    if (UnqualT->isScalarType())1152      return true;1153    if (UnqualT->isArrayType() || UnqualT->isVectorType())1154      return true;1155    const CXXRecordDecl *RD = UnqualT->getAsCXXRecordDecl();1156    if (!RD)1157      return false;1158 1159    // [class.prop] p91160    // A class S is an implicit-lifetime class if1161    //   - it is an aggregate whose destructor is not user-provided or1162    //   - it has at least one trivial eligible constructor and a trivial,1163    //     non-deleted destructor.1164    const CXXDestructorDecl *Dtor = RD->getDestructor();1165    if (UnqualT->isAggregateType() && (!Dtor || !Dtor->isUserProvided()))1166      return true;1167    bool HasTrivialNonDeletedDtr =1168        RD->hasTrivialDestructor() && (!Dtor || !Dtor->isDeleted());1169    if (!HasTrivialNonDeletedDtr)1170      return false;1171    for (CXXConstructorDecl *Ctr : RD->ctors()) {1172      if (Ctr->isIneligibleOrNotSelected() || Ctr->isDeleted())1173        continue;1174      if (Ctr->isTrivial())1175        return true;1176    }1177    if (RD->needsImplicitDefaultConstructor() &&1178        RD->hasTrivialDefaultConstructor() &&1179        !RD->hasNonTrivialDefaultConstructor())1180      return true;1181    if (RD->needsImplicitCopyConstructor() && RD->hasTrivialCopyConstructor() &&1182        !RD->defaultedCopyConstructorIsDeleted())1183      return true;1184    if (RD->needsImplicitMoveConstructor() && RD->hasTrivialMoveConstructor() &&1185        !RD->defaultedMoveConstructorIsDeleted())1186      return true;1187    return false;1188  }1189  case UTT_IsIntangibleType:1190    assert(Self.getLangOpts().HLSL && "intangible types are HLSL-only feature");1191    if (!T->isVoidType() && !T->isIncompleteArrayType())1192      if (Self.RequireCompleteType(TInfo->getTypeLoc().getBeginLoc(), T,1193                                   diag::err_incomplete_type))1194        return false;1195    if (DiagnoseVLAInCXXTypeTrait(Self, TInfo,1196                                  tok::kw___builtin_hlsl_is_intangible))1197      return false;1198    return T->isHLSLIntangibleType();1199 1200  case UTT_IsTypedResourceElementCompatible:1201    assert(Self.getLangOpts().HLSL &&1202           "typed resource element compatible types are an HLSL-only feature");1203    if (T->isIncompleteType())1204      return false;1205 1206    return Self.HLSL().IsTypedResourceElementCompatible(T);1207  }1208}1209 1210static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT,1211                                    const TypeSourceInfo *Lhs,1212                                    const TypeSourceInfo *Rhs,1213                                    SourceLocation KeyLoc);1214 1215static APValue EvaluateSizeTTypeTrait(Sema &S, TypeTrait Kind,1216                                      SourceLocation KWLoc,1217                                      ArrayRef<TypeSourceInfo *> Args,1218                                      SourceLocation RParenLoc,1219                                      bool IsDependent) {1220  if (IsDependent)1221    return APValue();1222 1223  switch (Kind) {1224  case TypeTrait::UTT_StructuredBindingSize: {1225    QualType T = Args[0]->getType();1226    SourceRange ArgRange = Args[0]->getTypeLoc().getSourceRange();1227    UnsignedOrNone Size =1228        S.GetDecompositionElementCount(T, ArgRange.getBegin());1229    if (!Size) {1230      S.Diag(KWLoc, diag::err_arg_is_not_destructurable) << T << ArgRange;1231      return APValue();1232    }1233    return APValue(1234        S.getASTContext().MakeIntValue(*Size, S.getASTContext().getSizeType()));1235    break;1236  }1237  default:1238    llvm_unreachable("Not a SizeT type trait");1239  }1240}1241 1242static bool EvaluateBooleanTypeTrait(Sema &S, TypeTrait Kind,1243                                     SourceLocation KWLoc,1244                                     ArrayRef<TypeSourceInfo *> Args,1245                                     SourceLocation RParenLoc,1246                                     bool IsDependent) {1247  if (IsDependent)1248    return false;1249 1250  if (Kind <= UTT_Last)1251    return EvaluateUnaryTypeTrait(S, Kind, KWLoc, Args[0]);1252 1253  // Evaluate ReferenceBindsToTemporary and ReferenceConstructsFromTemporary1254  // alongside the IsConstructible traits to avoid duplication.1255  if (Kind <= BTT_Last && Kind != BTT_ReferenceBindsToTemporary &&1256      Kind != BTT_ReferenceConstructsFromTemporary &&1257      Kind != BTT_ReferenceConvertsFromTemporary)1258    return EvaluateBinaryTypeTrait(S, Kind, Args[0], Args[1], RParenLoc);1259 1260  switch (Kind) {1261  case clang::BTT_ReferenceBindsToTemporary:1262  case clang::BTT_ReferenceConstructsFromTemporary:1263  case clang::BTT_ReferenceConvertsFromTemporary:1264  case clang::TT_IsConstructible:1265  case clang::TT_IsNothrowConstructible:1266  case clang::TT_IsTriviallyConstructible: {1267    // C++11 [meta.unary.prop]:1268    //   is_trivially_constructible is defined as:1269    //1270    //     is_constructible<T, Args...>::value is true and the variable1271    //     definition for is_constructible, as defined below, is known to call1272    //     no operation that is not trivial.1273    //1274    //   The predicate condition for a template specialization1275    //   is_constructible<T, Args...> shall be satisfied if and only if the1276    //   following variable definition would be well-formed for some invented1277    //   variable t:1278    //1279    //     T t(create<Args>()...);1280    assert(!Args.empty());1281 1282    // Precondition: T and all types in the parameter pack Args shall be1283    // complete types, (possibly cv-qualified) void, or arrays of1284    // unknown bound.1285    for (const auto *TSI : Args) {1286      QualType ArgTy = TSI->getType();1287      if (ArgTy->isVoidType() || ArgTy->isIncompleteArrayType())1288        continue;1289 1290      if (S.RequireCompleteType(1291              KWLoc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr))1292        return false;1293    }1294 1295    // Make sure the first argument is not incomplete nor a function type.1296    QualType T = Args[0]->getType();1297    if (T->isIncompleteType() || T->isFunctionType())1298      return false;1299 1300    // Make sure the first argument is not an abstract type.1301    CXXRecordDecl *RD = T->getAsCXXRecordDecl();1302    if (RD && RD->isAbstract())1303      return false;1304 1305    // LWG3819: For reference_meows_from_temporary traits, && is not added to1306    // the source object type.1307    // Otherwise, compute the result of add_rvalue_reference_t.1308    bool UseRawObjectType =1309        Kind == clang::BTT_ReferenceBindsToTemporary ||1310        Kind == clang::BTT_ReferenceConstructsFromTemporary ||1311        Kind == clang::BTT_ReferenceConvertsFromTemporary;1312 1313    llvm::BumpPtrAllocator OpaqueExprAllocator;1314    SmallVector<Expr *, 2> ArgExprs;1315    ArgExprs.reserve(Args.size() - 1);1316    for (unsigned I = 1, N = Args.size(); I != N; ++I) {1317      QualType ArgTy = Args[I]->getType();1318      if ((ArgTy->isObjectType() && !UseRawObjectType) ||1319          ArgTy->isFunctionType())1320        ArgTy = S.Context.getRValueReferenceType(ArgTy);1321      ArgExprs.push_back(1322          new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())1323              OpaqueValueExpr(Args[I]->getTypeLoc().getBeginLoc(),1324                              ArgTy.getNonLValueExprType(S.Context),1325                              Expr::getValueKindForType(ArgTy)));1326    }1327 1328    // Perform the initialization in an unevaluated context within a SFINAE1329    // trap at translation unit scope.1330    EnterExpressionEvaluationContext Unevaluated(1331        S, Sema::ExpressionEvaluationContext::Unevaluated);1332    Sema::SFINAETrap SFINAE(S, /*ForValidityCheck=*/true);1333    Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl());1334    InitializedEntity To(1335        InitializedEntity::InitializeTemporary(S.Context, Args[0]));1336    InitializationKind InitKind(1337        Kind == clang::BTT_ReferenceConvertsFromTemporary1338            ? InitializationKind::CreateCopy(KWLoc, KWLoc)1339            : InitializationKind::CreateDirect(KWLoc, KWLoc, RParenLoc));1340    InitializationSequence Init(S, To, InitKind, ArgExprs);1341    if (Init.Failed())1342      return false;1343 1344    ExprResult Result = Init.Perform(S, To, InitKind, ArgExprs);1345    if (Result.isInvalid() || SFINAE.hasErrorOccurred())1346      return false;1347 1348    if (Kind == clang::TT_IsConstructible)1349      return true;1350 1351    if (Kind == clang::BTT_ReferenceBindsToTemporary ||1352        Kind == clang::BTT_ReferenceConstructsFromTemporary ||1353        Kind == clang::BTT_ReferenceConvertsFromTemporary) {1354      if (!T->isReferenceType())1355        return false;1356 1357      // A function reference never binds to a temporary object.1358      if (T.getNonReferenceType()->isFunctionType())1359        return false;1360 1361      if (!Init.isDirectReferenceBinding())1362        return true;1363 1364      if (Kind == clang::BTT_ReferenceBindsToTemporary)1365        return false;1366 1367      QualType U = Args[1]->getType();1368      if (U->isReferenceType())1369        return false;1370 1371      TypeSourceInfo *TPtr = S.Context.CreateTypeSourceInfo(1372          S.Context.getPointerType(T.getNonReferenceType()));1373      TypeSourceInfo *UPtr = S.Context.CreateTypeSourceInfo(1374          S.Context.getPointerType(U.getNonReferenceType()));1375      return S.BuiltinIsConvertible(UPtr->getType(), TPtr->getType(),1376                                    RParenLoc);1377    }1378 1379    if (Kind == clang::TT_IsNothrowConstructible)1380      return S.canThrow(Result.get()) == CT_Cannot;1381 1382    if (Kind == clang::TT_IsTriviallyConstructible) {1383      // Under Objective-C ARC and Weak, if the destination has non-trivial1384      // Objective-C lifetime, this is a non-trivial construction.1385      if (T.getNonReferenceType().hasNonTrivialObjCLifetime())1386        return false;1387 1388      // The initialization succeeded; now make sure there are no non-trivial1389      // calls.1390      return !Result.get()->hasNonTrivialCall(S.Context);1391    }1392 1393    llvm_unreachable("unhandled type trait");1394    return false;1395  }1396  default:1397    llvm_unreachable("not a TT");1398  }1399 1400  return false;1401}1402 1403namespace {1404void DiagnoseBuiltinDeprecation(Sema &S, TypeTrait Kind, SourceLocation KWLoc) {1405  TypeTrait Replacement;1406  switch (Kind) {1407  case UTT_HasNothrowAssign:1408  case UTT_HasNothrowMoveAssign:1409    Replacement = BTT_IsNothrowAssignable;1410    break;1411  case UTT_HasNothrowCopy:1412  case UTT_HasNothrowConstructor:1413    Replacement = TT_IsNothrowConstructible;1414    break;1415  case UTT_HasTrivialAssign:1416  case UTT_HasTrivialMoveAssign:1417    Replacement = BTT_IsTriviallyAssignable;1418    break;1419  case UTT_HasTrivialCopy:1420    Replacement = UTT_IsTriviallyCopyable;1421    break;1422  case UTT_HasTrivialDefaultConstructor:1423  case UTT_HasTrivialMoveConstructor:1424    Replacement = TT_IsTriviallyConstructible;1425    break;1426  case UTT_HasTrivialDestructor:1427    Replacement = UTT_IsTriviallyDestructible;1428    break;1429  case UTT_IsTriviallyRelocatable:1430    Replacement = clang::UTT_IsCppTriviallyRelocatable;1431    break;1432  case BTT_ReferenceBindsToTemporary:1433    Replacement = clang::BTT_ReferenceConstructsFromTemporary;1434    break;1435  default:1436    return;1437  }1438  S.Diag(KWLoc, diag::warn_deprecated_builtin)1439      << getTraitSpelling(Kind) << getTraitSpelling(Replacement);1440}1441} // namespace1442 1443bool Sema::CheckTypeTraitArity(unsigned Arity, SourceLocation Loc, size_t N) {1444  if (Arity && N != Arity) {1445    Diag(Loc, diag::err_type_trait_arity)1446        << Arity << 0 << (Arity > 1) << (int)N << SourceRange(Loc);1447    return false;1448  }1449 1450  if (!Arity && N == 0) {1451    Diag(Loc, diag::err_type_trait_arity)1452        << 1 << 1 << 1 << (int)N << SourceRange(Loc);1453    return false;1454  }1455  return true;1456}1457 1458enum class TypeTraitReturnType {1459  Bool,1460  SizeT,1461};1462 1463static TypeTraitReturnType GetReturnType(TypeTrait Kind) {1464  if (Kind == TypeTrait::UTT_StructuredBindingSize)1465    return TypeTraitReturnType::SizeT;1466  return TypeTraitReturnType::Bool;1467}1468 1469ExprResult Sema::BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc,1470                                ArrayRef<TypeSourceInfo *> Args,1471                                SourceLocation RParenLoc) {1472  if (!CheckTypeTraitArity(getTypeTraitArity(Kind), KWLoc, Args.size()))1473    return ExprError();1474 1475  if (Kind <= UTT_Last && !CheckUnaryTypeTraitTypeCompleteness(1476                              *this, Kind, KWLoc, Args[0]->getType()))1477    return ExprError();1478 1479  DiagnoseBuiltinDeprecation(*this, Kind, KWLoc);1480 1481  bool Dependent = false;1482  for (unsigned I = 0, N = Args.size(); I != N; ++I) {1483    if (Args[I]->getType()->isDependentType()) {1484      Dependent = true;1485      break;1486    }1487  }1488 1489  switch (GetReturnType(Kind)) {1490  case TypeTraitReturnType::Bool: {1491    bool Result = EvaluateBooleanTypeTrait(*this, Kind, KWLoc, Args, RParenLoc,1492                                           Dependent);1493    return TypeTraitExpr::Create(Context, Context.getLogicalOperationType(),1494                                 KWLoc, Kind, Args, RParenLoc, Result);1495  }1496  case TypeTraitReturnType::SizeT: {1497    APValue Result =1498        EvaluateSizeTTypeTrait(*this, Kind, KWLoc, Args, RParenLoc, Dependent);1499    return TypeTraitExpr::Create(Context, Context.getSizeType(), KWLoc, Kind,1500                                 Args, RParenLoc, Result);1501  }1502  }1503  llvm_unreachable("unhandled type trait return type");1504}1505 1506ExprResult Sema::ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc,1507                                ArrayRef<ParsedType> Args,1508                                SourceLocation RParenLoc) {1509  SmallVector<TypeSourceInfo *, 4> ConvertedArgs;1510  ConvertedArgs.reserve(Args.size());1511 1512  for (unsigned I = 0, N = Args.size(); I != N; ++I) {1513    TypeSourceInfo *TInfo;1514    QualType T = GetTypeFromParser(Args[I], &TInfo);1515    if (!TInfo)1516      TInfo = Context.getTrivialTypeSourceInfo(T, KWLoc);1517 1518    ConvertedArgs.push_back(TInfo);1519  }1520 1521  return BuildTypeTrait(Kind, KWLoc, ConvertedArgs, RParenLoc);1522}1523 1524bool Sema::BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT,1525                           QualType RhsT) {1526  // C++0x [meta.rel]p21527  // Base is a base class of Derived without regard to cv-qualifiers or1528  // Base and Derived are not unions and name the same class type without1529  // regard to cv-qualifiers.1530 1531  const RecordType *lhsRecord = LhsT->getAsCanonical<RecordType>();1532  const RecordType *rhsRecord = RhsT->getAsCanonical<RecordType>();1533  if (!rhsRecord || !lhsRecord) {1534    const ObjCObjectType *LHSObjTy = LhsT->getAs<ObjCObjectType>();1535    const ObjCObjectType *RHSObjTy = RhsT->getAs<ObjCObjectType>();1536    if (!LHSObjTy || !RHSObjTy)1537      return false;1538 1539    ObjCInterfaceDecl *BaseInterface = LHSObjTy->getInterface();1540    ObjCInterfaceDecl *DerivedInterface = RHSObjTy->getInterface();1541    if (!BaseInterface || !DerivedInterface)1542      return false;1543 1544    if (RequireCompleteType(RhsTLoc, RhsT,1545                            diag::err_incomplete_type_used_in_type_trait_expr))1546      return false;1547 1548    return BaseInterface->isSuperClassOf(DerivedInterface);1549  }1550 1551  assert(Context.hasSameUnqualifiedType(LhsT, RhsT) ==1552         (lhsRecord == rhsRecord));1553 1554  // Unions are never base classes, and never have base classes.1555  // It doesn't matter if they are complete or not. See PR#418431556  if (lhsRecord && lhsRecord->getDecl()->isUnion())1557    return false;1558  if (rhsRecord && rhsRecord->getDecl()->isUnion())1559    return false;1560 1561  if (lhsRecord == rhsRecord)1562    return true;1563 1564  // C++0x [meta.rel]p2:1565  //   If Base and Derived are class types and are different types1566  //   (ignoring possible cv-qualifiers) then Derived shall be a1567  //   complete type.1568  if (RequireCompleteType(RhsTLoc, RhsT,1569                          diag::err_incomplete_type_used_in_type_trait_expr))1570    return false;1571 1572  return cast<CXXRecordDecl>(rhsRecord->getDecl())1573      ->isDerivedFrom(cast<CXXRecordDecl>(lhsRecord->getDecl()));1574}1575 1576static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT,1577                                    const TypeSourceInfo *Lhs,1578                                    const TypeSourceInfo *Rhs,1579                                    SourceLocation KeyLoc) {1580  QualType LhsT = Lhs->getType();1581  QualType RhsT = Rhs->getType();1582 1583  assert(!LhsT->isDependentType() && !RhsT->isDependentType() &&1584         "Cannot evaluate traits of dependent types");1585 1586  switch (BTT) {1587  case BTT_IsBaseOf:1588    return Self.BuiltinIsBaseOf(Rhs->getTypeLoc().getBeginLoc(), LhsT, RhsT);1589 1590  case BTT_IsVirtualBaseOf: {1591    const RecordType *BaseRecord = LhsT->getAsCanonical<RecordType>();1592    const RecordType *DerivedRecord = RhsT->getAsCanonical<RecordType>();1593 1594    if (!BaseRecord || !DerivedRecord) {1595      DiagnoseVLAInCXXTypeTrait(Self, Lhs,1596                                tok::kw___builtin_is_virtual_base_of);1597      DiagnoseVLAInCXXTypeTrait(Self, Rhs,1598                                tok::kw___builtin_is_virtual_base_of);1599      return false;1600    }1601 1602    if (BaseRecord->isUnionType() || DerivedRecord->isUnionType())1603      return false;1604 1605    if (!BaseRecord->isStructureOrClassType() ||1606        !DerivedRecord->isStructureOrClassType())1607      return false;1608 1609    if (Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,1610                                 diag::err_incomplete_type))1611      return false;1612 1613    return cast<CXXRecordDecl>(DerivedRecord->getDecl())1614        ->isVirtuallyDerivedFrom(cast<CXXRecordDecl>(BaseRecord->getDecl()));1615  }1616  case BTT_IsSame:1617    return Self.Context.hasSameType(LhsT, RhsT);1618  case BTT_TypeCompatible: {1619    // GCC ignores cv-qualifiers on arrays for this builtin.1620    Qualifiers LhsQuals, RhsQuals;1621    QualType Lhs = Self.getASTContext().getUnqualifiedArrayType(LhsT, LhsQuals);1622    QualType Rhs = Self.getASTContext().getUnqualifiedArrayType(RhsT, RhsQuals);1623    return Self.Context.typesAreCompatible(Lhs, Rhs);1624  }1625  case BTT_IsConvertible:1626  case BTT_IsConvertibleTo:1627  case BTT_IsNothrowConvertible:1628    return Self.BuiltinIsConvertible(LhsT, RhsT, KeyLoc,1629                                     BTT == BTT_IsNothrowConvertible);1630 1631  case BTT_IsAssignable:1632  case BTT_IsNothrowAssignable:1633  case BTT_IsTriviallyAssignable: {1634    // C++11 [meta.unary.prop]p3:1635    //   is_trivially_assignable is defined as:1636    //     is_assignable<T, U>::value is true and the assignment, as defined by1637    //     is_assignable, is known to call no operation that is not trivial1638    //1639    //   is_assignable is defined as:1640    //     The expression declval<T>() = declval<U>() is well-formed when1641    //     treated as an unevaluated operand (Clause 5).1642    //1643    //   For both, T and U shall be complete types, (possibly cv-qualified)1644    //   void, or arrays of unknown bound.1645    if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType() &&1646        Self.RequireCompleteType(1647            Lhs->getTypeLoc().getBeginLoc(), LhsT,1648            diag::err_incomplete_type_used_in_type_trait_expr))1649      return false;1650    if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType() &&1651        Self.RequireCompleteType(1652            Rhs->getTypeLoc().getBeginLoc(), RhsT,1653            diag::err_incomplete_type_used_in_type_trait_expr))1654      return false;1655 1656    // cv void is never assignable.1657    if (LhsT->isVoidType() || RhsT->isVoidType())1658      return false;1659 1660    // Build expressions that emulate the effect of declval<T>() and1661    // declval<U>().1662    auto createDeclValExpr = [&](QualType Ty) -> OpaqueValueExpr {1663      if (Ty->isObjectType() || Ty->isFunctionType())1664        Ty = Self.Context.getRValueReferenceType(Ty);1665      return {KeyLoc, Ty.getNonLValueExprType(Self.Context),1666              Expr::getValueKindForType(Ty)};1667    };1668 1669    auto Lhs = createDeclValExpr(LhsT);1670    auto Rhs = createDeclValExpr(RhsT);1671 1672    // Attempt the assignment in an unevaluated context within a SFINAE1673    // trap at translation unit scope.1674    EnterExpressionEvaluationContext Unevaluated(1675        Self, Sema::ExpressionEvaluationContext::Unevaluated);1676    Sema::SFINAETrap SFINAE(Self, /*ForValidityCheck=*/true);1677    Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());1678    ExprResult Result =1679        Self.BuildBinOp(/*S=*/nullptr, KeyLoc, BO_Assign, &Lhs, &Rhs);1680    if (Result.isInvalid())1681      return false;1682 1683    // Treat the assignment as unused for the purpose of -Wdeprecated-volatile.1684    Self.CheckUnusedVolatileAssignment(Result.get());1685 1686    if (SFINAE.hasErrorOccurred())1687      return false;1688 1689    if (BTT == BTT_IsAssignable)1690      return true;1691 1692    if (BTT == BTT_IsNothrowAssignable)1693      return Self.canThrow(Result.get()) == CT_Cannot;1694 1695    if (BTT == BTT_IsTriviallyAssignable) {1696      // Under Objective-C ARC and Weak, if the destination has non-trivial1697      // Objective-C lifetime, this is a non-trivial assignment.1698      if (LhsT.getNonReferenceType().hasNonTrivialObjCLifetime())1699        return false;1700      const ASTContext &Context = Self.getASTContext();1701      if (Context.containsAddressDiscriminatedPointerAuth(LhsT) ||1702          Context.containsAddressDiscriminatedPointerAuth(RhsT))1703        return false;1704      return !Result.get()->hasNonTrivialCall(Self.Context);1705    }1706 1707    llvm_unreachable("unhandled type trait");1708    return false;1709  }1710  case BTT_IsLayoutCompatible: {1711    if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType())1712      Self.RequireCompleteType(Lhs->getTypeLoc().getBeginLoc(), LhsT,1713                               diag::err_incomplete_type);1714    if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType())1715      Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,1716                               diag::err_incomplete_type);1717 1718    DiagnoseVLAInCXXTypeTrait(Self, Lhs, tok::kw___is_layout_compatible);1719    DiagnoseVLAInCXXTypeTrait(Self, Rhs, tok::kw___is_layout_compatible);1720 1721    return Self.IsLayoutCompatible(LhsT, RhsT);1722  }1723  case BTT_IsPointerInterconvertibleBaseOf: {1724    if (LhsT->isStructureOrClassType() && RhsT->isStructureOrClassType() &&1725        !Self.getASTContext().hasSameUnqualifiedType(LhsT, RhsT)) {1726      Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,1727                               diag::err_incomplete_type);1728    }1729 1730    DiagnoseVLAInCXXTypeTrait(Self, Lhs,1731                              tok::kw___is_pointer_interconvertible_base_of);1732    DiagnoseVLAInCXXTypeTrait(Self, Rhs,1733                              tok::kw___is_pointer_interconvertible_base_of);1734 1735    return Self.IsPointerInterconvertibleBaseOf(Lhs, Rhs);1736  }1737  case BTT_IsDeducible: {1738    const auto *TSTToBeDeduced = cast<DeducedTemplateSpecializationType>(LhsT);1739    sema::TemplateDeductionInfo Info(KeyLoc);1740    return Self.DeduceTemplateArgumentsFromType(1741               TSTToBeDeduced->getTemplateName().getAsTemplateDecl(), RhsT,1742               Info) == TemplateDeductionResult::Success;1743  }1744  case BTT_IsScalarizedLayoutCompatible: {1745    if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType() &&1746        Self.RequireCompleteType(Lhs->getTypeLoc().getBeginLoc(), LhsT,1747                                 diag::err_incomplete_type))1748      return true;1749    if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType() &&1750        Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,1751                                 diag::err_incomplete_type))1752      return true;1753 1754    DiagnoseVLAInCXXTypeTrait(1755        Self, Lhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);1756    DiagnoseVLAInCXXTypeTrait(1757        Self, Rhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);1758 1759    return Self.HLSL().IsScalarizedLayoutCompatible(LhsT, RhsT);1760  }1761  case BTT_LtSynthesizesFromSpaceship:1762  case BTT_LeSynthesizesFromSpaceship:1763  case BTT_GtSynthesizesFromSpaceship:1764  case BTT_GeSynthesizesFromSpaceship: {1765    EnterExpressionEvaluationContext UnevaluatedContext(1766        Self, Sema::ExpressionEvaluationContext::Unevaluated);1767    Sema::SFINAETrap SFINAE(Self, /*ForValidityCheck=*/true);1768    Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());1769 1770    OpaqueValueExpr LHS(KeyLoc, LhsT.getNonReferenceType(),1771                        LhsT->isLValueReferenceType() ? ExprValueKind::VK_LValue1772                        : LhsT->isRValueReferenceType()1773                            ? ExprValueKind::VK_XValue1774                            : ExprValueKind::VK_PRValue);1775    OpaqueValueExpr RHS(KeyLoc, RhsT.getNonReferenceType(),1776                        RhsT->isLValueReferenceType() ? ExprValueKind::VK_LValue1777                        : RhsT->isRValueReferenceType()1778                            ? ExprValueKind::VK_XValue1779                            : ExprValueKind::VK_PRValue);1780 1781    auto OpKind = [&] {1782      switch (BTT) {1783      case BTT_LtSynthesizesFromSpaceship:1784        return BinaryOperatorKind::BO_LT;1785      case BTT_LeSynthesizesFromSpaceship:1786        return BinaryOperatorKind::BO_LE;1787      case BTT_GtSynthesizesFromSpaceship:1788        return BinaryOperatorKind::BO_GT;1789      case BTT_GeSynthesizesFromSpaceship:1790        return BinaryOperatorKind::BO_GE;1791      default:1792        llvm_unreachable("Trying to Synthesize non-comparison operator?");1793      }1794    }();1795 1796    UnresolvedSet<16> Functions;1797    Self.LookupBinOp(Self.TUScope, KeyLoc, OpKind, Functions);1798 1799    ExprResult Result =1800        Self.CreateOverloadedBinOp(KeyLoc, OpKind, Functions, &LHS, &RHS);1801    if (Result.isInvalid() || SFINAE.hasErrorOccurred())1802      return false;1803 1804    return isa<CXXRewrittenBinaryOperator>(Result.get());1805  }1806  default:1807    llvm_unreachable("not a BTT");1808  }1809  llvm_unreachable("Unknown type trait or not implemented");1810}1811 1812ExprResult Sema::ActOnArrayTypeTrait(ArrayTypeTrait ATT, SourceLocation KWLoc,1813                                     ParsedType Ty, Expr *DimExpr,1814                                     SourceLocation RParen) {1815  TypeSourceInfo *TSInfo;1816  QualType T = GetTypeFromParser(Ty, &TSInfo);1817  if (!TSInfo)1818    TSInfo = Context.getTrivialTypeSourceInfo(T);1819 1820  return BuildArrayTypeTrait(ATT, KWLoc, TSInfo, DimExpr, RParen);1821}1822 1823static uint64_t EvaluateArrayTypeTrait(Sema &Self, ArrayTypeTrait ATT,1824                                       QualType T, Expr *DimExpr,1825                                       SourceLocation KeyLoc) {1826  assert(!T->isDependentType() && "Cannot evaluate traits of dependent type");1827 1828  switch (ATT) {1829  case ATT_ArrayRank:1830    if (T->isArrayType()) {1831      unsigned Dim = 0;1832      while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {1833        ++Dim;1834        T = AT->getElementType();1835      }1836      return Dim;1837    }1838    return 0;1839 1840  case ATT_ArrayExtent: {1841    llvm::APSInt Value;1842    uint64_t Dim;1843    if (Self.VerifyIntegerConstantExpression(1844                DimExpr, &Value, diag::err_dimension_expr_not_constant_integer)1845            .isInvalid())1846      return 0;1847    if (Value.isSigned() && Value.isNegative()) {1848      Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer)1849          << DimExpr->getSourceRange();1850      return 0;1851    }1852    Dim = Value.getLimitedValue();1853 1854    if (T->isArrayType()) {1855      unsigned D = 0;1856      bool Matched = false;1857      while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {1858        if (Dim == D) {1859          Matched = true;1860          break;1861        }1862        ++D;1863        T = AT->getElementType();1864      }1865 1866      if (Matched && T->isArrayType()) {1867        if (const ConstantArrayType *CAT =1868                Self.Context.getAsConstantArrayType(T))1869          return CAT->getLimitedSize();1870      }1871    }1872    return 0;1873  }1874  }1875  llvm_unreachable("Unknown type trait or not implemented");1876}1877 1878ExprResult Sema::BuildArrayTypeTrait(ArrayTypeTrait ATT, SourceLocation KWLoc,1879                                     TypeSourceInfo *TSInfo, Expr *DimExpr,1880                                     SourceLocation RParen) {1881  QualType T = TSInfo->getType();1882 1883  // FIXME: This should likely be tracked as an APInt to remove any host1884  // assumptions about the width of size_t on the target.1885  uint64_t Value = 0;1886  if (!T->isDependentType())1887    Value = EvaluateArrayTypeTrait(*this, ATT, T, DimExpr, KWLoc);1888 1889  // While the specification for these traits from the Embarcadero C++1890  // compiler's documentation says the return type is 'unsigned int', Clang1891  // returns 'size_t'. On Windows, the primary platform for the Embarcadero1892  // compiler, there is no difference. On several other platforms this is an1893  // important distinction.1894  return new (Context) ArrayTypeTraitExpr(KWLoc, ATT, TSInfo, Value, DimExpr,1895                                          RParen, Context.getSizeType());1896}1897 1898ExprResult Sema::ActOnExpressionTrait(ExpressionTrait ET, SourceLocation KWLoc,1899                                      Expr *Queried, SourceLocation RParen) {1900  // If error parsing the expression, ignore.1901  if (!Queried)1902    return ExprError();1903 1904  ExprResult Result = BuildExpressionTrait(ET, KWLoc, Queried, RParen);1905 1906  return Result;1907}1908 1909static bool EvaluateExpressionTrait(ExpressionTrait ET, Expr *E) {1910  switch (ET) {1911  case ET_IsLValueExpr:1912    return E->isLValue();1913  case ET_IsRValueExpr:1914    return E->isPRValue();1915  }1916  llvm_unreachable("Expression trait not covered by switch");1917}1918 1919ExprResult Sema::BuildExpressionTrait(ExpressionTrait ET, SourceLocation KWLoc,1920                                      Expr *Queried, SourceLocation RParen) {1921  if (Queried->isTypeDependent()) {1922    // Delay type-checking for type-dependent expressions.1923  } else if (Queried->hasPlaceholderType()) {1924    ExprResult PE = CheckPlaceholderExpr(Queried);1925    if (PE.isInvalid())1926      return ExprError();1927    return BuildExpressionTrait(ET, KWLoc, PE.get(), RParen);1928  }1929 1930  bool Value = EvaluateExpressionTrait(ET, Queried);1931 1932  return new (Context)1933      ExpressionTraitExpr(KWLoc, ET, Queried, Value, RParen, Context.BoolTy);1934}1935 1936static std::optional<TypeTrait> StdNameToTypeTrait(StringRef Name) {1937  return llvm::StringSwitch<std::optional<TypeTrait>>(Name)1938      .Case("is_trivially_relocatable",1939            TypeTrait::UTT_IsCppTriviallyRelocatable)1940      .Case("is_replaceable", TypeTrait::UTT_IsReplaceable)1941      .Case("is_trivially_copyable", TypeTrait::UTT_IsTriviallyCopyable)1942      .Case("is_assignable", TypeTrait::BTT_IsAssignable)1943      .Case("is_empty", TypeTrait::UTT_IsEmpty)1944      .Case("is_standard_layout", TypeTrait::UTT_IsStandardLayout)1945      .Case("is_aggregate", TypeTrait::UTT_IsAggregate)1946      .Case("is_constructible", TypeTrait::TT_IsConstructible)1947      .Case("is_final", TypeTrait::UTT_IsFinal)1948      .Case("is_abstract", TypeTrait::UTT_IsAbstract)1949      .Default(std::nullopt);1950}1951 1952using ExtractedTypeTraitInfo =1953    std::optional<std::pair<TypeTrait, llvm::SmallVector<QualType, 1>>>;1954 1955// Recognize type traits that are builting type traits, or known standard1956// type traits in <type_traits>. Note that at this point we assume the1957// trait evaluated to false, so we need only to recognize the shape of the1958// outer-most symbol.1959static ExtractedTypeTraitInfo ExtractTypeTraitFromExpression(const Expr *E) {1960  llvm::SmallVector<QualType, 1> Args;1961  std::optional<TypeTrait> Trait;1962 1963  // builtins1964  if (const auto *TraitExpr = dyn_cast<TypeTraitExpr>(E)) {1965    Trait = TraitExpr->getTrait();1966    for (const auto *Arg : TraitExpr->getArgs())1967      Args.push_back(Arg->getType());1968    return {{Trait.value(), std::move(Args)}};1969  }1970  const auto *Ref = dyn_cast<DeclRefExpr>(E);1971  if (!Ref)1972    return std::nullopt;1973 1974  // std::is_xxx_v<>1975  if (const auto *VD =1976          dyn_cast<VarTemplateSpecializationDecl>(Ref->getDecl())) {1977    if (!VD->isInStdNamespace())1978      return std::nullopt;1979    StringRef Name = VD->getIdentifier()->getName();1980    if (!Name.consume_back("_v"))1981      return std::nullopt;1982    Trait = StdNameToTypeTrait(Name);1983    if (!Trait)1984      return std::nullopt;1985    for (const auto &Arg : VD->getTemplateArgs().asArray()) {1986      if (Arg.getKind() == TemplateArgument::ArgKind::Pack) {1987        for (const auto &InnerArg : Arg.pack_elements())1988          Args.push_back(InnerArg.getAsType());1989      } else if (Arg.getKind() == TemplateArgument::ArgKind::Type) {1990        Args.push_back(Arg.getAsType());1991      } else {1992        llvm_unreachable("Unexpected kind");1993      }1994    }1995    return {{Trait.value(), std::move(Args)}};1996  }1997 1998  // std::is_xxx<>::value1999  if (const auto *VD = dyn_cast<VarDecl>(Ref->getDecl());2000      Ref->hasQualifier() && VD && VD->getIdentifier()->isStr("value")) {2001    NestedNameSpecifier Qualifier = Ref->getQualifier();2002    if (Qualifier.getKind() != NestedNameSpecifier::Kind::Type)2003      return std::nullopt;2004    const auto *Ts = Qualifier.getAsType()->getAs<TemplateSpecializationType>();2005    if (!Ts)2006      return std::nullopt;2007    const TemplateDecl *D = Ts->getTemplateName().getAsTemplateDecl();2008    if (!D || !D->isInStdNamespace())2009      return std::nullopt;2010    Trait = StdNameToTypeTrait(D->getIdentifier()->getName());2011    if (!Trait)2012      return std::nullopt;2013    for (const auto &Arg : Ts->template_arguments())2014      Args.push_back(Arg.getAsType());2015    return {{Trait.value(), std::move(Args)}};2016  }2017  return std::nullopt;2018}2019 2020static void DiagnoseNonDefaultMovable(Sema &SemaRef, SourceLocation Loc,2021                                      const CXXRecordDecl *D) {2022  if (D->isUnion()) {2023    auto DiagSPM = [&](CXXSpecialMemberKind K, bool Has) {2024      if (Has)2025        SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2026            << diag::TraitNotSatisfiedReason::UnionWithUserDeclaredSMF << K;2027    };2028    DiagSPM(CXXSpecialMemberKind::CopyConstructor,2029            D->hasUserDeclaredCopyConstructor());2030    DiagSPM(CXXSpecialMemberKind::CopyAssignment,2031            D->hasUserDeclaredCopyAssignment());2032    DiagSPM(CXXSpecialMemberKind::MoveConstructor,2033            D->hasUserDeclaredMoveConstructor());2034    DiagSPM(CXXSpecialMemberKind::MoveAssignment,2035            D->hasUserDeclaredMoveAssignment());2036    return;2037  }2038 2039  if (!D->hasSimpleMoveConstructor() && !D->hasSimpleCopyConstructor()) {2040    const auto *Decl = cast_or_null<CXXConstructorDecl>(2041        LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/false));2042    if (Decl && Decl->isUserProvided())2043      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2044          << diag::TraitNotSatisfiedReason::UserProvidedCtr2045          << Decl->isMoveConstructor() << Decl->getSourceRange();2046  }2047  if (!D->hasSimpleMoveAssignment() && !D->hasSimpleCopyAssignment()) {2048    CXXMethodDecl *Decl =2049        LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/true);2050    if (Decl && Decl->isUserProvided())2051      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2052          << diag::TraitNotSatisfiedReason::UserProvidedAssign2053          << Decl->isMoveAssignmentOperator() << Decl->getSourceRange();2054  }2055  if (CXXDestructorDecl *Dtr = D->getDestructor()) {2056    Dtr = Dtr->getCanonicalDecl();2057    if (Dtr->isUserProvided() && !Dtr->isDefaulted())2058      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2059          << diag::TraitNotSatisfiedReason::DeletedDtr << /*User Provided*/ 12060          << Dtr->getSourceRange();2061  }2062}2063 2064static void DiagnoseNonTriviallyRelocatableReason(Sema &SemaRef,2065                                                  SourceLocation Loc,2066                                                  const CXXRecordDecl *D) {2067  for (const CXXBaseSpecifier &B : D->bases()) {2068    assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");2069    if (B.isVirtual())2070      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2071          << diag::TraitNotSatisfiedReason::VBase << B.getType()2072          << B.getSourceRange();2073    if (!SemaRef.IsCXXTriviallyRelocatableType(B.getType()))2074      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2075          << diag::TraitNotSatisfiedReason::NTRBase << B.getType()2076          << B.getSourceRange();2077  }2078  for (const FieldDecl *Field : D->fields()) {2079    if (!Field->getType()->isReferenceType() &&2080        !SemaRef.IsCXXTriviallyRelocatableType(Field->getType()))2081      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2082          << diag::TraitNotSatisfiedReason::NTRField << Field2083          << Field->getType() << Field->getSourceRange();2084  }2085  if (D->hasDeletedDestructor())2086    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2087        << diag::TraitNotSatisfiedReason::DeletedDtr << /*Deleted*/ 02088        << D->getDestructor()->getSourceRange();2089 2090  if (D->hasAttr<TriviallyRelocatableAttr>())2091    return;2092  DiagnoseNonDefaultMovable(SemaRef, Loc, D);2093}2094 2095static void DiagnoseNonTriviallyRelocatableReason(Sema &SemaRef,2096                                                  SourceLocation Loc,2097                                                  QualType T) {2098  SemaRef.Diag(Loc, diag::note_unsatisfied_trait)2099      << T << diag::TraitName::TriviallyRelocatable;2100  if (T->isVariablyModifiedType())2101    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2102        << diag::TraitNotSatisfiedReason::VLA;2103 2104  if (T->isReferenceType())2105    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2106        << diag::TraitNotSatisfiedReason::Ref;2107  T = T.getNonReferenceType();2108 2109  if (T.hasNonTrivialObjCLifetime())2110    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2111        << diag::TraitNotSatisfiedReason::HasArcLifetime;2112 2113  const CXXRecordDecl *D = T->getAsCXXRecordDecl();2114  if (!D || D->isInvalidDecl())2115    return;2116 2117  if (D->hasDefinition())2118    DiagnoseNonTriviallyRelocatableReason(SemaRef, Loc, D);2119 2120  SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;2121}2122 2123static void DiagnoseNonReplaceableReason(Sema &SemaRef, SourceLocation Loc,2124                                         const CXXRecordDecl *D) {2125  for (const CXXBaseSpecifier &B : D->bases()) {2126    assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");2127    if (!SemaRef.IsCXXReplaceableType(B.getType()))2128      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2129          << diag::TraitNotSatisfiedReason::NonReplaceableBase << B.getType()2130          << B.getSourceRange();2131  }2132  for (const FieldDecl *Field : D->fields()) {2133    if (!SemaRef.IsCXXReplaceableType(Field->getType()))2134      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2135          << diag::TraitNotSatisfiedReason::NonReplaceableField << Field2136          << Field->getType() << Field->getSourceRange();2137  }2138  if (D->hasDeletedDestructor())2139    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2140        << diag::TraitNotSatisfiedReason::DeletedDtr << /*Deleted*/ 02141        << D->getDestructor()->getSourceRange();2142 2143  if (!D->hasSimpleMoveConstructor() && !D->hasSimpleCopyConstructor()) {2144    const auto *Decl = cast<CXXConstructorDecl>(2145        LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/false));2146    if (Decl && Decl->isDeleted())2147      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2148          << diag::TraitNotSatisfiedReason::DeletedCtr2149          << Decl->isMoveConstructor() << Decl->getSourceRange();2150  }2151  if (!D->hasSimpleMoveAssignment() && !D->hasSimpleCopyAssignment()) {2152    CXXMethodDecl *Decl =2153        LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/true);2154    if (Decl && Decl->isDeleted())2155      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2156          << diag::TraitNotSatisfiedReason::DeletedAssign2157          << Decl->isMoveAssignmentOperator() << Decl->getSourceRange();2158  }2159 2160  if (D->hasAttr<ReplaceableAttr>())2161    return;2162  DiagnoseNonDefaultMovable(SemaRef, Loc, D);2163}2164 2165static void DiagnoseNonReplaceableReason(Sema &SemaRef, SourceLocation Loc,2166                                         QualType T) {2167  SemaRef.Diag(Loc, diag::note_unsatisfied_trait)2168      << T << diag::TraitName::Replaceable;2169 2170  if (T->isVariablyModifiedType())2171    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2172        << diag::TraitNotSatisfiedReason::VLA;2173 2174  if (T->isReferenceType())2175    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2176        << diag::TraitNotSatisfiedReason::Ref;2177  T = T.getNonReferenceType();2178 2179  if (T.isConstQualified())2180    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2181        << diag::TraitNotSatisfiedReason::Const;2182 2183  if (T.isVolatileQualified())2184    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2185        << diag::TraitNotSatisfiedReason::Volatile;2186 2187  bool IsArray = T->isArrayType();2188  T = SemaRef.getASTContext().getBaseElementType(T.getUnqualifiedType());2189 2190  if (T->isScalarType())2191    return;2192 2193  const CXXRecordDecl *D = T->getAsCXXRecordDecl();2194  if (!D) {2195    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2196        << diag::TraitNotSatisfiedReason::NotScalarOrClass << IsArray;2197    return;2198  }2199 2200  if (D->isInvalidDecl())2201    return;2202 2203  if (D->hasDefinition())2204    DiagnoseNonReplaceableReason(SemaRef, Loc, D);2205 2206  SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;2207}2208 2209static void DiagnoseNonTriviallyCopyableReason(Sema &SemaRef,2210                                               SourceLocation Loc,2211                                               const CXXRecordDecl *D) {2212  for (const CXXBaseSpecifier &B : D->bases()) {2213    assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");2214    if (B.isVirtual())2215      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2216          << diag::TraitNotSatisfiedReason::VBase << B.getType()2217          << B.getSourceRange();2218    if (!B.getType().isTriviallyCopyableType(D->getASTContext())) {2219      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2220          << diag::TraitNotSatisfiedReason::NTCBase << B.getType()2221          << B.getSourceRange();2222    }2223  }2224  for (const FieldDecl *Field : D->fields()) {2225    if (!Field->getType().isTriviallyCopyableType(Field->getASTContext()))2226      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2227          << diag::TraitNotSatisfiedReason::NTCField << Field2228          << Field->getType() << Field->getSourceRange();2229  }2230  CXXDestructorDecl *Dtr = D->getDestructor();2231  if (D->hasDeletedDestructor() || (Dtr && !Dtr->isTrivial()))2232    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2233        << diag::TraitNotSatisfiedReason::DeletedDtr2234        << !D->hasDeletedDestructor() << D->getDestructor()->getSourceRange();2235 2236  for (const CXXMethodDecl *Method : D->methods()) {2237    if (Method->isTrivial() || !Method->isUserProvided()) {2238      continue;2239    }2240    auto SpecialMemberKind =2241        SemaRef.getDefaultedFunctionKind(Method).asSpecialMember();2242    switch (SpecialMemberKind) {2243    case CXXSpecialMemberKind::CopyConstructor:2244    case CXXSpecialMemberKind::MoveConstructor:2245    case CXXSpecialMemberKind::CopyAssignment:2246    case CXXSpecialMemberKind::MoveAssignment: {2247      bool IsAssignment =2248          SpecialMemberKind == CXXSpecialMemberKind::CopyAssignment ||2249          SpecialMemberKind == CXXSpecialMemberKind::MoveAssignment;2250      bool IsMove =2251          SpecialMemberKind == CXXSpecialMemberKind::MoveConstructor ||2252          SpecialMemberKind == CXXSpecialMemberKind::MoveAssignment;2253 2254      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2255          << (IsAssignment ? diag::TraitNotSatisfiedReason::UserProvidedAssign2256                           : diag::TraitNotSatisfiedReason::UserProvidedCtr)2257          << IsMove << Method->getSourceRange();2258      break;2259    }2260    default:2261      break;2262    }2263  }2264}2265 2266static void DiagnoseNonConstructibleReason(2267    Sema &SemaRef, SourceLocation Loc,2268    const llvm::SmallVector<clang::QualType, 1> &Ts) {2269  if (Ts.empty()) {2270    return;2271  }2272 2273  bool ContainsVoid = false;2274  for (const QualType &ArgTy : Ts) {2275    ContainsVoid |= ArgTy->isVoidType();2276  }2277 2278  if (ContainsVoid)2279    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2280        << diag::TraitNotSatisfiedReason::CVVoidType;2281 2282  QualType T = Ts[0];2283  if (T->isFunctionType())2284    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2285        << diag::TraitNotSatisfiedReason::FunctionType;2286 2287  if (T->isIncompleteArrayType())2288    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2289        << diag::TraitNotSatisfiedReason::IncompleteArrayType;2290 2291  const CXXRecordDecl *D = T->getAsCXXRecordDecl();2292  if (!D || D->isInvalidDecl() || !D->hasDefinition())2293    return;2294 2295  llvm::BumpPtrAllocator OpaqueExprAllocator;2296  SmallVector<Expr *, 2> ArgExprs;2297  ArgExprs.reserve(Ts.size() - 1);2298  for (unsigned I = 1, N = Ts.size(); I != N; ++I) {2299    QualType ArgTy = Ts[I];2300    if (ArgTy->isObjectType() || ArgTy->isFunctionType())2301      ArgTy = SemaRef.Context.getRValueReferenceType(ArgTy);2302    ArgExprs.push_back(2303        new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())2304            OpaqueValueExpr(Loc, ArgTy.getNonLValueExprType(SemaRef.Context),2305                            Expr::getValueKindForType(ArgTy)));2306  }2307 2308  EnterExpressionEvaluationContext Unevaluated(2309      SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);2310  Sema::ContextRAII TUContext(SemaRef,2311                              SemaRef.Context.getTranslationUnitDecl());2312  InitializedEntity To(InitializedEntity::InitializeTemporary(T));2313  InitializationKind InitKind(InitializationKind::CreateDirect(Loc, Loc, Loc));2314  InitializationSequence Init(SemaRef, To, InitKind, ArgExprs);2315 2316  Init.Diagnose(SemaRef, To, InitKind, ArgExprs);2317  SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;2318}2319 2320static void DiagnoseNonTriviallyCopyableReason(Sema &SemaRef,2321                                               SourceLocation Loc, QualType T) {2322  SemaRef.Diag(Loc, diag::note_unsatisfied_trait)2323      << T << diag::TraitName::TriviallyCopyable;2324 2325  if (T->isReferenceType())2326    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2327        << diag::TraitNotSatisfiedReason::Ref;2328 2329  const CXXRecordDecl *D = T->getAsCXXRecordDecl();2330  if (!D || D->isInvalidDecl())2331    return;2332 2333  if (D->hasDefinition())2334    DiagnoseNonTriviallyCopyableReason(SemaRef, Loc, D);2335 2336  SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;2337}2338 2339static void DiagnoseNonAssignableReason(Sema &SemaRef, SourceLocation Loc,2340                                        QualType T, QualType U) {2341  const CXXRecordDecl *D = T->getAsCXXRecordDecl();2342 2343  auto createDeclValExpr = [&](QualType Ty) -> OpaqueValueExpr {2344    if (Ty->isObjectType() || Ty->isFunctionType())2345      Ty = SemaRef.Context.getRValueReferenceType(Ty);2346    return {Loc, Ty.getNonLValueExprType(SemaRef.Context),2347            Expr::getValueKindForType(Ty)};2348  };2349 2350  auto LHS = createDeclValExpr(T);2351  auto RHS = createDeclValExpr(U);2352 2353  EnterExpressionEvaluationContext Unevaluated(2354      SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);2355  Sema::ContextRAII TUContext(SemaRef,2356                              SemaRef.Context.getTranslationUnitDecl());2357  SemaRef.BuildBinOp(/*S=*/nullptr, Loc, BO_Assign, &LHS, &RHS);2358 2359  if (!D || D->isInvalidDecl())2360    return;2361 2362  SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;2363}2364 2365static void DiagnoseIsEmptyReason(Sema &S, SourceLocation Loc,2366                                  const CXXRecordDecl *D) {2367  // Non-static data members (ignore zero-width bit‐fields).2368  for (const auto *Field : D->fields()) {2369    if (Field->isZeroLengthBitField())2370      continue;2371    if (Field->isBitField()) {2372      S.Diag(Loc, diag::note_unsatisfied_trait_reason)2373          << diag::TraitNotSatisfiedReason::NonZeroLengthField << Field2374          << Field->getSourceRange();2375      continue;2376    }2377    S.Diag(Loc, diag::note_unsatisfied_trait_reason)2378        << diag::TraitNotSatisfiedReason::NonEmptyMember << Field2379        << Field->getType() << Field->getSourceRange();2380  }2381 2382  // Virtual functions.2383  for (const auto *M : D->methods()) {2384    if (M->isVirtual()) {2385      S.Diag(Loc, diag::note_unsatisfied_trait_reason)2386          << diag::TraitNotSatisfiedReason::VirtualFunction << M2387          << M->getSourceRange();2388      break;2389    }2390  }2391 2392  // Virtual bases and non-empty bases.2393  for (const auto &B : D->bases()) {2394    const auto *BR = B.getType()->getAsCXXRecordDecl();2395    if (!BR || BR->isInvalidDecl())2396      continue;2397    if (B.isVirtual()) {2398      S.Diag(Loc, diag::note_unsatisfied_trait_reason)2399          << diag::TraitNotSatisfiedReason::VBase << B.getType()2400          << B.getSourceRange();2401    }2402    if (!BR->isEmpty()) {2403      S.Diag(Loc, diag::note_unsatisfied_trait_reason)2404          << diag::TraitNotSatisfiedReason::NonEmptyBase << B.getType()2405          << B.getSourceRange();2406    }2407  }2408}2409 2410static void DiagnoseIsEmptyReason(Sema &S, SourceLocation Loc, QualType T) {2411  // Emit primary "not empty" diagnostic.2412  S.Diag(Loc, diag::note_unsatisfied_trait) << T << diag::TraitName::Empty;2413 2414  // While diagnosing is_empty<T>, we want to look at the actual type, not a2415  // reference or an array of it. So we need to massage the QualType param to2416  // strip refs and arrays.2417  if (T->isReferenceType())2418    S.Diag(Loc, diag::note_unsatisfied_trait_reason)2419        << diag::TraitNotSatisfiedReason::Ref;2420  T = T.getNonReferenceType();2421 2422  if (auto *AT = S.Context.getAsArrayType(T))2423    T = AT->getElementType();2424 2425  if (auto *D = T->getAsCXXRecordDecl()) {2426    if (D->hasDefinition()) {2427      DiagnoseIsEmptyReason(S, Loc, D);2428      S.Diag(D->getLocation(), diag::note_defined_here) << D;2429    }2430  }2431}2432 2433static void DiagnoseIsFinalReason(Sema &S, SourceLocation Loc,2434                                  const CXXRecordDecl *D) {2435  if (!D || D->isInvalidDecl())2436    return;2437 2438  // Complete record but not 'final'.2439  if (!D->isEffectivelyFinal()) {2440    S.Diag(Loc, diag::note_unsatisfied_trait_reason)2441        << diag::TraitNotSatisfiedReason::NotMarkedFinal;2442    S.Diag(D->getLocation(), diag::note_defined_here) << D;2443    return;2444  }2445}2446 2447static void DiagnoseIsFinalReason(Sema &S, SourceLocation Loc, QualType T) {2448  // Primary: “%0 is not final”2449  S.Diag(Loc, diag::note_unsatisfied_trait) << T << diag::TraitName::Final;2450  if (T->isReferenceType()) {2451    S.Diag(Loc, diag::note_unsatisfied_trait_reason)2452        << diag::TraitNotSatisfiedReason::Ref;2453    S.Diag(Loc, diag::note_unsatisfied_trait_reason)2454        << diag::TraitNotSatisfiedReason::NotClassOrUnion;2455    return;2456  }2457  // Arrays / functions / non-records → not a class/union.2458  if (S.Context.getAsArrayType(T)) {2459    S.Diag(Loc, diag::note_unsatisfied_trait_reason)2460        << diag::TraitNotSatisfiedReason::NotClassOrUnion;2461    return;2462  }2463  if (T->isFunctionType()) {2464    S.Diag(Loc, diag::note_unsatisfied_trait_reason)2465        << diag::TraitNotSatisfiedReason::FunctionType;2466    S.Diag(Loc, diag::note_unsatisfied_trait_reason)2467        << diag::TraitNotSatisfiedReason::NotClassOrUnion;2468    return;2469  }2470  if (!T->isRecordType()) {2471    S.Diag(Loc, diag::note_unsatisfied_trait_reason)2472        << diag::TraitNotSatisfiedReason::NotClassOrUnion;2473    return;2474  }2475  if (const auto *D = T->getAsCXXRecordDecl())2476    DiagnoseIsFinalReason(S, Loc, D);2477}2478 2479static bool hasMultipleDataBaseClassesWithFields(const CXXRecordDecl *D) {2480  int NumBasesWithFields = 0;2481  for (const CXXBaseSpecifier &Base : D->bases()) {2482    const CXXRecordDecl *BaseRD = Base.getType()->getAsCXXRecordDecl();2483    if (!BaseRD || BaseRD->isInvalidDecl())2484      continue;2485 2486    for (const FieldDecl *Field : BaseRD->fields()) {2487      if (!Field->isUnnamedBitField()) {2488        if (++NumBasesWithFields > 1)2489          return true; // found more than one base class with fields2490        break;         // no need to check further fields in this base class2491      }2492    }2493  }2494  return false;2495}2496 2497static void DiagnoseNonStandardLayoutReason(Sema &SemaRef, SourceLocation Loc,2498                                            const CXXRecordDecl *D) {2499  for (const CXXBaseSpecifier &B : D->bases()) {2500    assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");2501    if (B.isVirtual()) {2502      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2503          << diag::TraitNotSatisfiedReason::VBase << B.getType()2504          << B.getSourceRange();2505    }2506    if (!B.getType()->isStandardLayoutType()) {2507      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2508          << diag::TraitNotSatisfiedReason::NonStandardLayoutBase << B.getType()2509          << B.getSourceRange();2510    }2511  }2512  // Check for mixed access specifiers in fields.2513  const FieldDecl *FirstField = nullptr;2514  AccessSpecifier FirstAccess = AS_none;2515 2516  for (const FieldDecl *Field : D->fields()) {2517    if (Field->isUnnamedBitField())2518      continue;2519 2520    // Record the first field we see2521    if (!FirstField) {2522      FirstField = Field;2523      FirstAccess = Field->getAccess();2524      continue;2525    }2526 2527    // Check if the field has a different access specifier than the first one.2528    if (Field->getAccess() != FirstAccess) {2529      // Emit a diagnostic about mixed access specifiers.2530      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2531          << diag::TraitNotSatisfiedReason::MixedAccess;2532 2533      SemaRef.Diag(FirstField->getLocation(), diag::note_defined_here)2534          << FirstField;2535 2536      SemaRef.Diag(Field->getLocation(), diag::note_unsatisfied_trait_reason)2537          << diag::TraitNotSatisfiedReason::MixedAccessField << Field2538          << FirstField;2539 2540      // No need to check further fields, as we already found mixed access.2541      break;2542    }2543  }2544  if (hasMultipleDataBaseClassesWithFields(D)) {2545    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2546        << diag::TraitNotSatisfiedReason::MultipleDataBase;2547  }2548  if (D->isPolymorphic()) {2549    // Find the best location to point “defined here” at.2550    const CXXMethodDecl *VirtualMD = nullptr;2551    // First, look for a virtual method.2552    for (const auto *M : D->methods()) {2553      if (M->isVirtual()) {2554        VirtualMD = M;2555        break;2556      }2557    }2558    if (VirtualMD) {2559      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2560          << diag::TraitNotSatisfiedReason::VirtualFunction << VirtualMD;2561      SemaRef.Diag(VirtualMD->getLocation(), diag::note_defined_here)2562          << VirtualMD;2563    } else {2564      // If no virtual method, point to the record declaration itself.2565      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2566          << diag::TraitNotSatisfiedReason::VirtualFunction << D;2567      SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;2568    }2569  }2570  for (const FieldDecl *Field : D->fields()) {2571    if (!Field->getType()->isStandardLayoutType()) {2572      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2573          << diag::TraitNotSatisfiedReason::NonStandardLayoutMember << Field2574          << Field->getType() << Field->getSourceRange();2575    }2576  }2577  // Find any indirect base classes that have fields.2578  if (D->hasDirectFields()) {2579    const CXXRecordDecl *Indirect = nullptr;2580    D->forallBases([&](const CXXRecordDecl *BaseDef) {2581      if (BaseDef->hasDirectFields()) {2582        Indirect = BaseDef;2583        return false; // stop traversal2584      }2585      return true; // continue to the next base2586    });2587    if (Indirect) {2588      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2589          << diag::TraitNotSatisfiedReason::IndirectBaseWithFields << Indirect2590          << Indirect->getSourceRange();2591    }2592  }2593}2594 2595static void DiagnoseNonStandardLayoutReason(Sema &SemaRef, SourceLocation Loc,2596                                            QualType T) {2597  SemaRef.Diag(Loc, diag::note_unsatisfied_trait)2598      << T << diag::TraitName::StandardLayout;2599 2600  // Check type-level exclusion first.2601  if (T->isVariablyModifiedType()) {2602    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2603        << diag::TraitNotSatisfiedReason::VLA;2604    return;2605  }2606 2607  if (T->isReferenceType()) {2608    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2609        << diag::TraitNotSatisfiedReason::Ref;2610    return;2611  }2612  T = T.getNonReferenceType();2613  const CXXRecordDecl *D = T->getAsCXXRecordDecl();2614  if (!D || D->isInvalidDecl())2615    return;2616 2617  if (D->hasDefinition())2618    DiagnoseNonStandardLayoutReason(SemaRef, Loc, D);2619 2620  SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;2621}2622 2623static void DiagnoseNonAggregateReason(Sema &SemaRef, SourceLocation Loc,2624                                       const CXXRecordDecl *D) {2625  for (const CXXConstructorDecl *Ctor : D->ctors()) {2626    if (Ctor->isUserProvided())2627      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2628          << diag::TraitNotSatisfiedReason::UserDeclaredCtr;2629    if (Ctor->isInheritingConstructor())2630      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2631          << diag::TraitNotSatisfiedReason::InheritedCtr;2632  }2633 2634  if (llvm::any_of(D->decls(), [](auto const *Sub) {2635        return isa<ConstructorUsingShadowDecl>(Sub);2636      })) {2637    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2638        << diag::TraitNotSatisfiedReason::InheritedCtr;2639  }2640 2641  if (D->isPolymorphic())2642    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2643        << diag::TraitNotSatisfiedReason::PolymorphicType2644        << D->getSourceRange();2645 2646  for (const CXXBaseSpecifier &B : D->bases()) {2647    if (B.isVirtual()) {2648      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2649          << diag::TraitNotSatisfiedReason::VBase << B.getType()2650          << B.getSourceRange();2651      continue;2652    }2653    auto AccessSpecifier = B.getAccessSpecifier();2654    switch (AccessSpecifier) {2655    case AS_private:2656    case AS_protected:2657      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2658          << diag::TraitNotSatisfiedReason::PrivateProtectedDirectBase2659          << (AccessSpecifier == AS_protected);2660      break;2661    default:2662      break;2663    }2664  }2665 2666  for (const CXXMethodDecl *Method : D->methods()) {2667    if (Method->isVirtual()) {2668      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2669          << diag::TraitNotSatisfiedReason::VirtualFunction << Method2670          << Method->getSourceRange();2671    }2672  }2673 2674  for (const FieldDecl *Field : D->fields()) {2675    auto AccessSpecifier = Field->getAccess();2676    switch (AccessSpecifier) {2677    case AS_private:2678    case AS_protected:2679      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2680          << diag::TraitNotSatisfiedReason::PrivateProtectedDirectDataMember2681          << (AccessSpecifier == AS_protected);2682      break;2683    default:2684      break;2685    }2686  }2687 2688  SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;2689}2690 2691static void DiagnoseNonAggregateReason(Sema &SemaRef, SourceLocation Loc,2692                                       QualType T) {2693  SemaRef.Diag(Loc, diag::note_unsatisfied_trait)2694      << T << diag::TraitName::Aggregate;2695 2696  if (T->isVoidType())2697    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2698        << diag::TraitNotSatisfiedReason::CVVoidType;2699 2700  T = T.getNonReferenceType();2701  const CXXRecordDecl *D = T->getAsCXXRecordDecl();2702  if (!D || D->isInvalidDecl())2703    return;2704 2705  if (D->hasDefinition())2706    DiagnoseNonAggregateReason(SemaRef, Loc, D);2707}2708 2709static void DiagnoseNonAbstractReason(Sema &SemaRef, SourceLocation Loc,2710                                      const CXXRecordDecl *D) {2711  // If this type has any abstract base classes, their respective virtual2712  // functions must have been overridden.2713  for (const CXXBaseSpecifier &B : D->bases()) {2714    if (B.getType()->castAsCXXRecordDecl()->isAbstract()) {2715      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2716          << diag::TraitNotSatisfiedReason::OverridesAllPureVirtual2717          << B.getType() << B.getSourceRange();2718    }2719  }2720}2721 2722static void DiagnoseNonAbstractReason(Sema &SemaRef, SourceLocation Loc,2723                                      QualType T) {2724  SemaRef.Diag(Loc, diag::note_unsatisfied_trait)2725      << T << diag::TraitName::Abstract;2726 2727  if (T->isReferenceType()) {2728    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2729        << diag::TraitNotSatisfiedReason::Ref;2730    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2731        << diag::TraitNotSatisfiedReason::NotStructOrClass;2732    return;2733  }2734 2735  if (T->isUnionType()) {2736    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2737        << diag::TraitNotSatisfiedReason::UnionType;2738    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2739        << diag::TraitNotSatisfiedReason::NotStructOrClass;2740    return;2741  }2742 2743  if (SemaRef.Context.getAsArrayType(T)) {2744    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2745        << diag::TraitNotSatisfiedReason::ArrayType;2746    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2747        << diag::TraitNotSatisfiedReason::NotStructOrClass;2748    return;2749  }2750 2751  if (T->isFunctionType()) {2752    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2753        << diag::TraitNotSatisfiedReason::FunctionType;2754    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2755        << diag::TraitNotSatisfiedReason::NotStructOrClass;2756    return;2757  }2758 2759  if (T->isPointerType()) {2760    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2761        << diag::TraitNotSatisfiedReason::PointerType;2762    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2763        << diag::TraitNotSatisfiedReason::NotStructOrClass;2764    return;2765  }2766 2767  if (!T->isStructureOrClassType()) {2768    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)2769        << diag::TraitNotSatisfiedReason::NotStructOrClass;2770    return;2771  }2772 2773  const CXXRecordDecl *D = T->getAsCXXRecordDecl();2774  if (D->hasDefinition())2775    DiagnoseNonAbstractReason(SemaRef, Loc, D);2776}2777 2778void Sema::DiagnoseTypeTraitDetails(const Expr *E) {2779  E = E->IgnoreParenImpCasts();2780  if (E->containsErrors())2781    return;2782 2783  ExtractedTypeTraitInfo TraitInfo = ExtractTypeTraitFromExpression(E);2784  if (!TraitInfo)2785    return;2786 2787  const auto &[Trait, Args] = TraitInfo.value();2788  switch (Trait) {2789  case UTT_IsCppTriviallyRelocatable:2790    DiagnoseNonTriviallyRelocatableReason(*this, E->getBeginLoc(), Args[0]);2791    break;2792  case UTT_IsReplaceable:2793    DiagnoseNonReplaceableReason(*this, E->getBeginLoc(), Args[0]);2794    break;2795  case UTT_IsTriviallyCopyable:2796    DiagnoseNonTriviallyCopyableReason(*this, E->getBeginLoc(), Args[0]);2797    break;2798  case BTT_IsAssignable:2799    DiagnoseNonAssignableReason(*this, E->getBeginLoc(), Args[0], Args[1]);2800    break;2801  case UTT_IsEmpty:2802    DiagnoseIsEmptyReason(*this, E->getBeginLoc(), Args[0]);2803    break;2804  case UTT_IsStandardLayout:2805    DiagnoseNonStandardLayoutReason(*this, E->getBeginLoc(), Args[0]);2806    break;2807  case TT_IsConstructible:2808    DiagnoseNonConstructibleReason(*this, E->getBeginLoc(), Args);2809    break;2810  case UTT_IsAggregate:2811    DiagnoseNonAggregateReason(*this, E->getBeginLoc(), Args[0]);2812    break;2813  case UTT_IsFinal: {2814    QualType QT = Args[0];2815    if (QT->isDependentType())2816      break;2817    const auto *RD = QT->getAsCXXRecordDecl();2818    if (!RD || !RD->isEffectivelyFinal())2819      DiagnoseIsFinalReason(*this, E->getBeginLoc(), QT); // unsatisfied2820    break;2821  }2822  case UTT_IsAbstract:2823    DiagnoseNonAbstractReason(*this, E->getBeginLoc(), Args[0]);2824    break;2825  default:2826    break;2827  }2828}2829