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