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 SourceLocation KeyLoc) {
509
510 EnterExpressionEvaluationContext UnevaluatedContext(
512 Sema::SFINAETrap SFINAE(S, /*WithAccessChecking=*/true);
514
515 // const ClassT& obj;
516 OpaqueValueExpr Operand(KeyLoc, T.withConst(), ExprValueKind::VK_LValue);
517 UnresolvedSet<16> Functions;
518 // obj == obj;
519 S.LookupBinOp(S.TUScope, {}, BinaryOperatorKind::BO_EQ, Functions);
520
521 ExprResult Result = S.CreateOverloadedBinOp(KeyLoc, BinaryOperatorKind::BO_EQ,
522 Functions, &Operand, &Operand);
523 if (Result.isInvalid() || SFINAE.hasErrorOccurred())
524 return false;
525
526 const auto *CallExpr = dyn_cast<CXXOperatorCallExpr>(Result.get());
527 if (!CallExpr)
528 return isa<EnumDecl>(Decl);
529 const auto *Callee = CallExpr->getDirectCallee();
530 auto ParamT = Callee->getParamDecl(0)->getType();
531 if (!Callee->isDefaulted())
532 return false;
533 if (!ParamT->isReferenceType()) {
534 const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Decl);
535 if (RD && !RD->isTriviallyCopyable())
536 return false;
537 }
538 return S.Context.hasSameUnqualifiedType(ParamT.getNonReferenceType(), T);
539}
540
542 const CXXRecordDecl *Decl,
543 SourceLocation KeyLoc) {
544 if (Decl->isUnion())
545 return false;
546 if (Decl->isLambda())
547 return Decl->isCapturelessLambda();
548
549 if (!equalityComparisonIsDefaulted(S, Decl, KeyLoc))
550 return false;
551
552 return llvm::all_of(Decl->bases(),
553 [&](const CXXBaseSpecifier &BS) {
554 if (const auto *RD = BS.getType()->getAsCXXRecordDecl())
555 return HasNonDeletedDefaultedEqualityComparison(
556 S, RD, KeyLoc);
557 return true;
558 }) &&
559 llvm::all_of(Decl->fields(), [&](const FieldDecl *FD) {
560 auto Type = FD->getType();
561 if (Type->isArrayType())
562 Type = Type->getBaseElementTypeUnsafe()
563 ->getCanonicalTypeUnqualified();
564
565 if (Type->isReferenceType())
566 return false;
567 if (Type->isEnumeralType()) {
568 EnumDecl *ED =
569 Type->castAs<EnumType>()->getDecl()->getDefinitionOrSelf();
570 return equalityComparisonIsDefaulted(S, ED, KeyLoc);
571 } else if (const auto *RD = Type->getAsCXXRecordDecl())
572 return HasNonDeletedDefaultedEqualityComparison(S, RD, KeyLoc);
573 return true;
574 });
575}
576
578 SourceLocation KeyLoc) {
579 QualType CanonicalType = Type.getCanonicalType();
580 if (CanonicalType->isIncompleteType() || CanonicalType->isDependentType() ||
581 CanonicalType->isArrayType())
582 return false;
583
584 if (CanonicalType->isEnumeralType()) {
585 EnumDecl *ED =
586 CanonicalType->castAs<EnumType>()->getDecl()->getDefinitionOrSelf();
587 return equalityComparisonIsDefaulted(S, ED, KeyLoc);
588 }
589
590 if (const auto *RD = CanonicalType->getAsCXXRecordDecl()) {
592 return false;
593 }
594
596 CanonicalType, /*CheckIfTriviallyCopyable=*/false);
597}
598
599static bool IsTriviallyRelocatableType(Sema &SemaRef, QualType T) {
600 QualType BaseElementType = SemaRef.getASTContext().getBaseElementType(T);
601
602 if (BaseElementType->isIncompleteType())
603 return false;
604 if (!BaseElementType->isObjectType())
605 return false;
606
607 // The deprecated __builtin_is_trivially_relocatable does not have
608 // an equivalent to __builtin_trivially_relocate, so there is no
609 // safe way to use it if there are any address discriminated values.
611 return false;
612
613 if (const auto *RD = BaseElementType->getAsCXXRecordDecl();
614 RD && !RD->isPolymorphic() && SemaRef.IsCXXTriviallyRelocatableType(*RD))
615 return true;
616
617 if (const auto *RD = BaseElementType->getAsRecordDecl())
618 return RD->canPassInRegisters();
619
620 if (BaseElementType.isTriviallyCopyableType(SemaRef.getASTContext()))
621 return true;
622
623 switch (T.isNonTrivialToPrimitiveDestructiveMove()) {
625 return !T.isDestructedType();
627 return true;
628 default:
629 return false;
630 }
631}
632
634 SourceLocation KeyLoc,
635 TypeSourceInfo *TInfo) {
636 QualType T = TInfo->getType();
637 assert(!T->isDependentType() && "Cannot evaluate traits of dependent type");
638
639 ASTContext &C = Self.Context;
640 switch (UTT) {
641 default:
642 llvm_unreachable("not a UTT");
643 // Type trait expressions corresponding to the primary type category
644 // predicates in C++0x [meta.unary.cat].
645 case UTT_IsVoid:
646 return T->isVoidType();
647 case UTT_IsIntegral:
648 return T->isIntegralType(C);
649 case UTT_IsFloatingPoint:
650 return T->isFloatingType();
651 case UTT_IsArray:
652 // Zero-sized arrays aren't considered arrays in partial specializations,
653 // so __is_array shouldn't consider them arrays either.
654 if (const auto *CAT = C.getAsConstantArrayType(T))
655 return CAT->getSize() != 0;
656 return T->isArrayType();
657 case UTT_IsBoundedArray:
658 if (DiagnoseVLAInCXXTypeTrait(Self, TInfo, tok::kw___is_bounded_array))
659 return false;
660 // Zero-sized arrays aren't considered arrays in partial specializations,
661 // so __is_bounded_array shouldn't consider them arrays either.
662 if (const auto *CAT = C.getAsConstantArrayType(T))
663 return CAT->getSize() != 0;
664 return T->isArrayType() && !T->isIncompleteArrayType();
665 case UTT_IsUnboundedArray:
666 if (DiagnoseVLAInCXXTypeTrait(Self, TInfo, tok::kw___is_unbounded_array))
667 return false;
668 return T->isIncompleteArrayType();
669 case UTT_IsPointer:
670 return T->isAnyPointerType();
671 case UTT_IsLvalueReference:
672 return T->isLValueReferenceType();
673 case UTT_IsRvalueReference:
674 return T->isRValueReferenceType();
675 case UTT_IsMemberFunctionPointer:
676 return T->isMemberFunctionPointerType();
677 case UTT_IsMemberObjectPointer:
678 return T->isMemberDataPointerType();
679 case UTT_IsEnum:
680 return T->isEnumeralType();
681 case UTT_IsScopedEnum:
682 return T->isScopedEnumeralType();
683 case UTT_IsUnion:
684 return T->isUnionType();
685 case UTT_IsClass:
686 return T->isClassType() || T->isStructureType() || T->isInterfaceType();
687 case UTT_IsFunction:
688 return T->isFunctionType();
689
690 // Type trait expressions which correspond to the convenient composition
691 // predicates in C++0x [meta.unary.comp].
692 case UTT_IsReference:
693 return T->isReferenceType();
694 case UTT_IsArithmetic:
695 return T->isArithmeticType() && !T->isEnumeralType();
696 case UTT_IsFundamental:
697 return T->isFundamentalType();
698 case UTT_IsObject:
699 return T->isObjectType();
700 case UTT_IsScalar:
701 // Note: semantic analysis depends on Objective-C lifetime types to be
702 // considered scalar types. However, such types do not actually behave
703 // like scalar types at run time (since they may require retain/release
704 // operations), so we report them as non-scalar.
705 if (T->isObjCLifetimeType()) {
706 switch (T.getObjCLifetime()) {
709 return true;
710
714 return false;
715 }
716 }
717
718 return T->isScalarType();
719 case UTT_IsCompound:
720 return T->isCompoundType();
721 case UTT_IsMemberPointer:
722 return T->isMemberPointerType();
723
724 // Type trait expressions which correspond to the type property predicates
725 // in C++0x [meta.unary.prop].
726 case UTT_IsConst:
727 return T.isConstQualified();
728 case UTT_IsVolatile:
729 return T.isVolatileQualified();
730 case UTT_IsTrivial:
731 return T.isTrivialType(C);
732 case UTT_IsTriviallyCopyable:
733 return T.isTriviallyCopyableType(C);
734 case UTT_IsStandardLayout:
735 return T->isStandardLayoutType();
736 case UTT_IsPOD:
737 return T.isPODType(C);
738 case UTT_IsLiteral:
739 return T->isLiteralType(C);
740 case UTT_IsEmpty:
741 if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
742 return !RD->isUnion() && RD->isEmpty();
743 return false;
744 case UTT_IsPolymorphic:
745 if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
746 return !RD->isUnion() && RD->isPolymorphic();
747 return false;
748 case UTT_IsAbstract:
749 if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
750 return !RD->isUnion() && RD->isAbstract();
751 return false;
752 case UTT_IsAggregate:
753 // Report vector extensions and complex types as aggregates because they
754 // support aggregate initialization. GCC mirrors this behavior for vectors
755 // but not _Complex.
756 return T->isAggregateType() || T->isVectorType() || T->isExtVectorType() ||
757 T->isAnyComplexType();
758 // __is_interface_class only returns true when CL is invoked in /CLR mode and
759 // even then only when it is used with the 'interface struct ...' syntax
760 // Clang doesn't support /CLR which makes this type trait moot.
761 case UTT_IsInterfaceClass:
762 return false;
763 case UTT_IsFinal:
764 case UTT_IsSealed:
765 if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
766 return RD->hasAttr<FinalAttr>();
767 return false;
768 case UTT_IsSigned:
769 // Enum types should always return false.
770 // Floating points should always return true.
771 return T->isFloatingType() ||
772 (T->isSignedIntegerType() && !T->isEnumeralType());
773 case UTT_IsUnsigned:
774 // Enum types should always return false.
775 return T->isUnsignedIntegerType() && !T->isEnumeralType();
776
777 // Type trait expressions which query classes regarding their construction,
778 // destruction, and copying. Rather than being based directly on the
779 // related type predicates in the standard, they are specified by both
780 // GCC[1] and the Embarcadero C++ compiler[2], and Clang implements those
781 // specifications.
782 //
783 // 1: http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
784 // 2:
785 // http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index
786 //
787 // Note that these builtins do not behave as documented in g++: if a class
788 // has both a trivial and a non-trivial special member of a particular kind,
789 // they return false! For now, we emulate this behavior.
790 // FIXME: This appears to be a g++ bug: more complex cases reveal that it
791 // does not correctly compute triviality in the presence of multiple special
792 // members of the same kind. Revisit this once the g++ bug is fixed.
793 case UTT_HasTrivialDefaultConstructor:
794 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
795 // If __is_pod (type) is true then the trait is true, else if type is
796 // a cv class or union type (or array thereof) with a trivial default
797 // constructor ([class.ctor]) then the trait is true, else it is false.
798 if (T.isPODType(C))
799 return true;
800 if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
801 return RD->hasTrivialDefaultConstructor() &&
803 return false;
804 case UTT_HasTrivialMoveConstructor:
805 // This trait is implemented by MSVC 2012 and needed to parse the
806 // standard library headers. Specifically this is used as the logic
807 // behind std::is_trivially_move_constructible (20.9.4.3).
808 if (T.isPODType(C))
809 return true;
810 if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
811 return RD->hasTrivialMoveConstructor() &&
813 return false;
814 case UTT_HasTrivialCopy:
815 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
816 // If __is_pod (type) is true or type is a reference type then
817 // the trait is true, else if type is a cv class or union type
818 // with a trivial copy constructor ([class.copy]) then the trait
819 // is true, else it is false.
820 if (T.isPODType(C) || T->isReferenceType())
821 return true;
822 if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
823 return RD->hasTrivialCopyConstructor() &&
825 return false;
826 case UTT_HasTrivialMoveAssign:
827 // This trait is implemented by MSVC 2012 and needed to parse the
828 // standard library headers. Specifically it is used as the logic
829 // behind std::is_trivially_move_assignable (20.9.4.3)
830 if (T.isPODType(C))
831 return true;
832 if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
833 return RD->hasTrivialMoveAssignment() &&
835 return false;
836 case UTT_HasTrivialAssign:
837 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
838 // If type is const qualified or is a reference type then the
839 // trait is false. Otherwise if __is_pod (type) is true then the
840 // trait is true, else if type is a cv class or union type with
841 // a trivial copy assignment ([class.copy]) then the trait is
842 // true, else it is false.
843 // Note: the const and reference restrictions are interesting,
844 // given that const and reference members don't prevent a class
845 // from having a trivial copy assignment operator (but do cause
846 // errors if the copy assignment operator is actually used, q.v.
847 // [class.copy]p12).
848
849 if (T.isConstQualified())
850 return false;
851 if (T.isPODType(C))
852 return true;
853 if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
854 return RD->hasTrivialCopyAssignment() &&
856 return false;
857 case UTT_IsDestructible:
858 case UTT_IsTriviallyDestructible:
859 case UTT_IsNothrowDestructible:
860 // C++14 [meta.unary.prop]:
861 // For reference types, is_destructible<T>::value is true.
862 if (T->isReferenceType())
863 return true;
864
865 // Objective-C++ ARC: autorelease types don't require destruction.
866 if (T->isObjCLifetimeType() &&
867 T.getObjCLifetime() == Qualifiers::OCL_Autoreleasing)
868 return true;
869
870 // C++14 [meta.unary.prop]:
871 // For incomplete types and function types, is_destructible<T>::value is
872 // false.
873 if (T->isIncompleteType() || T->isFunctionType())
874 return false;
875
876 // A type that requires destruction (via a non-trivial destructor or ARC
877 // lifetime semantics) is not trivially-destructible.
878 if (UTT == UTT_IsTriviallyDestructible && T.isDestructedType())
879 return false;
880
881 // C++14 [meta.unary.prop]:
882 // For object types and given U equal to remove_all_extents_t<T>, if the
883 // expression std::declval<U&>().~U() is well-formed when treated as an
884 // unevaluated operand (Clause 5), then is_destructible<T>::value is true
885 if (auto *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) {
886 CXXDestructorDecl *Destructor = Self.LookupDestructor(RD);
887 if (!Destructor)
888 return false;
889 // C++14 [dcl.fct.def.delete]p2:
890 // A program that refers to a deleted function implicitly or
891 // explicitly, other than to declare it, is ill-formed.
892 if (Destructor->isDeleted())
893 return false;
894 if (C.getLangOpts().AccessControl && Destructor->getAccess() != AS_public)
895 return false;
896 if (UTT == UTT_IsNothrowDestructible) {
897 auto *CPT = Destructor->getType()->castAs<FunctionProtoType>();
898 CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
899 if (!CPT || !CPT->isNothrow())
900 return false;
901 }
902 }
903 return true;
904
905 case UTT_HasTrivialDestructor:
906 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
907 // If __is_pod (type) is true or type is a reference type
908 // then the trait is true, else if type is a cv class or union
909 // type (or array thereof) with a trivial destructor
910 // ([class.dtor]) then the trait is true, else it is
911 // false.
912 if (T.isPODType(C) || T->isReferenceType())
913 return true;
914
915 // Objective-C++ ARC: autorelease types don't require destruction.
916 if (T->isObjCLifetimeType() &&
917 T.getObjCLifetime() == Qualifiers::OCL_Autoreleasing)
918 return true;
919
920 if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
921 return RD->hasTrivialDestructor();
922 return false;
923 // TODO: Propagate nothrowness for implicitly declared special members.
924 case UTT_HasNothrowAssign:
925 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
926 // If type is const qualified or is a reference type then the
927 // trait is false. Otherwise if __has_trivial_assign (type)
928 // is true then the trait is true, else if type is a cv class
929 // or union type with copy assignment operators that are known
930 // not to throw an exception then the trait is true, else it is
931 // false.
932 if (C.getBaseElementType(T).isConstQualified())
933 return false;
934 if (T->isReferenceType())
935 return false;
936 if (T.isPODType(C) || T->isObjCLifetimeType())
937 return true;
938
939 if (auto *RD = T->getAsCXXRecordDecl())
940 return HasNoThrowOperator(RD, OO_Equal, Self, KeyLoc, C,
944 return false;
945 case UTT_HasNothrowMoveAssign:
946 // This trait is implemented by MSVC 2012 and needed to parse the
947 // standard library headers. Specifically this is used as the logic
948 // behind std::is_nothrow_move_assignable (20.9.4.3).
949 if (T.isPODType(C))
950 return true;
951
952 if (auto *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
953 return HasNoThrowOperator(RD, OO_Equal, Self, KeyLoc, C,
957 return false;
958 case UTT_HasNothrowCopy:
959 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
960 // If __has_trivial_copy (type) is true then the trait is true, else
961 // if type is a cv class or union type with copy constructors that are
962 // known not to throw an exception then the trait is true, else it is
963 // false.
964 if (T.isPODType(C) || T->isReferenceType() || T->isObjCLifetimeType())
965 return true;
966 if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) {
967 if (RD->hasTrivialCopyConstructor() &&
969 return true;
970
971 bool FoundConstructor = false;
972 unsigned FoundTQs;
973 for (const auto *ND : Self.LookupConstructors(RD)) {
974 // A template constructor is never a copy constructor.
975 // FIXME: However, it may actually be selected at the actual overload
976 // resolution point.
977 if (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl()))
978 continue;
979 // UsingDecl itself is not a constructor
980 if (isa<UsingDecl>(ND))
981 continue;
982 auto *Constructor = cast<CXXConstructorDecl>(ND->getUnderlyingDecl());
983 if (Constructor->isCopyConstructor(FoundTQs)) {
984 FoundConstructor = true;
985 auto *CPT = Constructor->getType()->castAs<FunctionProtoType>();
986 CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
987 if (!CPT)
988 return false;
989 // TODO: check whether evaluating default arguments can throw.
990 // For now, we'll be conservative and assume that they can throw.
991 if (!CPT->isNothrow() || CPT->getNumParams() > 1)
992 return false;
993 }
994 }
995
996 return FoundConstructor;
997 }
998 return false;
999 case UTT_HasNothrowConstructor:
1000 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
1001 // If __has_trivial_constructor (type) is true then the trait is
1002 // true, else if type is a cv class or union type (or array
1003 // thereof) with a default constructor that is known not to
1004 // throw an exception then the trait is true, else it is false.
1005 if (T.isPODType(C) || T->isObjCLifetimeType())
1006 return true;
1007 if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) {
1009 return true;
1010
1011 bool FoundConstructor = false;
1012 for (const auto *ND : Self.LookupConstructors(RD)) {
1013 // FIXME: In C++0x, a constructor template can be a default constructor.
1014 if (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl()))
1015 continue;
1016 // UsingDecl itself is not a constructor
1017 if (isa<UsingDecl>(ND))
1018 continue;
1019 auto *Constructor = cast<CXXConstructorDecl>(ND->getUnderlyingDecl());
1020 if (Constructor->isDefaultConstructor()) {
1021 FoundConstructor = true;
1022 auto *CPT = Constructor->getType()->castAs<FunctionProtoType>();
1023 CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
1024 if (!CPT)
1025 return false;
1026 // FIXME: check whether evaluating default arguments can throw.
1027 // For now, we'll be conservative and assume that they can throw.
1028 if (!CPT->isNothrow() || CPT->getNumParams() > 0)
1029 return false;
1030 }
1031 }
1032 return FoundConstructor;
1033 }
1034 return false;
1035 case UTT_HasVirtualDestructor:
1036 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
1037 // If type is a class type with a virtual destructor ([class.dtor])
1038 // then the trait is true, else it is false.
1039 if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
1040 if (CXXDestructorDecl *Destructor = Self.LookupDestructor(RD))
1041 return Destructor->isVirtual();
1042 return false;
1043
1044 // These type trait expressions are modeled on the specifications for the
1045 // Embarcadero C++0x type trait functions:
1046 // http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index
1047 case UTT_IsCompleteType:
1048 // http://docwiki.embarcadero.com/RADStudio/XE/en/Is_complete_type_(typename_T_):
1049 // Returns True if and only if T is a complete type at the point of the
1050 // function call.
1051 return !T->isIncompleteType();
1052 case UTT_HasUniqueObjectRepresentations:
1053 return C.hasUniqueObjectRepresentations(T);
1054 case UTT_IsTriviallyRelocatable:
1056 case UTT_IsBitwiseCloneable:
1057 return T.isBitwiseCloneableType(C);
1058 case UTT_IsCppTriviallyRelocatable:
1059 return Self.IsCXXTriviallyRelocatableType(T);
1060 case UTT_CanPassInRegs:
1061 if (CXXRecordDecl *RD = T->getAsCXXRecordDecl(); RD && !T.hasQualifiers())
1062 return RD->canPassInRegisters();
1063 Self.Diag(KeyLoc, diag::err_builtin_pass_in_regs_non_class) << T;
1064 return false;
1065 case UTT_IsTriviallyEqualityComparable:
1066 return isTriviallyEqualityComparableType(Self, T, KeyLoc);
1067 case UTT_IsImplicitLifetime: {
1069 tok::kw___builtin_is_implicit_lifetime);
1071 tok::kw___builtin_is_implicit_lifetime);
1072
1073 // [basic.types.general] p9
1074 // Scalar types, implicit-lifetime class types ([class.prop]),
1075 // array types, and cv-qualified versions of these types
1076 // are collectively called implicit-lifetime types.
1078 if (UnqualT->isScalarType())
1079 return true;
1080 if (UnqualT->isArrayType() || UnqualT->isVectorType())
1081 return true;
1082 const CXXRecordDecl *RD = UnqualT->getAsCXXRecordDecl();
1083 if (!RD)
1084 return false;
1085
1086 // [class.prop] p9
1087 // A class S is an implicit-lifetime class if
1088 // - it is an aggregate whose destructor is not user-provided or
1089 // - it has at least one trivial eligible constructor and a trivial,
1090 // non-deleted destructor.
1091 const CXXDestructorDecl *Dtor = RD->getDestructor();
1092 if (UnqualT->isAggregateType() && (!Dtor || !Dtor->isUserProvided()))
1093 return true;
1094 bool HasTrivialNonDeletedDtr =
1095 RD->hasTrivialDestructor() && (!Dtor || !Dtor->isDeleted());
1096 if (!HasTrivialNonDeletedDtr)
1097 return false;
1098 for (CXXConstructorDecl *Ctr : RD->ctors()) {
1099 if (Ctr->isIneligibleOrNotSelected() || Ctr->isDeleted())
1100 continue;
1101 if (Ctr->isTrivial())
1102 return true;
1103 }
1107 return true;
1110 return true;
1113 return true;
1114 return false;
1115 }
1116 case UTT_IsIntangibleType:
1117 assert(Self.getLangOpts().HLSL && "intangible types are HLSL-only feature");
1118 if (!T->isVoidType() && !T->isIncompleteArrayType())
1119 if (Self.RequireCompleteType(TInfo->getTypeLoc().getBeginLoc(), T,
1120 diag::err_incomplete_type))
1121 return false;
1123 tok::kw___builtin_hlsl_is_intangible))
1124 return false;
1125 return T->isHLSLIntangibleType();
1126
1127 case UTT_IsTypedResourceElementCompatible:
1128 assert(Self.getLangOpts().HLSL &&
1129 "typed resource element compatible types are an HLSL-only feature");
1130 if (T->isIncompleteType())
1131 return false;
1132
1133 return Self.HLSL().IsTypedResourceElementCompatible(T);
1134 }
1135}
1136
1137static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT,
1138 const TypeSourceInfo *Lhs,
1139 const TypeSourceInfo *Rhs,
1140 SourceLocation KeyLoc);
1141
1143 Sema &Self, const TypeSourceInfo *Lhs, const TypeSourceInfo *Rhs,
1144 SourceLocation KeyLoc, llvm::BumpPtrAllocator &OpaqueExprAllocator) {
1145
1146 QualType LhsT = Lhs->getType();
1147 QualType RhsT = Rhs->getType();
1148
1149 // C++0x [meta.rel]p4:
1150 // Given the following function prototype:
1151 //
1152 // template <class T>
1153 // typename add_rvalue_reference<T>::type create();
1154 //
1155 // the predicate condition for a template specialization
1156 // is_convertible<From, To> shall be satisfied if and only if
1157 // the return expression in the following code would be
1158 // well-formed, including any implicit conversions to the return
1159 // type of the function:
1160 //
1161 // To test() {
1162 // return create<From>();
1163 // }
1164 //
1165 // Access checking is performed as if in a context unrelated to To and
1166 // From. Only the validity of the immediate context of the expression
1167 // of the return-statement (including conversions to the return type)
1168 // is considered.
1169 //
1170 // We model the initialization as a copy-initialization of a temporary
1171 // of the appropriate type, which for this expression is identical to the
1172 // return statement (since NRVO doesn't apply).
1173
1174 // Functions aren't allowed to return function or array types.
1175 if (RhsT->isFunctionType() || RhsT->isArrayType())
1176 return ExprError();
1177
1178 // A function definition requires a complete, non-abstract return type.
1179 if (!Self.isCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT) ||
1180 Self.isAbstractType(Rhs->getTypeLoc().getBeginLoc(), RhsT))
1181 return ExprError();
1182
1183 // Compute the result of add_rvalue_reference.
1184 if (LhsT->isObjectType() || LhsT->isFunctionType())
1185 LhsT = Self.Context.getRValueReferenceType(LhsT);
1186
1187 // Build a fake source and destination for initialization.
1189 Expr *From = new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
1190 OpaqueValueExpr(KeyLoc, LhsT.getNonLValueExprType(Self.Context),
1192 InitializationKind Kind =
1194
1195 // Perform the initialization in an unevaluated context within a SFINAE
1196 // trap at translation unit scope.
1199 Sema::SFINAETrap SFINAE(Self, /*ForValidityCheck=*/true);
1200 Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
1201 InitializationSequence Init(Self, To, Kind, From);
1202 if (Init.Failed())
1203 return ExprError();
1204
1205 ExprResult Result = Init.Perform(Self, To, Kind, From);
1206 if (Result.isInvalid() || SFINAE.hasErrorOccurred())
1207 return ExprError();
1208
1209 return Result;
1210}
1211
1213 SourceLocation KWLoc,
1215 SourceLocation RParenLoc,
1216 bool IsDependent) {
1217 if (IsDependent)
1218 return APValue();
1219
1220 switch (Kind) {
1221 case TypeTrait::UTT_StructuredBindingSize: {
1222 QualType T = Args[0]->getType();
1223 SourceRange ArgRange = Args[0]->getTypeLoc().getSourceRange();
1224 UnsignedOrNone Size =
1225 S.GetDecompositionElementCount(T, ArgRange.getBegin());
1226 if (!Size) {
1227 S.Diag(KWLoc, diag::err_arg_is_not_destructurable) << T << ArgRange;
1228 return APValue();
1229 }
1230 return APValue(
1232 break;
1233 }
1234 default:
1235 llvm_unreachable("Not a SizeT type trait");
1236 }
1237}
1238
1240 SourceLocation KWLoc,
1242 SourceLocation RParenLoc,
1243 bool IsDependent) {
1244 if (IsDependent)
1245 return false;
1246
1247 if (Kind <= UTT_Last)
1248 return EvaluateUnaryTypeTrait(S, Kind, KWLoc, Args[0]);
1249
1250 // Evaluate ReferenceBindsToTemporary and ReferenceConstructsFromTemporary
1251 // alongside the IsConstructible traits to avoid duplication.
1252 if (Kind <= BTT_Last && Kind != BTT_ReferenceBindsToTemporary &&
1253 Kind != BTT_ReferenceConstructsFromTemporary &&
1254 Kind != BTT_ReferenceConvertsFromTemporary)
1255 return EvaluateBinaryTypeTrait(S, Kind, Args[0], Args[1], RParenLoc);
1256
1257 switch (Kind) {
1258 case clang::BTT_ReferenceBindsToTemporary:
1259 case clang::BTT_ReferenceConstructsFromTemporary:
1260 case clang::BTT_ReferenceConvertsFromTemporary:
1261 case clang::TT_IsConstructible:
1262 case clang::TT_IsNothrowConstructible:
1263 case clang::TT_IsTriviallyConstructible: {
1264 // C++11 [meta.unary.prop]:
1265 // is_trivially_constructible is defined as:
1266 //
1267 // is_constructible<T, Args...>::value is true and the variable
1268 // definition for is_constructible, as defined below, is known to call
1269 // no operation that is not trivial.
1270 //
1271 // The predicate condition for a template specialization
1272 // is_constructible<T, Args...> shall be satisfied if and only if the
1273 // following variable definition would be well-formed for some invented
1274 // variable t:
1275 //
1276 // T t(create<Args>()...);
1277 assert(!Args.empty());
1278
1279 // Precondition: T and all types in the parameter pack Args shall be
1280 // complete types, (possibly cv-qualified) void, or arrays of
1281 // unknown bound.
1282 for (const auto *TSI : Args) {
1283 QualType ArgTy = TSI->getType();
1284 if (ArgTy->isVoidType() || ArgTy->isIncompleteArrayType())
1285 continue;
1286
1287 if (S.RequireCompleteType(
1288 KWLoc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr))
1289 return false;
1290 }
1291
1292 // Make sure the first argument is not incomplete nor a function type.
1293 QualType T = Args[0]->getType();
1294 if (T->isIncompleteType() || T->isFunctionType())
1295 return false;
1296
1297 // Make sure the first argument is not an abstract type.
1298 CXXRecordDecl *RD = T->getAsCXXRecordDecl();
1299 if (RD && RD->isAbstract())
1300 return false;
1301
1302 // LWG3819: For reference_meows_from_temporary traits, && is not added to
1303 // the source object type.
1304 // Otherwise, compute the result of add_rvalue_reference_t.
1305 bool UseRawObjectType =
1306 Kind == clang::BTT_ReferenceBindsToTemporary ||
1307 Kind == clang::BTT_ReferenceConstructsFromTemporary ||
1308 Kind == clang::BTT_ReferenceConvertsFromTemporary;
1309
1310 llvm::BumpPtrAllocator OpaqueExprAllocator;
1311 SmallVector<Expr *, 2> ArgExprs;
1312 ArgExprs.reserve(Args.size() - 1);
1313 for (unsigned I = 1, N = Args.size(); I != N; ++I) {
1314 QualType ArgTy = Args[I]->getType();
1315 if ((ArgTy->isObjectType() && !UseRawObjectType) ||
1316 ArgTy->isFunctionType())
1317 ArgTy = S.Context.getRValueReferenceType(ArgTy);
1318 ArgExprs.push_back(
1319 new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
1320 OpaqueValueExpr(Args[I]->getTypeLoc().getBeginLoc(),
1323 }
1324
1325 // Perform the initialization in an unevaluated context within a SFINAE
1326 // trap at translation unit scope.
1329 Sema::SFINAETrap SFINAE(S, /*ForValidityCheck=*/true);
1333 InitializationKind InitKind(
1334 Kind == clang::BTT_ReferenceConvertsFromTemporary
1335 ? InitializationKind::CreateCopy(KWLoc, KWLoc)
1336 : InitializationKind::CreateDirect(KWLoc, KWLoc, RParenLoc));
1337 InitializationSequence Init(S, To, InitKind, ArgExprs);
1338 if (Init.Failed())
1339 return false;
1340
1341 ExprResult Result = Init.Perform(S, To, InitKind, ArgExprs);
1342 if (Result.isInvalid() || SFINAE.hasErrorOccurred())
1343 return false;
1344
1345 if (Kind == clang::TT_IsConstructible)
1346 return true;
1347
1348 if (Kind == clang::BTT_ReferenceBindsToTemporary ||
1349 Kind == clang::BTT_ReferenceConstructsFromTemporary ||
1350 Kind == clang::BTT_ReferenceConvertsFromTemporary) {
1351 if (!T->isReferenceType())
1352 return false;
1353
1354 // A function reference never binds to a temporary object.
1355 if (T.getNonReferenceType()->isFunctionType())
1356 return false;
1357
1358 if (!Init.isDirectReferenceBinding())
1359 return true;
1360
1361 if (Kind == clang::BTT_ReferenceBindsToTemporary)
1362 return false;
1363
1364 QualType U = Args[1]->getType();
1365 if (U->isReferenceType())
1366 return false;
1367
1369 S.Context.getPointerType(T.getNonReferenceType()));
1371 S.Context.getPointerType(U.getNonReferenceType()));
1372 return !CheckConvertibilityForTypeTraits(S, UPtr, TPtr, RParenLoc,
1373 OpaqueExprAllocator)
1374 .isInvalid();
1375 }
1376
1377 if (Kind == clang::TT_IsNothrowConstructible)
1378 return S.canThrow(Result.get()) == CT_Cannot;
1379
1380 if (Kind == clang::TT_IsTriviallyConstructible) {
1381 // Under Objective-C ARC and Weak, if the destination has non-trivial
1382 // Objective-C lifetime, this is a non-trivial construction.
1383 if (T.getNonReferenceType().hasNonTrivialObjCLifetime())
1384 return false;
1385
1386 // The initialization succeeded; now make sure there are no non-trivial
1387 // calls.
1388 return !Result.get()->hasNonTrivialCall(S.Context);
1389 }
1390
1391 llvm_unreachable("unhandled type trait");
1392 return false;
1393 }
1394 default:
1395 llvm_unreachable("not a TT");
1396 }
1397
1398 return false;
1399}
1400
1401namespace {
1402void DiagnoseBuiltinDeprecation(Sema &S, TypeTrait Kind, SourceLocation KWLoc) {
1403 TypeTrait Replacement;
1404 switch (Kind) {
1405 case UTT_HasNothrowAssign:
1406 case UTT_HasNothrowMoveAssign:
1407 Replacement = BTT_IsNothrowAssignable;
1408 break;
1409 case UTT_HasNothrowCopy:
1410 case UTT_HasNothrowConstructor:
1411 Replacement = TT_IsNothrowConstructible;
1412 break;
1413 case UTT_HasTrivialAssign:
1414 case UTT_HasTrivialMoveAssign:
1415 Replacement = BTT_IsTriviallyAssignable;
1416 break;
1417 case UTT_HasTrivialCopy:
1418 Replacement = UTT_IsTriviallyCopyable;
1419 break;
1420 case UTT_HasTrivialDefaultConstructor:
1421 case UTT_HasTrivialMoveConstructor:
1422 Replacement = TT_IsTriviallyConstructible;
1423 break;
1424 case UTT_HasTrivialDestructor:
1425 Replacement = UTT_IsTriviallyDestructible;
1426 break;
1427 case UTT_IsTriviallyRelocatable:
1428 Replacement = clang::UTT_IsCppTriviallyRelocatable;
1429 break;
1430 case BTT_ReferenceBindsToTemporary:
1431 Replacement = clang::BTT_ReferenceConstructsFromTemporary;
1432 break;
1433 default:
1434 return;
1435 }
1436 S.Diag(KWLoc, diag::warn_deprecated_builtin)
1437 << getTraitSpelling(Kind) << getTraitSpelling(Replacement);
1438}
1439} // namespace
1440
1441bool Sema::CheckTypeTraitArity(unsigned Arity, SourceLocation Loc, size_t N) {
1442 if (Arity && N != Arity) {
1443 Diag(Loc, diag::err_type_trait_arity)
1444 << Arity << 0 << (Arity > 1) << (int)N << SourceRange(Loc);
1445 return false;
1446 }
1447
1448 if (!Arity && N == 0) {
1449 Diag(Loc, diag::err_type_trait_arity)
1450 << 1 << 1 << 1 << (int)N << SourceRange(Loc);
1451 return false;
1452 }
1453 return true;
1454}
1455
1460
1462 if (Kind == TypeTrait::UTT_StructuredBindingSize)
1465}
1466
1469 SourceLocation RParenLoc) {
1470 if (!CheckTypeTraitArity(getTypeTraitArity(Kind), KWLoc, Args.size()))
1471 return ExprError();
1472
1474 *this, Kind, KWLoc, Args[0]->getType()))
1475 return ExprError();
1476
1477 DiagnoseBuiltinDeprecation(*this, Kind, KWLoc);
1478
1479 bool Dependent = false;
1480 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
1481 if (Args[I]->getType()->isDependentType()) {
1482 Dependent = true;
1483 break;
1484 }
1485 }
1486
1487 switch (GetReturnType(Kind)) {
1489 bool Result = EvaluateBooleanTypeTrait(*this, Kind, KWLoc, Args, RParenLoc,
1490 Dependent);
1491 return TypeTraitExpr::Create(Context, Context.getLogicalOperationType(),
1492 KWLoc, Kind, Args, RParenLoc, Result);
1493 }
1495 APValue Result =
1496 EvaluateSizeTTypeTrait(*this, Kind, KWLoc, Args, RParenLoc, Dependent);
1497 return TypeTraitExpr::Create(Context, Context.getSizeType(), KWLoc, Kind,
1498 Args, RParenLoc, Result);
1499 }
1500 }
1501 llvm_unreachable("unhandled type trait return type");
1502}
1503
1506 SourceLocation RParenLoc) {
1508 ConvertedArgs.reserve(Args.size());
1509
1510 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
1511 TypeSourceInfo *TInfo;
1512 QualType T = GetTypeFromParser(Args[I], &TInfo);
1513 if (!TInfo)
1514 TInfo = Context.getTrivialTypeSourceInfo(T, KWLoc);
1515
1516 ConvertedArgs.push_back(TInfo);
1517 }
1518
1519 return BuildTypeTrait(Kind, KWLoc, ConvertedArgs, RParenLoc);
1520}
1521
1523 QualType RhsT) {
1524 // C++0x [meta.rel]p2
1525 // Base is a base class of Derived without regard to cv-qualifiers or
1526 // Base and Derived are not unions and name the same class type without
1527 // regard to cv-qualifiers.
1528
1529 const RecordType *lhsRecord = LhsT->getAsCanonical<RecordType>();
1530 const RecordType *rhsRecord = RhsT->getAsCanonical<RecordType>();
1531 if (!rhsRecord || !lhsRecord) {
1532 const ObjCObjectType *LHSObjTy = LhsT->getAs<ObjCObjectType>();
1533 const ObjCObjectType *RHSObjTy = RhsT->getAs<ObjCObjectType>();
1534 if (!LHSObjTy || !RHSObjTy)
1535 return false;
1536
1537 ObjCInterfaceDecl *BaseInterface = LHSObjTy->getInterface();
1538 ObjCInterfaceDecl *DerivedInterface = RHSObjTy->getInterface();
1539 if (!BaseInterface || !DerivedInterface)
1540 return false;
1541
1542 if (RequireCompleteType(RhsTLoc, RhsT,
1543 diag::err_incomplete_type_used_in_type_trait_expr))
1544 return false;
1545
1546 return BaseInterface->isSuperClassOf(DerivedInterface);
1547 }
1548
1549 assert(Context.hasSameUnqualifiedType(LhsT, RhsT) ==
1550 (lhsRecord == rhsRecord));
1551
1552 // Unions are never base classes, and never have base classes.
1553 // It doesn't matter if they are complete or not. See PR#41843
1554 if (lhsRecord && lhsRecord->getDecl()->isUnion())
1555 return false;
1556 if (rhsRecord && rhsRecord->getDecl()->isUnion())
1557 return false;
1558
1559 if (lhsRecord == rhsRecord)
1560 return true;
1561
1562 // C++0x [meta.rel]p2:
1563 // If Base and Derived are class types and are different types
1564 // (ignoring possible cv-qualifiers) then Derived shall be a
1565 // complete type.
1566 if (RequireCompleteType(RhsTLoc, RhsT,
1567 diag::err_incomplete_type_used_in_type_trait_expr))
1568 return false;
1569
1570 return cast<CXXRecordDecl>(rhsRecord->getDecl())
1571 ->isDerivedFrom(cast<CXXRecordDecl>(lhsRecord->getDecl()));
1572}
1573
1575 const TypeSourceInfo *Lhs,
1576 const TypeSourceInfo *Rhs,
1577 SourceLocation KeyLoc) {
1578 QualType LhsT = Lhs->getType();
1579 QualType RhsT = Rhs->getType();
1580
1581 assert(!LhsT->isDependentType() && !RhsT->isDependentType() &&
1582 "Cannot evaluate traits of dependent types");
1583
1584 switch (BTT) {
1585 case BTT_IsBaseOf:
1586 return Self.BuiltinIsBaseOf(Rhs->getTypeLoc().getBeginLoc(), LhsT, RhsT);
1587
1588 case BTT_IsVirtualBaseOf: {
1589 const RecordType *BaseRecord = LhsT->getAsCanonical<RecordType>();
1590 const RecordType *DerivedRecord = RhsT->getAsCanonical<RecordType>();
1591
1592 if (!BaseRecord || !DerivedRecord) {
1594 tok::kw___builtin_is_virtual_base_of);
1596 tok::kw___builtin_is_virtual_base_of);
1597 return false;
1598 }
1599
1600 if (BaseRecord->isUnionType() || DerivedRecord->isUnionType())
1601 return false;
1602
1603 if (!BaseRecord->isStructureOrClassType() ||
1604 !DerivedRecord->isStructureOrClassType())
1605 return false;
1606
1607 if (Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1608 diag::err_incomplete_type))
1609 return false;
1610
1611 return cast<CXXRecordDecl>(DerivedRecord->getDecl())
1612 ->isVirtuallyDerivedFrom(cast<CXXRecordDecl>(BaseRecord->getDecl()));
1613 }
1614 case BTT_IsSame:
1615 return Self.Context.hasSameType(LhsT, RhsT);
1616 case BTT_TypeCompatible: {
1617 // GCC ignores cv-qualifiers on arrays for this builtin.
1618 Qualifiers LhsQuals, RhsQuals;
1619 QualType Lhs = Self.getASTContext().getUnqualifiedArrayType(LhsT, LhsQuals);
1620 QualType Rhs = Self.getASTContext().getUnqualifiedArrayType(RhsT, RhsQuals);
1621 return Self.Context.typesAreCompatible(Lhs, Rhs);
1622 }
1623 case BTT_IsConvertible:
1624 case BTT_IsConvertibleTo:
1625 case BTT_IsNothrowConvertible: {
1626 if (RhsT->isVoidType())
1627 return LhsT->isVoidType();
1628 llvm::BumpPtrAllocator OpaqueExprAllocator;
1629 ExprResult Result = CheckConvertibilityForTypeTraits(Self, Lhs, Rhs, KeyLoc,
1630 OpaqueExprAllocator);
1631 if (Result.isInvalid())
1632 return false;
1633
1634 if (BTT != BTT_IsNothrowConvertible)
1635 return true;
1636
1637 return Self.canThrow(Result.get()) == CT_Cannot;
1638 }
1639
1640 case BTT_IsAssignable:
1641 case BTT_IsNothrowAssignable:
1642 case BTT_IsTriviallyAssignable: {
1643 // C++11 [meta.unary.prop]p3:
1644 // is_trivially_assignable is defined as:
1645 // is_assignable<T, U>::value is true and the assignment, as defined by
1646 // is_assignable, is known to call no operation that is not trivial
1647 //
1648 // is_assignable is defined as:
1649 // The expression declval<T>() = declval<U>() is well-formed when
1650 // treated as an unevaluated operand (Clause 5).
1651 //
1652 // For both, T and U shall be complete types, (possibly cv-qualified)
1653 // void, or arrays of unknown bound.
1654 if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType() &&
1655 Self.RequireCompleteType(
1656 Lhs->getTypeLoc().getBeginLoc(), LhsT,
1657 diag::err_incomplete_type_used_in_type_trait_expr))
1658 return false;
1659 if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType() &&
1660 Self.RequireCompleteType(
1661 Rhs->getTypeLoc().getBeginLoc(), RhsT,
1662 diag::err_incomplete_type_used_in_type_trait_expr))
1663 return false;
1664
1665 // cv void is never assignable.
1666 if (LhsT->isVoidType() || RhsT->isVoidType())
1667 return false;
1668
1669 // Build expressions that emulate the effect of declval<T>() and
1670 // declval<U>().
1671 auto createDeclValExpr = [&](QualType Ty) -> OpaqueValueExpr {
1672 if (Ty->isObjectType() || Ty->isFunctionType())
1673 Ty = Self.Context.getRValueReferenceType(Ty);
1674 return {KeyLoc, Ty.getNonLValueExprType(Self.Context),
1676 };
1677
1678 auto Lhs = createDeclValExpr(LhsT);
1679 auto Rhs = createDeclValExpr(RhsT);
1680
1681 // Attempt the assignment in an unevaluated context within a SFINAE
1682 // trap at translation unit scope.
1685 Sema::SFINAETrap SFINAE(Self, /*ForValidityCheck=*/true);
1686 Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
1687 ExprResult Result =
1688 Self.BuildBinOp(/*S=*/nullptr, KeyLoc, BO_Assign, &Lhs, &Rhs);
1689 if (Result.isInvalid())
1690 return false;
1691
1692 // Treat the assignment as unused for the purpose of -Wdeprecated-volatile.
1693 Self.CheckUnusedVolatileAssignment(Result.get());
1694
1695 if (SFINAE.hasErrorOccurred())
1696 return false;
1697
1698 if (BTT == BTT_IsAssignable)
1699 return true;
1700
1701 if (BTT == BTT_IsNothrowAssignable)
1702 return Self.canThrow(Result.get()) == CT_Cannot;
1703
1704 if (BTT == BTT_IsTriviallyAssignable) {
1705 // Under Objective-C ARC and Weak, if the destination has non-trivial
1706 // Objective-C lifetime, this is a non-trivial assignment.
1708 return false;
1709 const ASTContext &Context = Self.getASTContext();
1710 if (Context.containsAddressDiscriminatedPointerAuth(LhsT) ||
1711 Context.containsAddressDiscriminatedPointerAuth(RhsT))
1712 return false;
1713 return !Result.get()->hasNonTrivialCall(Self.Context);
1714 }
1715
1716 llvm_unreachable("unhandled type trait");
1717 return false;
1718 }
1719 case BTT_IsLayoutCompatible: {
1720 if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType())
1721 Self.RequireCompleteType(Lhs->getTypeLoc().getBeginLoc(), LhsT,
1722 diag::err_incomplete_type);
1723 if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType())
1724 Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1725 diag::err_incomplete_type);
1726
1727 DiagnoseVLAInCXXTypeTrait(Self, Lhs, tok::kw___is_layout_compatible);
1728 DiagnoseVLAInCXXTypeTrait(Self, Rhs, tok::kw___is_layout_compatible);
1729
1730 return Self.IsLayoutCompatible(LhsT, RhsT);
1731 }
1732 case BTT_IsPointerInterconvertibleBaseOf: {
1733 if (LhsT->isStructureOrClassType() && RhsT->isStructureOrClassType() &&
1734 !Self.getASTContext().hasSameUnqualifiedType(LhsT, RhsT)) {
1735 Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1736 diag::err_incomplete_type);
1737 }
1738
1740 tok::kw___is_pointer_interconvertible_base_of);
1742 tok::kw___is_pointer_interconvertible_base_of);
1743
1744 return Self.IsPointerInterconvertibleBaseOf(Lhs, Rhs);
1745 }
1746 case BTT_IsDeducible: {
1747 const auto *TSTToBeDeduced = cast<DeducedTemplateSpecializationType>(LhsT);
1748 sema::TemplateDeductionInfo Info(KeyLoc);
1749 return Self.DeduceTemplateArgumentsFromType(
1750 TSTToBeDeduced->getTemplateName().getAsTemplateDecl(), RhsT,
1752 }
1753 case BTT_IsScalarizedLayoutCompatible: {
1754 if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType() &&
1755 Self.RequireCompleteType(Lhs->getTypeLoc().getBeginLoc(), LhsT,
1756 diag::err_incomplete_type))
1757 return true;
1758 if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType() &&
1759 Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1760 diag::err_incomplete_type))
1761 return true;
1762
1764 Self, Lhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1766 Self, Rhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1767
1768 return Self.HLSL().IsScalarizedLayoutCompatible(LhsT, RhsT);
1769 }
1770 case BTT_LtSynthesizesFromSpaceship:
1771 case BTT_LeSynthesizesFromSpaceship:
1772 case BTT_GtSynthesizesFromSpaceship:
1773 case BTT_GeSynthesizesFromSpaceship: {
1774 EnterExpressionEvaluationContext UnevaluatedContext(
1776 Sema::SFINAETrap SFINAE(Self, /*ForValidityCheck=*/true);
1777 Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
1778
1779 OpaqueValueExpr LHS(KeyLoc, LhsT.getNonReferenceType(),
1781 : LhsT->isRValueReferenceType()
1784 OpaqueValueExpr RHS(KeyLoc, RhsT.getNonReferenceType(),
1786 : RhsT->isRValueReferenceType()
1789
1790 auto OpKind = [&] {
1791 switch (BTT) {
1792 case BTT_LtSynthesizesFromSpaceship:
1793 return BinaryOperatorKind::BO_LT;
1794 case BTT_LeSynthesizesFromSpaceship:
1795 return BinaryOperatorKind::BO_LE;
1796 case BTT_GtSynthesizesFromSpaceship:
1797 return BinaryOperatorKind::BO_GT;
1798 case BTT_GeSynthesizesFromSpaceship:
1799 return BinaryOperatorKind::BO_GE;
1800 default:
1801 llvm_unreachable("Trying to Synthesize non-comparison operator?");
1802 }
1803 }();
1804
1805 UnresolvedSet<16> Functions;
1806 Self.LookupBinOp(Self.TUScope, KeyLoc, OpKind, Functions);
1807
1808 ExprResult Result =
1809 Self.CreateOverloadedBinOp(KeyLoc, OpKind, Functions, &LHS, &RHS);
1810 if (Result.isInvalid() || SFINAE.hasErrorOccurred())
1811 return false;
1812
1813 return isa<CXXRewrittenBinaryOperator>(Result.get());
1814 }
1815 default:
1816 llvm_unreachable("not a BTT");
1817 }
1818 llvm_unreachable("Unknown type trait or not implemented");
1819}
1820
1822 ParsedType Ty, Expr *DimExpr,
1823 SourceLocation RParen) {
1824 TypeSourceInfo *TSInfo;
1825 QualType T = GetTypeFromParser(Ty, &TSInfo);
1826 if (!TSInfo)
1827 TSInfo = Context.getTrivialTypeSourceInfo(T);
1828
1829 return BuildArrayTypeTrait(ATT, KWLoc, TSInfo, DimExpr, RParen);
1830}
1831
1833 QualType T, Expr *DimExpr,
1834 SourceLocation KeyLoc) {
1835 assert(!T->isDependentType() && "Cannot evaluate traits of dependent type");
1836
1837 switch (ATT) {
1838 case ATT_ArrayRank:
1839 if (T->isArrayType()) {
1840 unsigned Dim = 0;
1841 while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {
1842 ++Dim;
1843 T = AT->getElementType();
1844 }
1845 return Dim;
1846 }
1847 return 0;
1848
1849 case ATT_ArrayExtent: {
1850 llvm::APSInt Value;
1851 uint64_t Dim;
1852 if (Self.VerifyIntegerConstantExpression(
1853 DimExpr, &Value, diag::err_dimension_expr_not_constant_integer)
1854 .isInvalid())
1855 return 0;
1856 if (Value.isSigned() && Value.isNegative()) {
1857 Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer)
1858 << DimExpr->getSourceRange();
1859 return 0;
1860 }
1861 Dim = Value.getLimitedValue();
1862
1863 if (T->isArrayType()) {
1864 unsigned D = 0;
1865 bool Matched = false;
1866 while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {
1867 if (Dim == D) {
1868 Matched = true;
1869 break;
1870 }
1871 ++D;
1872 T = AT->getElementType();
1873 }
1874
1875 if (Matched && T->isArrayType()) {
1876 if (const ConstantArrayType *CAT =
1877 Self.Context.getAsConstantArrayType(T))
1878 return CAT->getLimitedSize();
1879 }
1880 }
1881 return 0;
1882 }
1883 }
1884 llvm_unreachable("Unknown type trait or not implemented");
1885}
1886
1888 TypeSourceInfo *TSInfo, Expr *DimExpr,
1889 SourceLocation RParen) {
1890 QualType T = TSInfo->getType();
1891
1892 // FIXME: This should likely be tracked as an APInt to remove any host
1893 // assumptions about the width of size_t on the target.
1894 uint64_t Value = 0;
1895 if (!T->isDependentType())
1896 Value = EvaluateArrayTypeTrait(*this, ATT, T, DimExpr, KWLoc);
1897
1898 // While the specification for these traits from the Embarcadero C++
1899 // compiler's documentation says the return type is 'unsigned int', Clang
1900 // returns 'size_t'. On Windows, the primary platform for the Embarcadero
1901 // compiler, there is no difference. On several other platforms this is an
1902 // important distinction.
1903 return new (Context) ArrayTypeTraitExpr(KWLoc, ATT, TSInfo, Value, DimExpr,
1904 RParen, Context.getSizeType());
1905}
1906
1908 Expr *Queried, SourceLocation RParen) {
1909 // If error parsing the expression, ignore.
1910 if (!Queried)
1911 return ExprError();
1912
1913 ExprResult Result = BuildExpressionTrait(ET, KWLoc, Queried, RParen);
1914
1915 return Result;
1916}
1917
1919 switch (ET) {
1920 case ET_IsLValueExpr:
1921 return E->isLValue();
1922 case ET_IsRValueExpr:
1923 return E->isPRValue();
1924 }
1925 llvm_unreachable("Expression trait not covered by switch");
1926}
1927
1929 Expr *Queried, SourceLocation RParen) {
1930 if (Queried->isTypeDependent()) {
1931 // Delay type-checking for type-dependent expressions.
1932 } else if (Queried->hasPlaceholderType()) {
1933 ExprResult PE = CheckPlaceholderExpr(Queried);
1934 if (PE.isInvalid())
1935 return ExprError();
1936 return BuildExpressionTrait(ET, KWLoc, PE.get(), RParen);
1937 }
1938
1939 bool Value = EvaluateExpressionTrait(ET, Queried);
1940
1941 return new (Context)
1942 ExpressionTraitExpr(KWLoc, ET, Queried, Value, RParen, Context.BoolTy);
1943}
1944
1945static std::optional<TypeTrait> StdNameToTypeTrait(StringRef Name) {
1946 return llvm::StringSwitch<std::optional<TypeTrait>>(Name)
1947 .Case("is_trivially_relocatable",
1948 TypeTrait::UTT_IsCppTriviallyRelocatable)
1949 .Case("is_trivially_copyable", TypeTrait::UTT_IsTriviallyCopyable)
1950 .Case("is_assignable", TypeTrait::BTT_IsAssignable)
1951 .Case("is_empty", TypeTrait::UTT_IsEmpty)
1952 .Case("is_standard_layout", TypeTrait::UTT_IsStandardLayout)
1953 .Case("is_aggregate", TypeTrait::UTT_IsAggregate)
1954 .Case("is_constructible", TypeTrait::TT_IsConstructible)
1955 .Case("is_final", TypeTrait::UTT_IsFinal)
1956 .Case("is_abstract", TypeTrait::UTT_IsAbstract)
1957 .Default(std::nullopt);
1958}
1959
1961 std::optional<std::pair<TypeTrait, llvm::SmallVector<QualType, 1>>>;
1962
1963// Recognize type traits that are builting type traits, or known standard
1964// type traits in <type_traits>. Note that at this point we assume the
1965// trait evaluated to false, so we need only to recognize the shape of the
1966// outer-most symbol.
1969 std::optional<TypeTrait> Trait;
1970
1971 // builtins
1972 if (const auto *TraitExpr = dyn_cast<TypeTraitExpr>(E)) {
1973 Trait = TraitExpr->getTrait();
1974 for (const auto *Arg : TraitExpr->getArgs())
1975 Args.push_back(Arg->getType());
1976 return {{Trait.value(), std::move(Args)}};
1977 }
1978 const auto *Ref = dyn_cast<DeclRefExpr>(E);
1979 if (!Ref)
1980 return std::nullopt;
1981
1982 // std::is_xxx_v<>
1983 if (const auto *VD =
1984 dyn_cast<VarTemplateSpecializationDecl>(Ref->getDecl())) {
1985 if (!VD->isInStdNamespace())
1986 return std::nullopt;
1987 StringRef Name = VD->getIdentifier()->getName();
1988 if (!Name.consume_back("_v"))
1989 return std::nullopt;
1990 Trait = StdNameToTypeTrait(Name);
1991 if (!Trait)
1992 return std::nullopt;
1993 for (const auto &Arg : VD->getTemplateArgs().asArray()) {
1994 if (Arg.getKind() == TemplateArgument::ArgKind::Pack) {
1995 for (const auto &InnerArg : Arg.pack_elements())
1996 Args.push_back(InnerArg.getAsType());
1997 } else if (Arg.getKind() == TemplateArgument::ArgKind::Type) {
1998 Args.push_back(Arg.getAsType());
1999 } else {
2000 llvm_unreachable("Unexpected kind");
2001 }
2002 }
2003 return {{Trait.value(), std::move(Args)}};
2004 }
2005
2006 // std::is_xxx<>::value
2007 if (const auto *VD = dyn_cast<VarDecl>(Ref->getDecl());
2008 Ref->hasQualifier() && VD && VD->getIdentifier()->isStr("value")) {
2009 NestedNameSpecifier Qualifier = Ref->getQualifier();
2010 if (Qualifier.getKind() != NestedNameSpecifier::Kind::Type)
2011 return std::nullopt;
2012 const auto *Ts = Qualifier.getAsType()->getAs<TemplateSpecializationType>();
2013 if (!Ts)
2014 return std::nullopt;
2015 const TemplateDecl *D = Ts->getTemplateName().getAsTemplateDecl();
2016 if (!D || !D->isInStdNamespace())
2017 return std::nullopt;
2018 Trait = StdNameToTypeTrait(D->getIdentifier()->getName());
2019 if (!Trait)
2020 return std::nullopt;
2021 for (const auto &Arg : Ts->template_arguments())
2022 Args.push_back(Arg.getAsType());
2023 return {{Trait.value(), std::move(Args)}};
2024 }
2025 return std::nullopt;
2026}
2027
2029 const CXXRecordDecl *D) {
2030 if (D->isUnion()) {
2031 auto DiagSPM = [&](CXXSpecialMemberKind K, bool Has) {
2032 if (Has)
2033 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2034 << diag::TraitNotSatisfiedReason::UnionWithUserDeclaredSMF << K;
2035 };
2044 return;
2045 }
2046
2048 const auto *Decl = cast_or_null<CXXConstructorDecl>(
2049 LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/false));
2050 if (Decl && Decl->isUserProvided())
2051 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2052 << diag::TraitNotSatisfiedReason::UserProvidedCtr
2053 << Decl->isMoveConstructor() << Decl->getSourceRange();
2054 }
2057 LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/true);
2058 if (Decl && Decl->isUserProvided())
2059 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2060 << diag::TraitNotSatisfiedReason::UserProvidedAssign
2061 << Decl->isMoveAssignmentOperator() << Decl->getSourceRange();
2062 }
2063 if (CXXDestructorDecl *Dtr = D->getDestructor()) {
2064 Dtr = Dtr->getCanonicalDecl();
2065 if (Dtr->isUserProvided() && !Dtr->isDefaulted())
2066 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2067 << diag::TraitNotSatisfiedReason::DeletedDtr << /*User Provided*/ 1
2068 << Dtr->getSourceRange();
2069 }
2070}
2071
2073 SourceLocation Loc,
2074 const CXXRecordDecl *D) {
2075 for (const CXXBaseSpecifier &B : D->bases()) {
2076 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2077 if (B.isVirtual())
2078 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2079 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2080 << B.getSourceRange();
2081 if (!SemaRef.IsCXXTriviallyRelocatableType(B.getType()))
2082 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2083 << diag::TraitNotSatisfiedReason::NTRBase << B.getType()
2084 << B.getSourceRange();
2085 }
2086 for (const FieldDecl *Field : D->fields()) {
2087 if (!Field->getType()->isReferenceType() &&
2088 !SemaRef.IsCXXTriviallyRelocatableType(Field->getType()))
2089 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2090 << diag::TraitNotSatisfiedReason::NTRField << Field
2091 << Field->getType() << Field->getSourceRange();
2092 }
2093 if (D->hasDeletedDestructor())
2094 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2095 << diag::TraitNotSatisfiedReason::DeletedDtr << /*Deleted*/ 0
2096 << D->getDestructor()->getSourceRange();
2097
2098 DiagnoseNonDefaultMovable(SemaRef, Loc, D);
2099}
2100
2102 SourceLocation Loc,
2103 QualType T) {
2104 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2105 << T << diag::TraitName::TriviallyRelocatable;
2106 if (T->isVariablyModifiedType())
2107 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2108 << diag::TraitNotSatisfiedReason::VLA;
2109
2110 if (T->isReferenceType())
2111 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2112 << diag::TraitNotSatisfiedReason::Ref;
2113 T = T.getNonReferenceType();
2114
2115 if (T.hasNonTrivialObjCLifetime())
2116 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2117 << diag::TraitNotSatisfiedReason::HasArcLifetime;
2118
2119 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2120 if (!D || D->isInvalidDecl())
2121 return;
2122
2123 if (D->hasDefinition())
2125
2126 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2127}
2128
2130 SourceLocation Loc,
2131 const CXXRecordDecl *D) {
2132 for (const CXXBaseSpecifier &B : D->bases()) {
2133 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2134 if (B.isVirtual())
2135 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2136 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2137 << B.getSourceRange();
2138 if (!B.getType().isTriviallyCopyableType(D->getASTContext())) {
2139 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2140 << diag::TraitNotSatisfiedReason::NTCBase << B.getType()
2141 << B.getSourceRange();
2142 }
2143 }
2144 for (const FieldDecl *Field : D->fields()) {
2145 if (!Field->getType().isTriviallyCopyableType(Field->getASTContext()))
2146 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2147 << diag::TraitNotSatisfiedReason::NTCField << Field
2148 << Field->getType() << Field->getSourceRange();
2149 }
2150 CXXDestructorDecl *Dtr = D->getDestructor();
2151 if (D->hasDeletedDestructor() || (Dtr && !Dtr->isTrivial()))
2152 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2153 << diag::TraitNotSatisfiedReason::DeletedDtr
2155
2156 for (const CXXMethodDecl *Method : D->methods()) {
2157 if (Method->isTrivial() || !Method->isUserProvided()) {
2158 continue;
2159 }
2160 auto SpecialMemberKind =
2161 SemaRef.getDefaultedFunctionKind(Method).asSpecialMember();
2162 switch (SpecialMemberKind) {
2167 bool IsAssignment =
2168 SpecialMemberKind == CXXSpecialMemberKind::CopyAssignment ||
2169 SpecialMemberKind == CXXSpecialMemberKind::MoveAssignment;
2170 bool IsMove =
2171 SpecialMemberKind == CXXSpecialMemberKind::MoveConstructor ||
2172 SpecialMemberKind == CXXSpecialMemberKind::MoveAssignment;
2173
2174 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2175 << (IsAssignment ? diag::TraitNotSatisfiedReason::UserProvidedAssign
2176 : diag::TraitNotSatisfiedReason::UserProvidedCtr)
2177 << IsMove << Method->getSourceRange();
2178 break;
2179 }
2180 default:
2181 break;
2182 }
2183 }
2184}
2185
2187 Sema &SemaRef, SourceLocation Loc,
2189 if (Ts.empty()) {
2190 return;
2191 }
2192
2193 bool ContainsVoid = false;
2194 for (const QualType &ArgTy : Ts) {
2195 ContainsVoid |= ArgTy->isVoidType();
2196 }
2197
2198 if (ContainsVoid)
2199 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2200 << diag::TraitNotSatisfiedReason::CVVoidType;
2201
2202 QualType T = Ts[0];
2203 if (T->isFunctionType())
2204 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2205 << diag::TraitNotSatisfiedReason::FunctionType;
2206
2207 if (T->isIncompleteArrayType())
2208 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2209 << diag::TraitNotSatisfiedReason::IncompleteArrayType;
2210
2211 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2212 if (!D || D->isInvalidDecl() || !D->hasDefinition())
2213 return;
2214
2215 llvm::BumpPtrAllocator OpaqueExprAllocator;
2216 SmallVector<Expr *, 2> ArgExprs;
2217 ArgExprs.reserve(Ts.size() - 1);
2218 for (unsigned I = 1, N = Ts.size(); I != N; ++I) {
2219 QualType ArgTy = Ts[I];
2220 if (ArgTy->isObjectType() || ArgTy->isFunctionType())
2221 ArgTy = SemaRef.Context.getRValueReferenceType(ArgTy);
2222 ArgExprs.push_back(
2223 new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
2224 OpaqueValueExpr(Loc, ArgTy.getNonLValueExprType(SemaRef.Context),
2226 }
2227
2230 Sema::ContextRAII TUContext(SemaRef,
2234 InitializationSequence Init(SemaRef, To, InitKind, ArgExprs);
2235
2236 Init.Diagnose(SemaRef, To, InitKind, ArgExprs);
2237 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2238}
2239
2241 SourceLocation Loc, QualType T) {
2242 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2243 << T << diag::TraitName::TriviallyCopyable;
2244
2245 if (T->isReferenceType())
2246 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2247 << diag::TraitNotSatisfiedReason::Ref;
2248
2249 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2250 if (!D || D->isInvalidDecl())
2251 return;
2252
2253 if (D->hasDefinition())
2254 DiagnoseNonTriviallyCopyableReason(SemaRef, Loc, D);
2255
2256 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2257}
2258
2260 QualType T, QualType U) {
2261 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2262
2263 auto createDeclValExpr = [&](QualType Ty) -> OpaqueValueExpr {
2264 if (Ty->isObjectType() || Ty->isFunctionType())
2265 Ty = SemaRef.Context.getRValueReferenceType(Ty);
2266 return {Loc, Ty.getNonLValueExprType(SemaRef.Context),
2268 };
2269
2270 auto LHS = createDeclValExpr(T);
2271 auto RHS = createDeclValExpr(U);
2272
2275 Sema::ContextRAII TUContext(SemaRef,
2277 SemaRef.BuildBinOp(/*S=*/nullptr, Loc, BO_Assign, &LHS, &RHS);
2278
2279 if (!D || D->isInvalidDecl())
2280 return;
2281
2282 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2283}
2284
2286 const CXXRecordDecl *D) {
2287 // Non-static data members (ignore zero-width bit‐fields).
2288 for (const auto *Field : D->fields()) {
2289 if (Field->isZeroLengthBitField())
2290 continue;
2291 if (Field->isBitField()) {
2292 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2293 << diag::TraitNotSatisfiedReason::NonZeroLengthField << Field
2294 << Field->getSourceRange();
2295 continue;
2296 }
2297 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2298 << diag::TraitNotSatisfiedReason::NonEmptyMember << Field
2299 << Field->getType() << Field->getSourceRange();
2300 }
2301
2302 // Virtual functions.
2303 for (const auto *M : D->methods()) {
2304 if (M->isVirtual()) {
2305 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2306 << diag::TraitNotSatisfiedReason::VirtualFunction << M
2307 << M->getSourceRange();
2308 break;
2309 }
2310 }
2311
2312 // Virtual bases and non-empty bases.
2313 for (const auto &B : D->bases()) {
2314 const auto *BR = B.getType()->getAsCXXRecordDecl();
2315 if (!BR || BR->isInvalidDecl())
2316 continue;
2317 if (B.isVirtual()) {
2318 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2319 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2320 << B.getSourceRange();
2321 }
2322 if (!BR->isEmpty()) {
2323 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2324 << diag::TraitNotSatisfiedReason::NonEmptyBase << B.getType()
2325 << B.getSourceRange();
2326 }
2327 }
2328}
2329
2331 // Emit primary "not empty" diagnostic.
2332 S.Diag(Loc, diag::note_unsatisfied_trait) << T << diag::TraitName::Empty;
2333
2334 // While diagnosing is_empty<T>, we want to look at the actual type, not a
2335 // reference or an array of it. So we need to massage the QualType param to
2336 // strip refs and arrays.
2337 if (T->isReferenceType())
2338 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2339 << diag::TraitNotSatisfiedReason::Ref;
2340 T = T.getNonReferenceType();
2341
2342 if (auto *AT = S.Context.getAsArrayType(T))
2343 T = AT->getElementType();
2344
2345 if (auto *D = T->getAsCXXRecordDecl()) {
2346 if (D->hasDefinition()) {
2347 DiagnoseIsEmptyReason(S, Loc, D);
2348 S.Diag(D->getLocation(), diag::note_defined_here) << D;
2349 }
2350 }
2351}
2352
2354 const CXXRecordDecl *D) {
2355 if (!D || D->isInvalidDecl())
2356 return;
2357
2358 // Complete record but not 'final'.
2359 if (!D->isEffectivelyFinal()) {
2360 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2361 << diag::TraitNotSatisfiedReason::NotMarkedFinal;
2362 S.Diag(D->getLocation(), diag::note_defined_here) << D;
2363 return;
2364 }
2365}
2366
2368 // Primary: “%0 is not final”
2369 S.Diag(Loc, diag::note_unsatisfied_trait) << T << diag::TraitName::Final;
2370 if (T->isReferenceType()) {
2371 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2372 << diag::TraitNotSatisfiedReason::Ref;
2373 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2374 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2375 return;
2376 }
2377 // Arrays / functions / non-records → not a class/union.
2378 if (S.Context.getAsArrayType(T)) {
2379 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2380 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2381 return;
2382 }
2383 if (T->isFunctionType()) {
2384 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2385 << diag::TraitNotSatisfiedReason::FunctionType;
2386 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2387 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2388 return;
2389 }
2390 if (!T->isRecordType()) {
2391 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2392 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2393 return;
2394 }
2395 if (const auto *D = T->getAsCXXRecordDecl())
2396 DiagnoseIsFinalReason(S, Loc, D);
2397}
2398
2400 int NumBasesWithFields = 0;
2401 for (const CXXBaseSpecifier &Base : D->bases()) {
2402 const CXXRecordDecl *BaseRD = Base.getType()->getAsCXXRecordDecl();
2403 if (!BaseRD || BaseRD->isInvalidDecl())
2404 continue;
2405
2406 for (const FieldDecl *Field : BaseRD->fields()) {
2407 if (!Field->isUnnamedBitField()) {
2408 if (++NumBasesWithFields > 1)
2409 return true; // found more than one base class with fields
2410 break; // no need to check further fields in this base class
2411 }
2412 }
2413 }
2414 return false;
2415}
2416
2418 const CXXRecordDecl *D) {
2419 for (const CXXBaseSpecifier &B : D->bases()) {
2420 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2421 if (B.isVirtual()) {
2422 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2423 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2424 << B.getSourceRange();
2425 }
2426 if (!B.getType()->isStandardLayoutType()) {
2427 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2428 << diag::TraitNotSatisfiedReason::NonStandardLayoutBase << B.getType()
2429 << B.getSourceRange();
2430 }
2431 }
2432 // Check for mixed access specifiers in fields.
2433 const FieldDecl *FirstField = nullptr;
2434 AccessSpecifier FirstAccess = AS_none;
2435
2436 for (const FieldDecl *Field : D->fields()) {
2437 if (Field->isUnnamedBitField())
2438 continue;
2439
2440 // Record the first field we see
2441 if (!FirstField) {
2442 FirstField = Field;
2443 FirstAccess = Field->getAccess();
2444 continue;
2445 }
2446
2447 // Check if the field has a different access specifier than the first one.
2448 if (Field->getAccess() != FirstAccess) {
2449 // Emit a diagnostic about mixed access specifiers.
2450 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2451 << diag::TraitNotSatisfiedReason::MixedAccess;
2452
2453 SemaRef.Diag(FirstField->getLocation(), diag::note_defined_here)
2454 << FirstField;
2455
2456 SemaRef.Diag(Field->getLocation(), diag::note_unsatisfied_trait_reason)
2457 << diag::TraitNotSatisfiedReason::MixedAccessField << Field
2458 << FirstField;
2459
2460 // No need to check further fields, as we already found mixed access.
2461 break;
2462 }
2463 }
2465 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2466 << diag::TraitNotSatisfiedReason::MultipleDataBase;
2467 }
2468 if (D->isPolymorphic()) {
2469 // Find the best location to point “defined here” at.
2470 const CXXMethodDecl *VirtualMD = nullptr;
2471 // First, look for a virtual method.
2472 for (const auto *M : D->methods()) {
2473 if (M->isVirtual()) {
2474 VirtualMD = M;
2475 break;
2476 }
2477 }
2478 if (VirtualMD) {
2479 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2480 << diag::TraitNotSatisfiedReason::VirtualFunction << VirtualMD;
2481 SemaRef.Diag(VirtualMD->getLocation(), diag::note_defined_here)
2482 << VirtualMD;
2483 } else {
2484 // If no virtual method, point to the record declaration itself.
2485 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2486 << diag::TraitNotSatisfiedReason::VirtualFunction << D;
2487 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2488 }
2489 }
2490 for (const FieldDecl *Field : D->fields()) {
2491 if (!Field->getType()->isStandardLayoutType()) {
2492 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2493 << diag::TraitNotSatisfiedReason::NonStandardLayoutMember << Field
2494 << Field->getType() << Field->getSourceRange();
2495 }
2496 }
2497 // Find any indirect base classes that have fields.
2498 if (D->hasDirectFields()) {
2499 const CXXRecordDecl *Indirect = nullptr;
2500 D->forallBases([&](const CXXRecordDecl *BaseDef) {
2501 if (BaseDef->hasDirectFields()) {
2502 Indirect = BaseDef;
2503 return false; // stop traversal
2504 }
2505 return true; // continue to the next base
2506 });
2507 if (Indirect) {
2508 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2509 << diag::TraitNotSatisfiedReason::IndirectBaseWithFields << Indirect
2510 << Indirect->getSourceRange();
2511 }
2512 }
2513}
2514
2516 QualType T) {
2517 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2518 << T << diag::TraitName::StandardLayout;
2519
2520 // Check type-level exclusion first.
2521 if (T->isVariablyModifiedType()) {
2522 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2523 << diag::TraitNotSatisfiedReason::VLA;
2524 return;
2525 }
2526
2527 if (T->isReferenceType()) {
2528 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2529 << diag::TraitNotSatisfiedReason::Ref;
2530 return;
2531 }
2532 T = T.getNonReferenceType();
2533 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2534 if (!D || D->isInvalidDecl())
2535 return;
2536
2537 if (D->hasDefinition())
2538 DiagnoseNonStandardLayoutReason(SemaRef, Loc, D);
2539
2540 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2541}
2542
2544 const CXXRecordDecl *D) {
2545 for (const CXXConstructorDecl *Ctor : D->ctors()) {
2546 if (Ctor->isUserProvided())
2547 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2548 << diag::TraitNotSatisfiedReason::UserDeclaredCtr;
2549 if (Ctor->isInheritingConstructor())
2550 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2551 << diag::TraitNotSatisfiedReason::InheritedCtr;
2552 }
2553
2554 if (llvm::any_of(D->decls(), [](auto const *Sub) {
2555 return isa<ConstructorUsingShadowDecl>(Sub);
2556 })) {
2557 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2558 << diag::TraitNotSatisfiedReason::InheritedCtr;
2559 }
2560
2561 if (D->isPolymorphic())
2562 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2563 << diag::TraitNotSatisfiedReason::PolymorphicType
2564 << D->getSourceRange();
2565
2566 for (const CXXBaseSpecifier &B : D->bases()) {
2567 if (B.isVirtual()) {
2568 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2569 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2570 << B.getSourceRange();
2571 continue;
2572 }
2573 auto AccessSpecifier = B.getAccessSpecifier();
2574 switch (AccessSpecifier) {
2575 case AS_private:
2576 case AS_protected:
2577 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2578 << diag::TraitNotSatisfiedReason::PrivateProtectedDirectBase
2580 break;
2581 default:
2582 break;
2583 }
2584 }
2585
2586 for (const CXXMethodDecl *Method : D->methods()) {
2587 if (Method->isVirtual()) {
2588 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2589 << diag::TraitNotSatisfiedReason::VirtualFunction << Method
2590 << Method->getSourceRange();
2591 }
2592 }
2593
2594 for (const FieldDecl *Field : D->fields()) {
2595 auto AccessSpecifier = Field->getAccess();
2596 switch (AccessSpecifier) {
2597 case AS_private:
2598 case AS_protected:
2599 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2600 << diag::TraitNotSatisfiedReason::PrivateProtectedDirectDataMember
2602 break;
2603 default:
2604 break;
2605 }
2606 }
2607
2608 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2609}
2610
2612 QualType T) {
2613 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2614 << T << diag::TraitName::Aggregate;
2615
2616 if (T->isVoidType())
2617 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2618 << diag::TraitNotSatisfiedReason::CVVoidType;
2619
2620 T = T.getNonReferenceType();
2621 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2622 if (!D || D->isInvalidDecl())
2623 return;
2624
2625 if (D->hasDefinition())
2626 DiagnoseNonAggregateReason(SemaRef, Loc, D);
2627}
2628
2630 const CXXRecordDecl *D) {
2631 // If this type has any abstract base classes, their respective virtual
2632 // functions must have been overridden.
2633 for (const CXXBaseSpecifier &B : D->bases()) {
2634 if (B.getType()->castAsCXXRecordDecl()->isAbstract()) {
2635 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2636 << diag::TraitNotSatisfiedReason::OverridesAllPureVirtual
2637 << B.getType() << B.getSourceRange();
2638 }
2639 }
2640}
2641
2643 QualType T) {
2644 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2645 << T << diag::TraitName::Abstract;
2646
2647 if (T->isReferenceType()) {
2648 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2649 << diag::TraitNotSatisfiedReason::Ref;
2650 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2651 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2652 return;
2653 }
2654
2655 if (T->isUnionType()) {
2656 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2657 << diag::TraitNotSatisfiedReason::UnionType;
2658 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2659 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2660 return;
2661 }
2662
2663 if (SemaRef.Context.getAsArrayType(T)) {
2664 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2665 << diag::TraitNotSatisfiedReason::ArrayType;
2666 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2667 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2668 return;
2669 }
2670
2671 if (T->isFunctionType()) {
2672 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2673 << diag::TraitNotSatisfiedReason::FunctionType;
2674 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2675 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2676 return;
2677 }
2678
2679 if (T->isPointerType()) {
2680 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2681 << diag::TraitNotSatisfiedReason::PointerType;
2682 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2683 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2684 return;
2685 }
2686
2687 if (!T->isStructureOrClassType()) {
2688 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2689 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2690 return;
2691 }
2692
2693 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2694 if (D->hasDefinition())
2695 DiagnoseNonAbstractReason(SemaRef, Loc, D);
2696}
2697
2699 E = E->IgnoreParenImpCasts();
2700 if (E->containsErrors())
2701 return;
2702
2704 if (!TraitInfo)
2705 return;
2706
2707 const auto &[Trait, Args] = TraitInfo.value();
2708 switch (Trait) {
2709 case UTT_IsCppTriviallyRelocatable:
2711 break;
2712 case UTT_IsTriviallyCopyable:
2713 DiagnoseNonTriviallyCopyableReason(*this, E->getBeginLoc(), Args[0]);
2714 break;
2715 case BTT_IsAssignable:
2716 DiagnoseNonAssignableReason(*this, E->getBeginLoc(), Args[0], Args[1]);
2717 break;
2718 case UTT_IsEmpty:
2719 DiagnoseIsEmptyReason(*this, E->getBeginLoc(), Args[0]);
2720 break;
2721 case UTT_IsStandardLayout:
2722 DiagnoseNonStandardLayoutReason(*this, E->getBeginLoc(), Args[0]);
2723 break;
2724 case TT_IsConstructible:
2726 break;
2727 case UTT_IsAggregate:
2728 DiagnoseNonAggregateReason(*this, E->getBeginLoc(), Args[0]);
2729 break;
2730 case UTT_IsFinal: {
2731 QualType QT = Args[0];
2732 if (QT->isDependentType())
2733 break;
2734 const auto *RD = QT->getAsCXXRecordDecl();
2735 if (!RD || !RD->isEffectivelyFinal())
2736 DiagnoseIsFinalReason(*this, E->getBeginLoc(), QT); // unsatisfied
2737 break;
2738 }
2739 case UTT_IsAbstract:
2740 DiagnoseNonAbstractReason(*this, E->getBeginLoc(), Args[0]);
2741 break;
2742 default:
2743 break;
2744 }
2745}
static CanQualType GetReturnType(QualType RetTy)
Returns the "extra-canonicalized" return type, which discards qualifiers on the return type.
Definition CGCall.cpp:154
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 bool equalityComparisonIsDefaulted(Sema &S, const TagDecl *Decl, SourceLocation KeyLoc)
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:226
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:801
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:702
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:2997
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition TypeBase.h:3730
Represents a base class of a C++ class.
Definition DeclCXX.h:146
Represents a C++ constructor within a class.
Definition DeclCXX.h:2611
Represents a C++ destructor within a class.
Definition DeclCXX.h:2876
CXXDestructorDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition DeclCXX.h:2924
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2136
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
Definition DeclCXX.cpp:2753
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
Definition DeclCXX.cpp:2732
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:1347
bool isTriviallyCopyable() const
Determine whether this class is considered trivially copyable per (C++11 [class]p6).
Definition DeclCXX.cpp:610
bool hasNonTrivialCopyAssignment() const
Determine whether this class has a non-trivial copy assignment operator (C++ [class....
Definition DeclCXX.h:1340
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
Definition DeclCXX.cpp:2343
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:1246
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
Definition DeclCXX.h:1372
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:2150
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:1307
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:1284
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:1334
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:1319
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:2131
bool hasNonTrivialMoveAssignment() const
Determine whether this class has a non-trivial move assignment operator (C++11 [class....
Definition DeclCXX.h:1354
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:1253
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:1294
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:2946
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition Expr.h:3129
Represents the canonical version of C arrays with a specified constant size.
Definition TypeBase.h:3768
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.
Represents an enum.
Definition Decl.h:4013
The return type of classify().
Definition Expr.h:339
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:3090
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:415
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
Definition Expr.h:526
static ExprValueKind getValueKindForType(QualType T)
getValueKindForType - Given a formal return or parameter type, give its value kind.
Definition Expr.h:437
An expression trait intrinsic.
Definition ExprCXX.h:3070
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:4550
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:5315
unsigned getNumParams() const
Definition TypeBase.h:5593
bool isNothrow(bool ResultIfDependent=false) const
Determine whether this function type has a non-throwing exception specification.
Definition TypeBase.h:5714
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:1181
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:2911
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type.
Definition Type.cpp:3624
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:8573
bool hasNonTrivialObjCLifetime() const
Definition TypeBase.h:1448
@ PCK_Trivial
The type does not fall into any of the following categories.
Definition TypeBase.h:1499
@ PCK_ARCStrong
The type is an Objective-C retainable pointer type that is qualified with the ARC __strong qualifier.
Definition TypeBase.h:1508
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:4464
field_range fields() const
Definition Decl.h:4530
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:3518
CXXSpecialMemberKind asSpecialMember() const
Definition Sema.h:6434
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
Definition Sema.h:12517
bool hasErrorOccurred() const
Determine whether any SFINAE errors have been trapped.
Definition Sema.h:12551
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:868
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:9382
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:1300
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:939
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:932
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:6759
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:1259
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:343
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Stmt.cpp:355
Represents the declaration of a struct/union/class/enum.
Definition Decl.h:3717
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4894
bool isUnion() const
Definition Decl.h:3928
bool isDependentType() const
Whether this declaration declares a type that is dependent, i.e., a type that somehow depends on temp...
Definition Decl.h:3863
@ 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:8359
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:8370
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:1839
bool isVoidType() const
Definition TypeBase.h:8991
bool isIncompleteArrayType() const
Definition TypeBase.h:8732
bool isRValueReferenceType() const
Definition TypeBase.h:8657
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:8724
CanQualType getCanonicalTypeUnqualified() const
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9285
bool isEnumeralType() const
Definition TypeBase.h:8756
bool isScalarType() const
Definition TypeBase.h:9097
bool isVariableArrayType() const
Definition TypeBase.h:8736
bool isLValueReferenceType() const
Definition TypeBase.h:8653
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition TypeBase.h:2790
bool isAggregateType() const
Determines whether the type is a C++ aggregate type or C aggregate or union type.
Definition Type.cpp:2455
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
Definition TypeBase.h:9171
bool isObjectType() const
Determine whether this type is an object type.
Definition TypeBase.h:2516
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
Definition Type.cpp:2479
bool isFunctionType() const
Definition TypeBase.h:8621
bool isStructureOrClassType() const
Definition Type.cpp:707
bool isVectorType() const
Definition TypeBase.h:8764
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition TypeBase.h:2929
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9218
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.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ 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
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...