clang 23.0.0git
SemaTypeTraits.cpp
Go to the documentation of this file.
1//===----- SemaTypeTraits.cpp - Semantic Analysis for C++ Type Traits -----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements semantic analysis for C++ type traits.
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/AST/DeclCXX.h"
15#include "clang/AST/Type.h"
23#include "clang/Sema/Lookup.h"
24#include "clang/Sema/Overload.h"
25#include "clang/Sema/Sema.h"
26#include "clang/Sema/SemaHLSL.h"
27#include "llvm/ADT/STLExtras.h"
28
29using namespace clang;
30
32 const CXXRecordDecl *RD,
33 bool Assign) {
34 RD = RD->getDefinition();
35 SourceLocation LookupLoc = RD->getLocation();
36
37 CanQualType CanTy = SemaRef.getASTContext().getCanonicalTagType(RD);
38 DeclarationName Name;
39 Expr *Arg = nullptr;
40 unsigned NumArgs;
41
42 QualType ArgType = CanTy;
44
45 if (Assign)
46 Name =
48 else
49 Name =
51
52 OpaqueValueExpr FakeArg(LookupLoc, ArgType, VK);
53 NumArgs = 1;
54 Arg = &FakeArg;
55
56 // Create the object argument
57 QualType ThisTy = CanTy;
58 Expr::Classification Classification =
59 OpaqueValueExpr(LookupLoc, ThisTy, VK_LValue)
60 .Classify(SemaRef.getASTContext());
61
62 // Now we perform lookup on the name we computed earlier and do overload
63 // resolution. Lookup is only performed directly into the class since there
64 // will always be a (possibly implicit) declaration to shadow any others.
67
68 if (R.empty())
69 return nullptr;
70
71 // Copy the candidates as our processing of them may load new declarations
72 // from an external source and invalidate lookup_result.
73 SmallVector<NamedDecl *, 8> Candidates(R.begin(), R.end());
74
75 for (NamedDecl *CandDecl : Candidates) {
76 if (CandDecl->isInvalidDecl())
77 continue;
78
80 auto CtorInfo = getConstructorInfo(Cand);
81 if (CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(Cand->getUnderlyingDecl())) {
82 if (Assign)
83 SemaRef.AddMethodCandidate(M, Cand, const_cast<CXXRecordDecl *>(RD),
84 ThisTy, Classification,
85 llvm::ArrayRef(&Arg, NumArgs), OCS, true);
86 else {
87 assert(CtorInfo);
88 SemaRef.AddOverloadCandidate(CtorInfo.Constructor, CtorInfo.FoundDecl,
89 llvm::ArrayRef(&Arg, NumArgs), OCS,
90 /*SuppressUserConversions*/ true);
91 }
92 } else if (FunctionTemplateDecl *Tmpl =
93 dyn_cast<FunctionTemplateDecl>(Cand->getUnderlyingDecl())) {
94 if (Assign)
96 Tmpl, Cand, const_cast<CXXRecordDecl *>(RD), nullptr, ThisTy,
97 Classification, llvm::ArrayRef(&Arg, NumArgs), OCS, true);
98 else {
99 assert(CtorInfo);
101 CtorInfo.ConstructorTmpl, CtorInfo.FoundDecl, nullptr,
102 llvm::ArrayRef(&Arg, NumArgs), OCS, true);
103 }
104 }
105 }
106
108 switch (OCS.BestViableFunction(SemaRef, LookupLoc, Best)) {
109 case OR_Success:
110 case OR_Deleted:
111 return cast<CXXMethodDecl>(Best->Function)->getCanonicalDecl();
112 default:
113 return nullptr;
114 }
115}
116
118 const CXXRecordDecl *D,
119 bool AllowUserDefined) {
120 assert(D->hasDefinition() && !D->isInvalidDecl());
121
123 return true;
124
126 LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/false);
127 return Decl && (AllowUserDefined || !Decl->isUserProvided()) &&
128 !Decl->isDeleted();
129}
130
132 Sema &SemaRef, const CXXRecordDecl *D, bool AllowUserDefined) {
133 assert(D->hasDefinition() && !D->isInvalidDecl());
134
136 return true;
137
139 LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/true);
140 if (!Decl)
141 return false;
142
143 return Decl && (AllowUserDefined || !Decl->isUserProvided()) &&
144 !Decl->isDeleted();
145}
146
147// [C++26][class.prop]
148// A class C is default-movable if
149// - overload resolution for direct-initializing an object of type C
150// from an xvalue of type C selects a constructor that is a direct member of C
151// and is neither user-provided nor deleted,
152// - overload resolution for assigning to an lvalue of type C from an xvalue of
153// type C selects an assignment operator function that is a direct member of C
154// and is neither user-provided nor deleted, and C has a destructor that is
155// neither user-provided nor deleted.
156static bool IsDefaultMovable(Sema &SemaRef, const CXXRecordDecl *D) {
158 /*AllowUserDefined=*/false))
159 return false;
160
162 SemaRef, D, /*AllowUserDefined=*/false))
163 return false;
164
166
167 if (!Dtr)
168 return true;
169
170 Dtr = Dtr->getCanonicalDecl();
171
172 if (Dtr->isUserProvided() && (!Dtr->isDefaulted() || Dtr->isDeleted()))
173 return false;
174
175 return !Dtr->isDeleted();
176}
177
178// [C++26][class.prop]
179// A class is eligible for trivial relocation unless it...
181 const CXXRecordDecl *D) {
182
183 for (const CXXBaseSpecifier &B : D->bases()) {
184 const auto *BaseDecl = B.getType()->getAsCXXRecordDecl();
185 if (!BaseDecl)
186 continue;
187 // ... has any virtual base classes
188 // ... has a base class that is not a trivially relocatable class
189 if (B.isVirtual() || (!BaseDecl->isDependentType() &&
190 !SemaRef.IsCXXTriviallyRelocatableType(B.getType())))
191 return false;
192 }
193
194 bool IsUnion = D->isUnion();
195 for (const FieldDecl *Field : D->fields()) {
196 if (Field->getType()->isDependentType())
197 continue;
198 if (Field->getType()->isReferenceType())
199 continue;
200 // ... has a non-static data member of an object type that is not
201 // of a trivially relocatable type
202 if (!SemaRef.IsCXXTriviallyRelocatableType(Field->getType()))
203 return false;
204
205 // A union contains values with address discriminated pointer auth
206 // cannot be relocated.
208 Field->getType()))
209 return false;
210 }
211 return !D->hasDeletedDestructor();
212}
213
217
218 if (!getLangOpts().CPlusPlus || D->isInvalidDecl())
219 return Info;
220
221 assert(D->hasDefinition());
222
223 auto IsUnion = [&, Is = std::optional<bool>{}]() mutable {
224 if (!Is.has_value())
225 Is = D->isUnion() && !D->hasUserDeclaredCopyConstructor() &&
229 return *Is;
230 };
231
232 auto IsDefaultMovable = [&, Is = std::optional<bool>{}]() mutable {
233 if (!Is.has_value())
234 Is = ::IsDefaultMovable(*this, D);
235 return *Is;
236 };
237
238 Info.IsRelocatable = [&] {
239 if (D->isDependentType())
240 return false;
241
242 // if it is eligible for trivial relocation
243 if (!IsEligibleForTrivialRelocation(*this, D))
244 return false;
245
246 // is a union with no user-declared special member functions, or
247 if (IsUnion())
248 return true;
249
250 // is default-movable.
251 return IsDefaultMovable();
252 }();
253
254 return Info;
255}
256
258 if (std::optional<ASTContext::CXXRecordDeclRelocationInfo> Info =
259 getASTContext().getRelocationInfoForCXXRecord(&RD))
260 return Info->IsRelocatable;
263 return Info.IsRelocatable;
264}
265
267 QualType BaseElementType = getASTContext().getBaseElementType(Type);
268
270 return false;
271
272 if (BaseElementType.hasNonTrivialObjCLifetime())
273 return false;
274
275 if (BaseElementType->isIncompleteType())
276 return false;
277
278 if (Context.containsNonRelocatablePointerAuth(Type))
279 return false;
280
281 if (BaseElementType->isScalarType() || BaseElementType->isVectorType())
282 return true;
283
284 if (const auto *RD = BaseElementType->getAsCXXRecordDecl())
286
287 return false;
288}
289
290/// Checks that type T is not a VLA.
291///
292/// @returns @c true if @p T is VLA and a diagnostic was emitted,
293/// @c false otherwise.
295 clang::tok::TokenKind TypeTraitID) {
296 if (!T->getType()->isVariableArrayType())
297 return false;
298
299 S.Diag(T->getTypeLoc().getBeginLoc(), diag::err_vla_unsupported)
300 << 1 << TypeTraitID;
301 return true;
302}
303
304/// Checks that type T is not an atomic type (_Atomic).
305///
306/// @returns @c true if @p T is VLA and a diagnostic was emitted,
307/// @c false otherwise.
309 clang::tok::TokenKind TypeTraitID) {
310 if (!T->getType()->isAtomicType())
311 return false;
312
313 S.Diag(T->getTypeLoc().getBeginLoc(), diag::err_atomic_unsupported)
314 << TypeTraitID;
315 return true;
316}
317
318/// Check the completeness of a type in a unary type trait.
319///
320/// If the particular type trait requires a complete type, tries to complete
321/// it. If completing the type fails, a diagnostic is emitted and false
322/// returned. If completing the type succeeds or no completion was required,
323/// returns true.
325 SourceLocation Loc,
326 QualType ArgTy) {
327 // C++0x [meta.unary.prop]p3:
328 // For all of the class templates X declared in this Clause, instantiating
329 // that template with a template argument that is a class template
330 // specialization may result in the implicit instantiation of the template
331 // argument if and only if the semantics of X require that the argument
332 // must be a complete type.
333 // We apply this rule to all the type trait expressions used to implement
334 // these class templates. We also try to follow any GCC documented behavior
335 // in these expressions to ensure portability of standard libraries.
336 switch (UTT) {
337 default:
338 llvm_unreachable("not a UTT");
339 // is_complete_type somewhat obviously cannot require a complete type.
340 case UTT_IsCompleteType:
341 // Fall-through
342
343 // These traits are modeled on the type predicates in C++0x
344 // [meta.unary.cat] and [meta.unary.comp]. They are not specified as
345 // requiring a complete type, as whether or not they return true cannot be
346 // impacted by the completeness of the type.
347 case UTT_IsVoid:
348 case UTT_IsIntegral:
349 case UTT_IsFloatingPoint:
350 case UTT_IsArray:
351 case UTT_IsBoundedArray:
352 case UTT_IsPointer:
353 case UTT_IsLvalueReference:
354 case UTT_IsRvalueReference:
355 case UTT_IsMemberFunctionPointer:
356 case UTT_IsMemberObjectPointer:
357 case UTT_IsEnum:
358 case UTT_IsScopedEnum:
359 case UTT_IsUnion:
360 case UTT_IsClass:
361 case UTT_IsFunction:
362 case UTT_IsReference:
363 case UTT_IsArithmetic:
364 case UTT_IsFundamental:
365 case UTT_IsObject:
366 case UTT_IsScalar:
367 case UTT_IsCompound:
368 case UTT_IsMemberPointer:
369 case UTT_IsTypedResourceElementCompatible:
370 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
600static bool IsTriviallyRelocatableType(Sema &SemaRef, QualType T) {
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
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.
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
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 =
1234 S.GetDecompositionElementCount(T, ArgRange.getBegin());
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
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
1472 if (Kind == TypeTrait::UTT_StructuredBindingSize)
1475}
1476
1479 SourceLocation RParenLoc) {
1480 if (!CheckTypeTraitArity(getTypeTraitArity(Kind), KWLoc, Args.size()))
1481 return ExprError();
1482
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
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
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
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 .Case("is_trivially_relocatable",
1958 TypeTrait::UTT_IsCppTriviallyRelocatable)
1959 .Case("is_trivially_copyable", TypeTrait::UTT_IsTriviallyCopyable)
1960 .Case("is_assignable", TypeTrait::BTT_IsAssignable)
1961 .Case("is_empty", TypeTrait::UTT_IsEmpty)
1962 .Case("is_standard_layout", TypeTrait::UTT_IsStandardLayout)
1963 .Case("is_aggregate", TypeTrait::UTT_IsAggregate)
1964 .Case("is_constructible", TypeTrait::TT_IsConstructible)
1965 .Case("is_final", TypeTrait::UTT_IsFinal)
1966 .Case("is_abstract", TypeTrait::UTT_IsAbstract)
1967 .Default(std::nullopt);
1968}
1969
1971 std::optional<std::pair<TypeTrait, llvm::SmallVector<QualType, 1>>>;
1972
1973// Recognize type traits that are builting type traits, or known standard
1974// type traits in <type_traits>. Note that at this point we assume the
1975// trait evaluated to false, so we need only to recognize the shape of the
1976// outer-most symbol.
1979 std::optional<TypeTrait> Trait;
1980
1981 // builtins
1982 if (const auto *TraitExpr = dyn_cast<TypeTraitExpr>(E)) {
1983 Trait = TraitExpr->getTrait();
1984 for (const auto *Arg : TraitExpr->getArgs())
1985 Args.push_back(Arg->getType());
1986 return {{Trait.value(), std::move(Args)}};
1987 }
1988 const auto *Ref = dyn_cast<DeclRefExpr>(E);
1989 if (!Ref)
1990 return std::nullopt;
1991
1992 // std::is_xxx_v<>
1993 if (const auto *VD =
1994 dyn_cast<VarTemplateSpecializationDecl>(Ref->getDecl())) {
1995 if (!VD->isInStdNamespace())
1996 return std::nullopt;
1997 StringRef Name = VD->getIdentifier()->getName();
1998 if (!Name.consume_back("_v"))
1999 return std::nullopt;
2000 Trait = StdNameToTypeTrait(Name);
2001 if (!Trait)
2002 return std::nullopt;
2003 for (const auto &Arg : VD->getTemplateArgs().asArray()) {
2004 if (Arg.getKind() == TemplateArgument::ArgKind::Pack) {
2005 for (const auto &InnerArg : Arg.pack_elements())
2006 Args.push_back(InnerArg.getAsType());
2007 } else if (Arg.getKind() == TemplateArgument::ArgKind::Type) {
2008 Args.push_back(Arg.getAsType());
2009 } else {
2010 llvm_unreachable("Unexpected kind");
2011 }
2012 }
2013 return {{Trait.value(), std::move(Args)}};
2014 }
2015
2016 // std::is_xxx<>::value
2017 if (const auto *VD = dyn_cast<VarDecl>(Ref->getDecl());
2018 Ref->hasQualifier() && VD && VD->getIdentifier()->isStr("value")) {
2019 NestedNameSpecifier Qualifier = Ref->getQualifier();
2020 if (Qualifier.getKind() != NestedNameSpecifier::Kind::Type)
2021 return std::nullopt;
2022 const auto *Ts = Qualifier.getAsType()->getAs<TemplateSpecializationType>();
2023 if (!Ts)
2024 return std::nullopt;
2025 const TemplateDecl *D = Ts->getTemplateName().getAsTemplateDecl();
2026 if (!D || !D->isInStdNamespace())
2027 return std::nullopt;
2028 Trait = StdNameToTypeTrait(D->getIdentifier()->getName());
2029 if (!Trait)
2030 return std::nullopt;
2031 for (const auto &Arg : Ts->template_arguments())
2032 Args.push_back(Arg.getAsType());
2033 return {{Trait.value(), std::move(Args)}};
2034 }
2035 return std::nullopt;
2036}
2037
2039 const CXXRecordDecl *D) {
2040 if (D->isUnion()) {
2041 auto DiagSPM = [&](CXXSpecialMemberKind K, bool Has) {
2042 if (Has)
2043 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2044 << diag::TraitNotSatisfiedReason::UnionWithUserDeclaredSMF << K;
2045 };
2054 return;
2055 }
2056
2058 const auto *Decl = cast_or_null<CXXConstructorDecl>(
2059 LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/false));
2060 if (Decl && Decl->isUserProvided())
2061 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2062 << diag::TraitNotSatisfiedReason::UserProvidedCtr
2063 << Decl->isMoveConstructor() << Decl->getSourceRange();
2064 }
2067 LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/true);
2068 if (Decl && Decl->isUserProvided())
2069 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2070 << diag::TraitNotSatisfiedReason::UserProvidedAssign
2071 << Decl->isMoveAssignmentOperator() << Decl->getSourceRange();
2072 }
2073 if (CXXDestructorDecl *Dtr = D->getDestructor()) {
2074 Dtr = Dtr->getCanonicalDecl();
2075 if (Dtr->isUserProvided() && !Dtr->isDefaulted())
2076 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2077 << diag::TraitNotSatisfiedReason::DeletedDtr << /*User Provided*/ 1
2078 << Dtr->getSourceRange();
2079 }
2080}
2081
2083 SourceLocation Loc,
2084 const CXXRecordDecl *D) {
2085 for (const CXXBaseSpecifier &B : D->bases()) {
2086 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2087 if (B.isVirtual())
2088 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2089 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2090 << B.getSourceRange();
2091 if (!SemaRef.IsCXXTriviallyRelocatableType(B.getType()))
2092 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2093 << diag::TraitNotSatisfiedReason::NTRBase << B.getType()
2094 << B.getSourceRange();
2095 }
2096 for (const FieldDecl *Field : D->fields()) {
2097 if (!Field->getType()->isReferenceType() &&
2098 !SemaRef.IsCXXTriviallyRelocatableType(Field->getType()))
2099 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2100 << diag::TraitNotSatisfiedReason::NTRField << Field
2101 << Field->getType() << Field->getSourceRange();
2102 }
2103 if (D->hasDeletedDestructor())
2104 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2105 << diag::TraitNotSatisfiedReason::DeletedDtr << /*Deleted*/ 0
2106 << D->getDestructor()->getSourceRange();
2107
2108 DiagnoseNonDefaultMovable(SemaRef, Loc, D);
2109}
2110
2112 SourceLocation Loc,
2113 QualType T) {
2114 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2115 << T << diag::TraitName::TriviallyRelocatable;
2116 if (T->isVariablyModifiedType())
2117 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2118 << diag::TraitNotSatisfiedReason::VLA;
2119
2120 if (T->isReferenceType())
2121 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2122 << diag::TraitNotSatisfiedReason::Ref;
2123 T = T.getNonReferenceType();
2124
2125 if (T.hasNonTrivialObjCLifetime())
2126 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2127 << diag::TraitNotSatisfiedReason::HasArcLifetime;
2128
2129 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2130 if (!D || D->isInvalidDecl())
2131 return;
2132
2133 if (D->hasDefinition())
2135
2136 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2137}
2138
2140 SourceLocation Loc,
2141 const CXXRecordDecl *D) {
2142 for (const CXXBaseSpecifier &B : D->bases()) {
2143 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2144 if (B.isVirtual())
2145 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2146 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2147 << B.getSourceRange();
2148 if (!B.getType().isTriviallyCopyableType(D->getASTContext())) {
2149 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2150 << diag::TraitNotSatisfiedReason::NTCBase << B.getType()
2151 << B.getSourceRange();
2152 }
2153 }
2154 for (const FieldDecl *Field : D->fields()) {
2155 if (!Field->getType().isTriviallyCopyableType(Field->getASTContext()))
2156 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2157 << diag::TraitNotSatisfiedReason::NTCField << Field
2158 << Field->getType() << Field->getSourceRange();
2159 }
2160 CXXDestructorDecl *Dtr = D->getDestructor();
2161 if (D->hasDeletedDestructor() || (Dtr && !Dtr->isTrivial()))
2162 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2163 << diag::TraitNotSatisfiedReason::DeletedDtr
2165
2166 for (const CXXMethodDecl *Method : D->methods()) {
2167 if (Method->isTrivial() || !Method->isUserProvided()) {
2168 continue;
2169 }
2170 auto SpecialMemberKind =
2171 SemaRef.getDefaultedFunctionKind(Method).asSpecialMember();
2172 switch (SpecialMemberKind) {
2177 bool IsAssignment =
2178 SpecialMemberKind == CXXSpecialMemberKind::CopyAssignment ||
2179 SpecialMemberKind == CXXSpecialMemberKind::MoveAssignment;
2180 bool IsMove =
2181 SpecialMemberKind == CXXSpecialMemberKind::MoveConstructor ||
2182 SpecialMemberKind == CXXSpecialMemberKind::MoveAssignment;
2183
2184 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2185 << (IsAssignment ? diag::TraitNotSatisfiedReason::UserProvidedAssign
2186 : diag::TraitNotSatisfiedReason::UserProvidedCtr)
2187 << IsMove << Method->getSourceRange();
2188 break;
2189 }
2190 default:
2191 break;
2192 }
2193 }
2194}
2195
2197 Sema &SemaRef, SourceLocation Loc,
2199 if (Ts.empty()) {
2200 return;
2201 }
2202
2203 bool ContainsVoid = false;
2204 for (const QualType &ArgTy : Ts) {
2205 ContainsVoid |= ArgTy->isVoidType();
2206 }
2207
2208 if (ContainsVoid)
2209 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2210 << diag::TraitNotSatisfiedReason::CVVoidType;
2211
2212 QualType T = Ts[0];
2213 if (T->isFunctionType())
2214 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2215 << diag::TraitNotSatisfiedReason::FunctionType;
2216
2217 if (T->isIncompleteArrayType())
2218 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2219 << diag::TraitNotSatisfiedReason::IncompleteArrayType;
2220
2221 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2222 if (!D || D->isInvalidDecl() || !D->hasDefinition())
2223 return;
2224
2225 llvm::BumpPtrAllocator OpaqueExprAllocator;
2226 SmallVector<Expr *, 2> ArgExprs;
2227 ArgExprs.reserve(Ts.size() - 1);
2228 for (unsigned I = 1, N = Ts.size(); I != N; ++I) {
2229 QualType ArgTy = Ts[I];
2230 if (ArgTy->isObjectType() || ArgTy->isFunctionType())
2231 ArgTy = SemaRef.Context.getRValueReferenceType(ArgTy);
2232 ArgExprs.push_back(
2233 new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
2234 OpaqueValueExpr(Loc, ArgTy.getNonLValueExprType(SemaRef.Context),
2236 }
2237
2240 Sema::ContextRAII TUContext(SemaRef,
2244 InitializationSequence Init(SemaRef, To, InitKind, ArgExprs);
2245
2246 Init.Diagnose(SemaRef, To, InitKind, ArgExprs);
2247 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2248}
2249
2251 SourceLocation Loc, QualType T) {
2252 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2253 << T << diag::TraitName::TriviallyCopyable;
2254
2255 if (T->isReferenceType())
2256 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2257 << diag::TraitNotSatisfiedReason::Ref;
2258
2259 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2260 if (!D || D->isInvalidDecl())
2261 return;
2262
2263 if (D->hasDefinition())
2264 DiagnoseNonTriviallyCopyableReason(SemaRef, Loc, D);
2265
2266 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2267}
2268
2270 QualType T, QualType U) {
2271 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2272
2273 auto createDeclValExpr = [&](QualType Ty) -> OpaqueValueExpr {
2274 if (Ty->isObjectType() || Ty->isFunctionType())
2275 Ty = SemaRef.Context.getRValueReferenceType(Ty);
2276 return {Loc, Ty.getNonLValueExprType(SemaRef.Context),
2278 };
2279
2280 auto LHS = createDeclValExpr(T);
2281 auto RHS = createDeclValExpr(U);
2282
2285 Sema::ContextRAII TUContext(SemaRef,
2287 SemaRef.BuildBinOp(/*S=*/nullptr, Loc, BO_Assign, &LHS, &RHS);
2288
2289 if (!D || D->isInvalidDecl())
2290 return;
2291
2292 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2293}
2294
2296 const CXXRecordDecl *D) {
2297 // Non-static data members (ignore zero-width bit‐fields).
2298 for (const auto *Field : D->fields()) {
2299 if (Field->isZeroLengthBitField())
2300 continue;
2301 if (Field->isBitField()) {
2302 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2303 << diag::TraitNotSatisfiedReason::NonZeroLengthField << Field
2304 << Field->getSourceRange();
2305 continue;
2306 }
2307 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2308 << diag::TraitNotSatisfiedReason::NonEmptyMember << Field
2309 << Field->getType() << Field->getSourceRange();
2310 }
2311
2312 // Virtual functions.
2313 for (const auto *M : D->methods()) {
2314 if (M->isVirtual()) {
2315 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2316 << diag::TraitNotSatisfiedReason::VirtualFunction << M
2317 << M->getSourceRange();
2318 break;
2319 }
2320 }
2321
2322 // Virtual bases and non-empty bases.
2323 for (const auto &B : D->bases()) {
2324 const auto *BR = B.getType()->getAsCXXRecordDecl();
2325 if (!BR || BR->isInvalidDecl())
2326 continue;
2327 if (B.isVirtual()) {
2328 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2329 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2330 << B.getSourceRange();
2331 }
2332 if (!BR->isEmpty()) {
2333 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2334 << diag::TraitNotSatisfiedReason::NonEmptyBase << B.getType()
2335 << B.getSourceRange();
2336 }
2337 }
2338}
2339
2341 // Emit primary "not empty" diagnostic.
2342 S.Diag(Loc, diag::note_unsatisfied_trait) << T << diag::TraitName::Empty;
2343
2344 // While diagnosing is_empty<T>, we want to look at the actual type, not a
2345 // reference or an array of it. So we need to massage the QualType param to
2346 // strip refs and arrays.
2347 if (T->isReferenceType())
2348 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2349 << diag::TraitNotSatisfiedReason::Ref;
2350 T = T.getNonReferenceType();
2351
2352 if (auto *AT = S.Context.getAsArrayType(T))
2353 T = AT->getElementType();
2354
2355 if (auto *D = T->getAsCXXRecordDecl()) {
2356 if (D->hasDefinition()) {
2357 DiagnoseIsEmptyReason(S, Loc, D);
2358 S.Diag(D->getLocation(), diag::note_defined_here) << D;
2359 }
2360 }
2361}
2362
2364 const CXXRecordDecl *D) {
2365 if (!D || D->isInvalidDecl())
2366 return;
2367
2368 // Complete record but not 'final'.
2369 if (!D->isEffectivelyFinal()) {
2370 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2371 << diag::TraitNotSatisfiedReason::NotMarkedFinal;
2372 S.Diag(D->getLocation(), diag::note_defined_here) << D;
2373 return;
2374 }
2375}
2376
2378 // Primary: “%0 is not final”
2379 S.Diag(Loc, diag::note_unsatisfied_trait) << T << diag::TraitName::Final;
2380 if (T->isReferenceType()) {
2381 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2382 << diag::TraitNotSatisfiedReason::Ref;
2383 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2384 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2385 return;
2386 }
2387 // Arrays / functions / non-records → not a class/union.
2388 if (S.Context.getAsArrayType(T)) {
2389 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2390 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2391 return;
2392 }
2393 if (T->isFunctionType()) {
2394 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2395 << diag::TraitNotSatisfiedReason::FunctionType;
2396 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2397 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2398 return;
2399 }
2400 if (!T->isRecordType()) {
2401 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2402 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2403 return;
2404 }
2405 if (const auto *D = T->getAsCXXRecordDecl())
2406 DiagnoseIsFinalReason(S, Loc, D);
2407}
2408
2410 int NumBasesWithFields = 0;
2411 for (const CXXBaseSpecifier &Base : D->bases()) {
2412 const CXXRecordDecl *BaseRD = Base.getType()->getAsCXXRecordDecl();
2413 if (!BaseRD || BaseRD->isInvalidDecl())
2414 continue;
2415
2416 for (const FieldDecl *Field : BaseRD->fields()) {
2417 if (!Field->isUnnamedBitField()) {
2418 if (++NumBasesWithFields > 1)
2419 return true; // found more than one base class with fields
2420 break; // no need to check further fields in this base class
2421 }
2422 }
2423 }
2424 return false;
2425}
2426
2428 const CXXRecordDecl *D) {
2429 for (const CXXBaseSpecifier &B : D->bases()) {
2430 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2431 if (B.isVirtual()) {
2432 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2433 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2434 << B.getSourceRange();
2435 }
2436 if (!B.getType()->isStandardLayoutType()) {
2437 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2438 << diag::TraitNotSatisfiedReason::NonStandardLayoutBase << B.getType()
2439 << B.getSourceRange();
2440 }
2441 }
2442 // Check for mixed access specifiers in fields.
2443 const FieldDecl *FirstField = nullptr;
2444 AccessSpecifier FirstAccess = AS_none;
2445
2446 for (const FieldDecl *Field : D->fields()) {
2447 if (Field->isUnnamedBitField())
2448 continue;
2449
2450 // Record the first field we see
2451 if (!FirstField) {
2452 FirstField = Field;
2453 FirstAccess = Field->getAccess();
2454 continue;
2455 }
2456
2457 // Check if the field has a different access specifier than the first one.
2458 if (Field->getAccess() != FirstAccess) {
2459 // Emit a diagnostic about mixed access specifiers.
2460 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2461 << diag::TraitNotSatisfiedReason::MixedAccess;
2462
2463 SemaRef.Diag(FirstField->getLocation(), diag::note_defined_here)
2464 << FirstField;
2465
2466 SemaRef.Diag(Field->getLocation(), diag::note_unsatisfied_trait_reason)
2467 << diag::TraitNotSatisfiedReason::MixedAccessField << Field
2468 << FirstField;
2469
2470 // No need to check further fields, as we already found mixed access.
2471 break;
2472 }
2473 }
2475 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2476 << diag::TraitNotSatisfiedReason::MultipleDataBase;
2477 }
2478 if (D->isPolymorphic()) {
2479 // Find the best location to point “defined here” at.
2480 const CXXMethodDecl *VirtualMD = nullptr;
2481 // First, look for a virtual method.
2482 for (const auto *M : D->methods()) {
2483 if (M->isVirtual()) {
2484 VirtualMD = M;
2485 break;
2486 }
2487 }
2488 if (VirtualMD) {
2489 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2490 << diag::TraitNotSatisfiedReason::VirtualFunction << VirtualMD;
2491 SemaRef.Diag(VirtualMD->getLocation(), diag::note_defined_here)
2492 << VirtualMD;
2493 } else {
2494 // If no virtual method, point to the record declaration itself.
2495 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2496 << diag::TraitNotSatisfiedReason::VirtualFunction << D;
2497 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2498 }
2499 }
2500 for (const FieldDecl *Field : D->fields()) {
2501 if (!Field->getType()->isStandardLayoutType()) {
2502 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2503 << diag::TraitNotSatisfiedReason::NonStandardLayoutMember << Field
2504 << Field->getType() << Field->getSourceRange();
2505 }
2506 }
2507 // Find any indirect base classes that have fields.
2508 if (D->hasDirectFields()) {
2509 const CXXRecordDecl *Indirect = nullptr;
2510 D->forallBases([&](const CXXRecordDecl *BaseDef) {
2511 if (BaseDef->hasDirectFields()) {
2512 Indirect = BaseDef;
2513 return false; // stop traversal
2514 }
2515 return true; // continue to the next base
2516 });
2517 if (Indirect) {
2518 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2519 << diag::TraitNotSatisfiedReason::IndirectBaseWithFields << Indirect
2520 << Indirect->getSourceRange();
2521 }
2522 }
2523}
2524
2526 QualType T) {
2527 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2528 << T << diag::TraitName::StandardLayout;
2529
2530 // Check type-level exclusion first.
2531 if (T->isVariablyModifiedType()) {
2532 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2533 << diag::TraitNotSatisfiedReason::VLA;
2534 return;
2535 }
2536
2537 if (T->isReferenceType()) {
2538 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2539 << diag::TraitNotSatisfiedReason::Ref;
2540 return;
2541 }
2542 T = T.getNonReferenceType();
2543 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2544 if (!D || D->isInvalidDecl())
2545 return;
2546
2547 if (D->hasDefinition())
2548 DiagnoseNonStandardLayoutReason(SemaRef, Loc, D);
2549
2550 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2551}
2552
2554 const CXXRecordDecl *D) {
2555 for (const CXXConstructorDecl *Ctor : D->ctors()) {
2556 if (Ctor->isUserProvided())
2557 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2558 << diag::TraitNotSatisfiedReason::UserDeclaredCtr;
2559 if (Ctor->isInheritingConstructor())
2560 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2561 << diag::TraitNotSatisfiedReason::InheritedCtr;
2562 }
2563
2564 if (llvm::any_of(D->decls(), [](auto const *Sub) {
2565 return isa<ConstructorUsingShadowDecl>(Sub);
2566 })) {
2567 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2568 << diag::TraitNotSatisfiedReason::InheritedCtr;
2569 }
2570
2571 if (D->isPolymorphic())
2572 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2573 << diag::TraitNotSatisfiedReason::PolymorphicType
2574 << D->getSourceRange();
2575
2576 for (const CXXBaseSpecifier &B : D->bases()) {
2577 if (B.isVirtual()) {
2578 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2579 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2580 << B.getSourceRange();
2581 continue;
2582 }
2583 auto AccessSpecifier = B.getAccessSpecifier();
2584 switch (AccessSpecifier) {
2585 case AS_private:
2586 case AS_protected:
2587 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2588 << diag::TraitNotSatisfiedReason::PrivateProtectedDirectBase
2590 break;
2591 default:
2592 break;
2593 }
2594 }
2595
2596 for (const CXXMethodDecl *Method : D->methods()) {
2597 if (Method->isVirtual()) {
2598 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2599 << diag::TraitNotSatisfiedReason::VirtualFunction << Method
2600 << Method->getSourceRange();
2601 }
2602 }
2603
2604 for (const FieldDecl *Field : D->fields()) {
2605 auto AccessSpecifier = Field->getAccess();
2606 switch (AccessSpecifier) {
2607 case AS_private:
2608 case AS_protected:
2609 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2610 << diag::TraitNotSatisfiedReason::PrivateProtectedDirectDataMember
2612 break;
2613 default:
2614 break;
2615 }
2616 }
2617
2618 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2619}
2620
2622 QualType T) {
2623 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2624 << T << diag::TraitName::Aggregate;
2625
2626 if (T->isVoidType())
2627 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2628 << diag::TraitNotSatisfiedReason::CVVoidType;
2629
2630 T = T.getNonReferenceType();
2631 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2632 if (!D || D->isInvalidDecl())
2633 return;
2634
2635 if (D->hasDefinition())
2636 DiagnoseNonAggregateReason(SemaRef, Loc, D);
2637}
2638
2640 const CXXRecordDecl *D) {
2641 // If this type has any abstract base classes, their respective virtual
2642 // functions must have been overridden.
2643 for (const CXXBaseSpecifier &B : D->bases()) {
2644 if (B.getType()->castAsCXXRecordDecl()->isAbstract()) {
2645 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2646 << diag::TraitNotSatisfiedReason::OverridesAllPureVirtual
2647 << B.getType() << B.getSourceRange();
2648 }
2649 }
2650}
2651
2653 QualType T) {
2654 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2655 << T << diag::TraitName::Abstract;
2656
2657 if (T->isReferenceType()) {
2658 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2659 << diag::TraitNotSatisfiedReason::Ref;
2660 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2661 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2662 return;
2663 }
2664
2665 if (T->isUnionType()) {
2666 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2667 << diag::TraitNotSatisfiedReason::UnionType;
2668 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2669 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2670 return;
2671 }
2672
2673 if (SemaRef.Context.getAsArrayType(T)) {
2674 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2675 << diag::TraitNotSatisfiedReason::ArrayType;
2676 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2677 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2678 return;
2679 }
2680
2681 if (T->isFunctionType()) {
2682 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2683 << diag::TraitNotSatisfiedReason::FunctionType;
2684 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2685 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2686 return;
2687 }
2688
2689 if (T->isPointerType()) {
2690 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2691 << diag::TraitNotSatisfiedReason::PointerType;
2692 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2693 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2694 return;
2695 }
2696
2697 if (!T->isStructureOrClassType()) {
2698 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2699 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2700 return;
2701 }
2702
2703 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2704 if (D->hasDefinition())
2705 DiagnoseNonAbstractReason(SemaRef, Loc, D);
2706}
2707
2709 E = E->IgnoreParenImpCasts();
2710 if (E->containsErrors())
2711 return;
2712
2714 if (!TraitInfo)
2715 return;
2716
2717 const auto &[Trait, Args] = TraitInfo.value();
2718 switch (Trait) {
2719 case UTT_IsCppTriviallyRelocatable:
2721 break;
2722 case UTT_IsTriviallyCopyable:
2723 DiagnoseNonTriviallyCopyableReason(*this, E->getBeginLoc(), Args[0]);
2724 break;
2725 case BTT_IsAssignable:
2726 DiagnoseNonAssignableReason(*this, E->getBeginLoc(), Args[0], Args[1]);
2727 break;
2728 case UTT_IsEmpty:
2729 DiagnoseIsEmptyReason(*this, E->getBeginLoc(), Args[0]);
2730 break;
2731 case UTT_IsStandardLayout:
2732 DiagnoseNonStandardLayoutReason(*this, E->getBeginLoc(), Args[0]);
2733 break;
2734 case TT_IsConstructible:
2736 break;
2737 case UTT_IsAggregate:
2738 DiagnoseNonAggregateReason(*this, E->getBeginLoc(), Args[0]);
2739 break;
2740 case UTT_IsFinal: {
2741 QualType QT = Args[0];
2742 if (QT->isDependentType())
2743 break;
2744 const auto *RD = QT->getAsCXXRecordDecl();
2745 if (!RD || !RD->isEffectivelyFinal())
2746 DiagnoseIsFinalReason(*this, E->getBeginLoc(), QT); // unsatisfied
2747 break;
2748 }
2749 case UTT_IsAbstract:
2750 DiagnoseNonAbstractReason(*this, E->getBeginLoc(), Args[0]);
2751 break;
2752 default:
2753 break;
2754 }
2755}
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
static void DiagnoseNonAggregateReason(Sema &SemaRef, SourceLocation Loc, const CXXRecordDecl *D)
static bool EvaluateBooleanTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, ArrayRef< TypeSourceInfo * > Args, SourceLocation RParenLoc, bool IsDependent)
static bool isTriviallyEqualityComparableType(Sema &S, QualType Type, SourceLocation KeyLoc)
Defines various enumerations that describe declaration and type specifiers.
Defines enumerations for the type traits support.
C Language Family Type Representation.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition APValue.h:122
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h: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:809
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:710
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:3000
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition TypeBase.h:3786
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:2749
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
Definition DeclCXX.cpp:2728
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:611
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:2339
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:2146
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:2127
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:3824
A POD class for pairing a NamedDecl* with an access specifier.
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
DeclContextLookupResult lookup_result
Definition DeclBase.h:2594
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:2390
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
bool isInStdNamespace() const
Definition DeclBase.cpp:450
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:547
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:4046
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:3099
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:3073
Represents a member of a struct/union/class.
Definition Decl.h:3195
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition Decl.h:2404
bool isDeleted() const
Whether this function has been deleted.
Definition Decl.h:2567
bool isDefaulted() const
Whether this function is defaulted.
Definition Decl.h:2412
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4546
bool isUserProvided() const
True if this method is user-declared and was not deleted or defaulted on its first declaration.
Definition Decl.h:2437
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5371
unsigned getNumParams() const
Definition TypeBase.h:5649
bool isNothrow(bool ResultIfDependent=false) const
Determine whether this function type has a non-throwing exception specification.
Definition TypeBase.h:5770
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:937
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:8632
bool hasNonTrivialObjCLifetime() const
Definition TypeBase.h:1457
@ PCK_Trivial
The type does not fall into any of the following categories.
Definition TypeBase.h:1508
@ PCK_ARCStrong
The type is an Objective-C retainable pointer type that is qualified with the ARC __strong qualifier.
Definition TypeBase.h:1517
The collection of all-type qualifiers we support.
Definition TypeBase.h:331
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
Definition TypeBase.h:361
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
Definition TypeBase.h:354
@ OCL_None
There is no lifetime qualification on this type.
Definition TypeBase.h:350
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Definition TypeBase.h:364
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
Definition TypeBase.h:367
bool canPassInRegisters() const
Determine whether this class can be passed in registers.
Definition Decl.h:4497
field_range fields() const
Definition Decl.h:4563
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:6472
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
Definition Sema.h:12550
bool hasErrorOccurred() const
Determine whether any SFINAE errors have been trapped.
Definition Sema.h:12584
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:869
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:9415
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:6797
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:3752
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4890
bool isUnion() const
Definition Decl.h:3963
bool isDependentType() const
Whether this declaration declares a type that is dependent, i.e., a type that somehow depends on temp...
Definition Decl.h:3898
@ 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:8418
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:8429
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:1907
The base class of the type hierarchy.
Definition TypeBase.h:1875
bool isVoidType() const
Definition TypeBase.h:9050
bool isIncompleteArrayType() const
Definition TypeBase.h:8791
bool isRValueReferenceType() const
Definition TypeBase.h:8716
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:8783
CanQualType getCanonicalTypeUnqualified() const
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9344
bool isEnumeralType() const
Definition TypeBase.h:8815
bool isScalarType() const
Definition TypeBase.h:9156
bool isVariableArrayType() const
Definition TypeBase.h:8795
bool isLValueReferenceType() const
Definition TypeBase.h:8712
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition TypeBase.h:2846
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:9230
bool isObjectType() const
Determine whether this type is an object type.
Definition TypeBase.h:2570
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:8680
bool isStructureOrClassType() const
Definition Type.cpp:743
bool isVectorType() const
Definition TypeBase.h:8823
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition TypeBase.h:2985
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9277
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:27
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
bool isa(CodeGen::Address addr)
Definition Address.h:330
ArrayTypeTrait
Names for the array type traits.
Definition TypeTraits.h:42
@ CPlusPlus
unsigned getTypeTraitArity(TypeTrait T) LLVM_READONLY
Return the arity of the type trait T.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ OR_Deleted
Succeeded, but refers to a deleted function.
Definition Overload.h:61
@ OR_Success
Overload resolution succeeded.
Definition Overload.h:52
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition Specifiers.h: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
@ Result
The result type of a method or function.
Definition TypeBase.h:905
OptionalUnsigned< unsigned > UnsignedOrNone
ExprResult ExprError()
Definition Ownership.h:265
CXXSpecialMemberKind
Kinds of C++ special members.
Definition Sema.h:427
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
Definition Specifiers.h: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
const char * getTraitSpelling(ExpressionTrait T) LLVM_READONLY
Return the spelling of the type trait TT. Never null.
@ Success
Template argument deduction was successful.
Definition Sema.h:371
U cast(CodeGen::Address addr)
Definition Address.h:327
ConstructorInfo getConstructorInfo(NamedDecl *ND)
Definition Overload.h:1519
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
Definition Ownership.h:230
ActionResult< Expr * > ExprResult
Definition Ownership.h:249
TypeTrait
Names for traits that operate specifically on types.
Definition TypeTraits.h:21
@ BTT_Last
Definition TypeTraits.h:30
@ UTT_Last
Definition TypeTraits.h:24
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...