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