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 // Precondition: T and all types in the parameter pack Args shall be
1289 // complete types, (possibly cv-qualified) void, or arrays of
1290 // unknown bound.
1291 for (const auto *TSI : Args) {
1292 QualType ArgTy = TSI->getType();
1293 if (ArgTy->isVoidType() || ArgTy->isIncompleteArrayType())
1294 continue;
1295
1296 if (S.RequireCompleteType(
1297 KWLoc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr))
1298 return false;
1299 }
1300
1301 // Make sure the first argument is not incomplete nor a function type.
1302 QualType T = Args[0]->getType();
1303 if (T->isIncompleteType() || T->isFunctionType())
1304 return false;
1305
1306 // Make sure the first argument is not an abstract type.
1307 CXXRecordDecl *RD = T->getAsCXXRecordDecl();
1308 if (RD && RD->isAbstract())
1309 return false;
1310
1311 // LWG3819: For reference_meows_from_temporary traits, && is not added to
1312 // the source object type.
1313 // Otherwise, compute the result of add_rvalue_reference_t.
1314 bool UseRawObjectType =
1315 Kind == clang::BTT_ReferenceBindsToTemporary ||
1316 Kind == clang::BTT_ReferenceConstructsFromTemporary ||
1317 Kind == clang::BTT_ReferenceConvertsFromTemporary;
1318
1319 llvm::BumpPtrAllocator OpaqueExprAllocator;
1320 SmallVector<Expr *, 2> ArgExprs;
1321 ArgExprs.reserve(Args.size() - 1);
1322 for (unsigned I = 1, N = Args.size(); I != N; ++I) {
1323 QualType ArgTy = Args[I]->getType();
1324 if ((ArgTy->isObjectType() && !UseRawObjectType) ||
1325 ArgTy->isFunctionType())
1326 ArgTy = S.Context.getRValueReferenceType(ArgTy);
1327 ArgExprs.push_back(
1328 new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
1329 OpaqueValueExpr(Args[I]->getTypeLoc().getBeginLoc(),
1332 }
1333
1334 // Perform the initialization in an unevaluated context within a SFINAE
1335 // trap at translation unit scope.
1338 Sema::SFINAETrap SFINAE(S, /*ForValidityCheck=*/true);
1342 InitializationKind InitKind(
1343 Kind == clang::BTT_ReferenceConvertsFromTemporary
1344 ? InitializationKind::CreateCopy(KWLoc, KWLoc)
1345 : InitializationKind::CreateDirect(KWLoc, KWLoc, RParenLoc));
1346 InitializationSequence Init(S, To, InitKind, ArgExprs);
1347 if (Init.Failed())
1348 return false;
1349
1350 ExprResult Result = Init.Perform(S, To, InitKind, ArgExprs);
1351 if (Result.isInvalid() || SFINAE.hasErrorOccurred())
1352 return false;
1353
1354 if (Kind == clang::TT_IsConstructible)
1355 return true;
1356
1357 if (Kind == clang::BTT_ReferenceBindsToTemporary ||
1358 Kind == clang::BTT_ReferenceConstructsFromTemporary ||
1359 Kind == clang::BTT_ReferenceConvertsFromTemporary) {
1360 if (!T->isReferenceType())
1361 return false;
1362
1363 // A function reference never binds to a temporary object.
1364 if (T.getNonReferenceType()->isFunctionType())
1365 return false;
1366
1367 if (!Init.isDirectReferenceBinding())
1368 return true;
1369
1370 if (Kind == clang::BTT_ReferenceBindsToTemporary)
1371 return false;
1372
1373 QualType U = Args[1]->getType();
1374 if (U->isReferenceType())
1375 return false;
1376
1378 S.Context.getPointerType(T.getNonReferenceType()));
1380 S.Context.getPointerType(U.getNonReferenceType()));
1381 return !CheckConvertibilityForTypeTraits(S, UPtr, TPtr, RParenLoc,
1382 OpaqueExprAllocator)
1383 .isInvalid();
1384 }
1385
1386 if (Kind == clang::TT_IsNothrowConstructible)
1387 return S.canThrow(Result.get()) == CT_Cannot;
1388
1389 if (Kind == clang::TT_IsTriviallyConstructible) {
1390 // Under Objective-C ARC and Weak, if the destination has non-trivial
1391 // Objective-C lifetime, this is a non-trivial construction.
1392 if (T.getNonReferenceType().hasNonTrivialObjCLifetime())
1393 return false;
1394
1395 // The initialization succeeded; now make sure there are no non-trivial
1396 // calls.
1397 return !Result.get()->hasNonTrivialCall(S.Context);
1398 }
1399
1400 llvm_unreachable("unhandled type trait");
1401 return false;
1402 }
1403 default:
1404 llvm_unreachable("not a TT");
1405 }
1406
1407 return false;
1408}
1409
1410namespace {
1411void DiagnoseBuiltinDeprecation(Sema &S, TypeTrait Kind, SourceLocation KWLoc) {
1412 TypeTrait Replacement;
1413 switch (Kind) {
1414 case UTT_HasNothrowAssign:
1415 case UTT_HasNothrowMoveAssign:
1416 Replacement = BTT_IsNothrowAssignable;
1417 break;
1418 case UTT_HasNothrowCopy:
1419 case UTT_HasNothrowConstructor:
1420 Replacement = TT_IsNothrowConstructible;
1421 break;
1422 case UTT_HasTrivialAssign:
1423 case UTT_HasTrivialMoveAssign:
1424 Replacement = BTT_IsTriviallyAssignable;
1425 break;
1426 case UTT_HasTrivialCopy:
1427 Replacement = UTT_IsTriviallyCopyable;
1428 break;
1429 case UTT_HasTrivialDefaultConstructor:
1430 case UTT_HasTrivialMoveConstructor:
1431 Replacement = TT_IsTriviallyConstructible;
1432 break;
1433 case UTT_HasTrivialDestructor:
1434 Replacement = UTT_IsTriviallyDestructible;
1435 break;
1436 case UTT_IsTriviallyRelocatable:
1437 Replacement = clang::UTT_IsCppTriviallyRelocatable;
1438 break;
1439 case BTT_ReferenceBindsToTemporary:
1440 Replacement = clang::BTT_ReferenceConstructsFromTemporary;
1441 break;
1442 default:
1443 return;
1444 }
1445 S.Diag(KWLoc, diag::warn_deprecated_builtin)
1446 << getTraitSpelling(Kind) << getTraitSpelling(Replacement);
1447}
1448} // namespace
1449
1450bool Sema::CheckTypeTraitArity(unsigned Arity, SourceLocation Loc, size_t N) {
1451 if (Arity && N != Arity) {
1452 Diag(Loc, diag::err_type_trait_arity)
1453 << Arity << 0 << (Arity > 1) << (int)N << SourceRange(Loc);
1454 return false;
1455 }
1456
1457 if (!Arity && N == 0) {
1458 Diag(Loc, diag::err_type_trait_arity)
1459 << 1 << 1 << 1 << (int)N << SourceRange(Loc);
1460 return false;
1461 }
1462 return true;
1463}
1464
1469
1471 if (Kind == TypeTrait::UTT_StructuredBindingSize)
1474}
1475
1478 SourceLocation RParenLoc) {
1479 if (!CheckTypeTraitArity(getTypeTraitArity(Kind), KWLoc, Args.size()))
1480 return ExprError();
1481
1483 *this, Kind, KWLoc, Args[0]->getType()))
1484 return ExprError();
1485
1486 DiagnoseBuiltinDeprecation(*this, Kind, KWLoc);
1487
1488 bool Dependent = false;
1489 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
1490 if (Args[I]->getType()->isDependentType()) {
1491 Dependent = true;
1492 break;
1493 }
1494 }
1495
1496 switch (GetReturnType(Kind)) {
1498 bool Result = EvaluateBooleanTypeTrait(*this, Kind, KWLoc, Args, RParenLoc,
1499 Dependent);
1500 return TypeTraitExpr::Create(Context, Context.getLogicalOperationType(),
1501 KWLoc, Kind, Args, RParenLoc, Result);
1502 }
1504 APValue Result =
1505 EvaluateSizeTTypeTrait(*this, Kind, KWLoc, Args, RParenLoc, Dependent);
1506 return TypeTraitExpr::Create(Context, Context.getSizeType(), KWLoc, Kind,
1507 Args, RParenLoc, Result);
1508 }
1509 }
1510 llvm_unreachable("unhandled type trait return type");
1511}
1512
1515 SourceLocation RParenLoc) {
1517 ConvertedArgs.reserve(Args.size());
1518
1519 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
1520 TypeSourceInfo *TInfo;
1521 QualType T = GetTypeFromParser(Args[I], &TInfo);
1522 if (!TInfo)
1523 TInfo = Context.getTrivialTypeSourceInfo(T, KWLoc);
1524
1525 ConvertedArgs.push_back(TInfo);
1526 }
1527
1528 return BuildTypeTrait(Kind, KWLoc, ConvertedArgs, RParenLoc);
1529}
1530
1532 QualType RhsT) {
1533 // C++0x [meta.rel]p2
1534 // Base is a base class of Derived without regard to cv-qualifiers or
1535 // Base and Derived are not unions and name the same class type without
1536 // regard to cv-qualifiers.
1537
1538 const RecordType *lhsRecord = LhsT->getAsCanonical<RecordType>();
1539 const RecordType *rhsRecord = RhsT->getAsCanonical<RecordType>();
1540 if (!rhsRecord || !lhsRecord) {
1541 const ObjCObjectType *LHSObjTy = LhsT->getAs<ObjCObjectType>();
1542 const ObjCObjectType *RHSObjTy = RhsT->getAs<ObjCObjectType>();
1543 if (!LHSObjTy || !RHSObjTy)
1544 return false;
1545
1546 ObjCInterfaceDecl *BaseInterface = LHSObjTy->getInterface();
1547 ObjCInterfaceDecl *DerivedInterface = RHSObjTy->getInterface();
1548 if (!BaseInterface || !DerivedInterface)
1549 return false;
1550
1551 if (RequireCompleteType(RhsTLoc, RhsT,
1552 diag::err_incomplete_type_used_in_type_trait_expr))
1553 return false;
1554
1555 return BaseInterface->isSuperClassOf(DerivedInterface);
1556 }
1557
1558 assert(Context.hasSameUnqualifiedType(LhsT, RhsT) ==
1559 (lhsRecord == rhsRecord));
1560
1561 // Unions are never base classes, and never have base classes.
1562 // It doesn't matter if they are complete or not. See PR#41843
1563 if (lhsRecord && lhsRecord->getDecl()->isUnion())
1564 return false;
1565 if (rhsRecord && rhsRecord->getDecl()->isUnion())
1566 return false;
1567
1568 if (lhsRecord == rhsRecord)
1569 return true;
1570
1571 // C++0x [meta.rel]p2:
1572 // If Base and Derived are class types and are different types
1573 // (ignoring possible cv-qualifiers) then Derived shall be a
1574 // complete type.
1575 if (RequireCompleteType(RhsTLoc, RhsT,
1576 diag::err_incomplete_type_used_in_type_trait_expr))
1577 return false;
1578
1579 return cast<CXXRecordDecl>(rhsRecord->getDecl())
1580 ->isDerivedFrom(cast<CXXRecordDecl>(lhsRecord->getDecl()));
1581}
1582
1584 const TypeSourceInfo *Lhs,
1585 const TypeSourceInfo *Rhs,
1586 SourceLocation KeyLoc) {
1587 QualType LhsT = Lhs->getType();
1588 QualType RhsT = Rhs->getType();
1589
1590 assert(!LhsT->isDependentType() && !RhsT->isDependentType() &&
1591 "Cannot evaluate traits of dependent types");
1592
1593 switch (BTT) {
1594 case BTT_IsBaseOf:
1595 return Self.BuiltinIsBaseOf(Rhs->getTypeLoc().getBeginLoc(), LhsT, RhsT);
1596
1597 case BTT_IsVirtualBaseOf: {
1598 const RecordType *BaseRecord = LhsT->getAsCanonical<RecordType>();
1599 const RecordType *DerivedRecord = RhsT->getAsCanonical<RecordType>();
1600
1601 if (!BaseRecord || !DerivedRecord) {
1603 tok::kw___builtin_is_virtual_base_of);
1605 tok::kw___builtin_is_virtual_base_of);
1606 return false;
1607 }
1608
1609 if (BaseRecord->isUnionType() || DerivedRecord->isUnionType())
1610 return false;
1611
1612 if (!BaseRecord->isStructureOrClassType() ||
1613 !DerivedRecord->isStructureOrClassType())
1614 return false;
1615
1616 if (Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1617 diag::err_incomplete_type))
1618 return false;
1619
1620 return cast<CXXRecordDecl>(DerivedRecord->getDecl())
1621 ->isVirtuallyDerivedFrom(cast<CXXRecordDecl>(BaseRecord->getDecl()));
1622 }
1623 case BTT_IsSame:
1624 return Self.Context.hasSameType(LhsT, RhsT);
1625 case BTT_TypeCompatible: {
1626 // GCC ignores cv-qualifiers on arrays for this builtin.
1627 Qualifiers LhsQuals, RhsQuals;
1628 QualType Lhs = Self.getASTContext().getUnqualifiedArrayType(LhsT, LhsQuals);
1629 QualType Rhs = Self.getASTContext().getUnqualifiedArrayType(RhsT, RhsQuals);
1630 return Self.Context.typesAreCompatible(Lhs, Rhs);
1631 }
1632 case BTT_IsConvertible:
1633 case BTT_IsConvertibleTo:
1634 case BTT_IsNothrowConvertible: {
1635 if (RhsT->isVoidType())
1636 return LhsT->isVoidType();
1637 llvm::BumpPtrAllocator OpaqueExprAllocator;
1639 OpaqueExprAllocator);
1640 if (Result.isInvalid())
1641 return false;
1642
1643 if (BTT != BTT_IsNothrowConvertible)
1644 return true;
1645
1646 return Self.canThrow(Result.get()) == CT_Cannot;
1647 }
1648
1649 case BTT_IsAssignable:
1650 case BTT_IsNothrowAssignable:
1651 case BTT_IsTriviallyAssignable: {
1652 // C++11 [meta.unary.prop]p3:
1653 // is_trivially_assignable is defined as:
1654 // is_assignable<T, U>::value is true and the assignment, as defined by
1655 // is_assignable, is known to call no operation that is not trivial
1656 //
1657 // is_assignable is defined as:
1658 // The expression declval<T>() = declval<U>() is well-formed when
1659 // treated as an unevaluated operand (Clause 5).
1660 //
1661 // For both, T and U shall be complete types, (possibly cv-qualified)
1662 // void, or arrays of unknown bound.
1663 if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType() &&
1664 Self.RequireCompleteType(
1665 Lhs->getTypeLoc().getBeginLoc(), LhsT,
1666 diag::err_incomplete_type_used_in_type_trait_expr))
1667 return false;
1668 if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType() &&
1669 Self.RequireCompleteType(
1670 Rhs->getTypeLoc().getBeginLoc(), RhsT,
1671 diag::err_incomplete_type_used_in_type_trait_expr))
1672 return false;
1673
1674 // cv void is never assignable.
1675 if (LhsT->isVoidType() || RhsT->isVoidType())
1676 return false;
1677
1678 // Build expressions that emulate the effect of declval<T>() and
1679 // declval<U>().
1680 auto createDeclValExpr = [&](QualType Ty) -> OpaqueValueExpr {
1681 if (Ty->isObjectType() || Ty->isFunctionType())
1682 Ty = Self.Context.getRValueReferenceType(Ty);
1683 return {KeyLoc, Ty.getNonLValueExprType(Self.Context),
1685 };
1686
1687 auto Lhs = createDeclValExpr(LhsT);
1688 auto Rhs = createDeclValExpr(RhsT);
1689
1690 // Attempt the assignment in an unevaluated context within a SFINAE
1691 // trap at translation unit scope.
1694 Sema::SFINAETrap SFINAE(Self, /*ForValidityCheck=*/true);
1695 Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
1697 Self.BuildBinOp(/*S=*/nullptr, KeyLoc, BO_Assign, &Lhs, &Rhs);
1698 if (Result.isInvalid())
1699 return false;
1700
1701 // Treat the assignment as unused for the purpose of -Wdeprecated-volatile.
1702 Self.CheckUnusedVolatileAssignment(Result.get());
1703
1704 if (SFINAE.hasErrorOccurred())
1705 return false;
1706
1707 if (BTT == BTT_IsAssignable)
1708 return true;
1709
1710 if (BTT == BTT_IsNothrowAssignable)
1711 return Self.canThrow(Result.get()) == CT_Cannot;
1712
1713 if (BTT == BTT_IsTriviallyAssignable) {
1714 // Under Objective-C ARC and Weak, if the destination has non-trivial
1715 // Objective-C lifetime, this is a non-trivial assignment.
1717 return false;
1718 const ASTContext &Context = Self.getASTContext();
1719 if (Context.containsAddressDiscriminatedPointerAuth(LhsT) ||
1720 Context.containsAddressDiscriminatedPointerAuth(RhsT))
1721 return false;
1722 return !Result.get()->hasNonTrivialCall(Self.Context);
1723 }
1724
1725 llvm_unreachable("unhandled type trait");
1726 return false;
1727 }
1728 case BTT_IsLayoutCompatible: {
1729 if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType())
1730 Self.RequireCompleteType(Lhs->getTypeLoc().getBeginLoc(), LhsT,
1731 diag::err_incomplete_type);
1732 if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType())
1733 Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1734 diag::err_incomplete_type);
1735
1736 DiagnoseVLAInCXXTypeTrait(Self, Lhs, tok::kw___is_layout_compatible);
1737 DiagnoseVLAInCXXTypeTrait(Self, Rhs, tok::kw___is_layout_compatible);
1738
1739 return Self.IsLayoutCompatible(LhsT, RhsT);
1740 }
1741 case BTT_IsPointerInterconvertibleBaseOf: {
1742 if (LhsT->isStructureOrClassType() && RhsT->isStructureOrClassType() &&
1743 !Self.getASTContext().hasSameUnqualifiedType(LhsT, RhsT)) {
1744 Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1745 diag::err_incomplete_type);
1746 }
1747
1749 tok::kw___is_pointer_interconvertible_base_of);
1751 tok::kw___is_pointer_interconvertible_base_of);
1752
1753 return Self.IsPointerInterconvertibleBaseOf(Lhs, Rhs);
1754 }
1755 case BTT_IsDeducible: {
1756 const auto *TSTToBeDeduced = cast<DeducedTemplateSpecializationType>(LhsT);
1757 sema::TemplateDeductionInfo Info(KeyLoc);
1758 return Self.DeduceTemplateArgumentsFromType(
1759 TSTToBeDeduced->getTemplateName().getAsTemplateDecl(), RhsT,
1761 }
1762 case BTT_IsScalarizedLayoutCompatible: {
1763 if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType() &&
1764 Self.RequireCompleteType(Lhs->getTypeLoc().getBeginLoc(), LhsT,
1765 diag::err_incomplete_type))
1766 return true;
1767 if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType() &&
1768 Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1769 diag::err_incomplete_type))
1770 return true;
1771
1773 Self, Lhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1775 Self, Rhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1776
1777 return Self.HLSL().IsScalarizedLayoutCompatible(LhsT, RhsT);
1778 }
1779 case BTT_LtSynthesizesFromSpaceship:
1780 case BTT_LeSynthesizesFromSpaceship:
1781 case BTT_GtSynthesizesFromSpaceship:
1782 case BTT_GeSynthesizesFromSpaceship: {
1783 EnterExpressionEvaluationContext UnevaluatedContext(
1785 Sema::SFINAETrap SFINAE(Self, /*ForValidityCheck=*/true);
1786 Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
1787
1788 OpaqueValueExpr LHS(KeyLoc, LhsT.getNonReferenceType(),
1790 : LhsT->isRValueReferenceType()
1793 OpaqueValueExpr RHS(KeyLoc, RhsT.getNonReferenceType(),
1795 : RhsT->isRValueReferenceType()
1798
1799 auto OpKind = [&] {
1800 switch (BTT) {
1801 case BTT_LtSynthesizesFromSpaceship:
1802 return BinaryOperatorKind::BO_LT;
1803 case BTT_LeSynthesizesFromSpaceship:
1804 return BinaryOperatorKind::BO_LE;
1805 case BTT_GtSynthesizesFromSpaceship:
1806 return BinaryOperatorKind::BO_GT;
1807 case BTT_GeSynthesizesFromSpaceship:
1808 return BinaryOperatorKind::BO_GE;
1809 default:
1810 llvm_unreachable("Trying to Synthesize non-comparison operator?");
1811 }
1812 }();
1813
1814 UnresolvedSet<16> Functions;
1815 Self.LookupBinOp(Self.TUScope, KeyLoc, OpKind, Functions);
1816
1818 Self.CreateOverloadedBinOp(KeyLoc, OpKind, Functions, &LHS, &RHS);
1819 if (Result.isInvalid() || SFINAE.hasErrorOccurred())
1820 return false;
1821
1823 }
1824 default:
1825 llvm_unreachable("not a BTT");
1826 }
1827 llvm_unreachable("Unknown type trait or not implemented");
1828}
1829
1831 ParsedType Ty, Expr *DimExpr,
1832 SourceLocation RParen) {
1833 TypeSourceInfo *TSInfo;
1834 QualType T = GetTypeFromParser(Ty, &TSInfo);
1835 if (!TSInfo)
1836 TSInfo = Context.getTrivialTypeSourceInfo(T);
1837
1838 return BuildArrayTypeTrait(ATT, KWLoc, TSInfo, DimExpr, RParen);
1839}
1840
1842 QualType T, Expr *DimExpr,
1843 SourceLocation KeyLoc) {
1844 assert(!T->isDependentType() && "Cannot evaluate traits of dependent type");
1845
1846 switch (ATT) {
1847 case ATT_ArrayRank:
1848 if (T->isArrayType()) {
1849 unsigned Dim = 0;
1850 while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {
1851 ++Dim;
1852 T = AT->getElementType();
1853 }
1854 return Dim;
1855 }
1856 return 0;
1857
1858 case ATT_ArrayExtent: {
1859 llvm::APSInt Value;
1860 uint64_t Dim;
1861 if (Self.VerifyIntegerConstantExpression(
1862 DimExpr, &Value, diag::err_dimension_expr_not_constant_integer)
1863 .isInvalid())
1864 return 0;
1865 if (Value.isSigned() && Value.isNegative()) {
1866 Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer)
1867 << DimExpr->getSourceRange();
1868 return 0;
1869 }
1870 Dim = Value.getLimitedValue();
1871
1872 if (T->isArrayType()) {
1873 unsigned D = 0;
1874 bool Matched = false;
1875 while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {
1876 if (Dim == D) {
1877 Matched = true;
1878 break;
1879 }
1880 ++D;
1881 T = AT->getElementType();
1882 }
1883
1884 if (Matched && T->isArrayType()) {
1885 if (const ConstantArrayType *CAT =
1886 Self.Context.getAsConstantArrayType(T))
1887 return CAT->getLimitedSize();
1888 }
1889 }
1890 return 0;
1891 }
1892 }
1893 llvm_unreachable("Unknown type trait or not implemented");
1894}
1895
1897 TypeSourceInfo *TSInfo, Expr *DimExpr,
1898 SourceLocation RParen) {
1899 QualType T = TSInfo->getType();
1900
1901 // FIXME: This should likely be tracked as an APInt to remove any host
1902 // assumptions about the width of size_t on the target.
1903 uint64_t Value = 0;
1904 if (!T->isDependentType())
1905 Value = EvaluateArrayTypeTrait(*this, ATT, T, DimExpr, KWLoc);
1906
1907 // While the specification for these traits from the Embarcadero C++
1908 // compiler's documentation says the return type is 'unsigned int', Clang
1909 // returns 'size_t'. On Windows, the primary platform for the Embarcadero
1910 // compiler, there is no difference. On several other platforms this is an
1911 // important distinction.
1912 return new (Context) ArrayTypeTraitExpr(KWLoc, ATT, TSInfo, Value, DimExpr,
1913 RParen, Context.getSizeType());
1914}
1915
1917 Expr *Queried, SourceLocation RParen) {
1918 // If error parsing the expression, ignore.
1919 if (!Queried)
1920 return ExprError();
1921
1922 ExprResult Result = BuildExpressionTrait(ET, KWLoc, Queried, RParen);
1923
1924 return Result;
1925}
1926
1928 switch (ET) {
1929 case ET_IsLValueExpr:
1930 return E->isLValue();
1931 case ET_IsRValueExpr:
1932 return E->isPRValue();
1933 }
1934 llvm_unreachable("Expression trait not covered by switch");
1935}
1936
1938 Expr *Queried, SourceLocation RParen) {
1939 if (Queried->isTypeDependent()) {
1940 // Delay type-checking for type-dependent expressions.
1941 } else if (Queried->hasPlaceholderType()) {
1942 ExprResult PE = CheckPlaceholderExpr(Queried);
1943 if (PE.isInvalid())
1944 return ExprError();
1945 return BuildExpressionTrait(ET, KWLoc, PE.get(), RParen);
1946 }
1947
1948 bool Value = EvaluateExpressionTrait(ET, Queried);
1949
1950 return new (Context)
1951 ExpressionTraitExpr(KWLoc, ET, Queried, Value, RParen, Context.BoolTy);
1952}
1953
1954static std::optional<TypeTrait> StdNameToTypeTrait(StringRef Name) {
1955 return llvm::StringSwitch<std::optional<TypeTrait>>(Name)
1956 .Case("is_trivially_relocatable",
1957 TypeTrait::UTT_IsCppTriviallyRelocatable)
1958 .Case("is_trivially_copyable", TypeTrait::UTT_IsTriviallyCopyable)
1959 .Case("is_assignable", TypeTrait::BTT_IsAssignable)
1960 .Case("is_empty", TypeTrait::UTT_IsEmpty)
1961 .Case("is_standard_layout", TypeTrait::UTT_IsStandardLayout)
1962 .Case("is_aggregate", TypeTrait::UTT_IsAggregate)
1963 .Case("is_constructible", TypeTrait::TT_IsConstructible)
1964 .Case("is_final", TypeTrait::UTT_IsFinal)
1965 .Case("is_abstract", TypeTrait::UTT_IsAbstract)
1966 .Default(std::nullopt);
1967}
1968
1970 std::optional<std::pair<TypeTrait, llvm::SmallVector<QualType, 1>>>;
1971
1972// Recognize type traits that are builting type traits, or known standard
1973// type traits in <type_traits>. Note that at this point we assume the
1974// trait evaluated to false, so we need only to recognize the shape of the
1975// outer-most symbol.
1978 std::optional<TypeTrait> Trait;
1979
1980 // builtins
1981 if (const auto *TraitExpr = dyn_cast<TypeTraitExpr>(E)) {
1982 Trait = TraitExpr->getTrait();
1983 for (const auto *Arg : TraitExpr->getArgs())
1984 Args.push_back(Arg->getType());
1985 return {{Trait.value(), std::move(Args)}};
1986 }
1987 const auto *Ref = dyn_cast<DeclRefExpr>(E);
1988 if (!Ref)
1989 return std::nullopt;
1990
1991 // std::is_xxx_v<>
1992 if (const auto *VD =
1993 dyn_cast<VarTemplateSpecializationDecl>(Ref->getDecl())) {
1994 if (!VD->isInStdNamespace())
1995 return std::nullopt;
1996 StringRef Name = VD->getIdentifier()->getName();
1997 if (!Name.consume_back("_v"))
1998 return std::nullopt;
1999 Trait = StdNameToTypeTrait(Name);
2000 if (!Trait)
2001 return std::nullopt;
2002 for (const auto &Arg : VD->getTemplateArgs().asArray()) {
2003 if (Arg.getKind() == TemplateArgument::ArgKind::Pack) {
2004 for (const auto &InnerArg : Arg.pack_elements())
2005 Args.push_back(InnerArg.getAsType());
2006 } else if (Arg.getKind() == TemplateArgument::ArgKind::Type) {
2007 Args.push_back(Arg.getAsType());
2008 } else {
2009 llvm_unreachable("Unexpected kind");
2010 }
2011 }
2012 return {{Trait.value(), std::move(Args)}};
2013 }
2014
2015 // std::is_xxx<>::value
2016 if (const auto *VD = dyn_cast<VarDecl>(Ref->getDecl());
2017 Ref->hasQualifier() && VD && VD->getIdentifier()->isStr("value")) {
2018 NestedNameSpecifier Qualifier = Ref->getQualifier();
2019 if (Qualifier.getKind() != NestedNameSpecifier::Kind::Type)
2020 return std::nullopt;
2021 const auto *Ts = Qualifier.getAsType()->getAs<TemplateSpecializationType>();
2022 if (!Ts)
2023 return std::nullopt;
2024 const TemplateDecl *D = Ts->getTemplateName().getAsTemplateDecl();
2025 if (!D || !D->isInStdNamespace())
2026 return std::nullopt;
2027 Trait = StdNameToTypeTrait(D->getIdentifier()->getName());
2028 if (!Trait)
2029 return std::nullopt;
2030 for (const auto &Arg : Ts->template_arguments())
2031 Args.push_back(Arg.getAsType());
2032 return {{Trait.value(), std::move(Args)}};
2033 }
2034 return std::nullopt;
2035}
2036
2038 const CXXRecordDecl *D) {
2039 if (D->isUnion()) {
2040 auto DiagSPM = [&](CXXSpecialMemberKind K, bool Has) {
2041 if (Has)
2042 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2043 << diag::TraitNotSatisfiedReason::UnionWithUserDeclaredSMF << K;
2044 };
2053 return;
2054 }
2055
2057 const auto *Decl = cast_or_null<CXXConstructorDecl>(
2058 LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/false));
2059 if (Decl && Decl->isUserProvided())
2060 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2061 << diag::TraitNotSatisfiedReason::UserProvidedCtr
2062 << Decl->isMoveConstructor() << Decl->getSourceRange();
2063 }
2066 LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/true);
2067 if (Decl && Decl->isUserProvided())
2068 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2069 << diag::TraitNotSatisfiedReason::UserProvidedAssign
2070 << Decl->isMoveAssignmentOperator() << Decl->getSourceRange();
2071 }
2072 if (CXXDestructorDecl *Dtr = D->getDestructor()) {
2073 Dtr = Dtr->getCanonicalDecl();
2074 if (Dtr->isUserProvided() && !Dtr->isDefaulted())
2075 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2076 << diag::TraitNotSatisfiedReason::DeletedDtr << /*User Provided*/ 1
2077 << Dtr->getSourceRange();
2078 }
2079}
2080
2082 SourceLocation Loc,
2083 const CXXRecordDecl *D) {
2084 for (const CXXBaseSpecifier &B : D->bases()) {
2085 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2086 if (B.isVirtual())
2087 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2088 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2089 << B.getSourceRange();
2090 if (!SemaRef.IsCXXTriviallyRelocatableType(B.getType()))
2091 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2092 << diag::TraitNotSatisfiedReason::NTRBase << B.getType()
2093 << B.getSourceRange();
2094 }
2095 for (const FieldDecl *Field : D->fields()) {
2096 if (!Field->getType()->isReferenceType() &&
2097 !SemaRef.IsCXXTriviallyRelocatableType(Field->getType()))
2098 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2099 << diag::TraitNotSatisfiedReason::NTRField << Field
2100 << Field->getType() << Field->getSourceRange();
2101 }
2102 if (D->hasDeletedDestructor())
2103 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2104 << diag::TraitNotSatisfiedReason::DeletedDtr << /*Deleted*/ 0
2105 << D->getDestructor()->getSourceRange();
2106
2107 DiagnoseNonDefaultMovable(SemaRef, Loc, D);
2108}
2109
2111 SourceLocation Loc,
2112 QualType T) {
2113 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2114 << T << diag::TraitName::TriviallyRelocatable;
2115 if (T->isVariablyModifiedType())
2116 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2117 << diag::TraitNotSatisfiedReason::VLA;
2118
2119 if (T->isReferenceType())
2120 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2121 << diag::TraitNotSatisfiedReason::Ref;
2122 T = T.getNonReferenceType();
2123
2124 if (T.hasNonTrivialObjCLifetime())
2125 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2126 << diag::TraitNotSatisfiedReason::HasArcLifetime;
2127
2128 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2129 if (!D || D->isInvalidDecl())
2130 return;
2131
2132 if (D->hasDefinition())
2134
2135 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2136}
2137
2139 SourceLocation Loc,
2140 const CXXRecordDecl *D) {
2141 for (const CXXBaseSpecifier &B : D->bases()) {
2142 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2143 if (B.isVirtual())
2144 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2145 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2146 << B.getSourceRange();
2147 if (!B.getType().isTriviallyCopyableType(D->getASTContext())) {
2148 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2149 << diag::TraitNotSatisfiedReason::NTCBase << B.getType()
2150 << B.getSourceRange();
2151 }
2152 }
2153 for (const FieldDecl *Field : D->fields()) {
2154 if (!Field->getType().isTriviallyCopyableType(Field->getASTContext()))
2155 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2156 << diag::TraitNotSatisfiedReason::NTCField << Field
2157 << Field->getType() << Field->getSourceRange();
2158 }
2159 CXXDestructorDecl *Dtr = D->getDestructor();
2160 if (D->hasDeletedDestructor() || (Dtr && !Dtr->isTrivial()))
2161 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2162 << diag::TraitNotSatisfiedReason::DeletedDtr
2164
2165 for (const CXXMethodDecl *Method : D->methods()) {
2166 if (Method->isTrivial() || !Method->isUserProvided()) {
2167 continue;
2168 }
2169 auto SpecialMemberKind =
2170 SemaRef.getDefaultedFunctionKind(Method).asSpecialMember();
2171 switch (SpecialMemberKind) {
2176 bool IsAssignment =
2177 SpecialMemberKind == CXXSpecialMemberKind::CopyAssignment ||
2178 SpecialMemberKind == CXXSpecialMemberKind::MoveAssignment;
2179 bool IsMove =
2180 SpecialMemberKind == CXXSpecialMemberKind::MoveConstructor ||
2181 SpecialMemberKind == CXXSpecialMemberKind::MoveAssignment;
2182
2183 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2184 << (IsAssignment ? diag::TraitNotSatisfiedReason::UserProvidedAssign
2185 : diag::TraitNotSatisfiedReason::UserProvidedCtr)
2186 << IsMove << Method->getSourceRange();
2187 break;
2188 }
2189 default:
2190 break;
2191 }
2192 }
2193}
2194
2196 Sema &SemaRef, SourceLocation Loc,
2198 if (Ts.empty()) {
2199 return;
2200 }
2201
2202 bool ContainsVoid = false;
2203 for (const QualType &ArgTy : Ts) {
2204 ContainsVoid |= ArgTy->isVoidType();
2205 }
2206
2207 if (ContainsVoid)
2208 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2209 << diag::TraitNotSatisfiedReason::CVVoidType;
2210
2211 QualType T = Ts[0];
2212 if (T->isFunctionType())
2213 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2214 << diag::TraitNotSatisfiedReason::FunctionType;
2215
2216 if (T->isIncompleteArrayType())
2217 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2218 << diag::TraitNotSatisfiedReason::IncompleteArrayType;
2219
2220 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2221 if (!D || D->isInvalidDecl() || !D->hasDefinition())
2222 return;
2223
2224 llvm::BumpPtrAllocator OpaqueExprAllocator;
2225 SmallVector<Expr *, 2> ArgExprs;
2226 ArgExprs.reserve(Ts.size() - 1);
2227 for (unsigned I = 1, N = Ts.size(); I != N; ++I) {
2228 QualType ArgTy = Ts[I];
2229 if (ArgTy->isObjectType() || ArgTy->isFunctionType())
2230 ArgTy = SemaRef.Context.getRValueReferenceType(ArgTy);
2231 ArgExprs.push_back(
2232 new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
2233 OpaqueValueExpr(Loc, ArgTy.getNonLValueExprType(SemaRef.Context),
2235 }
2236
2239 Sema::ContextRAII TUContext(SemaRef,
2243 InitializationSequence Init(SemaRef, To, InitKind, ArgExprs);
2244
2245 Init.Diagnose(SemaRef, To, InitKind, ArgExprs);
2246 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2247}
2248
2250 SourceLocation Loc, QualType T) {
2251 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2252 << T << diag::TraitName::TriviallyCopyable;
2253
2254 if (T->isReferenceType())
2255 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2256 << diag::TraitNotSatisfiedReason::Ref;
2257
2258 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2259 if (!D || D->isInvalidDecl())
2260 return;
2261
2262 if (D->hasDefinition())
2263 DiagnoseNonTriviallyCopyableReason(SemaRef, Loc, D);
2264
2265 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2266}
2267
2269 QualType T, QualType U) {
2270 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2271
2272 auto createDeclValExpr = [&](QualType Ty) -> OpaqueValueExpr {
2273 if (Ty->isObjectType() || Ty->isFunctionType())
2274 Ty = SemaRef.Context.getRValueReferenceType(Ty);
2275 return {Loc, Ty.getNonLValueExprType(SemaRef.Context),
2277 };
2278
2279 auto LHS = createDeclValExpr(T);
2280 auto RHS = createDeclValExpr(U);
2281
2284 Sema::ContextRAII TUContext(SemaRef,
2286 SemaRef.BuildBinOp(/*S=*/nullptr, Loc, BO_Assign, &LHS, &RHS);
2287
2288 if (!D || D->isInvalidDecl())
2289 return;
2290
2291 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2292}
2293
2295 const CXXRecordDecl *D) {
2296 // Non-static data members (ignore zero-width bit‐fields).
2297 for (const auto *Field : D->fields()) {
2298 if (Field->isZeroLengthBitField())
2299 continue;
2300 if (Field->isBitField()) {
2301 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2302 << diag::TraitNotSatisfiedReason::NonZeroLengthField << Field
2303 << Field->getSourceRange();
2304 continue;
2305 }
2306 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2307 << diag::TraitNotSatisfiedReason::NonEmptyMember << Field
2308 << Field->getType() << Field->getSourceRange();
2309 }
2310
2311 // Virtual functions.
2312 for (const auto *M : D->methods()) {
2313 if (M->isVirtual()) {
2314 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2315 << diag::TraitNotSatisfiedReason::VirtualFunction << M
2316 << M->getSourceRange();
2317 break;
2318 }
2319 }
2320
2321 // Virtual bases and non-empty bases.
2322 for (const auto &B : D->bases()) {
2323 const auto *BR = B.getType()->getAsCXXRecordDecl();
2324 if (!BR || BR->isInvalidDecl())
2325 continue;
2326 if (B.isVirtual()) {
2327 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2328 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2329 << B.getSourceRange();
2330 }
2331 if (!BR->isEmpty()) {
2332 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2333 << diag::TraitNotSatisfiedReason::NonEmptyBase << B.getType()
2334 << B.getSourceRange();
2335 }
2336 }
2337}
2338
2340 // Emit primary "not empty" diagnostic.
2341 S.Diag(Loc, diag::note_unsatisfied_trait) << T << diag::TraitName::Empty;
2342
2343 // While diagnosing is_empty<T>, we want to look at the actual type, not a
2344 // reference or an array of it. So we need to massage the QualType param to
2345 // strip refs and arrays.
2346 if (T->isReferenceType())
2347 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2348 << diag::TraitNotSatisfiedReason::Ref;
2349 T = T.getNonReferenceType();
2350
2351 if (auto *AT = S.Context.getAsArrayType(T))
2352 T = AT->getElementType();
2353
2354 if (auto *D = T->getAsCXXRecordDecl()) {
2355 if (D->hasDefinition()) {
2356 DiagnoseIsEmptyReason(S, Loc, D);
2357 S.Diag(D->getLocation(), diag::note_defined_here) << D;
2358 }
2359 }
2360}
2361
2363 const CXXRecordDecl *D) {
2364 if (!D || D->isInvalidDecl())
2365 return;
2366
2367 // Complete record but not 'final'.
2368 if (!D->isEffectivelyFinal()) {
2369 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2370 << diag::TraitNotSatisfiedReason::NotMarkedFinal;
2371 S.Diag(D->getLocation(), diag::note_defined_here) << D;
2372 return;
2373 }
2374}
2375
2377 // Primary: “%0 is not final”
2378 S.Diag(Loc, diag::note_unsatisfied_trait) << T << diag::TraitName::Final;
2379 if (T->isReferenceType()) {
2380 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2381 << diag::TraitNotSatisfiedReason::Ref;
2382 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2383 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2384 return;
2385 }
2386 // Arrays / functions / non-records → not a class/union.
2387 if (S.Context.getAsArrayType(T)) {
2388 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2389 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2390 return;
2391 }
2392 if (T->isFunctionType()) {
2393 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2394 << diag::TraitNotSatisfiedReason::FunctionType;
2395 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2396 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2397 return;
2398 }
2399 if (!T->isRecordType()) {
2400 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2401 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2402 return;
2403 }
2404 if (const auto *D = T->getAsCXXRecordDecl())
2405 DiagnoseIsFinalReason(S, Loc, D);
2406}
2407
2409 int NumBasesWithFields = 0;
2410 for (const CXXBaseSpecifier &Base : D->bases()) {
2411 const CXXRecordDecl *BaseRD = Base.getType()->getAsCXXRecordDecl();
2412 if (!BaseRD || BaseRD->isInvalidDecl())
2413 continue;
2414
2415 for (const FieldDecl *Field : BaseRD->fields()) {
2416 if (!Field->isUnnamedBitField()) {
2417 if (++NumBasesWithFields > 1)
2418 return true; // found more than one base class with fields
2419 break; // no need to check further fields in this base class
2420 }
2421 }
2422 }
2423 return false;
2424}
2425
2427 const CXXRecordDecl *D) {
2428 for (const CXXBaseSpecifier &B : D->bases()) {
2429 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2430 if (B.isVirtual()) {
2431 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2432 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2433 << B.getSourceRange();
2434 }
2435 if (!B.getType()->isStandardLayoutType()) {
2436 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2437 << diag::TraitNotSatisfiedReason::NonStandardLayoutBase << B.getType()
2438 << B.getSourceRange();
2439 }
2440 }
2441 // Check for mixed access specifiers in fields.
2442 const FieldDecl *FirstField = nullptr;
2443 AccessSpecifier FirstAccess = AS_none;
2444
2445 for (const FieldDecl *Field : D->fields()) {
2446 if (Field->isUnnamedBitField())
2447 continue;
2448
2449 // Record the first field we see
2450 if (!FirstField) {
2451 FirstField = Field;
2452 FirstAccess = Field->getAccess();
2453 continue;
2454 }
2455
2456 // Check if the field has a different access specifier than the first one.
2457 if (Field->getAccess() != FirstAccess) {
2458 // Emit a diagnostic about mixed access specifiers.
2459 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2460 << diag::TraitNotSatisfiedReason::MixedAccess;
2461
2462 SemaRef.Diag(FirstField->getLocation(), diag::note_defined_here)
2463 << FirstField;
2464
2465 SemaRef.Diag(Field->getLocation(), diag::note_unsatisfied_trait_reason)
2466 << diag::TraitNotSatisfiedReason::MixedAccessField << Field
2467 << FirstField;
2468
2469 // No need to check further fields, as we already found mixed access.
2470 break;
2471 }
2472 }
2474 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2475 << diag::TraitNotSatisfiedReason::MultipleDataBase;
2476 }
2477 if (D->isPolymorphic()) {
2478 // Find the best location to point “defined here” at.
2479 const CXXMethodDecl *VirtualMD = nullptr;
2480 // First, look for a virtual method.
2481 for (const auto *M : D->methods()) {
2482 if (M->isVirtual()) {
2483 VirtualMD = M;
2484 break;
2485 }
2486 }
2487 if (VirtualMD) {
2488 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2489 << diag::TraitNotSatisfiedReason::VirtualFunction << VirtualMD;
2490 SemaRef.Diag(VirtualMD->getLocation(), diag::note_defined_here)
2491 << VirtualMD;
2492 } else {
2493 // If no virtual method, point to the record declaration itself.
2494 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2495 << diag::TraitNotSatisfiedReason::VirtualFunction << D;
2496 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2497 }
2498 }
2499 for (const FieldDecl *Field : D->fields()) {
2500 if (!Field->getType()->isStandardLayoutType()) {
2501 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2502 << diag::TraitNotSatisfiedReason::NonStandardLayoutMember << Field
2503 << Field->getType() << Field->getSourceRange();
2504 }
2505 }
2506 // Find any indirect base classes that have fields.
2507 if (D->hasDirectFields()) {
2508 const CXXRecordDecl *Indirect = nullptr;
2509 D->forallBases([&](const CXXRecordDecl *BaseDef) {
2510 if (BaseDef->hasDirectFields()) {
2511 Indirect = BaseDef;
2512 return false; // stop traversal
2513 }
2514 return true; // continue to the next base
2515 });
2516 if (Indirect) {
2517 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2518 << diag::TraitNotSatisfiedReason::IndirectBaseWithFields << Indirect
2519 << Indirect->getSourceRange();
2520 }
2521 }
2522}
2523
2525 QualType T) {
2526 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2527 << T << diag::TraitName::StandardLayout;
2528
2529 // Check type-level exclusion first.
2530 if (T->isVariablyModifiedType()) {
2531 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2532 << diag::TraitNotSatisfiedReason::VLA;
2533 return;
2534 }
2535
2536 if (T->isReferenceType()) {
2537 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2538 << diag::TraitNotSatisfiedReason::Ref;
2539 return;
2540 }
2541 T = T.getNonReferenceType();
2542 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2543 if (!D || D->isInvalidDecl())
2544 return;
2545
2546 if (D->hasDefinition())
2547 DiagnoseNonStandardLayoutReason(SemaRef, Loc, D);
2548
2549 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2550}
2551
2553 const CXXRecordDecl *D) {
2554 for (const CXXConstructorDecl *Ctor : D->ctors()) {
2555 if (Ctor->isUserProvided())
2556 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2557 << diag::TraitNotSatisfiedReason::UserDeclaredCtr;
2558 if (Ctor->isInheritingConstructor())
2559 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2560 << diag::TraitNotSatisfiedReason::InheritedCtr;
2561 }
2562
2563 if (llvm::any_of(D->decls(), [](auto const *Sub) {
2564 return isa<ConstructorUsingShadowDecl>(Sub);
2565 })) {
2566 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2567 << diag::TraitNotSatisfiedReason::InheritedCtr;
2568 }
2569
2570 if (D->isPolymorphic())
2571 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2572 << diag::TraitNotSatisfiedReason::PolymorphicType
2573 << D->getSourceRange();
2574
2575 for (const CXXBaseSpecifier &B : D->bases()) {
2576 if (B.isVirtual()) {
2577 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2578 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2579 << B.getSourceRange();
2580 continue;
2581 }
2582 auto AccessSpecifier = B.getAccessSpecifier();
2583 switch (AccessSpecifier) {
2584 case AS_private:
2585 case AS_protected:
2586 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2587 << diag::TraitNotSatisfiedReason::PrivateProtectedDirectBase
2589 break;
2590 default:
2591 break;
2592 }
2593 }
2594
2595 for (const CXXMethodDecl *Method : D->methods()) {
2596 if (Method->isVirtual()) {
2597 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2598 << diag::TraitNotSatisfiedReason::VirtualFunction << Method
2599 << Method->getSourceRange();
2600 }
2601 }
2602
2603 for (const FieldDecl *Field : D->fields()) {
2604 auto AccessSpecifier = Field->getAccess();
2605 switch (AccessSpecifier) {
2606 case AS_private:
2607 case AS_protected:
2608 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2609 << diag::TraitNotSatisfiedReason::PrivateProtectedDirectDataMember
2611 break;
2612 default:
2613 break;
2614 }
2615 }
2616
2617 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2618}
2619
2621 QualType T) {
2622 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2623 << T << diag::TraitName::Aggregate;
2624
2625 if (T->isVoidType())
2626 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2627 << diag::TraitNotSatisfiedReason::CVVoidType;
2628
2629 T = T.getNonReferenceType();
2630 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2631 if (!D || D->isInvalidDecl())
2632 return;
2633
2634 if (D->hasDefinition())
2635 DiagnoseNonAggregateReason(SemaRef, Loc, D);
2636}
2637
2639 const CXXRecordDecl *D) {
2640 // If this type has any abstract base classes, their respective virtual
2641 // functions must have been overridden.
2642 for (const CXXBaseSpecifier &B : D->bases()) {
2643 if (B.getType()->castAsCXXRecordDecl()->isAbstract()) {
2644 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2645 << diag::TraitNotSatisfiedReason::OverridesAllPureVirtual
2646 << B.getType() << B.getSourceRange();
2647 }
2648 }
2649}
2650
2652 QualType T) {
2653 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2654 << T << diag::TraitName::Abstract;
2655
2656 if (T->isReferenceType()) {
2657 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2658 << diag::TraitNotSatisfiedReason::Ref;
2659 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2660 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2661 return;
2662 }
2663
2664 if (T->isUnionType()) {
2665 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2666 << diag::TraitNotSatisfiedReason::UnionType;
2667 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2668 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2669 return;
2670 }
2671
2672 if (SemaRef.Context.getAsArrayType(T)) {
2673 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2674 << diag::TraitNotSatisfiedReason::ArrayType;
2675 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2676 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2677 return;
2678 }
2679
2680 if (T->isFunctionType()) {
2681 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2682 << diag::TraitNotSatisfiedReason::FunctionType;
2683 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2684 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2685 return;
2686 }
2687
2688 if (T->isPointerType()) {
2689 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2690 << diag::TraitNotSatisfiedReason::PointerType;
2691 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2692 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2693 return;
2694 }
2695
2696 if (!T->isStructureOrClassType()) {
2697 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2698 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2699 return;
2700 }
2701
2702 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2703 if (D->hasDefinition())
2704 DiagnoseNonAbstractReason(SemaRef, Loc, D);
2705}
2706
2708 E = E->IgnoreParenImpCasts();
2709 if (E->containsErrors())
2710 return;
2711
2713 if (!TraitInfo)
2714 return;
2715
2716 const auto &[Trait, Args] = TraitInfo.value();
2717 switch (Trait) {
2718 case UTT_IsCppTriviallyRelocatable:
2720 break;
2721 case UTT_IsTriviallyCopyable:
2722 DiagnoseNonTriviallyCopyableReason(*this, E->getBeginLoc(), Args[0]);
2723 break;
2724 case BTT_IsAssignable:
2725 DiagnoseNonAssignableReason(*this, E->getBeginLoc(), Args[0], Args[1]);
2726 break;
2727 case UTT_IsEmpty:
2728 DiagnoseIsEmptyReason(*this, E->getBeginLoc(), Args[0]);
2729 break;
2730 case UTT_IsStandardLayout:
2731 DiagnoseNonStandardLayoutReason(*this, E->getBeginLoc(), Args[0]);
2732 break;
2733 case TT_IsConstructible:
2735 break;
2736 case UTT_IsAggregate:
2737 DiagnoseNonAggregateReason(*this, E->getBeginLoc(), Args[0]);
2738 break;
2739 case UTT_IsFinal: {
2740 QualType QT = Args[0];
2741 if (QT->isDependentType())
2742 break;
2743 const auto *RD = QT->getAsCXXRecordDecl();
2744 if (!RD || !RD->isEffectivelyFinal())
2745 DiagnoseIsFinalReason(*this, E->getBeginLoc(), QT); // unsatisfied
2746 break;
2747 }
2748 case UTT_IsAbstract:
2749 DiagnoseNonAbstractReason(*this, E->getBeginLoc(), Args[0]);
2750 break;
2751 default:
2752 break;
2753 }
2754}
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:227
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:3777
Represents a base class of a C++ class.
Definition DeclCXX.h:146
Represents a C++ constructor within a class.
Definition DeclCXX.h:2620
Represents a C++ destructor within a class.
Definition DeclCXX.h:2882
CXXDestructorDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition DeclCXX.h:2930
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2132
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
Definition DeclCXX.cpp:2753
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
Definition DeclCXX.cpp:2732
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
bool hasTrivialMoveAssignment() const
Determine whether this class has a trivial move assignment operator (C++11 [class....
Definition DeclCXX.h:1347
bool isTriviallyCopyable() const
Determine whether this class is considered trivially copyable per (C++11 [class]p6).
Definition DeclCXX.cpp:610
bool hasNonTrivialCopyAssignment() const
Determine whether this class has a non-trivial copy assignment operator (C++ [class....
Definition DeclCXX.h:1340
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
Definition DeclCXX.cpp:2343
bool hasSimpleMoveConstructor() const
true if we know for sure that this class has a single, accessible, unambiguous move constructor that ...
Definition DeclCXX.h:730
bool hasTrivialDefaultConstructor() const
Determine whether this class has a trivial default constructor (C++11 [class.ctor]p5).
Definition DeclCXX.h:1246
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
Definition DeclCXX.h:1372
bool hasUserDeclaredDestructor() const
Determine whether this class has a user-declared destructor.
Definition DeclCXX.h:1001
bool defaultedMoveConstructorIsDeleted() const
true if a defaulted move constructor for this class would be deleted.
Definition DeclCXX.h:706
bool hasUserDeclaredMoveAssignment() const
Determine whether this class has had a move assignment declared by the user.
Definition DeclCXX.h:961
bool hasDeletedDestructor() const
Returns the destructor decl for this class.
Definition DeclCXX.cpp:2150
base_class_range bases()
Definition DeclCXX.h:608
bool hasTrivialMoveConstructor() const
Determine whether this class has a trivial move constructor (C++11 [class.copy]p12)
Definition DeclCXX.h:1307
bool needsImplicitDefaultConstructor() const
Determine if we need to declare a default constructor for this class.
Definition DeclCXX.h:766
bool needsImplicitMoveConstructor() const
Determine whether this class should get an implicit move constructor or if any existing special membe...
Definition DeclCXX.h:892
bool hasUserDeclaredCopyAssignment() const
Determine whether this class has a user-declared copy assignment operator.
Definition DeclCXX.h:910
method_range methods() const
Definition DeclCXX.h:650
CXXRecordDecl * getDefinition() const
Definition DeclCXX.h:548
bool hasTrivialCopyConstructor() const
Determine whether this class has a trivial copy constructor (C++ [class.copy]p6, C++11 [class....
Definition DeclCXX.h:1284
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
Definition DeclCXX.h:1214
bool defaultedCopyConstructorIsDeleted() const
true if a defaulted copy constructor for this class would be deleted.
Definition DeclCXX.h:697
bool hasTrivialCopyAssignment() const
Determine whether this class has a trivial copy assignment operator (C++ [class.copy]p11,...
Definition DeclCXX.h:1334
ctor_range ctors() const
Definition DeclCXX.h:670
bool isAbstract() const
Determine whether this class has a pure virtual function.
Definition DeclCXX.h:1221
bool needsImplicitCopyConstructor() const
Determine whether this class needs an implicit copy constructor to be lazily declared.
Definition DeclCXX.h:799
bool hasSimpleMoveAssignment() const
true if we know for sure that this class has a single, accessible, unambiguous move assignment operat...
Definition DeclCXX.h:744
bool hasNonTrivialMoveConstructor() const
Determine whether this class has a non-trivial move constructor (C++11 [class.copy]p12)
Definition DeclCXX.h:1319
bool hasDirectFields() const
Determine whether this class has direct non-static data members.
Definition DeclCXX.h:1200
bool hasUserDeclaredCopyConstructor() const
Determine whether this class has a user-declared copy constructor.
Definition DeclCXX.h:793
bool hasDefinition() const
Definition DeclCXX.h:561
bool hasSimpleCopyConstructor() const
true if we know for sure that this class has a single, accessible, unambiguous copy constructor that ...
Definition DeclCXX.h:723
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
Definition DeclCXX.h:1186
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
Definition DeclCXX.cpp:2131
bool hasNonTrivialMoveAssignment() const
Determine whether this class has a non-trivial move assignment operator (C++11 [class....
Definition DeclCXX.h:1354
bool hasUserDeclaredMoveOperation() const
Whether this class has a user-declared move constructor or assignment operator.
Definition DeclCXX.h:839
bool hasNonTrivialDefaultConstructor() const
Determine whether this class has a non-trivial default constructor (C++11 [class.ctor]p5).
Definition DeclCXX.h:1253
bool hasUserDeclaredMoveConstructor() const
Determine whether this class has had a move constructor declared by the user.
Definition DeclCXX.h:846
bool forallBases(ForallBasesCallback BaseMatches) const
Determines if the given callback holds for all the direct or indirect base classes of this type.
bool hasNonTrivialCopyConstructor() const
Determine whether this class has a non-trivial copy constructor (C++ [class.copy]p6,...
Definition DeclCXX.h:1294
bool hasSimpleCopyAssignment() const
true if we know for sure that this class has a single, accessible, unambiguous copy assignment operat...
Definition DeclCXX.h:737
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2946
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition Expr.h:3129
Represents the canonical version of C arrays with a specified constant size.
Definition TypeBase.h:3815
A POD class for pairing a NamedDecl* with an access specifier.
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
DeclContextLookupResult lookup_result
Definition DeclBase.h:2590
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:2386
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:4029
The return type of classify().
Definition Expr.h:339
This represents one expression.
Definition Expr.h:112
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Definition Expr.h:194
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition Expr.cpp:3090
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
Definition Expr.h:246
bool isPRValue() const
Definition Expr.h:285
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
Definition Expr.h:284
Classification Classify(ASTContext &Ctx) const
Classify - Classify this expression according to the C++11 expression taxonomy.
Definition Expr.h:415
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
Definition Expr.h:526
static ExprValueKind getValueKindForType(QualType T)
getValueKindForType - Given a formal return or parameter type, give its value kind.
Definition Expr.h:437
An expression trait intrinsic.
Definition ExprCXX.h:3073
Represents a member of a struct/union/class.
Definition Decl.h:3178
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition Decl.h:2395
bool isDeleted() const
Whether this function has been deleted.
Definition Decl.h:2558
bool isDefaulted() const
Whether this function is defaulted.
Definition Decl.h:2403
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4544
bool isUserProvided() const
True if this method is user-declared and was not deleted or defaulted on its first declaration.
Definition Decl.h:2428
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5362
unsigned getNumParams() const
Definition TypeBase.h:5640
bool isNothrow(bool ResultIfDependent=false) const
Determine whether this function type has a non-throwing exception specification.
Definition TypeBase.h:5761
Declaration of a template function.
StringRef getName() const
Return the actual identifier string.
Describes the kind of initialization being performed, along with location information for tokens rela...
static InitializationKind CreateDirect(SourceLocation InitLoc, SourceLocation LParenLoc, SourceLocation RParenLoc)
Create a direct initialization.
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
Describes the sequence of initializations required to initialize a given object or reference with a s...
Describes an entity that is being initialized.
static InitializedEntity InitializeTemporary(QualType Type)
Create the initialization entity for a temporary.
Represents the results of name lookup.
Definition Lookup.h:147
UnresolvedSetImpl::iterator iterator
Definition Lookup.h:154
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
Definition Lookup.h:636
iterator end() const
Definition Lookup.h:359
iterator begin() const
Definition Lookup.h:358
This represents a decl that may have a name.
Definition Decl.h:274
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
Definition Decl.h:487
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:295
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
Represents an ObjC class declaration.
Definition DeclObjC.h:1154
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
Definition DeclObjC.h:1810
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition Expr.h:1181
OverloadCandidateSet - A set of overload candidates, used in C++ overload resolution (C++ 13....
Definition Overload.h:1160
@ CSK_Normal
Normal lookup.
Definition Overload.h:1164
SmallVectorImpl< OverloadCandidate >::iterator iterator
Definition Overload.h:1376
OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc, OverloadCandidateSet::iterator &Best)
Find the best viable function on this overload set, if it exists.
A (possibly-)qualified type.
Definition TypeBase.h:937
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
Definition Type.cpp:2961
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type.
Definition Type.cpp:3677
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:8621
bool hasNonTrivialObjCLifetime() const
Definition TypeBase.h:1453
@ PCK_Trivial
The type does not fall into any of the following categories.
Definition TypeBase.h:1504
@ PCK_ARCStrong
The type is an Objective-C retainable pointer type that is qualified with the ARC __strong qualifier.
Definition TypeBase.h:1513
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:4480
field_range fields() const
Definition Decl.h:4546
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:3526
CXXSpecialMemberKind asSpecialMember() const
Definition Sema.h:6465
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
Definition Sema.h:12551
bool hasErrorOccurred() const
Determine whether any SFINAE errors have been trapped.
Definition Sema.h:12585
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:868
DefaultedFunctionKind getDefaultedFunctionKind(const FunctionDecl *FD)
Determine the kind of defaulting that would be done for a given function.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
Definition Sema.h: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:1308
void DiagnoseTypeTraitDetails(const Expr *E)
If E represents a built-in type trait, or a known standard type trait, try to print more information ...
ASTContext & getASTContext() const
Definition Sema.h:939
void LookupBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, UnresolvedSetImpl &Functions)
ExprResult CreateOverloadedBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, const UnresolvedSetImpl &Fns, Expr *LHS, Expr *RHS, bool RequiresADL=true, bool AllowRewrittenCandidates=true, FunctionDecl *DefaultedFn=nullptr)
Create a binary operation that may resolve to an overloaded operator.
bool CheckTypeTraitArity(unsigned Arity, SourceLocation Loc, size_t N)
ExprResult ActOnArrayTypeTrait(ArrayTypeTrait ATT, SourceLocation KWLoc, ParsedType LhsTy, Expr *DimExpr, SourceLocation RParen)
ActOnArrayTypeTrait - Parsed one of the binary type trait support pseudo-functions.
void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, TemplateArgumentListInfo *ExplicitTemplateArgs, QualType ObjectType, Expr::Classification ObjectClassification, ArrayRef< Expr * > Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions=false, bool PartialOverloading=false, OverloadCandidateParamOrder PO={})
Add a C++ member function template as a candidate to the candidate set, using template argument deduc...
void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef< Expr * > Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions=false, bool PartialOverloading=false, bool AllowExplicit=true, ADLCallKind IsADLCandidate=ADLCallKind::NotADL, OverloadCandidateParamOrder PO={}, bool AggregateCandidateDeduction=false)
Add a C++ function template specialization as a candidate in the candidate set, using template argume...
const LangOptions & getLangOpts() const
Definition Sema.h:932
void AddOverloadCandidate(FunctionDecl *Function, DeclAccessPair FoundDecl, ArrayRef< Expr * > Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions=false, bool PartialOverloading=false, bool AllowExplicit=true, bool AllowExplicitConversion=false, ADLCallKind IsADLCandidate=ADLCallKind::NotADL, ConversionSequenceList EarlyConversions={}, OverloadCandidateParamOrder PO={}, bool AggregateCandidateDeduction=false, bool StrictPackMatch=false)
AddOverloadCandidate - Adds the given function to the set of candidate functions, using the given fun...
ExprResult BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc, ArrayRef< TypeSourceInfo * > Args, SourceLocation RParenLoc)
ExprResult BuildExpressionTrait(ExpressionTrait OET, SourceLocation KWLoc, Expr *Queried, SourceLocation RParen)
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
void AddMethodCandidate(DeclAccessPair FoundDecl, QualType ObjectType, Expr::Classification ObjectClassification, ArrayRef< Expr * > Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversion=false, OverloadCandidateParamOrder PO={})
AddMethodCandidate - Adds a named decl (which is some kind of method) as a method candidate to the gi...
CanThrowResult canThrow(const Stmt *E)
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
Definition Sema.h:6790
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:1267
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:3735
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4888
bool isUnion() const
Definition Decl.h:3946
bool isDependentType() const
Whether this declaration declares a type that is dependent, i.e., a type that somehow depends on temp...
Definition Decl.h:3881
@ 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:8407
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:8418
static TypeTraitExpr * Create(const ASTContext &C, QualType T, SourceLocation Loc, TypeTrait Kind, ArrayRef< TypeSourceInfo * > Args, SourceLocation RParenLoc, bool Value)
Create a new type trait expression.
Definition ExprCXX.cpp:1914
The base class of the type hierarchy.
Definition TypeBase.h:1871
bool isVoidType() const
Definition TypeBase.h:9039
bool isIncompleteArrayType() const
Definition TypeBase.h:8780
bool isRValueReferenceType() const
Definition TypeBase.h:8705
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:8772
CanQualType getCanonicalTypeUnqualified() const
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9333
bool isEnumeralType() const
Definition TypeBase.h:8804
bool isScalarType() const
Definition TypeBase.h:9145
bool isVariableArrayType() const
Definition TypeBase.h:8784
bool isLValueReferenceType() const
Definition TypeBase.h:8701
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition TypeBase.h:2837
bool isAggregateType() const
Determines whether the type is a C++ aggregate type or C aggregate or union type.
Definition Type.cpp:2503
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
Definition TypeBase.h:9219
bool isObjectType() const
Determine whether this type is an object type.
Definition TypeBase.h:2563
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
Definition Type.cpp:2527
bool isFunctionType() const
Definition TypeBase.h:8669
bool isStructureOrClassType() const
Definition Type.cpp:743
bool isVectorType() const
Definition TypeBase.h:8812
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition TypeBase.h:2976
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9266
A set of unresolved declarations.
QualType getType() const
Definition Decl.h:723
Provides information about an attempted template argument deduction, whose success or failure was des...
Definition SPIR.cpp:47
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Definition TokenKinds.h:25
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
bool isa(CodeGen::Address addr)
Definition Address.h:330
ArrayTypeTrait
Names for the array type traits.
Definition TypeTraits.h:42
@ CPlusPlus
unsigned getTypeTraitArity(TypeTrait T) LLVM_READONLY
Return the arity of the type trait T.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ OR_Deleted
Succeeded, but refers to a deleted function.
Definition Overload.h:61
@ OR_Success
Overload resolution succeeded.
Definition Overload.h:52
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition Specifiers.h: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...