clang 22.0.0git
SemaTypeTraits.cpp
Go to the documentation of this file.
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements semantic analysis for C++ type traits.
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/AST/DeclCXX.h"
15#include "clang/AST/Type.h"
22#include "clang/Sema/Lookup.h"
23#include "clang/Sema/Overload.h"
24#include "clang/Sema/Sema.h"
25#include "clang/Sema/SemaHLSL.h"
26
27using namespace clang;
28
30 const CXXRecordDecl *RD,
31 bool Assign) {
32 RD = RD->getDefinition();
33 SourceLocation LookupLoc = RD->getLocation();
34
35 CanQualType CanTy = SemaRef.getASTContext().getCanonicalTagType(RD);
36 DeclarationName Name;
37 Expr *Arg = nullptr;
38 unsigned NumArgs;
39
40 QualType ArgType = CanTy;
42
43 if (Assign)
44 Name =
46 else
47 Name =
49
50 OpaqueValueExpr FakeArg(LookupLoc, ArgType, VK);
51 NumArgs = 1;
52 Arg = &FakeArg;
53
54 // Create the object argument
55 QualType ThisTy = CanTy;
56 Expr::Classification Classification =
57 OpaqueValueExpr(LookupLoc, ThisTy, VK_LValue)
58 .Classify(SemaRef.getASTContext());
59
60 // Now we perform lookup on the name we computed earlier and do overload
61 // resolution. Lookup is only performed directly into the class since there
62 // will always be a (possibly implicit) declaration to shadow any others.
65
66 if (R.empty())
67 return nullptr;
68
69 // Copy the candidates as our processing of them may load new declarations
70 // from an external source and invalidate lookup_result.
71 SmallVector<NamedDecl *, 8> Candidates(R.begin(), R.end());
72
73 for (NamedDecl *CandDecl : Candidates) {
74 if (CandDecl->isInvalidDecl())
75 continue;
76
78 auto CtorInfo = getConstructorInfo(Cand);
79 if (CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(Cand->getUnderlyingDecl())) {
80 if (Assign)
81 SemaRef.AddMethodCandidate(M, Cand, const_cast<CXXRecordDecl *>(RD),
82 ThisTy, Classification,
83 llvm::ArrayRef(&Arg, NumArgs), OCS, true);
84 else {
85 assert(CtorInfo);
86 SemaRef.AddOverloadCandidate(CtorInfo.Constructor, CtorInfo.FoundDecl,
87 llvm::ArrayRef(&Arg, NumArgs), OCS,
88 /*SuppressUserConversions*/ true);
89 }
90 } else if (FunctionTemplateDecl *Tmpl =
91 dyn_cast<FunctionTemplateDecl>(Cand->getUnderlyingDecl())) {
92 if (Assign)
94 Tmpl, Cand, const_cast<CXXRecordDecl *>(RD), nullptr, ThisTy,
95 Classification, llvm::ArrayRef(&Arg, NumArgs), OCS, true);
96 else {
97 assert(CtorInfo);
99 CtorInfo.ConstructorTmpl, CtorInfo.FoundDecl, nullptr,
100 llvm::ArrayRef(&Arg, NumArgs), OCS, true);
101 }
102 }
103 }
104
106 switch (OCS.BestViableFunction(SemaRef, LookupLoc, Best)) {
107 case OR_Success:
108 case OR_Deleted:
109 return cast<CXXMethodDecl>(Best->Function)->getCanonicalDecl();
110 default:
111 return nullptr;
112 }
113}
114
116 const CXXRecordDecl *D,
117 bool AllowUserDefined) {
118 assert(D->hasDefinition() && !D->isInvalidDecl());
119
120 if (D->hasSimpleMoveConstructor() || D->hasSimpleCopyConstructor())
121 return true;
122
124 LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/false);
125 return Decl && (AllowUserDefined || !Decl->isUserProvided()) &&
126 !Decl->isDeleted();
127}
128
130 Sema &SemaRef, const CXXRecordDecl *D, bool AllowUserDefined) {
131 assert(D->hasDefinition() && !D->isInvalidDecl());
132
133 if (D->hasSimpleMoveAssignment() || D->hasSimpleCopyAssignment())
134 return true;
135
137 LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/true);
138 if (!Decl)
139 return false;
140
141 return Decl && (AllowUserDefined || !Decl->isUserProvided()) &&
142 !Decl->isDeleted();
143}
144
145// [C++26][class.prop]
146// A class C is default-movable if
147// - overload resolution for direct-initializing an object of type C
148// from an xvalue of type C selects a constructor that is a direct member of C
149// and is neither user-provided nor deleted,
150// - overload resolution for assigning to an lvalue of type C from an xvalue of
151// type C selects an assignment operator function that is a direct member of C
152// and is neither user-provided nor deleted, and C has a destructor that is
153// neither user-provided nor deleted.
154static bool IsDefaultMovable(Sema &SemaRef, const CXXRecordDecl *D) {
156 /*AllowUserDefined=*/false))
157 return false;
158
160 SemaRef, D, /*AllowUserDefined=*/false))
161 return false;
162
163 CXXDestructorDecl *Dtr = D->getDestructor();
164
165 if (!Dtr)
166 return true;
167
168 Dtr = Dtr->getCanonicalDecl();
169
170 if (Dtr->isUserProvided() && (!Dtr->isDefaulted() || Dtr->isDeleted()))
171 return false;
172
173 return !Dtr->isDeleted();
174}
175
176// [C++26][class.prop]
177// A class is eligible for trivial relocation unless it...
179 const CXXRecordDecl *D) {
180
181 for (const CXXBaseSpecifier &B : D->bases()) {
182 const auto *BaseDecl = B.getType()->getAsCXXRecordDecl();
183 if (!BaseDecl)
184 continue;
185 // ... has any virtual base classes
186 // ... has a base class that is not a trivially relocatable class
187 if (B.isVirtual() || (!BaseDecl->isDependentType() &&
188 !SemaRef.IsCXXTriviallyRelocatableType(B.getType())))
189 return false;
190 }
191
192 bool IsUnion = D->isUnion();
193 for (const FieldDecl *Field : D->fields()) {
194 if (Field->getType()->isDependentType())
195 continue;
196 if (Field->getType()->isReferenceType())
197 continue;
198 // ... has a non-static data member of an object type that is not
199 // of a trivially relocatable type
200 if (!SemaRef.IsCXXTriviallyRelocatableType(Field->getType()))
201 return false;
202
203 // A union contains values with address discriminated pointer auth
204 // cannot be relocated.
206 Field->getType()))
207 return false;
208 }
209 return !D->hasDeletedDestructor();
210}
211
212// [C++26][class.prop]
213// A class C is eligible for replacement unless
214static bool IsEligibleForReplacement(Sema &SemaRef, const CXXRecordDecl *D) {
215
216 for (const CXXBaseSpecifier &B : D->bases()) {
217 const auto *BaseDecl = B.getType()->getAsCXXRecordDecl();
218 if (!BaseDecl)
219 continue;
220 // it has a base class that is not a replaceable class
221 if (!BaseDecl->isDependentType() &&
222 !SemaRef.IsCXXReplaceableType(B.getType()))
223 return false;
224 }
225
226 for (const FieldDecl *Field : D->fields()) {
227 if (Field->getType()->isDependentType())
228 continue;
229
230 // it has a non-static data member that is not of a replaceable type,
231 if (!SemaRef.IsCXXReplaceableType(Field->getType()))
232 return false;
233 }
234 return !D->hasDeletedDestructor();
235}
236
240
242 return Info;
243
244 assert(D->hasDefinition());
245
246 // This is part of "eligible for replacement", however we defer it
247 // to avoid extraneous computations.
248 auto HasSuitableSMP = [&] {
250 /*AllowUserDefined=*/true) &&
252 *this, D, /*AllowUserDefined=*/true);
253 };
254
255 auto IsUnion = [&, Is = std::optional<bool>{}]() mutable {
256 if (!Is.has_value())
257 Is = D->isUnion() && !D->hasUserDeclaredCopyConstructor() &&
258 !D->hasUserDeclaredCopyAssignment() &&
259 !D->hasUserDeclaredMoveOperation() &&
260 !D->hasUserDeclaredDestructor();
261 return *Is;
262 };
263
264 auto IsDefaultMovable = [&, Is = std::optional<bool>{}]() mutable {
265 if (!Is.has_value())
266 Is = ::IsDefaultMovable(*this, D);
267 return *Is;
268 };
269
270 Info.IsRelocatable = [&] {
271 if (D->isDependentType())
272 return false;
273
274 // if it is eligible for trivial relocation
276 return false;
277
278 // has the trivially_relocatable_if_eligible class-property-specifier,
279 if (D->hasAttr<TriviallyRelocatableAttr>())
280 return true;
281
282 // is a union with no user-declared special member functions, or
283 if (IsUnion())
284 return true;
285
286 // is default-movable.
287 return IsDefaultMovable();
288 }();
289
290 Info.IsReplaceable = [&] {
291 if (D->isDependentType())
292 return false;
293
294 // A class C is a replaceable class if it is eligible for replacement
295 if (!IsEligibleForReplacement(*this, D))
296 return false;
297
298 // has the replaceable_if_eligible class-property-specifier
299 if (D->hasAttr<ReplaceableAttr>())
300 return HasSuitableSMP();
301
302 // is a union with no user-declared special member functions, or
303 if (IsUnion())
304 return HasSuitableSMP();
305
306 // is default-movable.
307 return IsDefaultMovable();
308 }();
309
310 return Info;
311}
312
314 if (std::optional<ASTContext::CXXRecordDeclRelocationInfo> Info =
315 getASTContext().getRelocationInfoForCXXRecord(&RD))
316 return Info->IsRelocatable;
320 return Info.IsRelocatable;
321}
322
324 QualType BaseElementType = getASTContext().getBaseElementType(Type);
325
327 return false;
328
329 if (BaseElementType.hasNonTrivialObjCLifetime())
330 return false;
331
332 if (BaseElementType->isIncompleteType())
333 return false;
334
336 return false;
337
338 if (BaseElementType->isScalarType() || BaseElementType->isVectorType())
339 return true;
340
341 if (const auto *RD = BaseElementType->getAsCXXRecordDecl())
343
344 return false;
345}
346
347static bool IsCXXReplaceableType(Sema &S, const CXXRecordDecl *RD) {
348 if (std::optional<ASTContext::CXXRecordDeclRelocationInfo> Info =
350 return Info->IsReplaceable;
354 return Info.IsReplaceable;
355}
356
358 if (Type.isConstQualified() || Type.isVolatileQualified())
359 return false;
360
362 return false;
363
364 QualType BaseElementType =
365 getASTContext().getBaseElementType(Type.getUnqualifiedType());
366 if (BaseElementType->isIncompleteType())
367 return false;
368 if (BaseElementType->isScalarType())
369 return true;
370 if (const auto *RD = BaseElementType->getAsCXXRecordDecl())
371 return ::IsCXXReplaceableType(*this, RD);
372 return false;
373}
374
375/// Checks that type T is not a VLA.
376///
377/// @returns @c true if @p T is VLA and a diagnostic was emitted,
378/// @c false otherwise.
380 clang::tok::TokenKind TypeTraitID) {
381 if (!T->getType()->isVariableArrayType())
382 return false;
383
384 S.Diag(T->getTypeLoc().getBeginLoc(), diag::err_vla_unsupported)
385 << 1 << TypeTraitID;
386 return true;
387}
388
389/// Checks that type T is not an atomic type (_Atomic).
390///
391/// @returns @c true if @p T is VLA and a diagnostic was emitted,
392/// @c false otherwise.
394 clang::tok::TokenKind TypeTraitID) {
395 if (!T->getType()->isAtomicType())
396 return false;
397
398 S.Diag(T->getTypeLoc().getBeginLoc(), diag::err_atomic_unsupported)
399 << TypeTraitID;
400 return true;
401}
402
403/// Check the completeness of a type in a unary type trait.
404///
405/// If the particular type trait requires a complete type, tries to complete
406/// it. If completing the type fails, a diagnostic is emitted and false
407/// returned. If completing the type succeeds or no completion was required,
408/// returns true.
411 QualType ArgTy) {
412 // C++0x [meta.unary.prop]p3:
413 // For all of the class templates X declared in this Clause, instantiating
414 // that template with a template argument that is a class template
415 // specialization may result in the implicit instantiation of the template
416 // argument if and only if the semantics of X require that the argument
417 // must be a complete type.
418 // We apply this rule to all the type trait expressions used to implement
419 // these class templates. We also try to follow any GCC documented behavior
420 // in these expressions to ensure portability of standard libraries.
421 switch (UTT) {
422 default:
423 llvm_unreachable("not a UTT");
424 // is_complete_type somewhat obviously cannot require a complete type.
425 case UTT_IsCompleteType:
426 // Fall-through
427
428 // These traits are modeled on the type predicates in C++0x
429 // [meta.unary.cat] and [meta.unary.comp]. They are not specified as
430 // requiring a complete type, as whether or not they return true cannot be
431 // impacted by the completeness of the type.
432 case UTT_IsVoid:
433 case UTT_IsIntegral:
434 case UTT_IsFloatingPoint:
435 case UTT_IsArray:
436 case UTT_IsBoundedArray:
437 case UTT_IsPointer:
438 case UTT_IsLvalueReference:
439 case UTT_IsRvalueReference:
440 case UTT_IsMemberFunctionPointer:
441 case UTT_IsMemberObjectPointer:
442 case UTT_IsEnum:
443 case UTT_IsScopedEnum:
444 case UTT_IsUnion:
445 case UTT_IsClass:
446 case UTT_IsFunction:
447 case UTT_IsReference:
448 case UTT_IsArithmetic:
449 case UTT_IsFundamental:
450 case UTT_IsObject:
451 case UTT_IsScalar:
452 case UTT_IsCompound:
453 case UTT_IsMemberPointer:
454 case UTT_IsTypedResourceElementCompatible:
455 // Fall-through
456
457 // These traits are modeled on type predicates in C++0x [meta.unary.prop]
458 // which requires some of its traits to have the complete type. However,
459 // the completeness of the type cannot impact these traits' semantics, and
460 // so they don't require it. This matches the comments on these traits in
461 // Table 49.
462 case UTT_IsConst:
463 case UTT_IsVolatile:
464 case UTT_IsSigned:
465 case UTT_IsUnboundedArray:
466 case UTT_IsUnsigned:
467
468 // This type trait always returns false, checking the type is moot.
469 case UTT_IsInterfaceClass:
470 return true;
471
472 // We diagnose incomplete class types later.
473 case UTT_StructuredBindingSize:
474 return true;
475
476 // C++14 [meta.unary.prop]:
477 // If T is a non-union class type, T shall be a complete type.
478 case UTT_IsEmpty:
479 case UTT_IsPolymorphic:
480 case UTT_IsAbstract:
481 if (const auto *RD = ArgTy->getAsCXXRecordDecl())
482 if (!RD->isUnion())
483 return !S.RequireCompleteType(
484 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
485 return true;
486
487 // C++14 [meta.unary.prop]:
488 // If T is a class type, T shall be a complete type.
489 case UTT_IsFinal:
490 case UTT_IsSealed:
491 if (ArgTy->getAsCXXRecordDecl())
492 return !S.RequireCompleteType(
493 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
494 return true;
495
496 // LWG3823: T shall be an array type, a complete type, or cv void.
497 case UTT_IsAggregate:
498 case UTT_IsImplicitLifetime:
499 if (ArgTy->isArrayType() || ArgTy->isVoidType())
500 return true;
501
502 return !S.RequireCompleteType(
503 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
504
505 // has_unique_object_representations<T>
506 // remove_all_extents_t<T> shall be a complete type or cv void (LWG4113).
507 case UTT_HasUniqueObjectRepresentations:
508 ArgTy = QualType(ArgTy->getBaseElementTypeUnsafe(), 0);
509 if (ArgTy->isVoidType())
510 return true;
511 return !S.RequireCompleteType(
512 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
513
514 // C++1z [meta.unary.prop]:
515 // remove_all_extents_t<T> shall be a complete type or cv void.
516 case UTT_IsTrivial:
517 case UTT_IsTriviallyCopyable:
518 case UTT_IsStandardLayout:
519 case UTT_IsPOD:
520 case UTT_IsLiteral:
521 case UTT_IsBitwiseCloneable:
522 // By analogy, is_trivially_relocatable and is_trivially_equality_comparable
523 // impose the same constraints.
524 case UTT_IsTriviallyRelocatable:
525 case UTT_IsTriviallyEqualityComparable:
526 case UTT_IsCppTriviallyRelocatable:
527 case UTT_IsReplaceable:
528 case UTT_CanPassInRegs:
529 // Per the GCC type traits documentation, T shall be a complete type, cv void,
530 // or an array of unknown bound. But GCC actually imposes the same constraints
531 // as above.
532 case UTT_HasNothrowAssign:
533 case UTT_HasNothrowMoveAssign:
534 case UTT_HasNothrowConstructor:
535 case UTT_HasNothrowCopy:
536 case UTT_HasTrivialAssign:
537 case UTT_HasTrivialMoveAssign:
538 case UTT_HasTrivialDefaultConstructor:
539 case UTT_HasTrivialMoveConstructor:
540 case UTT_HasTrivialCopy:
541 case UTT_HasTrivialDestructor:
542 case UTT_HasVirtualDestructor:
543 ArgTy = QualType(ArgTy->getBaseElementTypeUnsafe(), 0);
544 [[fallthrough]];
545 // C++1z [meta.unary.prop]:
546 // T shall be a complete type, cv void, or an array of unknown bound.
547 case UTT_IsDestructible:
548 case UTT_IsNothrowDestructible:
549 case UTT_IsTriviallyDestructible:
550 case UTT_IsIntangibleType:
551 if (ArgTy->isIncompleteArrayType() || ArgTy->isVoidType())
552 return true;
553
554 return !S.RequireCompleteType(
555 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
556 }
557}
558
561 bool (CXXRecordDecl::*HasTrivial)() const,
562 bool (CXXRecordDecl::*HasNonTrivial)() const,
563 bool (CXXMethodDecl::*IsDesiredOp)() const) {
564 if ((RD->*HasTrivial)() && !(RD->*HasNonTrivial)())
565 return true;
566
567 DeclarationName Name = C.DeclarationNames.getCXXOperatorName(Op);
568 DeclarationNameInfo NameInfo(Name, KeyLoc);
570 if (Self.LookupQualifiedName(Res, RD)) {
571 bool FoundOperator = false;
573 for (LookupResult::iterator Op = Res.begin(), OpEnd = Res.end();
574 Op != OpEnd; ++Op) {
575 if (isa<FunctionTemplateDecl>(*Op))
576 continue;
577
578 CXXMethodDecl *Operator = cast<CXXMethodDecl>(*Op);
579 if ((Operator->*IsDesiredOp)()) {
580 FoundOperator = true;
581 auto *CPT = Operator->getType()->castAs<FunctionProtoType>();
582 CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
583 if (!CPT || !CPT->isNothrow())
584 return false;
585 }
586 }
587 return FoundOperator;
588 }
589 return false;
590}
591
593 const CXXRecordDecl *Decl,
594 SourceLocation KeyLoc) {
595 if (Decl->isUnion())
596 return false;
597 if (Decl->isLambda())
598 return Decl->isCapturelessLambda();
599
601 {
602 EnterExpressionEvaluationContext UnevaluatedContext(
604 Sema::SFINAETrap SFINAE(S, /*ForValidityCheck=*/true);
606
607 // const ClassT& obj;
608 OpaqueValueExpr Operand(KeyLoc, T.withConst(), ExprValueKind::VK_LValue);
609 UnresolvedSet<16> Functions;
610 // obj == obj;
611 S.LookupBinOp(S.TUScope, {}, BinaryOperatorKind::BO_EQ, Functions);
612
613 auto Result = S.CreateOverloadedBinOp(KeyLoc, BinaryOperatorKind::BO_EQ,
614 Functions, &Operand, &Operand);
615 if (Result.isInvalid() || SFINAE.hasErrorOccurred())
616 return false;
617
618 const auto *CallExpr = dyn_cast<CXXOperatorCallExpr>(Result.get());
619 if (!CallExpr)
620 return false;
621 const auto *Callee = CallExpr->getDirectCallee();
622 auto ParamT = Callee->getParamDecl(0)->getType();
623 if (!Callee->isDefaulted())
624 return false;
625 if (!ParamT->isReferenceType() && !Decl->isTriviallyCopyable())
626 return false;
627 if (!S.Context.hasSameUnqualifiedType(ParamT.getNonReferenceType(), T))
628 return false;
629 }
630
631 return llvm::all_of(Decl->bases(),
632 [&](const CXXBaseSpecifier &BS) {
633 if (const auto *RD = BS.getType()->getAsCXXRecordDecl())
634 return HasNonDeletedDefaultedEqualityComparison(
635 S, RD, KeyLoc);
636 return true;
637 }) &&
638 llvm::all_of(Decl->fields(), [&](const FieldDecl *FD) {
639 auto Type = FD->getType();
640 if (Type->isArrayType())
641 Type = Type->getBaseElementTypeUnsafe()
642 ->getCanonicalTypeUnqualified();
643
644 if (Type->isReferenceType() || Type->isEnumeralType())
645 return false;
646 if (const auto *RD = Type->getAsCXXRecordDecl())
647 return HasNonDeletedDefaultedEqualityComparison(S, RD, KeyLoc);
648 return true;
649 });
650}
651
653 SourceLocation KeyLoc) {
654 QualType CanonicalType = Type.getCanonicalType();
655 if (CanonicalType->isIncompleteType() || CanonicalType->isDependentType() ||
656 CanonicalType->isEnumeralType() || CanonicalType->isArrayType())
657 return false;
658
659 if (const auto *RD = CanonicalType->getAsCXXRecordDecl()) {
661 return false;
662 }
663
665 CanonicalType, /*CheckIfTriviallyCopyable=*/false);
666}
667
669 QualType BaseElementType = SemaRef.getASTContext().getBaseElementType(T);
670
671 if (BaseElementType->isIncompleteType())
672 return false;
673 if (!BaseElementType->isObjectType())
674 return false;
675
676 // The deprecated __builtin_is_trivially_relocatable does not have
677 // an equivalent to __builtin_trivially_relocate, so there is no
678 // safe way to use it if there are any address discriminated values.
680 return false;
681
682 if (const auto *RD = BaseElementType->getAsCXXRecordDecl();
683 RD && !RD->isPolymorphic() && SemaRef.IsCXXTriviallyRelocatableType(*RD))
684 return true;
685
686 if (const auto *RD = BaseElementType->getAsRecordDecl())
687 return RD->canPassInRegisters();
688
689 if (BaseElementType.isTriviallyCopyableType(SemaRef.getASTContext()))
690 return true;
691
692 switch (T.isNonTrivialToPrimitiveDestructiveMove()) {
694 return !T.isDestructedType();
696 return true;
697 default:
698 return false;
699 }
700}
701
703 SourceLocation KeyLoc,
704 TypeSourceInfo *TInfo) {
705 QualType T = TInfo->getType();
706 assert(!T->isDependentType() && "Cannot evaluate traits of dependent type");
707
708 ASTContext &C = Self.Context;
709 switch (UTT) {
710 default:
711 llvm_unreachable("not a UTT");
712 // Type trait expressions corresponding to the primary type category
713 // predicates in C++0x [meta.unary.cat].
714 case UTT_IsVoid:
715 return T->isVoidType();
716 case UTT_IsIntegral:
717 return T->isIntegralType(C);
718 case UTT_IsFloatingPoint:
719 return T->isFloatingType();
720 case UTT_IsArray:
721 // Zero-sized arrays aren't considered arrays in partial specializations,
722 // so __is_array shouldn't consider them arrays either.
723 if (const auto *CAT = C.getAsConstantArrayType(T))
724 return CAT->getSize() != 0;
725 return T->isArrayType();
726 case UTT_IsBoundedArray:
727 if (DiagnoseVLAInCXXTypeTrait(Self, TInfo, tok::kw___is_bounded_array))
728 return false;
729 // Zero-sized arrays aren't considered arrays in partial specializations,
730 // so __is_bounded_array shouldn't consider them arrays either.
731 if (const auto *CAT = C.getAsConstantArrayType(T))
732 return CAT->getSize() != 0;
733 return T->isArrayType() && !T->isIncompleteArrayType();
734 case UTT_IsUnboundedArray:
735 if (DiagnoseVLAInCXXTypeTrait(Self, TInfo, tok::kw___is_unbounded_array))
736 return false;
737 return T->isIncompleteArrayType();
738 case UTT_IsPointer:
739 return T->isAnyPointerType();
740 case UTT_IsLvalueReference:
741 return T->isLValueReferenceType();
742 case UTT_IsRvalueReference:
743 return T->isRValueReferenceType();
744 case UTT_IsMemberFunctionPointer:
746 case UTT_IsMemberObjectPointer:
747 return T->isMemberDataPointerType();
748 case UTT_IsEnum:
749 return T->isEnumeralType();
750 case UTT_IsScopedEnum:
751 return T->isScopedEnumeralType();
752 case UTT_IsUnion:
753 return T->isUnionType();
754 case UTT_IsClass:
755 return T->isClassType() || T->isStructureType() || T->isInterfaceType();
756 case UTT_IsFunction:
757 return T->isFunctionType();
758
759 // Type trait expressions which correspond to the convenient composition
760 // predicates in C++0x [meta.unary.comp].
761 case UTT_IsReference:
762 return T->isReferenceType();
763 case UTT_IsArithmetic:
764 return T->isArithmeticType() && !T->isEnumeralType();
765 case UTT_IsFundamental:
766 return T->isFundamentalType();
767 case UTT_IsObject:
768 return T->isObjectType();
769 case UTT_IsScalar:
770 // Note: semantic analysis depends on Objective-C lifetime types to be
771 // considered scalar types. However, such types do not actually behave
772 // like scalar types at run time (since they may require retain/release
773 // operations), so we report them as non-scalar.
774 if (T->isObjCLifetimeType()) {
775 switch (T.getObjCLifetime()) {
778 return true;
779
783 return false;
784 }
785 }
786
787 return T->isScalarType();
788 case UTT_IsCompound:
789 return T->isCompoundType();
790 case UTT_IsMemberPointer:
791 return T->isMemberPointerType();
792
793 // Type trait expressions which correspond to the type property predicates
794 // in C++0x [meta.unary.prop].
795 case UTT_IsConst:
796 return T.isConstQualified();
797 case UTT_IsVolatile:
798 return T.isVolatileQualified();
799 case UTT_IsTrivial:
800 return T.isTrivialType(C);
801 case UTT_IsTriviallyCopyable:
802 return T.isTriviallyCopyableType(C);
803 case UTT_IsStandardLayout:
804 return T->isStandardLayoutType();
805 case UTT_IsPOD:
806 return T.isPODType(C);
807 case UTT_IsLiteral:
808 return T->isLiteralType(C);
809 case UTT_IsEmpty:
810 if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
811 return !RD->isUnion() && RD->isEmpty();
812 return false;
813 case UTT_IsPolymorphic:
814 if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
815 return !RD->isUnion() && RD->isPolymorphic();
816 return false;
817 case UTT_IsAbstract:
818 if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
819 return !RD->isUnion() && RD->isAbstract();
820 return false;
821 case UTT_IsAggregate:
822 // Report vector extensions and complex types as aggregates because they
823 // support aggregate initialization. GCC mirrors this behavior for vectors
824 // but not _Complex.
825 return T->isAggregateType() || T->isVectorType() || T->isExtVectorType() ||
827 // __is_interface_class only returns true when CL is invoked in /CLR mode and
828 // even then only when it is used with the 'interface struct ...' syntax
829 // Clang doesn't support /CLR which makes this type trait moot.
830 case UTT_IsInterfaceClass:
831 return false;
832 case UTT_IsFinal:
833 case UTT_IsSealed:
834 if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
835 return RD->hasAttr<FinalAttr>();
836 return false;
837 case UTT_IsSigned:
838 // Enum types should always return false.
839 // Floating points should always return true.
840 return T->isFloatingType() ||
842 case UTT_IsUnsigned:
843 // Enum types should always return false.
844 return T->isUnsignedIntegerType() && !T->isEnumeralType();
845
846 // Type trait expressions which query classes regarding their construction,
847 // destruction, and copying. Rather than being based directly on the
848 // related type predicates in the standard, they are specified by both
849 // GCC[1] and the Embarcadero C++ compiler[2], and Clang implements those
850 // specifications.
851 //
852 // 1: http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
853 // 2:
854 // http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index
855 //
856 // Note that these builtins do not behave as documented in g++: if a class
857 // has both a trivial and a non-trivial special member of a particular kind,
858 // they return false! For now, we emulate this behavior.
859 // FIXME: This appears to be a g++ bug: more complex cases reveal that it
860 // does not correctly compute triviality in the presence of multiple special
861 // members of the same kind. Revisit this once the g++ bug is fixed.
862 case UTT_HasTrivialDefaultConstructor:
863 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
864 // If __is_pod (type) is true then the trait is true, else if type is
865 // a cv class or union type (or array thereof) with a trivial default
866 // constructor ([class.ctor]) then the trait is true, else it is false.
867 if (T.isPODType(C))
868 return true;
869 if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
870 return RD->hasTrivialDefaultConstructor() &&
872 return false;
873 case UTT_HasTrivialMoveConstructor:
874 // This trait is implemented by MSVC 2012 and needed to parse the
875 // standard library headers. Specifically this is used as the logic
876 // behind std::is_trivially_move_constructible (20.9.4.3).
877 if (T.isPODType(C))
878 return true;
879 if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
880 return RD->hasTrivialMoveConstructor() &&
882 return false;
883 case UTT_HasTrivialCopy:
884 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
885 // If __is_pod (type) is true or type is a reference type then
886 // the trait is true, else if type is a cv class or union type
887 // with a trivial copy constructor ([class.copy]) then the trait
888 // is true, else it is false.
889 if (T.isPODType(C) || T->isReferenceType())
890 return true;
892 return RD->hasTrivialCopyConstructor() &&
894 return false;
895 case UTT_HasTrivialMoveAssign:
896 // This trait is implemented by MSVC 2012 and needed to parse the
897 // standard library headers. Specifically it is used as the logic
898 // behind std::is_trivially_move_assignable (20.9.4.3)
899 if (T.isPODType(C))
900 return true;
901 if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
902 return RD->hasTrivialMoveAssignment() &&
904 return false;
905 case UTT_HasTrivialAssign:
906 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
907 // If type is const qualified or is a reference type then the
908 // trait is false. Otherwise if __is_pod (type) is true then the
909 // trait is true, else if type is a cv class or union type with
910 // a trivial copy assignment ([class.copy]) then the trait is
911 // true, else it is false.
912 // Note: the const and reference restrictions are interesting,
913 // given that const and reference members don't prevent a class
914 // from having a trivial copy assignment operator (but do cause
915 // errors if the copy assignment operator is actually used, q.v.
916 // [class.copy]p12).
917
918 if (T.isConstQualified())
919 return false;
920 if (T.isPODType(C))
921 return true;
923 return RD->hasTrivialCopyAssignment() &&
925 return false;
926 case UTT_IsDestructible:
927 case UTT_IsTriviallyDestructible:
928 case UTT_IsNothrowDestructible:
929 // C++14 [meta.unary.prop]:
930 // For reference types, is_destructible<T>::value is true.
931 if (T->isReferenceType())
932 return true;
933
934 // Objective-C++ ARC: autorelease types don't require destruction.
935 if (T->isObjCLifetimeType() &&
936 T.getObjCLifetime() == Qualifiers::OCL_Autoreleasing)
937 return true;
938
939 // C++14 [meta.unary.prop]:
940 // For incomplete types and function types, is_destructible<T>::value is
941 // false.
942 if (T->isIncompleteType() || T->isFunctionType())
943 return false;
944
945 // A type that requires destruction (via a non-trivial destructor or ARC
946 // lifetime semantics) is not trivially-destructible.
947 if (UTT == UTT_IsTriviallyDestructible && T.isDestructedType())
948 return false;
949
950 // C++14 [meta.unary.prop]:
951 // For object types and given U equal to remove_all_extents_t<T>, if the
952 // expression std::declval<U&>().~U() is well-formed when treated as an
953 // unevaluated operand (Clause 5), then is_destructible<T>::value is true
954 if (auto *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) {
955 CXXDestructorDecl *Destructor = Self.LookupDestructor(RD);
956 if (!Destructor)
957 return false;
958 // C++14 [dcl.fct.def.delete]p2:
959 // A program that refers to a deleted function implicitly or
960 // explicitly, other than to declare it, is ill-formed.
961 if (Destructor->isDeleted())
962 return false;
963 if (C.getLangOpts().AccessControl && Destructor->getAccess() != AS_public)
964 return false;
965 if (UTT == UTT_IsNothrowDestructible) {
966 auto *CPT = Destructor->getType()->castAs<FunctionProtoType>();
967 CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
968 if (!CPT || !CPT->isNothrow())
969 return false;
970 }
971 }
972 return true;
973
974 case UTT_HasTrivialDestructor:
975 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
976 // If __is_pod (type) is true or type is a reference type
977 // then the trait is true, else if type is a cv class or union
978 // type (or array thereof) with a trivial destructor
979 // ([class.dtor]) then the trait is true, else it is
980 // false.
981 if (T.isPODType(C) || T->isReferenceType())
982 return true;
983
984 // Objective-C++ ARC: autorelease types don't require destruction.
985 if (T->isObjCLifetimeType() &&
986 T.getObjCLifetime() == Qualifiers::OCL_Autoreleasing)
987 return true;
988
989 if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
990 return RD->hasTrivialDestructor();
991 return false;
992 // TODO: Propagate nothrowness for implicitly declared special members.
993 case UTT_HasNothrowAssign:
994 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
995 // If type is const qualified or is a reference type then the
996 // trait is false. Otherwise if __has_trivial_assign (type)
997 // is true then the trait is true, else if type is a cv class
998 // or union type with copy assignment operators that are known
999 // not to throw an exception then the trait is true, else it is
1000 // false.
1001 if (C.getBaseElementType(T).isConstQualified())
1002 return false;
1003 if (T->isReferenceType())
1004 return false;
1005 if (T.isPODType(C) || T->isObjCLifetimeType())
1006 return true;
1007
1008 if (auto *RD = T->getAsCXXRecordDecl())
1009 return HasNoThrowOperator(RD, OO_Equal, Self, KeyLoc, C,
1013 return false;
1014 case UTT_HasNothrowMoveAssign:
1015 // This trait is implemented by MSVC 2012 and needed to parse the
1016 // standard library headers. Specifically this is used as the logic
1017 // behind std::is_nothrow_move_assignable (20.9.4.3).
1018 if (T.isPODType(C))
1019 return true;
1020
1021 if (auto *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
1022 return HasNoThrowOperator(RD, OO_Equal, Self, KeyLoc, C,
1026 return false;
1027 case UTT_HasNothrowCopy:
1028 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
1029 // If __has_trivial_copy (type) is true then the trait is true, else
1030 // if type is a cv class or union type with copy constructors that are
1031 // known not to throw an exception then the trait is true, else it is
1032 // false.
1033 if (T.isPODType(C) || T->isReferenceType() || T->isObjCLifetimeType())
1034 return true;
1035 if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) {
1036 if (RD->hasTrivialCopyConstructor() &&
1038 return true;
1039
1040 bool FoundConstructor = false;
1041 unsigned FoundTQs;
1042 for (const auto *ND : Self.LookupConstructors(RD)) {
1043 // A template constructor is never a copy constructor.
1044 // FIXME: However, it may actually be selected at the actual overload
1045 // resolution point.
1046 if (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl()))
1047 continue;
1048 // UsingDecl itself is not a constructor
1049 if (isa<UsingDecl>(ND))
1050 continue;
1051 auto *Constructor = cast<CXXConstructorDecl>(ND->getUnderlyingDecl());
1052 if (Constructor->isCopyConstructor(FoundTQs)) {
1053 FoundConstructor = true;
1054 auto *CPT = Constructor->getType()->castAs<FunctionProtoType>();
1055 CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
1056 if (!CPT)
1057 return false;
1058 // TODO: check whether evaluating default arguments can throw.
1059 // For now, we'll be conservative and assume that they can throw.
1060 if (!CPT->isNothrow() || CPT->getNumParams() > 1)
1061 return false;
1062 }
1063 }
1064
1065 return FoundConstructor;
1066 }
1067 return false;
1068 case UTT_HasNothrowConstructor:
1069 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
1070 // If __has_trivial_constructor (type) is true then the trait is
1071 // true, else if type is a cv class or union type (or array
1072 // thereof) with a default constructor that is known not to
1073 // throw an exception then the trait is true, else it is false.
1074 if (T.isPODType(C) || T->isObjCLifetimeType())
1075 return true;
1076 if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) {
1077 if (RD->hasTrivialDefaultConstructor() &&
1079 return true;
1080
1081 bool FoundConstructor = false;
1082 for (const auto *ND : Self.LookupConstructors(RD)) {
1083 // FIXME: In C++0x, a constructor template can be a default constructor.
1084 if (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl()))
1085 continue;
1086 // UsingDecl itself is not a constructor
1087 if (isa<UsingDecl>(ND))
1088 continue;
1089 auto *Constructor = cast<CXXConstructorDecl>(ND->getUnderlyingDecl());
1090 if (Constructor->isDefaultConstructor()) {
1091 FoundConstructor = true;
1092 auto *CPT = Constructor->getType()->castAs<FunctionProtoType>();
1093 CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
1094 if (!CPT)
1095 return false;
1096 // FIXME: check whether evaluating default arguments can throw.
1097 // For now, we'll be conservative and assume that they can throw.
1098 if (!CPT->isNothrow() || CPT->getNumParams() > 0)
1099 return false;
1100 }
1101 }
1102 return FoundConstructor;
1103 }
1104 return false;
1105 case UTT_HasVirtualDestructor:
1106 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
1107 // If type is a class type with a virtual destructor ([class.dtor])
1108 // then the trait is true, else it is false.
1109 if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
1110 if (CXXDestructorDecl *Destructor = Self.LookupDestructor(RD))
1111 return Destructor->isVirtual();
1112 return false;
1113
1114 // These type trait expressions are modeled on the specifications for the
1115 // Embarcadero C++0x type trait functions:
1116 // http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index
1117 case UTT_IsCompleteType:
1118 // http://docwiki.embarcadero.com/RADStudio/XE/en/Is_complete_type_(typename_T_):
1119 // Returns True if and only if T is a complete type at the point of the
1120 // function call.
1121 return !T->isIncompleteType();
1122 case UTT_HasUniqueObjectRepresentations:
1123 return C.hasUniqueObjectRepresentations(T);
1124 case UTT_IsTriviallyRelocatable:
1126 case UTT_IsBitwiseCloneable:
1127 return T.isBitwiseCloneableType(C);
1128 case UTT_IsCppTriviallyRelocatable:
1129 return Self.IsCXXTriviallyRelocatableType(T);
1130 case UTT_IsReplaceable:
1131 return Self.IsCXXReplaceableType(T);
1132 case UTT_CanPassInRegs:
1133 if (CXXRecordDecl *RD = T->getAsCXXRecordDecl(); RD && !T.hasQualifiers())
1134 return RD->canPassInRegisters();
1135 Self.Diag(KeyLoc, diag::err_builtin_pass_in_regs_non_class) << T;
1136 return false;
1137 case UTT_IsTriviallyEqualityComparable:
1138 return isTriviallyEqualityComparableType(Self, T, KeyLoc);
1139 case UTT_IsImplicitLifetime: {
1141 tok::kw___builtin_is_implicit_lifetime);
1143 tok::kw___builtin_is_implicit_lifetime);
1144
1145 // [basic.types.general] p9
1146 // Scalar types, implicit-lifetime class types ([class.prop]),
1147 // array types, and cv-qualified versions of these types
1148 // are collectively called implicit-lifetime types.
1150 if (UnqualT->isScalarType())
1151 return true;
1152 if (UnqualT->isArrayType() || UnqualT->isVectorType())
1153 return true;
1154 const CXXRecordDecl *RD = UnqualT->getAsCXXRecordDecl();
1155 if (!RD)
1156 return false;
1157
1158 // [class.prop] p9
1159 // A class S is an implicit-lifetime class if
1160 // - it is an aggregate whose destructor is not user-provided or
1161 // - it has at least one trivial eligible constructor and a trivial,
1162 // non-deleted destructor.
1163 const CXXDestructorDecl *Dtor = RD->getDestructor();
1164 if (UnqualT->isAggregateType())
1165 if (Dtor && !Dtor->isUserProvided())
1166 return true;
1167 if (RD->hasTrivialDestructor() && (!Dtor || !Dtor->isDeleted()))
1168 if (RD->hasTrivialDefaultConstructor() ||
1170 return true;
1171 return false;
1172 }
1173 case UTT_IsIntangibleType:
1174 assert(Self.getLangOpts().HLSL && "intangible types are HLSL-only feature");
1175 if (!T->isVoidType() && !T->isIncompleteArrayType())
1176 if (Self.RequireCompleteType(TInfo->getTypeLoc().getBeginLoc(), T,
1177 diag::err_incomplete_type))
1178 return false;
1180 tok::kw___builtin_hlsl_is_intangible))
1181 return false;
1182 return T->isHLSLIntangibleType();
1183
1184 case UTT_IsTypedResourceElementCompatible:
1185 assert(Self.getLangOpts().HLSL &&
1186 "typed resource element compatible types are an HLSL-only feature");
1187 if (T->isIncompleteType())
1188 return false;
1189
1190 return Self.HLSL().IsTypedResourceElementCompatible(T);
1191 }
1192}
1193
1194static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT,
1195 const TypeSourceInfo *Lhs,
1196 const TypeSourceInfo *Rhs,
1197 SourceLocation KeyLoc);
1198
1200 Sema &Self, const TypeSourceInfo *Lhs, const TypeSourceInfo *Rhs,
1201 SourceLocation KeyLoc, llvm::BumpPtrAllocator &OpaqueExprAllocator) {
1202
1203 QualType LhsT = Lhs->getType();
1204 QualType RhsT = Rhs->getType();
1205
1206 // C++0x [meta.rel]p4:
1207 // Given the following function prototype:
1208 //
1209 // template <class T>
1210 // typename add_rvalue_reference<T>::type create();
1211 //
1212 // the predicate condition for a template specialization
1213 // is_convertible<From, To> shall be satisfied if and only if
1214 // the return expression in the following code would be
1215 // well-formed, including any implicit conversions to the return
1216 // type of the function:
1217 //
1218 // To test() {
1219 // return create<From>();
1220 // }
1221 //
1222 // Access checking is performed as if in a context unrelated to To and
1223 // From. Only the validity of the immediate context of the expression
1224 // of the return-statement (including conversions to the return type)
1225 // is considered.
1226 //
1227 // We model the initialization as a copy-initialization of a temporary
1228 // of the appropriate type, which for this expression is identical to the
1229 // return statement (since NRVO doesn't apply).
1230
1231 // Functions aren't allowed to return function or array types.
1232 if (RhsT->isFunctionType() || RhsT->isArrayType())
1233 return ExprError();
1234
1235 // A function definition requires a complete, non-abstract return type.
1236 if (!Self.isCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT) ||
1237 Self.isAbstractType(Rhs->getTypeLoc().getBeginLoc(), RhsT))
1238 return ExprError();
1239
1240 // Compute the result of add_rvalue_reference.
1241 if (LhsT->isObjectType() || LhsT->isFunctionType())
1242 LhsT = Self.Context.getRValueReferenceType(LhsT);
1243
1244 // Build a fake source and destination for initialization.
1246 Expr *From = new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
1247 OpaqueValueExpr(KeyLoc, LhsT.getNonLValueExprType(Self.Context),
1249 InitializationKind Kind =
1251
1252 // Perform the initialization in an unevaluated context within a SFINAE
1253 // trap at translation unit scope.
1256 Sema::SFINAETrap SFINAE(Self, /*ForValidityCheck=*/true);
1257 Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
1258 InitializationSequence Init(Self, To, Kind, From);
1259 if (Init.Failed())
1260 return ExprError();
1261
1262 ExprResult Result = Init.Perform(Self, To, Kind, From);
1263 if (Result.isInvalid() || SFINAE.hasErrorOccurred())
1264 return ExprError();
1265
1266 return Result;
1267}
1268
1270 SourceLocation KWLoc,
1272 SourceLocation RParenLoc,
1273 bool IsDependent) {
1274 if (IsDependent)
1275 return APValue();
1276
1277 switch (Kind) {
1278 case TypeTrait::UTT_StructuredBindingSize: {
1279 QualType T = Args[0]->getType();
1280 SourceRange ArgRange = Args[0]->getTypeLoc().getSourceRange();
1281 UnsignedOrNone Size =
1283 if (!Size) {
1284 S.Diag(KWLoc, diag::err_arg_is_not_destructurable) << T << ArgRange;
1285 return APValue();
1286 }
1287 return APValue(
1289 break;
1290 }
1291 default:
1292 llvm_unreachable("Not a SizeT type trait");
1293 }
1294}
1295
1297 SourceLocation KWLoc,
1299 SourceLocation RParenLoc,
1300 bool IsDependent) {
1301 if (IsDependent)
1302 return false;
1303
1304 if (Kind <= UTT_Last)
1305 return EvaluateUnaryTypeTrait(S, Kind, KWLoc, Args[0]);
1306
1307 // Evaluate ReferenceBindsToTemporary and ReferenceConstructsFromTemporary
1308 // alongside the IsConstructible traits to avoid duplication.
1309 if (Kind <= BTT_Last && Kind != BTT_ReferenceBindsToTemporary &&
1310 Kind != BTT_ReferenceConstructsFromTemporary &&
1311 Kind != BTT_ReferenceConvertsFromTemporary)
1312 return EvaluateBinaryTypeTrait(S, Kind, Args[0], Args[1], RParenLoc);
1313
1314 switch (Kind) {
1315 case clang::BTT_ReferenceBindsToTemporary:
1316 case clang::BTT_ReferenceConstructsFromTemporary:
1317 case clang::BTT_ReferenceConvertsFromTemporary:
1318 case clang::TT_IsConstructible:
1319 case clang::TT_IsNothrowConstructible:
1320 case clang::TT_IsTriviallyConstructible: {
1321 // C++11 [meta.unary.prop]:
1322 // is_trivially_constructible is defined as:
1323 //
1324 // is_constructible<T, Args...>::value is true and the variable
1325 // definition for is_constructible, as defined below, is known to call
1326 // no operation that is not trivial.
1327 //
1328 // The predicate condition for a template specialization
1329 // is_constructible<T, Args...> shall be satisfied if and only if the
1330 // following variable definition would be well-formed for some invented
1331 // variable t:
1332 //
1333 // T t(create<Args>()...);
1334 assert(!Args.empty());
1335
1336 // Precondition: T and all types in the parameter pack Args shall be
1337 // complete types, (possibly cv-qualified) void, or arrays of
1338 // unknown bound.
1339 for (const auto *TSI : Args) {
1340 QualType ArgTy = TSI->getType();
1341 if (ArgTy->isVoidType() || ArgTy->isIncompleteArrayType())
1342 continue;
1343
1344 if (S.RequireCompleteType(
1345 KWLoc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr))
1346 return false;
1347 }
1348
1349 // Make sure the first argument is not incomplete nor a function type.
1350 QualType T = Args[0]->getType();
1351 if (T->isIncompleteType() || T->isFunctionType())
1352 return false;
1353
1354 // Make sure the first argument is not an abstract type.
1356 if (RD && RD->isAbstract())
1357 return false;
1358
1359 // LWG3819: For reference_meows_from_temporary traits, && is not added to
1360 // the source object type.
1361 // Otherwise, compute the result of add_rvalue_reference_t.
1362 bool UseRawObjectType =
1363 Kind == clang::BTT_ReferenceBindsToTemporary ||
1364 Kind == clang::BTT_ReferenceConstructsFromTemporary ||
1365 Kind == clang::BTT_ReferenceConvertsFromTemporary;
1366
1367 llvm::BumpPtrAllocator OpaqueExprAllocator;
1368 SmallVector<Expr *, 2> ArgExprs;
1369 ArgExprs.reserve(Args.size() - 1);
1370 for (unsigned I = 1, N = Args.size(); I != N; ++I) {
1371 QualType ArgTy = Args[I]->getType();
1372 if ((ArgTy->isObjectType() && !UseRawObjectType) ||
1373 ArgTy->isFunctionType())
1374 ArgTy = S.Context.getRValueReferenceType(ArgTy);
1375 ArgExprs.push_back(
1376 new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
1377 OpaqueValueExpr(Args[I]->getTypeLoc().getBeginLoc(),
1380 }
1381
1382 // Perform the initialization in an unevaluated context within a SFINAE
1383 // trap at translation unit scope.
1386 Sema::SFINAETrap SFINAE(S, /*ForValidityCheck=*/true);
1390 InitializationKind InitKind(
1391 Kind == clang::BTT_ReferenceConvertsFromTemporary
1392 ? InitializationKind::CreateCopy(KWLoc, KWLoc)
1393 : InitializationKind::CreateDirect(KWLoc, KWLoc, RParenLoc));
1394 InitializationSequence Init(S, To, InitKind, ArgExprs);
1395 if (Init.Failed())
1396 return false;
1397
1398 ExprResult Result = Init.Perform(S, To, InitKind, ArgExprs);
1399 if (Result.isInvalid() || SFINAE.hasErrorOccurred())
1400 return false;
1401
1402 if (Kind == clang::TT_IsConstructible)
1403 return true;
1404
1405 if (Kind == clang::BTT_ReferenceBindsToTemporary ||
1406 Kind == clang::BTT_ReferenceConstructsFromTemporary ||
1407 Kind == clang::BTT_ReferenceConvertsFromTemporary) {
1408 if (!T->isReferenceType())
1409 return false;
1410
1411 // A function reference never binds to a temporary object.
1412 if (T.getNonReferenceType()->isFunctionType())
1413 return false;
1414
1415 if (!Init.isDirectReferenceBinding())
1416 return true;
1417
1418 if (Kind == clang::BTT_ReferenceBindsToTemporary)
1419 return false;
1420
1421 QualType U = Args[1]->getType();
1422 if (U->isReferenceType())
1423 return false;
1424
1426 S.Context.getPointerType(T.getNonReferenceType()));
1428 S.Context.getPointerType(U.getNonReferenceType()));
1429 return !CheckConvertibilityForTypeTraits(S, UPtr, TPtr, RParenLoc,
1430 OpaqueExprAllocator)
1431 .isInvalid();
1432 }
1433
1434 if (Kind == clang::TT_IsNothrowConstructible)
1435 return S.canThrow(Result.get()) == CT_Cannot;
1436
1437 if (Kind == clang::TT_IsTriviallyConstructible) {
1438 // Under Objective-C ARC and Weak, if the destination has non-trivial
1439 // Objective-C lifetime, this is a non-trivial construction.
1440 if (T.getNonReferenceType().hasNonTrivialObjCLifetime())
1441 return false;
1442
1443 // The initialization succeeded; now make sure there are no non-trivial
1444 // calls.
1445 return !Result.get()->hasNonTrivialCall(S.Context);
1446 }
1447
1448 llvm_unreachable("unhandled type trait");
1449 return false;
1450 }
1451 default:
1452 llvm_unreachable("not a TT");
1453 }
1454
1455 return false;
1456}
1457
1458namespace {
1459void DiagnoseBuiltinDeprecation(Sema &S, TypeTrait Kind, SourceLocation KWLoc) {
1460 TypeTrait Replacement;
1461 switch (Kind) {
1462 case UTT_HasNothrowAssign:
1463 case UTT_HasNothrowMoveAssign:
1464 Replacement = BTT_IsNothrowAssignable;
1465 break;
1466 case UTT_HasNothrowCopy:
1467 case UTT_HasNothrowConstructor:
1468 Replacement = TT_IsNothrowConstructible;
1469 break;
1470 case UTT_HasTrivialAssign:
1471 case UTT_HasTrivialMoveAssign:
1472 Replacement = BTT_IsTriviallyAssignable;
1473 break;
1474 case UTT_HasTrivialCopy:
1475 Replacement = UTT_IsTriviallyCopyable;
1476 break;
1477 case UTT_HasTrivialDefaultConstructor:
1478 case UTT_HasTrivialMoveConstructor:
1479 Replacement = TT_IsTriviallyConstructible;
1480 break;
1481 case UTT_HasTrivialDestructor:
1482 Replacement = UTT_IsTriviallyDestructible;
1483 break;
1484 case UTT_IsTriviallyRelocatable:
1485 Replacement = clang::UTT_IsCppTriviallyRelocatable;
1486 break;
1487 case BTT_ReferenceBindsToTemporary:
1488 Replacement = clang::BTT_ReferenceConstructsFromTemporary;
1489 break;
1490 default:
1491 return;
1492 }
1493 S.Diag(KWLoc, diag::warn_deprecated_builtin)
1494 << getTraitSpelling(Kind) << getTraitSpelling(Replacement);
1495}
1496} // namespace
1497
1498bool Sema::CheckTypeTraitArity(unsigned Arity, SourceLocation Loc, size_t N) {
1499 if (Arity && N != Arity) {
1500 Diag(Loc, diag::err_type_trait_arity)
1501 << Arity << 0 << (Arity > 1) << (int)N << SourceRange(Loc);
1502 return false;
1503 }
1504
1505 if (!Arity && N == 0) {
1506 Diag(Loc, diag::err_type_trait_arity)
1507 << 1 << 1 << 1 << (int)N << SourceRange(Loc);
1508 return false;
1509 }
1510 return true;
1511}
1512
1514 Bool,
1515 SizeT,
1516};
1517
1519 if (Kind == TypeTrait::UTT_StructuredBindingSize)
1520 return TypeTraitReturnType::SizeT;
1521 return TypeTraitReturnType::Bool;
1522}
1523
1526 SourceLocation RParenLoc) {
1527 if (!CheckTypeTraitArity(getTypeTraitArity(Kind), KWLoc, Args.size()))
1528 return ExprError();
1529
1531 *this, Kind, KWLoc, Args[0]->getType()))
1532 return ExprError();
1533
1534 DiagnoseBuiltinDeprecation(*this, Kind, KWLoc);
1535
1536 bool Dependent = false;
1537 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
1538 if (Args[I]->getType()->isDependentType()) {
1539 Dependent = true;
1540 break;
1541 }
1542 }
1543
1544 switch (GetReturnType(Kind)) {
1545 case TypeTraitReturnType::Bool: {
1546 bool Result = EvaluateBooleanTypeTrait(*this, Kind, KWLoc, Args, RParenLoc,
1547 Dependent);
1549 KWLoc, Kind, Args, RParenLoc, Result);
1550 }
1551 case TypeTraitReturnType::SizeT: {
1552 APValue Result =
1553 EvaluateSizeTTypeTrait(*this, Kind, KWLoc, Args, RParenLoc, Dependent);
1554 return TypeTraitExpr::Create(Context, Context.getSizeType(), KWLoc, Kind,
1555 Args, RParenLoc, Result);
1556 }
1557 }
1558 llvm_unreachable("unhandled type trait return type");
1559}
1560
1563 SourceLocation RParenLoc) {
1565 ConvertedArgs.reserve(Args.size());
1566
1567 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
1568 TypeSourceInfo *TInfo;
1569 QualType T = GetTypeFromParser(Args[I], &TInfo);
1570 if (!TInfo)
1571 TInfo = Context.getTrivialTypeSourceInfo(T, KWLoc);
1572
1573 ConvertedArgs.push_back(TInfo);
1574 }
1575
1576 return BuildTypeTrait(Kind, KWLoc, ConvertedArgs, RParenLoc);
1577}
1578
1580 QualType RhsT) {
1581 // C++0x [meta.rel]p2
1582 // Base is a base class of Derived without regard to cv-qualifiers or
1583 // Base and Derived are not unions and name the same class type without
1584 // regard to cv-qualifiers.
1585
1586 const RecordType *lhsRecord = LhsT->getAsCanonical<RecordType>();
1587 const RecordType *rhsRecord = RhsT->getAsCanonical<RecordType>();
1588 if (!rhsRecord || !lhsRecord) {
1589 const ObjCObjectType *LHSObjTy = LhsT->getAs<ObjCObjectType>();
1590 const ObjCObjectType *RHSObjTy = RhsT->getAs<ObjCObjectType>();
1591 if (!LHSObjTy || !RHSObjTy)
1592 return false;
1593
1594 ObjCInterfaceDecl *BaseInterface = LHSObjTy->getInterface();
1595 ObjCInterfaceDecl *DerivedInterface = RHSObjTy->getInterface();
1596 if (!BaseInterface || !DerivedInterface)
1597 return false;
1598
1599 if (RequireCompleteType(RhsTLoc, RhsT,
1600 diag::err_incomplete_type_used_in_type_trait_expr))
1601 return false;
1602
1603 return BaseInterface->isSuperClassOf(DerivedInterface);
1604 }
1605
1606 assert(Context.hasSameUnqualifiedType(LhsT, RhsT) ==
1607 (lhsRecord == rhsRecord));
1608
1609 // Unions are never base classes, and never have base classes.
1610 // It doesn't matter if they are complete or not. See PR#41843
1611 if (lhsRecord && lhsRecord->getOriginalDecl()->isUnion())
1612 return false;
1613 if (rhsRecord && rhsRecord->getOriginalDecl()->isUnion())
1614 return false;
1615
1616 if (lhsRecord == rhsRecord)
1617 return true;
1618
1619 // C++0x [meta.rel]p2:
1620 // If Base and Derived are class types and are different types
1621 // (ignoring possible cv-qualifiers) then Derived shall be a
1622 // complete type.
1623 if (RequireCompleteType(RhsTLoc, RhsT,
1624 diag::err_incomplete_type_used_in_type_trait_expr))
1625 return false;
1626
1627 return cast<CXXRecordDecl>(rhsRecord->getOriginalDecl())
1628 ->isDerivedFrom(cast<CXXRecordDecl>(lhsRecord->getOriginalDecl()));
1629}
1630
1632 const TypeSourceInfo *Lhs,
1633 const TypeSourceInfo *Rhs,
1634 SourceLocation KeyLoc) {
1635 QualType LhsT = Lhs->getType();
1636 QualType RhsT = Rhs->getType();
1637
1638 assert(!LhsT->isDependentType() && !RhsT->isDependentType() &&
1639 "Cannot evaluate traits of dependent types");
1640
1641 switch (BTT) {
1642 case BTT_IsBaseOf:
1643 return Self.BuiltinIsBaseOf(Rhs->getTypeLoc().getBeginLoc(), LhsT, RhsT);
1644
1645 case BTT_IsVirtualBaseOf: {
1646 const RecordType *BaseRecord = LhsT->getAsCanonical<RecordType>();
1647 const RecordType *DerivedRecord = RhsT->getAsCanonical<RecordType>();
1648
1649 if (!BaseRecord || !DerivedRecord) {
1651 tok::kw___builtin_is_virtual_base_of);
1653 tok::kw___builtin_is_virtual_base_of);
1654 return false;
1655 }
1656
1657 if (BaseRecord->isUnionType() || DerivedRecord->isUnionType())
1658 return false;
1659
1660 if (!BaseRecord->isStructureOrClassType() ||
1661 !DerivedRecord->isStructureOrClassType())
1662 return false;
1663
1664 if (Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1665 diag::err_incomplete_type))
1666 return false;
1667
1668 return cast<CXXRecordDecl>(DerivedRecord->getOriginalDecl())
1669 ->isVirtuallyDerivedFrom(
1670 cast<CXXRecordDecl>(BaseRecord->getOriginalDecl()));
1671 }
1672 case BTT_IsSame:
1673 return Self.Context.hasSameType(LhsT, RhsT);
1674 case BTT_TypeCompatible: {
1675 // GCC ignores cv-qualifiers on arrays for this builtin.
1676 Qualifiers LhsQuals, RhsQuals;
1677 QualType Lhs = Self.getASTContext().getUnqualifiedArrayType(LhsT, LhsQuals);
1678 QualType Rhs = Self.getASTContext().getUnqualifiedArrayType(RhsT, RhsQuals);
1679 return Self.Context.typesAreCompatible(Lhs, Rhs);
1680 }
1681 case BTT_IsConvertible:
1682 case BTT_IsConvertibleTo:
1683 case BTT_IsNothrowConvertible: {
1684 if (RhsT->isVoidType())
1685 return LhsT->isVoidType();
1686 llvm::BumpPtrAllocator OpaqueExprAllocator;
1688 OpaqueExprAllocator);
1689 if (Result.isInvalid())
1690 return false;
1691
1692 if (BTT != BTT_IsNothrowConvertible)
1693 return true;
1694
1695 return Self.canThrow(Result.get()) == CT_Cannot;
1696 }
1697
1698 case BTT_IsAssignable:
1699 case BTT_IsNothrowAssignable:
1700 case BTT_IsTriviallyAssignable: {
1701 // C++11 [meta.unary.prop]p3:
1702 // is_trivially_assignable is defined as:
1703 // is_assignable<T, U>::value is true and the assignment, as defined by
1704 // is_assignable, is known to call no operation that is not trivial
1705 //
1706 // is_assignable is defined as:
1707 // The expression declval<T>() = declval<U>() is well-formed when
1708 // treated as an unevaluated operand (Clause 5).
1709 //
1710 // For both, T and U shall be complete types, (possibly cv-qualified)
1711 // void, or arrays of unknown bound.
1712 if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType() &&
1713 Self.RequireCompleteType(
1714 Lhs->getTypeLoc().getBeginLoc(), LhsT,
1715 diag::err_incomplete_type_used_in_type_trait_expr))
1716 return false;
1717 if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType() &&
1718 Self.RequireCompleteType(
1719 Rhs->getTypeLoc().getBeginLoc(), RhsT,
1720 diag::err_incomplete_type_used_in_type_trait_expr))
1721 return false;
1722
1723 // cv void is never assignable.
1724 if (LhsT->isVoidType() || RhsT->isVoidType())
1725 return false;
1726
1727 // Build expressions that emulate the effect of declval<T>() and
1728 // declval<U>().
1729 auto createDeclValExpr = [&](QualType Ty) -> OpaqueValueExpr {
1730 if (Ty->isObjectType() || Ty->isFunctionType())
1731 Ty = Self.Context.getRValueReferenceType(Ty);
1732 return {KeyLoc, Ty.getNonLValueExprType(Self.Context),
1734 };
1735
1736 auto Lhs = createDeclValExpr(LhsT);
1737 auto Rhs = createDeclValExpr(RhsT);
1738
1739 // Attempt the assignment in an unevaluated context within a SFINAE
1740 // trap at translation unit scope.
1743 Sema::SFINAETrap SFINAE(Self, /*ForValidityCheck=*/true);
1744 Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
1746 Self.BuildBinOp(/*S=*/nullptr, KeyLoc, BO_Assign, &Lhs, &Rhs);
1747 if (Result.isInvalid())
1748 return false;
1749
1750 // Treat the assignment as unused for the purpose of -Wdeprecated-volatile.
1751 Self.CheckUnusedVolatileAssignment(Result.get());
1752
1753 if (SFINAE.hasErrorOccurred())
1754 return false;
1755
1756 if (BTT == BTT_IsAssignable)
1757 return true;
1758
1759 if (BTT == BTT_IsNothrowAssignable)
1760 return Self.canThrow(Result.get()) == CT_Cannot;
1761
1762 if (BTT == BTT_IsTriviallyAssignable) {
1763 // Under Objective-C ARC and Weak, if the destination has non-trivial
1764 // Objective-C lifetime, this is a non-trivial assignment.
1766 return false;
1767 const ASTContext &Context = Self.getASTContext();
1768 if (Context.containsAddressDiscriminatedPointerAuth(LhsT) ||
1770 return false;
1771 return !Result.get()->hasNonTrivialCall(Self.Context);
1772 }
1773
1774 llvm_unreachable("unhandled type trait");
1775 return false;
1776 }
1777 case BTT_IsLayoutCompatible: {
1778 if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType())
1779 Self.RequireCompleteType(Lhs->getTypeLoc().getBeginLoc(), LhsT,
1780 diag::err_incomplete_type);
1781 if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType())
1782 Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1783 diag::err_incomplete_type);
1784
1785 DiagnoseVLAInCXXTypeTrait(Self, Lhs, tok::kw___is_layout_compatible);
1786 DiagnoseVLAInCXXTypeTrait(Self, Rhs, tok::kw___is_layout_compatible);
1787
1788 return Self.IsLayoutCompatible(LhsT, RhsT);
1789 }
1790 case BTT_IsPointerInterconvertibleBaseOf: {
1791 if (LhsT->isStructureOrClassType() && RhsT->isStructureOrClassType() &&
1792 !Self.getASTContext().hasSameUnqualifiedType(LhsT, RhsT)) {
1793 Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1794 diag::err_incomplete_type);
1795 }
1796
1798 tok::kw___is_pointer_interconvertible_base_of);
1800 tok::kw___is_pointer_interconvertible_base_of);
1801
1802 return Self.IsPointerInterconvertibleBaseOf(Lhs, Rhs);
1803 }
1804 case BTT_IsDeducible: {
1805 const auto *TSTToBeDeduced = cast<DeducedTemplateSpecializationType>(LhsT);
1806 sema::TemplateDeductionInfo Info(KeyLoc);
1807 return Self.DeduceTemplateArgumentsFromType(
1808 TSTToBeDeduced->getTemplateName().getAsTemplateDecl(), RhsT,
1810 }
1811 case BTT_IsScalarizedLayoutCompatible: {
1812 if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType() &&
1813 Self.RequireCompleteType(Lhs->getTypeLoc().getBeginLoc(), LhsT,
1814 diag::err_incomplete_type))
1815 return true;
1816 if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType() &&
1817 Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1818 diag::err_incomplete_type))
1819 return true;
1820
1822 Self, Lhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1824 Self, Rhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1825
1826 return Self.HLSL().IsScalarizedLayoutCompatible(LhsT, RhsT);
1827 }
1828 case BTT_LtSynthesisesFromSpaceship:
1829 case BTT_LeSynthesisesFromSpaceship:
1830 case BTT_GtSynthesisesFromSpaceship:
1831 case BTT_GeSynthesisesFromSpaceship: {
1832 EnterExpressionEvaluationContext UnevaluatedContext(
1834 Sema::SFINAETrap SFINAE(Self, /*ForValidityCheck=*/true);
1835 Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
1836
1837 OpaqueValueExpr LHS(KeyLoc, LhsT.getNonReferenceType(),
1839 : LhsT->isRValueReferenceType()
1842 OpaqueValueExpr RHS(KeyLoc, RhsT.getNonReferenceType(),
1844 : RhsT->isRValueReferenceType()
1847
1848 auto OpKind = [&] {
1849 switch (BTT) {
1850 case BTT_LtSynthesisesFromSpaceship:
1851 return BinaryOperatorKind::BO_LT;
1852 case BTT_LeSynthesisesFromSpaceship:
1853 return BinaryOperatorKind::BO_LE;
1854 case BTT_GtSynthesisesFromSpaceship:
1855 return BinaryOperatorKind::BO_GT;
1856 case BTT_GeSynthesisesFromSpaceship:
1857 return BinaryOperatorKind::BO_GE;
1858 default:
1859 llvm_unreachable("Trying to Synthesize non-comparison operator?");
1860 }
1861 }();
1862
1863 UnresolvedSet<16> Functions;
1864 Self.LookupBinOp(Self.TUScope, KeyLoc, OpKind, Functions);
1865
1867 Self.CreateOverloadedBinOp(KeyLoc, OpKind, Functions, &LHS, &RHS);
1868 if (Result.isInvalid() || SFINAE.hasErrorOccurred())
1869 return false;
1870
1871 return isa<CXXRewrittenBinaryOperator>(Result.get());
1872 }
1873 default:
1874 llvm_unreachable("not a BTT");
1875 }
1876 llvm_unreachable("Unknown type trait or not implemented");
1877}
1878
1880 ParsedType Ty, Expr *DimExpr,
1881 SourceLocation RParen) {
1882 TypeSourceInfo *TSInfo;
1883 QualType T = GetTypeFromParser(Ty, &TSInfo);
1884 if (!TSInfo)
1886
1887 return BuildArrayTypeTrait(ATT, KWLoc, TSInfo, DimExpr, RParen);
1888}
1889
1891 QualType T, Expr *DimExpr,
1892 SourceLocation KeyLoc) {
1893 assert(!T->isDependentType() && "Cannot evaluate traits of dependent type");
1894
1895 switch (ATT) {
1896 case ATT_ArrayRank:
1897 if (T->isArrayType()) {
1898 unsigned Dim = 0;
1899 while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {
1900 ++Dim;
1901 T = AT->getElementType();
1902 }
1903 return Dim;
1904 }
1905 return 0;
1906
1907 case ATT_ArrayExtent: {
1908 llvm::APSInt Value;
1909 uint64_t Dim;
1910 if (Self.VerifyIntegerConstantExpression(
1911 DimExpr, &Value, diag::err_dimension_expr_not_constant_integer)
1912 .isInvalid())
1913 return 0;
1914 if (Value.isSigned() && Value.isNegative()) {
1915 Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer)
1916 << DimExpr->getSourceRange();
1917 return 0;
1918 }
1919 Dim = Value.getLimitedValue();
1920
1921 if (T->isArrayType()) {
1922 unsigned D = 0;
1923 bool Matched = false;
1924 while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {
1925 if (Dim == D) {
1926 Matched = true;
1927 break;
1928 }
1929 ++D;
1930 T = AT->getElementType();
1931 }
1932
1933 if (Matched && T->isArrayType()) {
1934 if (const ConstantArrayType *CAT =
1935 Self.Context.getAsConstantArrayType(T))
1936 return CAT->getLimitedSize();
1937 }
1938 }
1939 return 0;
1940 }
1941 }
1942 llvm_unreachable("Unknown type trait or not implemented");
1943}
1944
1946 TypeSourceInfo *TSInfo, Expr *DimExpr,
1947 SourceLocation RParen) {
1948 QualType T = TSInfo->getType();
1949
1950 // FIXME: This should likely be tracked as an APInt to remove any host
1951 // assumptions about the width of size_t on the target.
1952 uint64_t Value = 0;
1953 if (!T->isDependentType())
1954 Value = EvaluateArrayTypeTrait(*this, ATT, T, DimExpr, KWLoc);
1955
1956 // While the specification for these traits from the Embarcadero C++
1957 // compiler's documentation says the return type is 'unsigned int', Clang
1958 // returns 'size_t'. On Windows, the primary platform for the Embarcadero
1959 // compiler, there is no difference. On several other platforms this is an
1960 // important distinction.
1961 return new (Context) ArrayTypeTraitExpr(KWLoc, ATT, TSInfo, Value, DimExpr,
1962 RParen, Context.getSizeType());
1963}
1964
1966 Expr *Queried, SourceLocation RParen) {
1967 // If error parsing the expression, ignore.
1968 if (!Queried)
1969 return ExprError();
1970
1971 ExprResult Result = BuildExpressionTrait(ET, KWLoc, Queried, RParen);
1972
1973 return Result;
1974}
1975
1977 switch (ET) {
1978 case ET_IsLValueExpr:
1979 return E->isLValue();
1980 case ET_IsRValueExpr:
1981 return E->isPRValue();
1982 }
1983 llvm_unreachable("Expression trait not covered by switch");
1984}
1985
1987 Expr *Queried, SourceLocation RParen) {
1988 if (Queried->isTypeDependent()) {
1989 // Delay type-checking for type-dependent expressions.
1990 } else if (Queried->hasPlaceholderType()) {
1991 ExprResult PE = CheckPlaceholderExpr(Queried);
1992 if (PE.isInvalid())
1993 return ExprError();
1994 return BuildExpressionTrait(ET, KWLoc, PE.get(), RParen);
1995 }
1996
1997 bool Value = EvaluateExpressionTrait(ET, Queried);
1998
1999 return new (Context)
2000 ExpressionTraitExpr(KWLoc, ET, Queried, Value, RParen, Context.BoolTy);
2001}
2002
2003static std::optional<TypeTrait> StdNameToTypeTrait(StringRef Name) {
2004 return llvm::StringSwitch<std::optional<TypeTrait>>(Name)
2005 .Case("is_trivially_relocatable",
2006 TypeTrait::UTT_IsCppTriviallyRelocatable)
2007 .Case("is_replaceable", TypeTrait::UTT_IsReplaceable)
2008 .Case("is_trivially_copyable", TypeTrait::UTT_IsTriviallyCopyable)
2009 .Case("is_assignable", TypeTrait::BTT_IsAssignable)
2010 .Case("is_empty", TypeTrait::UTT_IsEmpty)
2011 .Case("is_standard_layout", TypeTrait::UTT_IsStandardLayout)
2012 .Case("is_constructible", TypeTrait::TT_IsConstructible)
2013 .Case("is_final", TypeTrait::UTT_IsFinal)
2014 .Default(std::nullopt);
2015}
2016
2018 std::optional<std::pair<TypeTrait, llvm::SmallVector<QualType, 1>>>;
2019
2020// Recognize type traits that are builting type traits, or known standard
2021// type traits in <type_traits>. Note that at this point we assume the
2022// trait evaluated to false, so we need only to recognize the shape of the
2023// outer-most symbol.
2026 std::optional<TypeTrait> Trait;
2027
2028 // builtins
2029 if (const auto *TraitExpr = dyn_cast<TypeTraitExpr>(E)) {
2030 Trait = TraitExpr->getTrait();
2031 for (const auto *Arg : TraitExpr->getArgs())
2032 Args.push_back(Arg->getType());
2033 return {{Trait.value(), std::move(Args)}};
2034 }
2035 const auto *Ref = dyn_cast<DeclRefExpr>(E);
2036 if (!Ref)
2037 return std::nullopt;
2038
2039 // std::is_xxx_v<>
2040 if (const auto *VD =
2041 dyn_cast<VarTemplateSpecializationDecl>(Ref->getDecl())) {
2042 if (!VD->isInStdNamespace())
2043 return std::nullopt;
2044 StringRef Name = VD->getIdentifier()->getName();
2045 if (!Name.consume_back("_v"))
2046 return std::nullopt;
2047 Trait = StdNameToTypeTrait(Name);
2048 if (!Trait)
2049 return std::nullopt;
2050 for (const auto &Arg : VD->getTemplateArgs().asArray()) {
2051 if (Arg.getKind() == TemplateArgument::ArgKind::Pack) {
2052 for (const auto &InnerArg : Arg.pack_elements())
2053 Args.push_back(InnerArg.getAsType());
2054 } else if (Arg.getKind() == TemplateArgument::ArgKind::Type) {
2055 Args.push_back(Arg.getAsType());
2056 } else {
2057 llvm_unreachable("Unexpected kind");
2058 }
2059 }
2060 return {{Trait.value(), std::move(Args)}};
2061 }
2062
2063 // std::is_xxx<>::value
2064 if (const auto *VD = dyn_cast<VarDecl>(Ref->getDecl());
2065 Ref->hasQualifier() && VD && VD->getIdentifier()->isStr("value")) {
2066 NestedNameSpecifier Qualifier = Ref->getQualifier();
2067 if (Qualifier.getKind() != NestedNameSpecifier::Kind::Type)
2068 return std::nullopt;
2069 const auto *Ts = Qualifier.getAsType()->getAs<TemplateSpecializationType>();
2070 if (!Ts)
2071 return std::nullopt;
2072 const TemplateDecl *D = Ts->getTemplateName().getAsTemplateDecl();
2073 if (!D || !D->isInStdNamespace())
2074 return std::nullopt;
2075 Trait = StdNameToTypeTrait(D->getIdentifier()->getName());
2076 if (!Trait)
2077 return std::nullopt;
2078 for (const auto &Arg : Ts->template_arguments())
2079 Args.push_back(Arg.getAsType());
2080 return {{Trait.value(), std::move(Args)}};
2081 }
2082 return std::nullopt;
2083}
2084
2086 const CXXRecordDecl *D) {
2087 if (D->isUnion()) {
2088 auto DiagSPM = [&](CXXSpecialMemberKind K, bool Has) {
2089 if (Has)
2090 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2091 << diag::TraitNotSatisfiedReason::UnionWithUserDeclaredSMF << K;
2092 };
2094 D->hasUserDeclaredCopyConstructor());
2096 D->hasUserDeclaredCopyAssignment());
2098 D->hasUserDeclaredMoveConstructor());
2100 D->hasUserDeclaredMoveAssignment());
2101 return;
2102 }
2103
2104 if (!D->hasSimpleMoveConstructor() && !D->hasSimpleCopyConstructor()) {
2105 const auto *Decl = cast_or_null<CXXConstructorDecl>(
2106 LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/false));
2107 if (Decl && Decl->isUserProvided())
2108 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2109 << diag::TraitNotSatisfiedReason::UserProvidedCtr
2110 << Decl->isMoveConstructor() << Decl->getSourceRange();
2111 }
2112 if (!D->hasSimpleMoveAssignment() && !D->hasSimpleCopyAssignment()) {
2114 LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/true);
2115 if (Decl && Decl->isUserProvided())
2116 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2117 << diag::TraitNotSatisfiedReason::UserProvidedAssign
2118 << Decl->isMoveAssignmentOperator() << Decl->getSourceRange();
2119 }
2120 if (CXXDestructorDecl *Dtr = D->getDestructor()) {
2121 Dtr = Dtr->getCanonicalDecl();
2122 if (Dtr->isUserProvided() && !Dtr->isDefaulted())
2123 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2124 << diag::TraitNotSatisfiedReason::DeletedDtr << /*User Provided*/ 1
2125 << Dtr->getSourceRange();
2126 }
2127}
2128
2131 const CXXRecordDecl *D) {
2132 for (const CXXBaseSpecifier &B : D->bases()) {
2133 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2134 if (B.isVirtual())
2135 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2136 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2137 << B.getSourceRange();
2138 if (!SemaRef.IsCXXTriviallyRelocatableType(B.getType()))
2139 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2140 << diag::TraitNotSatisfiedReason::NTRBase << B.getType()
2141 << B.getSourceRange();
2142 }
2143 for (const FieldDecl *Field : D->fields()) {
2144 if (!Field->getType()->isReferenceType() &&
2145 !SemaRef.IsCXXTriviallyRelocatableType(Field->getType()))
2146 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2147 << diag::TraitNotSatisfiedReason::NTRField << Field
2148 << Field->getType() << Field->getSourceRange();
2149 }
2150 if (D->hasDeletedDestructor())
2151 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2152 << diag::TraitNotSatisfiedReason::DeletedDtr << /*Deleted*/ 0
2153 << D->getDestructor()->getSourceRange();
2154
2155 if (D->hasAttr<TriviallyRelocatableAttr>())
2156 return;
2157 DiagnoseNonDefaultMovable(SemaRef, Loc, D);
2158}
2159
2162 QualType T) {
2163 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2164 << T << diag::TraitName::TriviallyRelocatable;
2166 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2167 << diag::TraitNotSatisfiedReason::VLA;
2168
2169 if (T->isReferenceType())
2170 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2171 << diag::TraitNotSatisfiedReason::Ref;
2172 T = T.getNonReferenceType();
2173
2174 if (T.hasNonTrivialObjCLifetime())
2175 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2176 << diag::TraitNotSatisfiedReason::HasArcLifetime;
2177
2178 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2179 if (!D || D->isInvalidDecl())
2180 return;
2181
2182 if (D->hasDefinition())
2184
2185 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2186}
2187
2189 const CXXRecordDecl *D) {
2190 for (const CXXBaseSpecifier &B : D->bases()) {
2191 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2192 if (!SemaRef.IsCXXReplaceableType(B.getType()))
2193 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2194 << diag::TraitNotSatisfiedReason::NonReplaceableBase << B.getType()
2195 << B.getSourceRange();
2196 }
2197 for (const FieldDecl *Field : D->fields()) {
2198 if (!SemaRef.IsCXXReplaceableType(Field->getType()))
2199 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2200 << diag::TraitNotSatisfiedReason::NonReplaceableField << Field
2201 << Field->getType() << Field->getSourceRange();
2202 }
2203 if (D->hasDeletedDestructor())
2204 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2205 << diag::TraitNotSatisfiedReason::DeletedDtr << /*Deleted*/ 0
2206 << D->getDestructor()->getSourceRange();
2207
2208 if (!D->hasSimpleMoveConstructor() && !D->hasSimpleCopyConstructor()) {
2209 const auto *Decl = cast<CXXConstructorDecl>(
2210 LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/false));
2211 if (Decl && Decl->isDeleted())
2212 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2213 << diag::TraitNotSatisfiedReason::DeletedCtr
2214 << Decl->isMoveConstructor() << Decl->getSourceRange();
2215 }
2216 if (!D->hasSimpleMoveAssignment() && !D->hasSimpleCopyAssignment()) {
2218 LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/true);
2219 if (Decl && Decl->isDeleted())
2220 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2221 << diag::TraitNotSatisfiedReason::DeletedAssign
2222 << Decl->isMoveAssignmentOperator() << Decl->getSourceRange();
2223 }
2224
2225 if (D->hasAttr<ReplaceableAttr>())
2226 return;
2227 DiagnoseNonDefaultMovable(SemaRef, Loc, D);
2228}
2229
2231 QualType T) {
2232 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2233 << T << diag::TraitName::Replaceable;
2234
2236 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2237 << diag::TraitNotSatisfiedReason::VLA;
2238
2239 if (T->isReferenceType())
2240 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2241 << diag::TraitNotSatisfiedReason::Ref;
2242 T = T.getNonReferenceType();
2243
2244 if (T.isConstQualified())
2245 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2246 << diag::TraitNotSatisfiedReason::Const;
2247
2248 if (T.isVolatileQualified())
2249 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2250 << diag::TraitNotSatisfiedReason::Volatile;
2251
2252 bool IsArray = T->isArrayType();
2253 T = SemaRef.getASTContext().getBaseElementType(T.getUnqualifiedType());
2254
2255 if (T->isScalarType())
2256 return;
2257
2258 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2259 if (!D) {
2260 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2261 << diag::TraitNotSatisfiedReason::NotScalarOrClass << IsArray;
2262 return;
2263 }
2264
2265 if (D->isInvalidDecl())
2266 return;
2267
2268 if (D->hasDefinition())
2270
2271 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2272}
2273
2276 const CXXRecordDecl *D) {
2277 for (const CXXBaseSpecifier &B : D->bases()) {
2278 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2279 if (B.isVirtual())
2280 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2281 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2282 << B.getSourceRange();
2283 if (!B.getType().isTriviallyCopyableType(D->getASTContext())) {
2284 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2285 << diag::TraitNotSatisfiedReason::NTCBase << B.getType()
2286 << B.getSourceRange();
2287 }
2288 }
2289 for (const FieldDecl *Field : D->fields()) {
2290 if (!Field->getType().isTriviallyCopyableType(Field->getASTContext()))
2291 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2292 << diag::TraitNotSatisfiedReason::NTCField << Field
2293 << Field->getType() << Field->getSourceRange();
2294 }
2295 CXXDestructorDecl *Dtr = D->getDestructor();
2296 if (D->hasDeletedDestructor() || (Dtr && !Dtr->isTrivial()))
2297 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2298 << diag::TraitNotSatisfiedReason::DeletedDtr
2299 << !D->hasDeletedDestructor() << D->getDestructor()->getSourceRange();
2300
2301 for (const CXXMethodDecl *Method : D->methods()) {
2302 if (Method->isTrivial() || !Method->isUserProvided()) {
2303 continue;
2304 }
2305 auto SpecialMemberKind =
2307 switch (SpecialMemberKind) {
2312 bool IsAssignment =
2313 SpecialMemberKind == CXXSpecialMemberKind::CopyAssignment ||
2314 SpecialMemberKind == CXXSpecialMemberKind::MoveAssignment;
2315 bool IsMove =
2316 SpecialMemberKind == CXXSpecialMemberKind::MoveConstructor ||
2317 SpecialMemberKind == CXXSpecialMemberKind::MoveAssignment;
2318
2319 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2320 << (IsAssignment ? diag::TraitNotSatisfiedReason::UserProvidedAssign
2321 : diag::TraitNotSatisfiedReason::UserProvidedCtr)
2322 << IsMove << Method->getSourceRange();
2323 break;
2324 }
2325 default:
2326 break;
2327 }
2328 }
2329}
2330
2332 Sema &SemaRef, SourceLocation Loc,
2334 if (Ts.empty()) {
2335 return;
2336 }
2337
2338 bool ContainsVoid = false;
2339 for (const QualType &ArgTy : Ts) {
2340 ContainsVoid |= ArgTy->isVoidType();
2341 }
2342
2343 if (ContainsVoid)
2344 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2345 << diag::TraitNotSatisfiedReason::CVVoidType;
2346
2347 QualType T = Ts[0];
2348 if (T->isFunctionType())
2349 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2350 << diag::TraitNotSatisfiedReason::FunctionType;
2351
2352 if (T->isIncompleteArrayType())
2353 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2354 << diag::TraitNotSatisfiedReason::IncompleteArrayType;
2355
2356 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2357 if (!D || D->isInvalidDecl() || !D->hasDefinition())
2358 return;
2359
2360 llvm::BumpPtrAllocator OpaqueExprAllocator;
2361 SmallVector<Expr *, 2> ArgExprs;
2362 ArgExprs.reserve(Ts.size() - 1);
2363 for (unsigned I = 1, N = Ts.size(); I != N; ++I) {
2364 QualType ArgTy = Ts[I];
2365 if (ArgTy->isObjectType() || ArgTy->isFunctionType())
2366 ArgTy = SemaRef.Context.getRValueReferenceType(ArgTy);
2367 ArgExprs.push_back(
2368 new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
2371 }
2372
2375 Sema::ContextRAII TUContext(SemaRef,
2379 InitializationSequence Init(SemaRef, To, InitKind, ArgExprs);
2380
2381 Init.Diagnose(SemaRef, To, InitKind, ArgExprs);
2382 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2383}
2384
2387 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2388 << T << diag::TraitName::TriviallyCopyable;
2389
2390 if (T->isReferenceType())
2391 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2392 << diag::TraitNotSatisfiedReason::Ref;
2393
2394 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2395 if (!D || D->isInvalidDecl())
2396 return;
2397
2398 if (D->hasDefinition())
2400
2401 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2402}
2403
2405 QualType T, QualType U) {
2406 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2407
2408 auto createDeclValExpr = [&](QualType Ty) -> OpaqueValueExpr {
2409 if (Ty->isObjectType() || Ty->isFunctionType())
2410 Ty = SemaRef.Context.getRValueReferenceType(Ty);
2411 return {Loc, Ty.getNonLValueExprType(SemaRef.Context),
2413 };
2414
2415 auto LHS = createDeclValExpr(T);
2416 auto RHS = createDeclValExpr(U);
2417
2420 Sema::ContextRAII TUContext(SemaRef,
2422 SemaRef.BuildBinOp(/*S=*/nullptr, Loc, BO_Assign, &LHS, &RHS);
2423
2424 if (!D || D->isInvalidDecl())
2425 return;
2426
2427 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2428}
2429
2431 const CXXRecordDecl *D) {
2432 // Non-static data members (ignore zero-width bit‐fields).
2433 for (const auto *Field : D->fields()) {
2434 if (Field->isZeroLengthBitField())
2435 continue;
2436 if (Field->isBitField()) {
2437 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2438 << diag::TraitNotSatisfiedReason::NonZeroLengthField << Field
2439 << Field->getSourceRange();
2440 continue;
2441 }
2442 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2443 << diag::TraitNotSatisfiedReason::NonEmptyMember << Field
2444 << Field->getType() << Field->getSourceRange();
2445 }
2446
2447 // Virtual functions.
2448 for (const auto *M : D->methods()) {
2449 if (M->isVirtual()) {
2450 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2451 << diag::TraitNotSatisfiedReason::VirtualFunction << M
2452 << M->getSourceRange();
2453 break;
2454 }
2455 }
2456
2457 // Virtual bases and non-empty bases.
2458 for (const auto &B : D->bases()) {
2459 const auto *BR = B.getType()->getAsCXXRecordDecl();
2460 if (!BR || BR->isInvalidDecl())
2461 continue;
2462 if (B.isVirtual()) {
2463 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2464 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2465 << B.getSourceRange();
2466 }
2467 if (!BR->isEmpty()) {
2468 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2469 << diag::TraitNotSatisfiedReason::NonEmptyBase << B.getType()
2470 << B.getSourceRange();
2471 }
2472 }
2473}
2474
2476 // Emit primary "not empty" diagnostic.
2477 S.Diag(Loc, diag::note_unsatisfied_trait) << T << diag::TraitName::Empty;
2478
2479 // While diagnosing is_empty<T>, we want to look at the actual type, not a
2480 // reference or an array of it. So we need to massage the QualType param to
2481 // strip refs and arrays.
2482 if (T->isReferenceType())
2483 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2484 << diag::TraitNotSatisfiedReason::Ref;
2485 T = T.getNonReferenceType();
2486
2487 if (auto *AT = S.Context.getAsArrayType(T))
2488 T = AT->getElementType();
2489
2490 if (auto *D = T->getAsCXXRecordDecl()) {
2491 if (D->hasDefinition()) {
2493 S.Diag(D->getLocation(), diag::note_defined_here) << D;
2494 }
2495 }
2496}
2497
2499 const CXXRecordDecl *D) {
2500 if (!D || D->isInvalidDecl())
2501 return;
2502
2503 // Complete record but not 'final'.
2504 if (!D->isEffectivelyFinal()) {
2505 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2506 << diag::TraitNotSatisfiedReason::NotMarkedFinal;
2507 S.Diag(D->getLocation(), diag::note_defined_here) << D;
2508 return;
2509 }
2510}
2511
2513 // Primary: “%0 is not final”
2514 S.Diag(Loc, diag::note_unsatisfied_trait) << T << diag::TraitName::Final;
2515 if (T->isReferenceType()) {
2516 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2517 << diag::TraitNotSatisfiedReason::Ref;
2518 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2519 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2520 return;
2521 }
2522 // Arrays / functions / non-records → not a class/union.
2523 if (S.Context.getAsArrayType(T)) {
2524 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2525 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2526 return;
2527 }
2528 if (T->isFunctionType()) {
2529 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2530 << diag::TraitNotSatisfiedReason::FunctionType;
2531 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2532 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2533 return;
2534 }
2535 if (!T->isRecordType()) {
2536 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2537 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2538 return;
2539 }
2540 if (const auto *D = T->getAsCXXRecordDecl())
2542}
2543
2545 int NumBasesWithFields = 0;
2546 for (const CXXBaseSpecifier &Base : D->bases()) {
2547 const CXXRecordDecl *BaseRD = Base.getType()->getAsCXXRecordDecl();
2548 if (!BaseRD || BaseRD->isInvalidDecl())
2549 continue;
2550
2551 for (const FieldDecl *Field : BaseRD->fields()) {
2552 if (!Field->isUnnamedBitField()) {
2553 if (++NumBasesWithFields > 1)
2554 return true; // found more than one base class with fields
2555 break; // no need to check further fields in this base class
2556 }
2557 }
2558 }
2559 return false;
2560}
2561
2563 const CXXRecordDecl *D) {
2564 for (const CXXBaseSpecifier &B : D->bases()) {
2565 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2566 if (B.isVirtual()) {
2567 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2568 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2569 << B.getSourceRange();
2570 }
2571 if (!B.getType()->isStandardLayoutType()) {
2572 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2573 << diag::TraitNotSatisfiedReason::NonStandardLayoutBase << B.getType()
2574 << B.getSourceRange();
2575 }
2576 }
2577 // Check for mixed access specifiers in fields.
2578 const FieldDecl *FirstField = nullptr;
2579 AccessSpecifier FirstAccess = AS_none;
2580
2581 for (const FieldDecl *Field : D->fields()) {
2582 if (Field->isUnnamedBitField())
2583 continue;
2584
2585 // Record the first field we see
2586 if (!FirstField) {
2587 FirstField = Field;
2588 FirstAccess = Field->getAccess();
2589 continue;
2590 }
2591
2592 // Check if the field has a different access specifier than the first one.
2593 if (Field->getAccess() != FirstAccess) {
2594 // Emit a diagnostic about mixed access specifiers.
2595 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2596 << diag::TraitNotSatisfiedReason::MixedAccess;
2597
2598 SemaRef.Diag(FirstField->getLocation(), diag::note_defined_here)
2599 << FirstField;
2600
2601 SemaRef.Diag(Field->getLocation(), diag::note_unsatisfied_trait_reason)
2602 << diag::TraitNotSatisfiedReason::MixedAccessField << Field
2603 << FirstField;
2604
2605 // No need to check further fields, as we already found mixed access.
2606 break;
2607 }
2608 }
2610 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2611 << diag::TraitNotSatisfiedReason::MultipleDataBase;
2612 }
2613 if (D->isPolymorphic()) {
2614 // Find the best location to point “defined here” at.
2615 const CXXMethodDecl *VirtualMD = nullptr;
2616 // First, look for a virtual method.
2617 for (const auto *M : D->methods()) {
2618 if (M->isVirtual()) {
2619 VirtualMD = M;
2620 break;
2621 }
2622 }
2623 if (VirtualMD) {
2624 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2625 << diag::TraitNotSatisfiedReason::VirtualFunction << VirtualMD;
2626 SemaRef.Diag(VirtualMD->getLocation(), diag::note_defined_here)
2627 << VirtualMD;
2628 } else {
2629 // If no virtual method, point to the record declaration itself.
2630 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2631 << diag::TraitNotSatisfiedReason::VirtualFunction << D;
2632 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2633 }
2634 }
2635 for (const FieldDecl *Field : D->fields()) {
2636 if (!Field->getType()->isStandardLayoutType()) {
2637 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2638 << diag::TraitNotSatisfiedReason::NonStandardLayoutMember << Field
2639 << Field->getType() << Field->getSourceRange();
2640 }
2641 }
2642 // Find any indirect base classes that have fields.
2643 if (D->hasDirectFields()) {
2644 const CXXRecordDecl *Indirect = nullptr;
2645 D->forallBases([&](const CXXRecordDecl *BaseDef) {
2646 if (BaseDef->hasDirectFields()) {
2647 Indirect = BaseDef;
2648 return false; // stop traversal
2649 }
2650 return true; // continue to the next base
2651 });
2652 if (Indirect) {
2653 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2654 << diag::TraitNotSatisfiedReason::IndirectBaseWithFields << Indirect
2655 << Indirect->getSourceRange();
2656 }
2657 }
2658}
2659
2661 QualType T) {
2662 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2663 << T << diag::TraitName::StandardLayout;
2664
2665 // Check type-level exclusion first.
2666 if (T->isVariablyModifiedType()) {
2667 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2668 << diag::TraitNotSatisfiedReason::VLA;
2669 return;
2670 }
2671
2672 if (T->isReferenceType()) {
2673 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2674 << diag::TraitNotSatisfiedReason::Ref;
2675 return;
2676 }
2677 T = T.getNonReferenceType();
2678 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2679 if (!D || D->isInvalidDecl())
2680 return;
2681
2682 if (D->hasDefinition())
2684
2685 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2686}
2687
2689 E = E->IgnoreParenImpCasts();
2690 if (E->containsErrors())
2691 return;
2692
2694 if (!TraitInfo)
2695 return;
2696
2697 const auto &[Trait, Args] = TraitInfo.value();
2698 switch (Trait) {
2699 case UTT_IsCppTriviallyRelocatable:
2701 break;
2702 case UTT_IsReplaceable:
2703 DiagnoseNonReplaceableReason(*this, E->getBeginLoc(), Args[0]);
2704 break;
2705 case UTT_IsTriviallyCopyable:
2707 break;
2708 case BTT_IsAssignable:
2709 DiagnoseNonAssignableReason(*this, E->getBeginLoc(), Args[0], Args[1]);
2710 break;
2711 case UTT_IsEmpty:
2712 DiagnoseIsEmptyReason(*this, E->getBeginLoc(), Args[0]);
2713 break;
2714 case UTT_IsStandardLayout:
2715 DiagnoseNonStandardLayoutReason(*this, E->getBeginLoc(), Args[0]);
2716 break;
2717 case TT_IsConstructible:
2719 break;
2720 case UTT_IsFinal: {
2721 QualType QT = Args[0];
2722 if (QT->isDependentType())
2723 break;
2724 const auto *RD = QT->getAsCXXRecordDecl();
2725 if (!RD || !RD->isEffectivelyFinal())
2726 DiagnoseIsFinalReason(*this, E->getBeginLoc(), QT); // unsatisfied
2727 break;
2728 }
2729 default:
2730 break;
2731 }
2732}
static CanQualType GetReturnType(QualType RetTy)
Returns the "extra-canonicalized" return type, which discards qualifiers on the return type.
Definition: CGCall.cpp:151
const Decl * D
Expr * E
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the Diagnostic IDs-related interfaces.
This file declares semantic analysis for HLSL constructs.
SourceLocation Loc
Definition: SemaObjC.cpp:754
bool Indirect
Definition: SemaObjC.cpp:755
static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, const TypeSourceInfo *Lhs, const TypeSourceInfo *Rhs, SourceLocation KeyLoc)
static bool HasNonDeletedDefaultedEqualityComparison(Sema &S, const CXXRecordDecl *Decl, SourceLocation KeyLoc)
static APValue EvaluateSizeTTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, ArrayRef< TypeSourceInfo * > Args, SourceLocation RParenLoc, bool IsDependent)
static bool DiagnoseVLAInCXXTypeTrait(Sema &S, const TypeSourceInfo *T, clang::tok::TokenKind TypeTraitID)
Checks that type T is not a VLA.
static bool HasNoThrowOperator(CXXRecordDecl *RD, OverloadedOperatorKind Op, Sema &Self, SourceLocation KeyLoc, ASTContext &C, bool(CXXRecordDecl::*HasTrivial)() const, bool(CXXRecordDecl::*HasNonTrivial)() const, bool(CXXMethodDecl::*IsDesiredOp)() const)
static std::optional< TypeTrait > StdNameToTypeTrait(StringRef Name)
static void DiagnoseNonConstructibleReason(Sema &SemaRef, SourceLocation Loc, const llvm::SmallVector< clang::QualType, 1 > &Ts)
static bool IsEligibleForTrivialRelocation(Sema &SemaRef, const CXXRecordDecl *D)
static CXXMethodDecl * LookupSpecialMemberFromXValue(Sema &SemaRef, const CXXRecordDecl *RD, bool Assign)
static bool hasSuitableMoveAssignmentOperatorForRelocation(Sema &SemaRef, const CXXRecordDecl *D, bool AllowUserDefined)
static bool DiagnoseAtomicInCXXTypeTrait(Sema &S, const TypeSourceInfo *T, clang::tok::TokenKind TypeTraitID)
Checks that type T is not an atomic type (_Atomic).
static void DiagnoseNonStandardLayoutReason(Sema &SemaRef, SourceLocation Loc, const CXXRecordDecl *D)
static void DiagnoseIsFinalReason(Sema &S, SourceLocation Loc, const CXXRecordDecl *D)
static void DiagnoseIsEmptyReason(Sema &S, SourceLocation Loc, const CXXRecordDecl *D)
static bool hasMultipleDataBaseClassesWithFields(const CXXRecordDecl *D)
static bool IsEligibleForReplacement(Sema &SemaRef, const CXXRecordDecl *D)
static bool EvaluateExpressionTrait(ExpressionTrait ET, Expr *E)
static ExtractedTypeTraitInfo ExtractTypeTraitFromExpression(const Expr *E)
static void DiagnoseNonTriviallyRelocatableReason(Sema &SemaRef, SourceLocation Loc, const CXXRecordDecl *D)
static void DiagnoseNonAssignableReason(Sema &SemaRef, SourceLocation Loc, QualType T, QualType U)
static bool IsTriviallyRelocatableType(Sema &SemaRef, QualType T)
static void DiagnoseNonDefaultMovable(Sema &SemaRef, SourceLocation Loc, const CXXRecordDecl *D)
static bool IsDefaultMovable(Sema &SemaRef, const CXXRecordDecl *D)
static bool hasSuitableConstructorForRelocation(Sema &SemaRef, const CXXRecordDecl *D, bool AllowUserDefined)
static void DiagnoseNonTriviallyCopyableReason(Sema &SemaRef, SourceLocation Loc, const CXXRecordDecl *D)
static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, SourceLocation KeyLoc, TypeSourceInfo *TInfo)
static uint64_t EvaluateArrayTypeTrait(Sema &Self, ArrayTypeTrait ATT, QualType T, Expr *DimExpr, SourceLocation KeyLoc)
std::optional< std::pair< TypeTrait, llvm::SmallVector< QualType, 1 > > > ExtractedTypeTraitInfo
static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT, SourceLocation Loc, QualType ArgTy)
Check the completeness of a type in a unary type trait.
static ExprResult CheckConvertibilityForTypeTraits(Sema &Self, const TypeSourceInfo *Lhs, const TypeSourceInfo *Rhs, SourceLocation KeyLoc, llvm::BumpPtrAllocator &OpaqueExprAllocator)
TypeTraitReturnType
static void DiagnoseNonReplaceableReason(Sema &SemaRef, SourceLocation Loc, const CXXRecordDecl *D)
static bool EvaluateBooleanTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, ArrayRef< TypeSourceInfo * > Args, SourceLocation RParenLoc, bool IsDependent)
static bool IsCXXReplaceableType(Sema &S, const CXXRecordDecl *RD)
static bool isTriviallyEqualityComparableType(Sema &S, QualType Type, SourceLocation KeyLoc)
Defines enumerations for the type traits support.
C Language Family Type Representation.
__device__ int
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition: APValue.h:122
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
TranslationUnitDecl * getTranslationUnitDecl() const
Definition: ASTContext.h:1201
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type.
DeclarationNameTable DeclarationNames
Definition: ASTContext.h:744
bool containsNonRelocatablePointerAuth(QualType T)
Examines a given type, and returns whether the type itself or any data it transitively contains has a...
Definition: ASTContext.h:656
void setRelocationInfoForCXXRecord(const CXXRecordDecl *, CXXRecordDeclRelocationInfo)
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
bool containsAddressDiscriminatedPointerAuth(QualType T) const
Examines a given type, and returns whether the type itself is address discriminated,...
Definition: ASTContext.h:645
CanQualType getLogicalOperationType() const
The result type of logical operations, '<', '>', '!=', etc.
Definition: ASTContext.h:2269
bool hasUniqueObjectRepresentations(QualType Ty, bool CheckIfTriviallyCopyable=true) const
Return true if the specified type has unique object representations according to (C++17 [meta....
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
CanQualType BoolTy
Definition: ASTContext.h:1223
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Definition: ASTContext.h:2898
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
TypeSourceInfo * CreateTypeSourceInfo(QualType T, unsigned Size=0) const
Allocate an uninitialized TypeSourceInfo.
llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const
Make an APSInt of the appropriate width and signedness for the given Value and integer Type.
Definition: ASTContext.h:3310
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
CanQualType getCanonicalTagType(const TagDecl *TD) const
std::optional< CXXRecordDeclRelocationInfo > getRelocationInfoForCXXRecord(const CXXRecordDecl *) const
PtrTy get() const
Definition: Ownership.h:171
bool isInvalid() const
Definition: Ownership.h:167
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
Definition: ExprCXX.h:2990
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: TypeBase.h:3738
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2869
CXXDestructorDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclCXX.h:2915
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2129
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
Definition: DeclCXX.cpp:2735
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
Definition: DeclCXX.cpp:2714
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
bool hasTrivialMoveAssignment() const
Determine whether this class has a trivial move assignment operator (C++11 [class....
Definition: DeclCXX.h:1341
bool hasNonTrivialCopyAssignment() const
Determine whether this class has a non-trivial copy assignment operator (C++ [class....
Definition: DeclCXX.h:1334
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
Definition: DeclCXX.cpp:2325
bool hasTrivialDefaultConstructor() const
Determine whether this class has a trivial default constructor (C++11 [class.ctor]p5).
Definition: DeclCXX.h:1240
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
Definition: DeclCXX.h:1366
bool hasTrivialMoveConstructor() const
Determine whether this class has a trivial move constructor (C++11 [class.copy]p12)
Definition: DeclCXX.h:1301
CXXRecordDecl * getDefinition() const
Definition: DeclCXX.h:548
bool hasTrivialCopyConstructor() const
Determine whether this class has a trivial copy constructor (C++ [class.copy]p6, C++11 [class....
Definition: DeclCXX.h:1278
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
Definition: DeclCXX.h:1214
bool hasTrivialCopyAssignment() const
Determine whether this class has a trivial copy assignment operator (C++ [class.copy]p11,...
Definition: DeclCXX.h:1328
bool isAbstract() const
Determine whether this class has a pure virtual function.
Definition: DeclCXX.h:1221
bool hasNonTrivialMoveConstructor() const
Determine whether this class has a non-trivial move constructor (C++11 [class.copy]p12)
Definition: DeclCXX.h:1313
bool hasDirectFields() const
Determine whether this class has direct non-static data members.
Definition: DeclCXX.h:1200
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
Definition: DeclCXX.h:1186
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
Definition: DeclCXX.cpp:2121
bool hasNonTrivialMoveAssignment() const
Determine whether this class has a non-trivial move assignment operator (C++11 [class....
Definition: DeclCXX.h:1348
bool hasNonTrivialDefaultConstructor() const
Determine whether this class has a non-trivial default constructor (C++11 [class.ctor]p5).
Definition: DeclCXX.h:1247
bool hasNonTrivialCopyConstructor() const
Determine whether this class has a non-trivial copy constructor (C++ [class.copy]p6,...
Definition: DeclCXX.h:1288
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2879
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition: Expr.h:3062
Represents the canonical version of C arrays with a specified constant size.
Definition: TypeBase.h:3776
A POD class for pairing a NamedDecl* with an access specifier.
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
The results of name lookup within a DeclContext.
Definition: DeclBase.h:1382
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Definition: DeclBase.cpp:1879
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
bool isInStdNamespace() const
Definition: DeclBase.cpp:427
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:524
bool isInvalidDecl() const
Definition: DeclBase.h:588
SourceLocation getLocation() const
Definition: DeclBase.h:439
bool hasAttr() const
Definition: DeclBase.h:577
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Definition: DeclBase.h:427
DeclarationName getCXXOperatorName(OverloadedOperatorKind Op)
Get the name of the overloadable C++ operator corresponding to Op.
DeclarationName getCXXConstructorName(CanQualType Ty)
Returns the name of a C++ constructor for the given Type.
The name of a declaration.
RAII object that enters a new expression evaluation context.
The return type of classify().
Definition: Expr.h:337
This represents one expression.
Definition: Expr.h:112
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Definition: Expr.h:194
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition: Expr.cpp:3073
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
Definition: Expr.h:246
bool isPRValue() const
Definition: Expr.h:285
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
Definition: Expr.h:284
Classification Classify(ASTContext &Ctx) const
Classify - Classify this expression according to the C++11 expression taxonomy.
Definition: Expr.h:412
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
Definition: Expr.h:523
static ExprValueKind getValueKindForType(QualType T)
getValueKindForType - Given a formal return or parameter type, give its value kind.
Definition: Expr.h:434
An expression trait intrinsic.
Definition: ExprCXX.h:3063
Represents a member of a struct/union/class.
Definition: Decl.h:3157
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition: Decl.h:2376
bool isDeleted() const
Whether this function has been deleted.
Definition: Decl.h:2539
bool isDefaulted() const
Whether this function is defaulted.
Definition: Decl.h:2384
bool isUserProvided() const
True if this method is user-declared and was not deleted or defaulted on its first declaration.
Definition: Decl.h:2409
Represents a prototype with parameter type info, e.g.
Definition: TypeBase.h:5282
unsigned getNumParams() const
Definition: TypeBase.h:5560
bool isNothrow(bool ResultIfDependent=false) const
Determine whether this function type has a non-throwing exception specification.
Definition: TypeBase.h:5681
Declaration of a template function.
Definition: DeclTemplate.h:952
Describes the kind of initialization being performed, along with location information for tokens rela...
static InitializationKind CreateDirect(SourceLocation InitLoc, SourceLocation LParenLoc, SourceLocation RParenLoc)
Create a direct initialization.
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
Describes the sequence of initializations required to initialize a given object or reference with a s...
Describes an entity that is being initialized.
static InitializedEntity InitializeTemporary(QualType Type)
Create the initialization entity for a temporary.
Represents the results of name lookup.
Definition: Lookup.h:147
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
Definition: Lookup.h:636
iterator end() const
Definition: Lookup.h:359
iterator begin() const
Definition: Lookup.h:358
This represents a decl that may have a name.
Definition: Decl.h:273
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
Definition: Decl.h:486
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
@ Type
A type, stored as a Type*.
Represents an ObjC class declaration.
Definition: DeclObjC.h:1154
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
Definition: DeclObjC.h:1810
Represents a class type in Objective C.
Definition: TypeBase.h:7707
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface.
Definition: TypeBase.h:7940
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition: Expr.h:1180
OverloadCandidateSet - A set of overload candidates, used in C++ overload resolution (C++ 13....
Definition: Overload.h:1153
@ CSK_Normal
Normal lookup.
Definition: Overload.h:1157
SmallVectorImpl< OverloadCandidate >::iterator iterator
Definition: Overload.h:1369
OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc, OverloadCandidateSet::iterator &Best)
Find the best viable function on this overload set, if it exists.
A (possibly-)qualified type.
Definition: TypeBase.h:937
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
Definition: Type.cpp:2871
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type.
Definition: Type.cpp:3591
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Definition: TypeBase.h:8528
bool hasNonTrivialObjCLifetime() const
Definition: TypeBase.h:1442
@ PCK_Trivial
The type does not fall into any of the following categories.
Definition: TypeBase.h:1493
@ PCK_ARCStrong
The type is an Objective-C retainable pointer type that is qualified with the ARC __strong qualifier.
Definition: TypeBase.h:1502
The collection of all-type qualifiers we support.
Definition: TypeBase.h:331
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
Definition: TypeBase.h:361
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
Definition: TypeBase.h:354
@ OCL_None
There is no lifetime qualification on this type.
Definition: TypeBase.h:350
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Definition: TypeBase.h:364
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
Definition: TypeBase.h:367
bool canPassInRegisters() const
Determine whether this class can be passed in registers.
Definition: Decl.h:4446
field_range fields() const
Definition: Decl.h:4512
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: TypeBase.h:6502
RecordDecl * getOriginalDecl() const
Definition: TypeBase.h:6509
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: SemaBase.cpp:61
A RAII object to temporarily push a declaration context.
Definition: Sema.h:3468
CXXSpecialMemberKind asSpecialMember() const
Definition: Sema.h:6342
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
Definition: Sema.h:12359
bool hasErrorOccurred() const
Determine whether any SFINAE errors have been trapped.
Definition: Sema.h:12392
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:850
DefaultedFunctionKind getDefaultedFunctionKind(const FunctionDecl *FD)
Determine the kind of defaulting that would be done for a given function.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
Definition: Sema.h:9281
ExprResult ActOnExpressionTrait(ExpressionTrait OET, SourceLocation KWLoc, Expr *Queried, SourceLocation RParen)
ActOnExpressionTrait - Parsed one of the unary type trait support pseudo-functions.
bool IsCXXTriviallyRelocatableType(QualType T)
Determines if a type is trivially relocatable according to the C++26 rules.
bool BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT, QualType RhsT)
ASTContext & Context
Definition: Sema.h:1276
void DiagnoseTypeTraitDetails(const Expr *E)
If E represents a built-in type trait, or a known standard type trait, try to print more information ...
ASTContext & getASTContext() const
Definition: Sema.h:918
ASTContext::CXXRecordDeclRelocationInfo CheckCXX2CRelocatableAndReplaceable(const clang::CXXRecordDecl *D)
void LookupBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, UnresolvedSetImpl &Functions)
Definition: SemaExpr.cpp:15559
ExprResult CreateOverloadedBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, const UnresolvedSetImpl &Fns, Expr *LHS, Expr *RHS, bool RequiresADL=true, bool AllowRewrittenCandidates=true, FunctionDecl *DefaultedFn=nullptr)
Create a binary operation that may resolve to an overloaded operator.
bool CheckTypeTraitArity(unsigned Arity, SourceLocation Loc, size_t N)
ExprResult ActOnArrayTypeTrait(ArrayTypeTrait ATT, SourceLocation KWLoc, ParsedType LhsTy, Expr *DimExpr, SourceLocation RParen)
ActOnArrayTypeTrait - Parsed one of the binary type trait support pseudo-functions.
void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, TemplateArgumentListInfo *ExplicitTemplateArgs, QualType ObjectType, Expr::Classification ObjectClassification, ArrayRef< Expr * > Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions=false, bool PartialOverloading=false, OverloadCandidateParamOrder PO={})
Add a C++ member function template as a candidate to the candidate set, using template argument deduc...
void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef< Expr * > Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions=false, bool PartialOverloading=false, bool AllowExplicit=true, ADLCallKind IsADLCandidate=ADLCallKind::NotADL, OverloadCandidateParamOrder PO={}, bool AggregateCandidateDeduction=false)
Add a C++ function template specialization as a candidate in the candidate set, using template argume...
const LangOptions & getLangOpts() const
Definition: Sema.h:911
void AddOverloadCandidate(FunctionDecl *Function, DeclAccessPair FoundDecl, ArrayRef< Expr * > Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions=false, bool PartialOverloading=false, bool AllowExplicit=true, bool AllowExplicitConversion=false, ADLCallKind IsADLCandidate=ADLCallKind::NotADL, ConversionSequenceList EarlyConversions={}, OverloadCandidateParamOrder PO={}, bool AggregateCandidateDeduction=false, bool StrictPackMatch=false)
AddOverloadCandidate - Adds the given function to the set of candidate functions, using the given fun...
ExprResult BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc, ArrayRef< TypeSourceInfo * > Args, SourceLocation RParenLoc)
ExprResult BuildExpressionTrait(ExpressionTrait OET, SourceLocation KWLoc, Expr *Queried, SourceLocation RParen)
bool IsCXXReplaceableType(QualType T)
Determines if a type is replaceable according to the C++26 rules.
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
Definition: SemaExpr.cpp:21316
void AddMethodCandidate(DeclAccessPair FoundDecl, QualType ObjectType, Expr::Classification ObjectClassification, ArrayRef< Expr * > Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversion=false, OverloadCandidateParamOrder PO={})
AddMethodCandidate - Adds a named decl (which is some kind of method) as a method candidate to the gi...
CanThrowResult canThrow(const Stmt *E)
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Definition: SemaType.cpp:9241
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
Definition: Sema.h:1239
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr, bool ForFoldExpression=false)
Definition: SemaExpr.cpp:15609
ExprResult ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc, ArrayRef< ParsedType > Args, SourceLocation RParenLoc)
Parsed one of the type trait support pseudo-functions.
ExprResult BuildArrayTypeTrait(ArrayTypeTrait ATT, SourceLocation KWLoc, TypeSourceInfo *TSInfo, Expr *DimExpr, SourceLocation RParen)
UnsignedOrNone GetDecompositionElementCount(QualType DecompType, SourceLocation Loc)
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
Definition: SemaType.cpp:2773
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:334
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:346
bool isUnion() const
Definition: Decl.h:3919
@ Pack
The template argument is actually a parameter pack.
Definition: TemplateBase.h:107
@ Type
The template argument is a type.
Definition: TemplateBase.h:70
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:396
Represents a type template specialization; the template must be a class template, a type alias templa...
Definition: TypeBase.h:7290
SourceLocation getBeginLoc() const
Get the begin source location.
Definition: TypeLoc.cpp:193
A container of type source information.
Definition: TypeBase.h:8314
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition: TypeLoc.h:272
QualType getType() const
Return the type wrapped by this type source info.
Definition: TypeBase.h:8325
static TypeTraitExpr * Create(const ASTContext &C, QualType T, SourceLocation Loc, TypeTrait Kind, ArrayRef< TypeSourceInfo * > Args, SourceLocation RParenLoc, bool Value)
Create a new type trait expression.
Definition: ExprCXX.cpp:1914
The base class of the type hierarchy.
Definition: TypeBase.h:1833
bool isStructureType() const
Definition: Type.cpp:678
bool isVoidType() const
Definition: TypeBase.h:8936
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
Definition: Type.cpp:2998
bool isIncompleteArrayType() const
Definition: TypeBase.h:8687
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
Definition: Type.cpp:2209
bool isRValueReferenceType() const
Definition: TypeBase.h:8612
bool isFundamentalType() const
Tests whether the type is categorized as a fundamental type.
Definition: TypeBase.h:8543
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.h:26
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition: Type.h:41
bool isArrayType() const
Definition: TypeBase.h:8679
bool isArithmeticType() const
Definition: Type.cpp:2341
CanQualType getCanonicalTypeUnqualified() const
const T * castAs() const
Member-template castAs<specific type>.
Definition: TypeBase.h:9226
bool isReferenceType() const
Definition: TypeBase.h:8604
bool isHLSLIntangibleType() const
Definition: Type.cpp:5428
bool isEnumeralType() const
Definition: TypeBase.h:8711
bool isScalarType() const
Definition: TypeBase.h:9038
bool isInterfaceType() const
Definition: Type.cpp:700
bool isVariableArrayType() const
Definition: TypeBase.h:8691
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
Definition: Type.cpp:2107
bool isExtVectorType() const
Definition: TypeBase.h:8723
bool isMemberDataPointerType() const
Definition: TypeBase.h:8672
bool isLValueReferenceType() const
Definition: TypeBase.h:8608
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: TypeBase.h:2800
bool isAggregateType() const
Determines whether the type is a C++ aggregate type or C aggregate or union type.
Definition: Type.cpp:2415
bool isAnyComplexType() const
Definition: TypeBase.h:8715
bool isCompoundType() const
Tests whether the type is categorized as a compound type.
Definition: TypeBase.h:8554
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
Definition: TypeBase.h:9109
bool isMemberPointerType() const
Definition: TypeBase.h:8661
bool isAtomicType() const
Definition: TypeBase.h:8762
bool isStandardLayoutType() const
Test if this type is a standard-layout type.
Definition: Type.cpp:3079
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
Definition: TypeBase.h:2818
bool isObjCLifetimeType() const
Returns true if objects of this type have lifetime semantics under ARC.
Definition: Type.cpp:5355
bool isObjectType() const
Determine whether this type is an object type.
Definition: TypeBase.h:2528
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
Definition: Type.cpp:2440
bool isFunctionType() const
Definition: TypeBase.h:8576
bool isStructureOrClassType() const
Definition: Type.cpp:706
bool isMemberFunctionPointerType() const
Definition: TypeBase.h:8665
bool isVectorType() const
Definition: TypeBase.h:8719
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition: TypeBase.h:2939
bool isFloatingType() const
Definition: Type.cpp:2308
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
Definition: Type.cpp:2257
bool isAnyPointerType() const
Definition: TypeBase.h:8588
bool isClassType() const
Definition: Type.cpp:672
const T * getAs() const
Member-template getAs<specific type>'.
Definition: TypeBase.h:9159
bool isRecordType() const
Definition: TypeBase.h:8707
bool isUnionType() const
Definition: Type.cpp:718
bool isScopedEnumeralType() const
Determine whether this type is a scoped enumeration type.
Definition: Type.cpp:735
The iterator over UnresolvedSets.
Definition: UnresolvedSet.h:35
A set of unresolved declarations.
QualType getType() const
Definition: Decl.h:722
Provides information about an attempted template argument deduction, whose success or failure was des...
Definition: SPIR.cpp:47
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Definition: TokenKinds.h:25
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:21
ArrayTypeTrait
Names for the array type traits.
Definition: TypeTraits.h:42
@ CPlusPlus
Definition: LangStandard.h:55
unsigned getTypeTraitArity(TypeTrait T) LLVM_READONLY
Return the arity of the type trait T.
Definition: TypeTraits.cpp:106
@ OR_Deleted
Succeeded, but refers to a deleted function.
Definition: Overload.h:61
@ OR_Success
Overload resolution succeeded.
Definition: Overload.h:52
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition: Specifiers.h:123
@ AS_public
Definition: Specifiers.h:124
@ AS_none
Definition: Specifiers.h:127
@ Dependent
Parse the block as a dependent block, which may be used in some template instantiations but not other...
@ Result
The result type of a method or function.
ExprResult ExprError()
Definition: Ownership.h:265
CXXSpecialMemberKind
Kinds of C++ special members.
Definition: Sema.h:424
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
Definition: Specifiers.h:132
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
Definition: Specifiers.h:135
@ VK_XValue
An x-value expression is a reference to an object with independent storage but which can be "moved",...
Definition: Specifiers.h:144
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Definition: Specifiers.h:139
const char * getTraitSpelling(ExpressionTrait T) LLVM_READONLY
Return the spelling of the type trait TT. Never null.
const FunctionProtoType * T
@ Success
Template argument deduction was successful.
ConstructorInfo getConstructorInfo(NamedDecl *ND)
Definition: Overload.h:1512
TypeTrait
Names for traits that operate specifically on types.
Definition: TypeTraits.h:21
@ BTT_Last
Definition: TypeTraits.h:30
@ UTT_Last
Definition: TypeTraits.h:24
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...