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