clang 22.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
214// [C++26][class.prop]
215// A class C is eligible for replacement unless
216static bool IsEligibleForReplacement(Sema &SemaRef, const CXXRecordDecl *D) {
217
218 for (const CXXBaseSpecifier &B : D->bases()) {
219 const auto *BaseDecl = B.getType()->getAsCXXRecordDecl();
220 if (!BaseDecl)
221 continue;
222 // it has a base class that is not a replaceable class
223 if (!BaseDecl->isDependentType() &&
224 !SemaRef.IsCXXReplaceableType(B.getType()))
225 return false;
226 }
227
228 for (const FieldDecl *Field : D->fields()) {
229 if (Field->getType()->isDependentType())
230 continue;
231
232 // it has a non-static data member that is not of a replaceable type,
233 if (!SemaRef.IsCXXReplaceableType(Field->getType()))
234 return false;
235 }
236 return !D->hasDeletedDestructor();
237}
238
242
243 if (!getLangOpts().CPlusPlus || D->isInvalidDecl())
244 return Info;
245
246 assert(D->hasDefinition());
247
248 // This is part of "eligible for replacement", however we defer it
249 // to avoid extraneous computations.
250 auto HasSuitableSMP = [&] {
252 /*AllowUserDefined=*/true) &&
254 *this, D, /*AllowUserDefined=*/true);
255 };
256
257 auto IsUnion = [&, Is = std::optional<bool>{}]() mutable {
258 if (!Is.has_value())
259 Is = D->isUnion() && !D->hasUserDeclaredCopyConstructor() &&
263 return *Is;
264 };
265
266 auto IsDefaultMovable = [&, Is = std::optional<bool>{}]() mutable {
267 if (!Is.has_value())
268 Is = ::IsDefaultMovable(*this, D);
269 return *Is;
270 };
271
272 Info.IsRelocatable = [&] {
273 if (D->isDependentType())
274 return false;
275
276 // if it is eligible for trivial relocation
277 if (!IsEligibleForTrivialRelocation(*this, D))
278 return false;
279
280 // has the trivially_relocatable_if_eligible class-property-specifier,
281 if (D->hasAttr<TriviallyRelocatableAttr>())
282 return true;
283
284 // is a union with no user-declared special member functions, or
285 if (IsUnion())
286 return true;
287
288 // is default-movable.
289 return IsDefaultMovable();
290 }();
291
292 Info.IsReplaceable = [&] {
293 if (D->isDependentType())
294 return false;
295
296 // A class C is a replaceable class if it is eligible for replacement
297 if (!IsEligibleForReplacement(*this, D))
298 return false;
299
300 // has the replaceable_if_eligible class-property-specifier
301 if (D->hasAttr<ReplaceableAttr>())
302 return HasSuitableSMP();
303
304 // is a union with no user-declared special member functions, or
305 if (IsUnion())
306 return HasSuitableSMP();
307
308 // is default-movable.
309 return IsDefaultMovable();
310 }();
311
312 return Info;
313}
314
316 if (std::optional<ASTContext::CXXRecordDeclRelocationInfo> Info =
317 getASTContext().getRelocationInfoForCXXRecord(&RD))
318 return Info->IsRelocatable;
322 return Info.IsRelocatable;
323}
324
326 QualType BaseElementType = getASTContext().getBaseElementType(Type);
327
329 return false;
330
331 if (BaseElementType.hasNonTrivialObjCLifetime())
332 return false;
333
334 if (BaseElementType->isIncompleteType())
335 return false;
336
337 if (Context.containsNonRelocatablePointerAuth(Type))
338 return false;
339
340 if (BaseElementType->isScalarType() || BaseElementType->isVectorType())
341 return true;
342
343 if (const auto *RD = BaseElementType->getAsCXXRecordDecl())
345
346 return false;
347}
348
349static bool IsCXXReplaceableType(Sema &S, const CXXRecordDecl *RD) {
350 if (std::optional<ASTContext::CXXRecordDeclRelocationInfo> Info =
352 return Info->IsReplaceable;
356 return Info.IsReplaceable;
357}
358
360 if (Type.isConstQualified() || Type.isVolatileQualified())
361 return false;
362
364 return false;
365
366 QualType BaseElementType =
367 getASTContext().getBaseElementType(Type.getUnqualifiedType());
368 if (BaseElementType->isIncompleteType())
369 return false;
370 if (BaseElementType->isScalarType())
371 return true;
372 if (const auto *RD = BaseElementType->getAsCXXRecordDecl())
373 return ::IsCXXReplaceableType(*this, RD);
374 return false;
375}
376
377/// Checks that type T is not a VLA.
378///
379/// @returns @c true if @p T is VLA and a diagnostic was emitted,
380/// @c false otherwise.
382 clang::tok::TokenKind TypeTraitID) {
383 if (!T->getType()->isVariableArrayType())
384 return false;
385
386 S.Diag(T->getTypeLoc().getBeginLoc(), diag::err_vla_unsupported)
387 << 1 << TypeTraitID;
388 return true;
389}
390
391/// Checks that type T is not an atomic type (_Atomic).
392///
393/// @returns @c true if @p T is VLA and a diagnostic was emitted,
394/// @c false otherwise.
396 clang::tok::TokenKind TypeTraitID) {
397 if (!T->getType()->isAtomicType())
398 return false;
399
400 S.Diag(T->getTypeLoc().getBeginLoc(), diag::err_atomic_unsupported)
401 << TypeTraitID;
402 return true;
403}
404
405/// Check the completeness of a type in a unary type trait.
406///
407/// If the particular type trait requires a complete type, tries to complete
408/// it. If completing the type fails, a diagnostic is emitted and false
409/// returned. If completing the type succeeds or no completion was required,
410/// returns true.
412 SourceLocation Loc,
413 QualType ArgTy) {
414 // C++0x [meta.unary.prop]p3:
415 // For all of the class templates X declared in this Clause, instantiating
416 // that template with a template argument that is a class template
417 // specialization may result in the implicit instantiation of the template
418 // argument if and only if the semantics of X require that the argument
419 // must be a complete type.
420 // We apply this rule to all the type trait expressions used to implement
421 // these class templates. We also try to follow any GCC documented behavior
422 // in these expressions to ensure portability of standard libraries.
423 switch (UTT) {
424 default:
425 llvm_unreachable("not a UTT");
426 // is_complete_type somewhat obviously cannot require a complete type.
427 case UTT_IsCompleteType:
428 // Fall-through
429
430 // These traits are modeled on the type predicates in C++0x
431 // [meta.unary.cat] and [meta.unary.comp]. They are not specified as
432 // requiring a complete type, as whether or not they return true cannot be
433 // impacted by the completeness of the type.
434 case UTT_IsVoid:
435 case UTT_IsIntegral:
436 case UTT_IsFloatingPoint:
437 case UTT_IsArray:
438 case UTT_IsBoundedArray:
439 case UTT_IsPointer:
440 case UTT_IsLvalueReference:
441 case UTT_IsRvalueReference:
442 case UTT_IsMemberFunctionPointer:
443 case UTT_IsMemberObjectPointer:
444 case UTT_IsEnum:
445 case UTT_IsScopedEnum:
446 case UTT_IsUnion:
447 case UTT_IsClass:
448 case UTT_IsFunction:
449 case UTT_IsReference:
450 case UTT_IsArithmetic:
451 case UTT_IsFundamental:
452 case UTT_IsObject:
453 case UTT_IsScalar:
454 case UTT_IsCompound:
455 case UTT_IsMemberPointer:
456 case UTT_IsTypedResourceElementCompatible:
457 // Fall-through
458
459 // These traits are modeled on type predicates in C++0x [meta.unary.prop]
460 // which requires some of its traits to have the complete type. However,
461 // the completeness of the type cannot impact these traits' semantics, and
462 // so they don't require it. This matches the comments on these traits in
463 // Table 49.
464 case UTT_IsConst:
465 case UTT_IsVolatile:
466 case UTT_IsSigned:
467 case UTT_IsUnboundedArray:
468 case UTT_IsUnsigned:
469
470 // This type trait always returns false, checking the type is moot.
471 case UTT_IsInterfaceClass:
472 return true;
473
474 // We diagnose incomplete class types later.
475 case UTT_StructuredBindingSize:
476 return true;
477
478 // C++14 [meta.unary.prop]:
479 // If T is a non-union class type, T shall be a complete type.
480 case UTT_IsEmpty:
481 case UTT_IsPolymorphic:
482 case UTT_IsAbstract:
483 if (const auto *RD = ArgTy->getAsCXXRecordDecl())
484 if (!RD->isUnion())
485 return !S.RequireCompleteType(
486 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
487 return true;
488
489 // C++14 [meta.unary.prop]:
490 // If T is a class type, T shall be a complete type.
491 case UTT_IsFinal:
492 case UTT_IsSealed:
493 if (ArgTy->getAsCXXRecordDecl())
494 return !S.RequireCompleteType(
495 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
496 return true;
497
498 // LWG3823: T shall be an array type, a complete type, or cv void.
499 case UTT_IsAggregate:
500 case UTT_IsImplicitLifetime:
501 if (ArgTy->isArrayType() || ArgTy->isVoidType())
502 return true;
503
504 return !S.RequireCompleteType(
505 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
506
507 // has_unique_object_representations<T>
508 // remove_all_extents_t<T> shall be a complete type or cv void (LWG4113).
509 case UTT_HasUniqueObjectRepresentations:
510 ArgTy = QualType(ArgTy->getBaseElementTypeUnsafe(), 0);
511 if (ArgTy->isVoidType())
512 return true;
513 return !S.RequireCompleteType(
514 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
515
516 // C++1z [meta.unary.prop]:
517 // remove_all_extents_t<T> shall be a complete type or cv void.
518 case UTT_IsTrivial:
519 case UTT_IsTriviallyCopyable:
520 case UTT_IsStandardLayout:
521 case UTT_IsPOD:
522 case UTT_IsLiteral:
523 case UTT_IsBitwiseCloneable:
524 // By analogy, is_trivially_relocatable and is_trivially_equality_comparable
525 // impose the same constraints.
526 case UTT_IsTriviallyRelocatable:
527 case UTT_IsTriviallyEqualityComparable:
528 case UTT_IsCppTriviallyRelocatable:
529 case UTT_IsReplaceable:
530 case UTT_CanPassInRegs:
531 // Per the GCC type traits documentation, T shall be a complete type, cv void,
532 // or an array of unknown bound. But GCC actually imposes the same constraints
533 // as above.
534 case UTT_HasNothrowAssign:
535 case UTT_HasNothrowMoveAssign:
536 case UTT_HasNothrowConstructor:
537 case UTT_HasNothrowCopy:
538 case UTT_HasTrivialAssign:
539 case UTT_HasTrivialMoveAssign:
540 case UTT_HasTrivialDefaultConstructor:
541 case UTT_HasTrivialMoveConstructor:
542 case UTT_HasTrivialCopy:
543 case UTT_HasTrivialDestructor:
544 case UTT_HasVirtualDestructor:
545 ArgTy = QualType(ArgTy->getBaseElementTypeUnsafe(), 0);
546 [[fallthrough]];
547 // C++1z [meta.unary.prop]:
548 // T shall be a complete type, cv void, or an array of unknown bound.
549 case UTT_IsDestructible:
550 case UTT_IsNothrowDestructible:
551 case UTT_IsTriviallyDestructible:
552 case UTT_IsIntangibleType:
553 if (ArgTy->isIncompleteArrayType() || ArgTy->isVoidType())
554 return true;
555
556 return !S.RequireCompleteType(
557 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
558 }
559}
560
563 bool (CXXRecordDecl::*HasTrivial)() const,
564 bool (CXXRecordDecl::*HasNonTrivial)() const,
565 bool (CXXMethodDecl::*IsDesiredOp)() const) {
566 if ((RD->*HasTrivial)() && !(RD->*HasNonTrivial)())
567 return true;
568
569 DeclarationName Name = C.DeclarationNames.getCXXOperatorName(Op);
570 DeclarationNameInfo NameInfo(Name, KeyLoc);
572 if (Self.LookupQualifiedName(Res, RD)) {
573 bool FoundOperator = false;
575 for (LookupResult::iterator Op = Res.begin(), OpEnd = Res.end();
576 Op != OpEnd; ++Op) {
578 continue;
579
580 CXXMethodDecl *Operator = cast<CXXMethodDecl>(*Op);
581 if ((Operator->*IsDesiredOp)()) {
582 FoundOperator = true;
583 auto *CPT = Operator->getType()->castAs<FunctionProtoType>();
584 CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
585 if (!CPT || !CPT->isNothrow())
586 return false;
587 }
588 }
589 return FoundOperator;
590 }
591 return false;
592}
593
595 const CXXRecordDecl *Decl,
596 SourceLocation KeyLoc) {
597 if (Decl->isUnion())
598 return false;
599 if (Decl->isLambda())
600 return Decl->isCapturelessLambda();
601
603 {
604 EnterExpressionEvaluationContext UnevaluatedContext(
606 Sema::SFINAETrap SFINAE(S, /*ForValidityCheck=*/true);
608
609 // const ClassT& obj;
610 OpaqueValueExpr Operand(KeyLoc, T.withConst(), ExprValueKind::VK_LValue);
611 UnresolvedSet<16> Functions;
612 // obj == obj;
613 S.LookupBinOp(S.TUScope, {}, BinaryOperatorKind::BO_EQ, Functions);
614
615 auto Result = S.CreateOverloadedBinOp(KeyLoc, BinaryOperatorKind::BO_EQ,
616 Functions, &Operand, &Operand);
617 if (Result.isInvalid() || SFINAE.hasErrorOccurred())
618 return false;
619
620 const auto *CallExpr = dyn_cast<CXXOperatorCallExpr>(Result.get());
621 if (!CallExpr)
622 return false;
623 const auto *Callee = CallExpr->getDirectCallee();
624 auto ParamT = Callee->getParamDecl(0)->getType();
625 if (!Callee->isDefaulted())
626 return false;
627 if (!ParamT->isReferenceType() && !Decl->isTriviallyCopyable())
628 return false;
629 if (!S.Context.hasSameUnqualifiedType(ParamT.getNonReferenceType(), T))
630 return false;
631 }
632
633 return llvm::all_of(Decl->bases(),
634 [&](const CXXBaseSpecifier &BS) {
635 if (const auto *RD = BS.getType()->getAsCXXRecordDecl())
636 return HasNonDeletedDefaultedEqualityComparison(
637 S, RD, KeyLoc);
638 return true;
639 }) &&
640 llvm::all_of(Decl->fields(), [&](const FieldDecl *FD) {
641 auto Type = FD->getType();
642 if (Type->isArrayType())
643 Type = Type->getBaseElementTypeUnsafe()
644 ->getCanonicalTypeUnqualified();
645
646 if (Type->isReferenceType() || Type->isEnumeralType())
647 return false;
648 if (const auto *RD = Type->getAsCXXRecordDecl())
649 return HasNonDeletedDefaultedEqualityComparison(S, RD, KeyLoc);
650 return true;
651 });
652}
653
655 SourceLocation KeyLoc) {
656 QualType CanonicalType = Type.getCanonicalType();
657 if (CanonicalType->isIncompleteType() || CanonicalType->isDependentType() ||
658 CanonicalType->isEnumeralType() || CanonicalType->isArrayType())
659 return false;
660
661 if (const auto *RD = CanonicalType->getAsCXXRecordDecl()) {
663 return false;
664 }
665
667 CanonicalType, /*CheckIfTriviallyCopyable=*/false);
668}
669
671 QualType BaseElementType = SemaRef.getASTContext().getBaseElementType(T);
672
673 if (BaseElementType->isIncompleteType())
674 return false;
675 if (!BaseElementType->isObjectType())
676 return false;
677
678 // The deprecated __builtin_is_trivially_relocatable does not have
679 // an equivalent to __builtin_trivially_relocate, so there is no
680 // safe way to use it if there are any address discriminated values.
682 return false;
683
684 if (const auto *RD = BaseElementType->getAsCXXRecordDecl();
685 RD && !RD->isPolymorphic() && SemaRef.IsCXXTriviallyRelocatableType(*RD))
686 return true;
687
688 if (const auto *RD = BaseElementType->getAsRecordDecl())
689 return RD->canPassInRegisters();
690
691 if (BaseElementType.isTriviallyCopyableType(SemaRef.getASTContext()))
692 return true;
693
694 switch (T.isNonTrivialToPrimitiveDestructiveMove()) {
696 return !T.isDestructedType();
698 return true;
699 default:
700 return false;
701 }
702}
703
705 SourceLocation KeyLoc,
706 TypeSourceInfo *TInfo) {
707 QualType T = TInfo->getType();
708 assert(!T->isDependentType() && "Cannot evaluate traits of dependent type");
709
710 ASTContext &C = Self.Context;
711 switch (UTT) {
712 default:
713 llvm_unreachable("not a UTT");
714 // Type trait expressions corresponding to the primary type category
715 // predicates in C++0x [meta.unary.cat].
716 case UTT_IsVoid:
717 return T->isVoidType();
718 case UTT_IsIntegral:
719 return T->isIntegralType(C);
720 case UTT_IsFloatingPoint:
721 return T->isFloatingType();
722 case UTT_IsArray:
723 // Zero-sized arrays aren't considered arrays in partial specializations,
724 // so __is_array shouldn't consider them arrays either.
725 if (const auto *CAT = C.getAsConstantArrayType(T))
726 return CAT->getSize() != 0;
727 return T->isArrayType();
728 case UTT_IsBoundedArray:
729 if (DiagnoseVLAInCXXTypeTrait(Self, TInfo, tok::kw___is_bounded_array))
730 return false;
731 // Zero-sized arrays aren't considered arrays in partial specializations,
732 // so __is_bounded_array shouldn't consider them arrays either.
733 if (const auto *CAT = C.getAsConstantArrayType(T))
734 return CAT->getSize() != 0;
735 return T->isArrayType() && !T->isIncompleteArrayType();
736 case UTT_IsUnboundedArray:
737 if (DiagnoseVLAInCXXTypeTrait(Self, TInfo, tok::kw___is_unbounded_array))
738 return false;
739 return T->isIncompleteArrayType();
740 case UTT_IsPointer:
741 return T->isAnyPointerType();
742 case UTT_IsLvalueReference:
743 return T->isLValueReferenceType();
744 case UTT_IsRvalueReference:
745 return T->isRValueReferenceType();
746 case UTT_IsMemberFunctionPointer:
747 return T->isMemberFunctionPointerType();
748 case UTT_IsMemberObjectPointer:
749 return T->isMemberDataPointerType();
750 case UTT_IsEnum:
751 return T->isEnumeralType();
752 case UTT_IsScopedEnum:
753 return T->isScopedEnumeralType();
754 case UTT_IsUnion:
755 return T->isUnionType();
756 case UTT_IsClass:
757 return T->isClassType() || T->isStructureType() || T->isInterfaceType();
758 case UTT_IsFunction:
759 return T->isFunctionType();
760
761 // Type trait expressions which correspond to the convenient composition
762 // predicates in C++0x [meta.unary.comp].
763 case UTT_IsReference:
764 return T->isReferenceType();
765 case UTT_IsArithmetic:
766 return T->isArithmeticType() && !T->isEnumeralType();
767 case UTT_IsFundamental:
768 return T->isFundamentalType();
769 case UTT_IsObject:
770 return T->isObjectType();
771 case UTT_IsScalar:
772 // Note: semantic analysis depends on Objective-C lifetime types to be
773 // considered scalar types. However, such types do not actually behave
774 // like scalar types at run time (since they may require retain/release
775 // operations), so we report them as non-scalar.
776 if (T->isObjCLifetimeType()) {
777 switch (T.getObjCLifetime()) {
780 return true;
781
785 return false;
786 }
787 }
788
789 return T->isScalarType();
790 case UTT_IsCompound:
791 return T->isCompoundType();
792 case UTT_IsMemberPointer:
793 return T->isMemberPointerType();
794
795 // Type trait expressions which correspond to the type property predicates
796 // in C++0x [meta.unary.prop].
797 case UTT_IsConst:
798 return T.isConstQualified();
799 case UTT_IsVolatile:
800 return T.isVolatileQualified();
801 case UTT_IsTrivial:
802 return T.isTrivialType(C);
803 case UTT_IsTriviallyCopyable:
804 return T.isTriviallyCopyableType(C);
805 case UTT_IsStandardLayout:
806 return T->isStandardLayoutType();
807 case UTT_IsPOD:
808 return T.isPODType(C);
809 case UTT_IsLiteral:
810 return T->isLiteralType(C);
811 case UTT_IsEmpty:
812 if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
813 return !RD->isUnion() && RD->isEmpty();
814 return false;
815 case UTT_IsPolymorphic:
816 if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
817 return !RD->isUnion() && RD->isPolymorphic();
818 return false;
819 case UTT_IsAbstract:
820 if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
821 return !RD->isUnion() && RD->isAbstract();
822 return false;
823 case UTT_IsAggregate:
824 // Report vector extensions and complex types as aggregates because they
825 // support aggregate initialization. GCC mirrors this behavior for vectors
826 // but not _Complex.
827 return T->isAggregateType() || T->isVectorType() || T->isExtVectorType() ||
828 T->isAnyComplexType();
829 // __is_interface_class only returns true when CL is invoked in /CLR mode and
830 // even then only when it is used with the 'interface struct ...' syntax
831 // Clang doesn't support /CLR which makes this type trait moot.
832 case UTT_IsInterfaceClass:
833 return false;
834 case UTT_IsFinal:
835 case UTT_IsSealed:
836 if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
837 return RD->hasAttr<FinalAttr>();
838 return false;
839 case UTT_IsSigned:
840 // Enum types should always return false.
841 // Floating points should always return true.
842 return T->isFloatingType() ||
843 (T->isSignedIntegerType() && !T->isEnumeralType());
844 case UTT_IsUnsigned:
845 // Enum types should always return false.
846 return T->isUnsignedIntegerType() && !T->isEnumeralType();
847
848 // Type trait expressions which query classes regarding their construction,
849 // destruction, and copying. Rather than being based directly on the
850 // related type predicates in the standard, they are specified by both
851 // GCC[1] and the Embarcadero C++ compiler[2], and Clang implements those
852 // specifications.
853 //
854 // 1: http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
855 // 2:
856 // http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index
857 //
858 // Note that these builtins do not behave as documented in g++: if a class
859 // has both a trivial and a non-trivial special member of a particular kind,
860 // they return false! For now, we emulate this behavior.
861 // FIXME: This appears to be a g++ bug: more complex cases reveal that it
862 // does not correctly compute triviality in the presence of multiple special
863 // members of the same kind. Revisit this once the g++ bug is fixed.
864 case UTT_HasTrivialDefaultConstructor:
865 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
866 // If __is_pod (type) is true then the trait is true, else if type is
867 // a cv class or union type (or array thereof) with a trivial default
868 // constructor ([class.ctor]) then the trait is true, else it is false.
869 if (T.isPODType(C))
870 return true;
871 if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
872 return RD->hasTrivialDefaultConstructor() &&
874 return false;
875 case UTT_HasTrivialMoveConstructor:
876 // This trait is implemented by MSVC 2012 and needed to parse the
877 // standard library headers. Specifically this is used as the logic
878 // behind std::is_trivially_move_constructible (20.9.4.3).
879 if (T.isPODType(C))
880 return true;
881 if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
882 return RD->hasTrivialMoveConstructor() &&
884 return false;
885 case UTT_HasTrivialCopy:
886 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
887 // If __is_pod (type) is true or type is a reference type then
888 // the trait is true, else if type is a cv class or union type
889 // with a trivial copy constructor ([class.copy]) then the trait
890 // is true, else it is false.
891 if (T.isPODType(C) || T->isReferenceType())
892 return true;
893 if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
894 return RD->hasTrivialCopyConstructor() &&
896 return false;
897 case UTT_HasTrivialMoveAssign:
898 // This trait is implemented by MSVC 2012 and needed to parse the
899 // standard library headers. Specifically it is used as the logic
900 // behind std::is_trivially_move_assignable (20.9.4.3)
901 if (T.isPODType(C))
902 return true;
903 if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
904 return RD->hasTrivialMoveAssignment() &&
906 return false;
907 case UTT_HasTrivialAssign:
908 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
909 // If type is const qualified or is a reference type then the
910 // trait is false. Otherwise if __is_pod (type) is true then the
911 // trait is true, else if type is a cv class or union type with
912 // a trivial copy assignment ([class.copy]) then the trait is
913 // true, else it is false.
914 // Note: the const and reference restrictions are interesting,
915 // given that const and reference members don't prevent a class
916 // from having a trivial copy assignment operator (but do cause
917 // errors if the copy assignment operator is actually used, q.v.
918 // [class.copy]p12).
919
920 if (T.isConstQualified())
921 return false;
922 if (T.isPODType(C))
923 return true;
924 if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
925 return RD->hasTrivialCopyAssignment() &&
927 return false;
928 case UTT_IsDestructible:
929 case UTT_IsTriviallyDestructible:
930 case UTT_IsNothrowDestructible:
931 // C++14 [meta.unary.prop]:
932 // For reference types, is_destructible<T>::value is true.
933 if (T->isReferenceType())
934 return true;
935
936 // Objective-C++ ARC: autorelease types don't require destruction.
937 if (T->isObjCLifetimeType() &&
938 T.getObjCLifetime() == Qualifiers::OCL_Autoreleasing)
939 return true;
940
941 // C++14 [meta.unary.prop]:
942 // For incomplete types and function types, is_destructible<T>::value is
943 // false.
944 if (T->isIncompleteType() || T->isFunctionType())
945 return false;
946
947 // A type that requires destruction (via a non-trivial destructor or ARC
948 // lifetime semantics) is not trivially-destructible.
949 if (UTT == UTT_IsTriviallyDestructible && T.isDestructedType())
950 return false;
951
952 // C++14 [meta.unary.prop]:
953 // For object types and given U equal to remove_all_extents_t<T>, if the
954 // expression std::declval<U&>().~U() is well-formed when treated as an
955 // unevaluated operand (Clause 5), then is_destructible<T>::value is true
956 if (auto *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) {
957 CXXDestructorDecl *Destructor = Self.LookupDestructor(RD);
958 if (!Destructor)
959 return false;
960 // C++14 [dcl.fct.def.delete]p2:
961 // A program that refers to a deleted function implicitly or
962 // explicitly, other than to declare it, is ill-formed.
963 if (Destructor->isDeleted())
964 return false;
965 if (C.getLangOpts().AccessControl && Destructor->getAccess() != AS_public)
966 return false;
967 if (UTT == UTT_IsNothrowDestructible) {
968 auto *CPT = Destructor->getType()->castAs<FunctionProtoType>();
969 CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
970 if (!CPT || !CPT->isNothrow())
971 return false;
972 }
973 }
974 return true;
975
976 case UTT_HasTrivialDestructor:
977 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
978 // If __is_pod (type) is true or type is a reference type
979 // then the trait is true, else if type is a cv class or union
980 // type (or array thereof) with a trivial destructor
981 // ([class.dtor]) then the trait is true, else it is
982 // false.
983 if (T.isPODType(C) || T->isReferenceType())
984 return true;
985
986 // Objective-C++ ARC: autorelease types don't require destruction.
987 if (T->isObjCLifetimeType() &&
988 T.getObjCLifetime() == Qualifiers::OCL_Autoreleasing)
989 return true;
990
991 if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
992 return RD->hasTrivialDestructor();
993 return false;
994 // TODO: Propagate nothrowness for implicitly declared special members.
995 case UTT_HasNothrowAssign:
996 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
997 // If type is const qualified or is a reference type then the
998 // trait is false. Otherwise if __has_trivial_assign (type)
999 // is true then the trait is true, else if type is a cv class
1000 // or union type with copy assignment operators that are known
1001 // not to throw an exception then the trait is true, else it is
1002 // false.
1003 if (C.getBaseElementType(T).isConstQualified())
1004 return false;
1005 if (T->isReferenceType())
1006 return false;
1007 if (T.isPODType(C) || T->isObjCLifetimeType())
1008 return true;
1009
1010 if (auto *RD = T->getAsCXXRecordDecl())
1011 return HasNoThrowOperator(RD, OO_Equal, Self, KeyLoc, C,
1015 return false;
1016 case UTT_HasNothrowMoveAssign:
1017 // This trait is implemented by MSVC 2012 and needed to parse the
1018 // standard library headers. Specifically this is used as the logic
1019 // behind std::is_nothrow_move_assignable (20.9.4.3).
1020 if (T.isPODType(C))
1021 return true;
1022
1023 if (auto *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
1024 return HasNoThrowOperator(RD, OO_Equal, Self, KeyLoc, C,
1028 return false;
1029 case UTT_HasNothrowCopy:
1030 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
1031 // If __has_trivial_copy (type) is true then the trait is true, else
1032 // if type is a cv class or union type with copy constructors that are
1033 // known not to throw an exception then the trait is true, else it is
1034 // false.
1035 if (T.isPODType(C) || T->isReferenceType() || T->isObjCLifetimeType())
1036 return true;
1037 if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) {
1038 if (RD->hasTrivialCopyConstructor() &&
1040 return true;
1041
1042 bool FoundConstructor = false;
1043 unsigned FoundTQs;
1044 for (const auto *ND : Self.LookupConstructors(RD)) {
1045 // A template constructor is never a copy constructor.
1046 // FIXME: However, it may actually be selected at the actual overload
1047 // resolution point.
1048 if (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl()))
1049 continue;
1050 // UsingDecl itself is not a constructor
1051 if (isa<UsingDecl>(ND))
1052 continue;
1053 auto *Constructor = cast<CXXConstructorDecl>(ND->getUnderlyingDecl());
1054 if (Constructor->isCopyConstructor(FoundTQs)) {
1055 FoundConstructor = true;
1056 auto *CPT = Constructor->getType()->castAs<FunctionProtoType>();
1057 CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
1058 if (!CPT)
1059 return false;
1060 // TODO: check whether evaluating default arguments can throw.
1061 // For now, we'll be conservative and assume that they can throw.
1062 if (!CPT->isNothrow() || CPT->getNumParams() > 1)
1063 return false;
1064 }
1065 }
1066
1067 return FoundConstructor;
1068 }
1069 return false;
1070 case UTT_HasNothrowConstructor:
1071 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
1072 // If __has_trivial_constructor (type) is true then the trait is
1073 // true, else if type is a cv class or union type (or array
1074 // thereof) with a default constructor that is known not to
1075 // throw an exception then the trait is true, else it is false.
1076 if (T.isPODType(C) || T->isObjCLifetimeType())
1077 return true;
1078 if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) {
1079 if (RD->hasTrivialDefaultConstructor() &&
1081 return true;
1082
1083 bool FoundConstructor = false;
1084 for (const auto *ND : Self.LookupConstructors(RD)) {
1085 // FIXME: In C++0x, a constructor template can be a default constructor.
1086 if (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl()))
1087 continue;
1088 // UsingDecl itself is not a constructor
1089 if (isa<UsingDecl>(ND))
1090 continue;
1091 auto *Constructor = cast<CXXConstructorDecl>(ND->getUnderlyingDecl());
1092 if (Constructor->isDefaultConstructor()) {
1093 FoundConstructor = true;
1094 auto *CPT = Constructor->getType()->castAs<FunctionProtoType>();
1095 CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
1096 if (!CPT)
1097 return false;
1098 // FIXME: check whether evaluating default arguments can throw.
1099 // For now, we'll be conservative and assume that they can throw.
1100 if (!CPT->isNothrow() || CPT->getNumParams() > 0)
1101 return false;
1102 }
1103 }
1104 return FoundConstructor;
1105 }
1106 return false;
1107 case UTT_HasVirtualDestructor:
1108 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
1109 // If type is a class type with a virtual destructor ([class.dtor])
1110 // then the trait is true, else it is false.
1111 if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
1112 if (CXXDestructorDecl *Destructor = Self.LookupDestructor(RD))
1113 return Destructor->isVirtual();
1114 return false;
1115
1116 // These type trait expressions are modeled on the specifications for the
1117 // Embarcadero C++0x type trait functions:
1118 // http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index
1119 case UTT_IsCompleteType:
1120 // http://docwiki.embarcadero.com/RADStudio/XE/en/Is_complete_type_(typename_T_):
1121 // Returns True if and only if T is a complete type at the point of the
1122 // function call.
1123 return !T->isIncompleteType();
1124 case UTT_HasUniqueObjectRepresentations:
1125 return C.hasUniqueObjectRepresentations(T);
1126 case UTT_IsTriviallyRelocatable:
1128 case UTT_IsBitwiseCloneable:
1129 return T.isBitwiseCloneableType(C);
1130 case UTT_IsCppTriviallyRelocatable:
1131 return Self.IsCXXTriviallyRelocatableType(T);
1132 case UTT_IsReplaceable:
1133 return Self.IsCXXReplaceableType(T);
1134 case UTT_CanPassInRegs:
1135 if (CXXRecordDecl *RD = T->getAsCXXRecordDecl(); RD && !T.hasQualifiers())
1136 return RD->canPassInRegisters();
1137 Self.Diag(KeyLoc, diag::err_builtin_pass_in_regs_non_class) << T;
1138 return false;
1139 case UTT_IsTriviallyEqualityComparable:
1140 return isTriviallyEqualityComparableType(Self, T, KeyLoc);
1141 case UTT_IsImplicitLifetime: {
1143 tok::kw___builtin_is_implicit_lifetime);
1145 tok::kw___builtin_is_implicit_lifetime);
1146
1147 // [basic.types.general] p9
1148 // Scalar types, implicit-lifetime class types ([class.prop]),
1149 // array types, and cv-qualified versions of these types
1150 // are collectively called implicit-lifetime types.
1151 QualType UnqualT = T->getCanonicalTypeUnqualified();
1152 if (UnqualT->isScalarType())
1153 return true;
1154 if (UnqualT->isArrayType() || UnqualT->isVectorType())
1155 return true;
1156 const CXXRecordDecl *RD = UnqualT->getAsCXXRecordDecl();
1157 if (!RD)
1158 return false;
1159
1160 // [class.prop] p9
1161 // A class S is an implicit-lifetime class if
1162 // - it is an aggregate whose destructor is not user-provided or
1163 // - it has at least one trivial eligible constructor and a trivial,
1164 // non-deleted destructor.
1165 const CXXDestructorDecl *Dtor = RD->getDestructor();
1166 if (UnqualT->isAggregateType())
1167 if (Dtor && !Dtor->isUserProvided())
1168 return true;
1169 if (RD->hasTrivialDestructor() && (!Dtor || !Dtor->isDeleted()))
1170 if (RD->hasTrivialDefaultConstructor() ||
1172 return true;
1173 return false;
1174 }
1175 case UTT_IsIntangibleType:
1176 assert(Self.getLangOpts().HLSL && "intangible types are HLSL-only feature");
1177 if (!T->isVoidType() && !T->isIncompleteArrayType())
1178 if (Self.RequireCompleteType(TInfo->getTypeLoc().getBeginLoc(), T,
1179 diag::err_incomplete_type))
1180 return false;
1182 tok::kw___builtin_hlsl_is_intangible))
1183 return false;
1184 return T->isHLSLIntangibleType();
1185
1186 case UTT_IsTypedResourceElementCompatible:
1187 assert(Self.getLangOpts().HLSL &&
1188 "typed resource element compatible types are an HLSL-only feature");
1189 if (T->isIncompleteType())
1190 return false;
1191
1192 return Self.HLSL().IsTypedResourceElementCompatible(T);
1193 }
1194}
1195
1196static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT,
1197 const TypeSourceInfo *Lhs,
1198 const TypeSourceInfo *Rhs,
1199 SourceLocation KeyLoc);
1200
1202 Sema &Self, const TypeSourceInfo *Lhs, const TypeSourceInfo *Rhs,
1203 SourceLocation KeyLoc, llvm::BumpPtrAllocator &OpaqueExprAllocator) {
1204
1205 QualType LhsT = Lhs->getType();
1206 QualType RhsT = Rhs->getType();
1207
1208 // C++0x [meta.rel]p4:
1209 // Given the following function prototype:
1210 //
1211 // template <class T>
1212 // typename add_rvalue_reference<T>::type create();
1213 //
1214 // the predicate condition for a template specialization
1215 // is_convertible<From, To> shall be satisfied if and only if
1216 // the return expression in the following code would be
1217 // well-formed, including any implicit conversions to the return
1218 // type of the function:
1219 //
1220 // To test() {
1221 // return create<From>();
1222 // }
1223 //
1224 // Access checking is performed as if in a context unrelated to To and
1225 // From. Only the validity of the immediate context of the expression
1226 // of the return-statement (including conversions to the return type)
1227 // is considered.
1228 //
1229 // We model the initialization as a copy-initialization of a temporary
1230 // of the appropriate type, which for this expression is identical to the
1231 // return statement (since NRVO doesn't apply).
1232
1233 // Functions aren't allowed to return function or array types.
1234 if (RhsT->isFunctionType() || RhsT->isArrayType())
1235 return ExprError();
1236
1237 // A function definition requires a complete, non-abstract return type.
1238 if (!Self.isCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT) ||
1239 Self.isAbstractType(Rhs->getTypeLoc().getBeginLoc(), RhsT))
1240 return ExprError();
1241
1242 // Compute the result of add_rvalue_reference.
1243 if (LhsT->isObjectType() || LhsT->isFunctionType())
1244 LhsT = Self.Context.getRValueReferenceType(LhsT);
1245
1246 // Build a fake source and destination for initialization.
1248 Expr *From = new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
1249 OpaqueValueExpr(KeyLoc, LhsT.getNonLValueExprType(Self.Context),
1251 InitializationKind Kind =
1253
1254 // Perform the initialization in an unevaluated context within a SFINAE
1255 // trap at translation unit scope.
1258 Sema::SFINAETrap SFINAE(Self, /*ForValidityCheck=*/true);
1259 Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
1260 InitializationSequence Init(Self, To, Kind, From);
1261 if (Init.Failed())
1262 return ExprError();
1263
1264 ExprResult Result = Init.Perform(Self, To, Kind, From);
1265 if (Result.isInvalid() || SFINAE.hasErrorOccurred())
1266 return ExprError();
1267
1268 return Result;
1269}
1270
1272 SourceLocation KWLoc,
1274 SourceLocation RParenLoc,
1275 bool IsDependent) {
1276 if (IsDependent)
1277 return APValue();
1278
1279 switch (Kind) {
1280 case TypeTrait::UTT_StructuredBindingSize: {
1281 QualType T = Args[0]->getType();
1282 SourceRange ArgRange = Args[0]->getTypeLoc().getSourceRange();
1283 UnsignedOrNone Size =
1285 if (!Size) {
1286 S.Diag(KWLoc, diag::err_arg_is_not_destructurable) << T << ArgRange;
1287 return APValue();
1288 }
1289 return APValue(
1291 break;
1292 }
1293 default:
1294 llvm_unreachable("Not a SizeT type trait");
1295 }
1296}
1297
1299 SourceLocation KWLoc,
1301 SourceLocation RParenLoc,
1302 bool IsDependent) {
1303 if (IsDependent)
1304 return false;
1305
1306 if (Kind <= UTT_Last)
1307 return EvaluateUnaryTypeTrait(S, Kind, KWLoc, Args[0]);
1308
1309 // Evaluate ReferenceBindsToTemporary and ReferenceConstructsFromTemporary
1310 // alongside the IsConstructible traits to avoid duplication.
1311 if (Kind <= BTT_Last && Kind != BTT_ReferenceBindsToTemporary &&
1312 Kind != BTT_ReferenceConstructsFromTemporary &&
1313 Kind != BTT_ReferenceConvertsFromTemporary)
1314 return EvaluateBinaryTypeTrait(S, Kind, Args[0], Args[1], RParenLoc);
1315
1316 switch (Kind) {
1317 case clang::BTT_ReferenceBindsToTemporary:
1318 case clang::BTT_ReferenceConstructsFromTemporary:
1319 case clang::BTT_ReferenceConvertsFromTemporary:
1320 case clang::TT_IsConstructible:
1321 case clang::TT_IsNothrowConstructible:
1322 case clang::TT_IsTriviallyConstructible: {
1323 // C++11 [meta.unary.prop]:
1324 // is_trivially_constructible is defined as:
1325 //
1326 // is_constructible<T, Args...>::value is true and the variable
1327 // definition for is_constructible, as defined below, is known to call
1328 // no operation that is not trivial.
1329 //
1330 // The predicate condition for a template specialization
1331 // is_constructible<T, Args...> shall be satisfied if and only if the
1332 // following variable definition would be well-formed for some invented
1333 // variable t:
1334 //
1335 // T t(create<Args>()...);
1336 assert(!Args.empty());
1337
1338 // Precondition: T and all types in the parameter pack Args shall be
1339 // complete types, (possibly cv-qualified) void, or arrays of
1340 // unknown bound.
1341 for (const auto *TSI : Args) {
1342 QualType ArgTy = TSI->getType();
1343 if (ArgTy->isVoidType() || ArgTy->isIncompleteArrayType())
1344 continue;
1345
1346 if (S.RequireCompleteType(
1347 KWLoc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr))
1348 return false;
1349 }
1350
1351 // Make sure the first argument is not incomplete nor a function type.
1352 QualType T = Args[0]->getType();
1353 if (T->isIncompleteType() || T->isFunctionType())
1354 return false;
1355
1356 // Make sure the first argument is not an abstract type.
1357 CXXRecordDecl *RD = T->getAsCXXRecordDecl();
1358 if (RD && RD->isAbstract())
1359 return false;
1360
1361 // LWG3819: For reference_meows_from_temporary traits, && is not added to
1362 // the source object type.
1363 // Otherwise, compute the result of add_rvalue_reference_t.
1364 bool UseRawObjectType =
1365 Kind == clang::BTT_ReferenceBindsToTemporary ||
1366 Kind == clang::BTT_ReferenceConstructsFromTemporary ||
1367 Kind == clang::BTT_ReferenceConvertsFromTemporary;
1368
1369 llvm::BumpPtrAllocator OpaqueExprAllocator;
1370 SmallVector<Expr *, 2> ArgExprs;
1371 ArgExprs.reserve(Args.size() - 1);
1372 for (unsigned I = 1, N = Args.size(); I != N; ++I) {
1373 QualType ArgTy = Args[I]->getType();
1374 if ((ArgTy->isObjectType() && !UseRawObjectType) ||
1375 ArgTy->isFunctionType())
1376 ArgTy = S.Context.getRValueReferenceType(ArgTy);
1377 ArgExprs.push_back(
1378 new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
1379 OpaqueValueExpr(Args[I]->getTypeLoc().getBeginLoc(),
1382 }
1383
1384 // Perform the initialization in an unevaluated context within a SFINAE
1385 // trap at translation unit scope.
1388 Sema::SFINAETrap SFINAE(S, /*ForValidityCheck=*/true);
1392 InitializationKind InitKind(
1393 Kind == clang::BTT_ReferenceConvertsFromTemporary
1394 ? InitializationKind::CreateCopy(KWLoc, KWLoc)
1395 : InitializationKind::CreateDirect(KWLoc, KWLoc, RParenLoc));
1396 InitializationSequence Init(S, To, InitKind, ArgExprs);
1397 if (Init.Failed())
1398 return false;
1399
1400 ExprResult Result = Init.Perform(S, To, InitKind, ArgExprs);
1401 if (Result.isInvalid() || SFINAE.hasErrorOccurred())
1402 return false;
1403
1404 if (Kind == clang::TT_IsConstructible)
1405 return true;
1406
1407 if (Kind == clang::BTT_ReferenceBindsToTemporary ||
1408 Kind == clang::BTT_ReferenceConstructsFromTemporary ||
1409 Kind == clang::BTT_ReferenceConvertsFromTemporary) {
1410 if (!T->isReferenceType())
1411 return false;
1412
1413 // A function reference never binds to a temporary object.
1414 if (T.getNonReferenceType()->isFunctionType())
1415 return false;
1416
1417 if (!Init.isDirectReferenceBinding())
1418 return true;
1419
1420 if (Kind == clang::BTT_ReferenceBindsToTemporary)
1421 return false;
1422
1423 QualType U = Args[1]->getType();
1424 if (U->isReferenceType())
1425 return false;
1426
1428 S.Context.getPointerType(T.getNonReferenceType()));
1430 S.Context.getPointerType(U.getNonReferenceType()));
1431 return !CheckConvertibilityForTypeTraits(S, UPtr, TPtr, RParenLoc,
1432 OpaqueExprAllocator)
1433 .isInvalid();
1434 }
1435
1436 if (Kind == clang::TT_IsNothrowConstructible)
1437 return S.canThrow(Result.get()) == CT_Cannot;
1438
1439 if (Kind == clang::TT_IsTriviallyConstructible) {
1440 // Under Objective-C ARC and Weak, if the destination has non-trivial
1441 // Objective-C lifetime, this is a non-trivial construction.
1442 if (T.getNonReferenceType().hasNonTrivialObjCLifetime())
1443 return false;
1444
1445 // The initialization succeeded; now make sure there are no non-trivial
1446 // calls.
1447 return !Result.get()->hasNonTrivialCall(S.Context);
1448 }
1449
1450 llvm_unreachable("unhandled type trait");
1451 return false;
1452 }
1453 default:
1454 llvm_unreachable("not a TT");
1455 }
1456
1457 return false;
1458}
1459
1460namespace {
1461void DiagnoseBuiltinDeprecation(Sema &S, TypeTrait Kind, SourceLocation KWLoc) {
1462 TypeTrait Replacement;
1463 switch (Kind) {
1464 case UTT_HasNothrowAssign:
1465 case UTT_HasNothrowMoveAssign:
1466 Replacement = BTT_IsNothrowAssignable;
1467 break;
1468 case UTT_HasNothrowCopy:
1469 case UTT_HasNothrowConstructor:
1470 Replacement = TT_IsNothrowConstructible;
1471 break;
1472 case UTT_HasTrivialAssign:
1473 case UTT_HasTrivialMoveAssign:
1474 Replacement = BTT_IsTriviallyAssignable;
1475 break;
1476 case UTT_HasTrivialCopy:
1477 Replacement = UTT_IsTriviallyCopyable;
1478 break;
1479 case UTT_HasTrivialDefaultConstructor:
1480 case UTT_HasTrivialMoveConstructor:
1481 Replacement = TT_IsTriviallyConstructible;
1482 break;
1483 case UTT_HasTrivialDestructor:
1484 Replacement = UTT_IsTriviallyDestructible;
1485 break;
1486 case UTT_IsTriviallyRelocatable:
1487 Replacement = clang::UTT_IsCppTriviallyRelocatable;
1488 break;
1489 case BTT_ReferenceBindsToTemporary:
1490 Replacement = clang::BTT_ReferenceConstructsFromTemporary;
1491 break;
1492 default:
1493 return;
1494 }
1495 S.Diag(KWLoc, diag::warn_deprecated_builtin)
1496 << getTraitSpelling(Kind) << getTraitSpelling(Replacement);
1497}
1498} // namespace
1499
1500bool Sema::CheckTypeTraitArity(unsigned Arity, SourceLocation Loc, size_t N) {
1501 if (Arity && N != Arity) {
1502 Diag(Loc, diag::err_type_trait_arity)
1503 << Arity << 0 << (Arity > 1) << (int)N << SourceRange(Loc);
1504 return false;
1505 }
1506
1507 if (!Arity && N == 0) {
1508 Diag(Loc, diag::err_type_trait_arity)
1509 << 1 << 1 << 1 << (int)N << SourceRange(Loc);
1510 return false;
1511 }
1512 return true;
1513}
1514
1519
1521 if (Kind == TypeTrait::UTT_StructuredBindingSize)
1524}
1525
1528 SourceLocation RParenLoc) {
1529 if (!CheckTypeTraitArity(getTypeTraitArity(Kind), KWLoc, Args.size()))
1530 return ExprError();
1531
1533 *this, Kind, KWLoc, Args[0]->getType()))
1534 return ExprError();
1535
1536 DiagnoseBuiltinDeprecation(*this, Kind, KWLoc);
1537
1538 bool Dependent = false;
1539 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
1540 if (Args[I]->getType()->isDependentType()) {
1541 Dependent = true;
1542 break;
1543 }
1544 }
1545
1546 switch (GetReturnType(Kind)) {
1548 bool Result = EvaluateBooleanTypeTrait(*this, Kind, KWLoc, Args, RParenLoc,
1549 Dependent);
1550 return TypeTraitExpr::Create(Context, Context.getLogicalOperationType(),
1551 KWLoc, Kind, Args, RParenLoc, Result);
1552 }
1554 APValue Result =
1555 EvaluateSizeTTypeTrait(*this, Kind, KWLoc, Args, RParenLoc, Dependent);
1556 return TypeTraitExpr::Create(Context, Context.getSizeType(), KWLoc, Kind,
1557 Args, RParenLoc, Result);
1558 }
1559 }
1560 llvm_unreachable("unhandled type trait return type");
1561}
1562
1565 SourceLocation RParenLoc) {
1567 ConvertedArgs.reserve(Args.size());
1568
1569 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
1570 TypeSourceInfo *TInfo;
1571 QualType T = GetTypeFromParser(Args[I], &TInfo);
1572 if (!TInfo)
1573 TInfo = Context.getTrivialTypeSourceInfo(T, KWLoc);
1574
1575 ConvertedArgs.push_back(TInfo);
1576 }
1577
1578 return BuildTypeTrait(Kind, KWLoc, ConvertedArgs, RParenLoc);
1579}
1580
1582 QualType RhsT) {
1583 // C++0x [meta.rel]p2
1584 // Base is a base class of Derived without regard to cv-qualifiers or
1585 // Base and Derived are not unions and name the same class type without
1586 // regard to cv-qualifiers.
1587
1588 const RecordType *lhsRecord = LhsT->getAsCanonical<RecordType>();
1589 const RecordType *rhsRecord = RhsT->getAsCanonical<RecordType>();
1590 if (!rhsRecord || !lhsRecord) {
1591 const ObjCObjectType *LHSObjTy = LhsT->getAs<ObjCObjectType>();
1592 const ObjCObjectType *RHSObjTy = RhsT->getAs<ObjCObjectType>();
1593 if (!LHSObjTy || !RHSObjTy)
1594 return false;
1595
1596 ObjCInterfaceDecl *BaseInterface = LHSObjTy->getInterface();
1597 ObjCInterfaceDecl *DerivedInterface = RHSObjTy->getInterface();
1598 if (!BaseInterface || !DerivedInterface)
1599 return false;
1600
1601 if (RequireCompleteType(RhsTLoc, RhsT,
1602 diag::err_incomplete_type_used_in_type_trait_expr))
1603 return false;
1604
1605 return BaseInterface->isSuperClassOf(DerivedInterface);
1606 }
1607
1608 assert(Context.hasSameUnqualifiedType(LhsT, RhsT) ==
1609 (lhsRecord == rhsRecord));
1610
1611 // Unions are never base classes, and never have base classes.
1612 // It doesn't matter if they are complete or not. See PR#41843
1613 if (lhsRecord && lhsRecord->getOriginalDecl()->isUnion())
1614 return false;
1615 if (rhsRecord && rhsRecord->getOriginalDecl()->isUnion())
1616 return false;
1617
1618 if (lhsRecord == rhsRecord)
1619 return true;
1620
1621 // C++0x [meta.rel]p2:
1622 // If Base and Derived are class types and are different types
1623 // (ignoring possible cv-qualifiers) then Derived shall be a
1624 // complete type.
1625 if (RequireCompleteType(RhsTLoc, RhsT,
1626 diag::err_incomplete_type_used_in_type_trait_expr))
1627 return false;
1628
1629 return cast<CXXRecordDecl>(rhsRecord->getOriginalDecl())
1630 ->isDerivedFrom(cast<CXXRecordDecl>(lhsRecord->getOriginalDecl()));
1631}
1632
1634 const TypeSourceInfo *Lhs,
1635 const TypeSourceInfo *Rhs,
1636 SourceLocation KeyLoc) {
1637 QualType LhsT = Lhs->getType();
1638 QualType RhsT = Rhs->getType();
1639
1640 assert(!LhsT->isDependentType() && !RhsT->isDependentType() &&
1641 "Cannot evaluate traits of dependent types");
1642
1643 switch (BTT) {
1644 case BTT_IsBaseOf:
1645 return Self.BuiltinIsBaseOf(Rhs->getTypeLoc().getBeginLoc(), LhsT, RhsT);
1646
1647 case BTT_IsVirtualBaseOf: {
1648 const RecordType *BaseRecord = LhsT->getAsCanonical<RecordType>();
1649 const RecordType *DerivedRecord = RhsT->getAsCanonical<RecordType>();
1650
1651 if (!BaseRecord || !DerivedRecord) {
1653 tok::kw___builtin_is_virtual_base_of);
1655 tok::kw___builtin_is_virtual_base_of);
1656 return false;
1657 }
1658
1659 if (BaseRecord->isUnionType() || DerivedRecord->isUnionType())
1660 return false;
1661
1662 if (!BaseRecord->isStructureOrClassType() ||
1663 !DerivedRecord->isStructureOrClassType())
1664 return false;
1665
1666 if (Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1667 diag::err_incomplete_type))
1668 return false;
1669
1670 return cast<CXXRecordDecl>(DerivedRecord->getOriginalDecl())
1671 ->isVirtuallyDerivedFrom(
1672 cast<CXXRecordDecl>(BaseRecord->getOriginalDecl()));
1673 }
1674 case BTT_IsSame:
1675 return Self.Context.hasSameType(LhsT, RhsT);
1676 case BTT_TypeCompatible: {
1677 // GCC ignores cv-qualifiers on arrays for this builtin.
1678 Qualifiers LhsQuals, RhsQuals;
1679 QualType Lhs = Self.getASTContext().getUnqualifiedArrayType(LhsT, LhsQuals);
1680 QualType Rhs = Self.getASTContext().getUnqualifiedArrayType(RhsT, RhsQuals);
1681 return Self.Context.typesAreCompatible(Lhs, Rhs);
1682 }
1683 case BTT_IsConvertible:
1684 case BTT_IsConvertibleTo:
1685 case BTT_IsNothrowConvertible: {
1686 if (RhsT->isVoidType())
1687 return LhsT->isVoidType();
1688 llvm::BumpPtrAllocator OpaqueExprAllocator;
1689 ExprResult Result = CheckConvertibilityForTypeTraits(Self, Lhs, Rhs, KeyLoc,
1690 OpaqueExprAllocator);
1691 if (Result.isInvalid())
1692 return false;
1693
1694 if (BTT != BTT_IsNothrowConvertible)
1695 return true;
1696
1697 return Self.canThrow(Result.get()) == CT_Cannot;
1698 }
1699
1700 case BTT_IsAssignable:
1701 case BTT_IsNothrowAssignable:
1702 case BTT_IsTriviallyAssignable: {
1703 // C++11 [meta.unary.prop]p3:
1704 // is_trivially_assignable is defined as:
1705 // is_assignable<T, U>::value is true and the assignment, as defined by
1706 // is_assignable, is known to call no operation that is not trivial
1707 //
1708 // is_assignable is defined as:
1709 // The expression declval<T>() = declval<U>() is well-formed when
1710 // treated as an unevaluated operand (Clause 5).
1711 //
1712 // For both, T and U shall be complete types, (possibly cv-qualified)
1713 // void, or arrays of unknown bound.
1714 if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType() &&
1715 Self.RequireCompleteType(
1716 Lhs->getTypeLoc().getBeginLoc(), LhsT,
1717 diag::err_incomplete_type_used_in_type_trait_expr))
1718 return false;
1719 if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType() &&
1720 Self.RequireCompleteType(
1721 Rhs->getTypeLoc().getBeginLoc(), RhsT,
1722 diag::err_incomplete_type_used_in_type_trait_expr))
1723 return false;
1724
1725 // cv void is never assignable.
1726 if (LhsT->isVoidType() || RhsT->isVoidType())
1727 return false;
1728
1729 // Build expressions that emulate the effect of declval<T>() and
1730 // declval<U>().
1731 auto createDeclValExpr = [&](QualType Ty) -> OpaqueValueExpr {
1732 if (Ty->isObjectType() || Ty->isFunctionType())
1733 Ty = Self.Context.getRValueReferenceType(Ty);
1734 return {KeyLoc, Ty.getNonLValueExprType(Self.Context),
1736 };
1737
1738 auto Lhs = createDeclValExpr(LhsT);
1739 auto Rhs = createDeclValExpr(RhsT);
1740
1741 // Attempt the assignment in an unevaluated context within a SFINAE
1742 // trap at translation unit scope.
1745 Sema::SFINAETrap SFINAE(Self, /*ForValidityCheck=*/true);
1746 Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
1747 ExprResult Result =
1748 Self.BuildBinOp(/*S=*/nullptr, KeyLoc, BO_Assign, &Lhs, &Rhs);
1749 if (Result.isInvalid())
1750 return false;
1751
1752 // Treat the assignment as unused for the purpose of -Wdeprecated-volatile.
1753 Self.CheckUnusedVolatileAssignment(Result.get());
1754
1755 if (SFINAE.hasErrorOccurred())
1756 return false;
1757
1758 if (BTT == BTT_IsAssignable)
1759 return true;
1760
1761 if (BTT == BTT_IsNothrowAssignable)
1762 return Self.canThrow(Result.get()) == CT_Cannot;
1763
1764 if (BTT == BTT_IsTriviallyAssignable) {
1765 // Under Objective-C ARC and Weak, if the destination has non-trivial
1766 // Objective-C lifetime, this is a non-trivial assignment.
1768 return false;
1769 const ASTContext &Context = Self.getASTContext();
1770 if (Context.containsAddressDiscriminatedPointerAuth(LhsT) ||
1771 Context.containsAddressDiscriminatedPointerAuth(RhsT))
1772 return false;
1773 return !Result.get()->hasNonTrivialCall(Self.Context);
1774 }
1775
1776 llvm_unreachable("unhandled type trait");
1777 return false;
1778 }
1779 case BTT_IsLayoutCompatible: {
1780 if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType())
1781 Self.RequireCompleteType(Lhs->getTypeLoc().getBeginLoc(), LhsT,
1782 diag::err_incomplete_type);
1783 if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType())
1784 Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1785 diag::err_incomplete_type);
1786
1787 DiagnoseVLAInCXXTypeTrait(Self, Lhs, tok::kw___is_layout_compatible);
1788 DiagnoseVLAInCXXTypeTrait(Self, Rhs, tok::kw___is_layout_compatible);
1789
1790 return Self.IsLayoutCompatible(LhsT, RhsT);
1791 }
1792 case BTT_IsPointerInterconvertibleBaseOf: {
1793 if (LhsT->isStructureOrClassType() && RhsT->isStructureOrClassType() &&
1794 !Self.getASTContext().hasSameUnqualifiedType(LhsT, RhsT)) {
1795 Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1796 diag::err_incomplete_type);
1797 }
1798
1800 tok::kw___is_pointer_interconvertible_base_of);
1802 tok::kw___is_pointer_interconvertible_base_of);
1803
1804 return Self.IsPointerInterconvertibleBaseOf(Lhs, Rhs);
1805 }
1806 case BTT_IsDeducible: {
1807 const auto *TSTToBeDeduced = cast<DeducedTemplateSpecializationType>(LhsT);
1808 sema::TemplateDeductionInfo Info(KeyLoc);
1809 return Self.DeduceTemplateArgumentsFromType(
1810 TSTToBeDeduced->getTemplateName().getAsTemplateDecl(), RhsT,
1812 }
1813 case BTT_IsScalarizedLayoutCompatible: {
1814 if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType() &&
1815 Self.RequireCompleteType(Lhs->getTypeLoc().getBeginLoc(), LhsT,
1816 diag::err_incomplete_type))
1817 return true;
1818 if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType() &&
1819 Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1820 diag::err_incomplete_type))
1821 return true;
1822
1824 Self, Lhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1826 Self, Rhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1827
1828 return Self.HLSL().IsScalarizedLayoutCompatible(LhsT, RhsT);
1829 }
1830 case BTT_LtSynthesisesFromSpaceship:
1831 case BTT_LeSynthesisesFromSpaceship:
1832 case BTT_GtSynthesisesFromSpaceship:
1833 case BTT_GeSynthesisesFromSpaceship: {
1834 EnterExpressionEvaluationContext UnevaluatedContext(
1836 Sema::SFINAETrap SFINAE(Self, /*ForValidityCheck=*/true);
1837 Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
1838
1839 OpaqueValueExpr LHS(KeyLoc, LhsT.getNonReferenceType(),
1841 : LhsT->isRValueReferenceType()
1844 OpaqueValueExpr RHS(KeyLoc, RhsT.getNonReferenceType(),
1846 : RhsT->isRValueReferenceType()
1849
1850 auto OpKind = [&] {
1851 switch (BTT) {
1852 case BTT_LtSynthesisesFromSpaceship:
1853 return BinaryOperatorKind::BO_LT;
1854 case BTT_LeSynthesisesFromSpaceship:
1855 return BinaryOperatorKind::BO_LE;
1856 case BTT_GtSynthesisesFromSpaceship:
1857 return BinaryOperatorKind::BO_GT;
1858 case BTT_GeSynthesisesFromSpaceship:
1859 return BinaryOperatorKind::BO_GE;
1860 default:
1861 llvm_unreachable("Trying to Synthesize non-comparison operator?");
1862 }
1863 }();
1864
1865 UnresolvedSet<16> Functions;
1866 Self.LookupBinOp(Self.TUScope, KeyLoc, OpKind, Functions);
1867
1868 ExprResult Result =
1869 Self.CreateOverloadedBinOp(KeyLoc, OpKind, Functions, &LHS, &RHS);
1870 if (Result.isInvalid() || SFINAE.hasErrorOccurred())
1871 return false;
1872
1873 return isa<CXXRewrittenBinaryOperator>(Result.get());
1874 }
1875 default:
1876 llvm_unreachable("not a BTT");
1877 }
1878 llvm_unreachable("Unknown type trait or not implemented");
1879}
1880
1882 ParsedType Ty, Expr *DimExpr,
1883 SourceLocation RParen) {
1884 TypeSourceInfo *TSInfo;
1885 QualType T = GetTypeFromParser(Ty, &TSInfo);
1886 if (!TSInfo)
1887 TSInfo = Context.getTrivialTypeSourceInfo(T);
1888
1889 return BuildArrayTypeTrait(ATT, KWLoc, TSInfo, DimExpr, RParen);
1890}
1891
1893 QualType T, Expr *DimExpr,
1894 SourceLocation KeyLoc) {
1895 assert(!T->isDependentType() && "Cannot evaluate traits of dependent type");
1896
1897 switch (ATT) {
1898 case ATT_ArrayRank:
1899 if (T->isArrayType()) {
1900 unsigned Dim = 0;
1901 while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {
1902 ++Dim;
1903 T = AT->getElementType();
1904 }
1905 return Dim;
1906 }
1907 return 0;
1908
1909 case ATT_ArrayExtent: {
1910 llvm::APSInt Value;
1911 uint64_t Dim;
1912 if (Self.VerifyIntegerConstantExpression(
1913 DimExpr, &Value, diag::err_dimension_expr_not_constant_integer)
1914 .isInvalid())
1915 return 0;
1916 if (Value.isSigned() && Value.isNegative()) {
1917 Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer)
1918 << DimExpr->getSourceRange();
1919 return 0;
1920 }
1921 Dim = Value.getLimitedValue();
1922
1923 if (T->isArrayType()) {
1924 unsigned D = 0;
1925 bool Matched = false;
1926 while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {
1927 if (Dim == D) {
1928 Matched = true;
1929 break;
1930 }
1931 ++D;
1932 T = AT->getElementType();
1933 }
1934
1935 if (Matched && T->isArrayType()) {
1936 if (const ConstantArrayType *CAT =
1937 Self.Context.getAsConstantArrayType(T))
1938 return CAT->getLimitedSize();
1939 }
1940 }
1941 return 0;
1942 }
1943 }
1944 llvm_unreachable("Unknown type trait or not implemented");
1945}
1946
1948 TypeSourceInfo *TSInfo, Expr *DimExpr,
1949 SourceLocation RParen) {
1950 QualType T = TSInfo->getType();
1951
1952 // FIXME: This should likely be tracked as an APInt to remove any host
1953 // assumptions about the width of size_t on the target.
1954 uint64_t Value = 0;
1955 if (!T->isDependentType())
1956 Value = EvaluateArrayTypeTrait(*this, ATT, T, DimExpr, KWLoc);
1957
1958 // While the specification for these traits from the Embarcadero C++
1959 // compiler's documentation says the return type is 'unsigned int', Clang
1960 // returns 'size_t'. On Windows, the primary platform for the Embarcadero
1961 // compiler, there is no difference. On several other platforms this is an
1962 // important distinction.
1963 return new (Context) ArrayTypeTraitExpr(KWLoc, ATT, TSInfo, Value, DimExpr,
1964 RParen, Context.getSizeType());
1965}
1966
1968 Expr *Queried, SourceLocation RParen) {
1969 // If error parsing the expression, ignore.
1970 if (!Queried)
1971 return ExprError();
1972
1973 ExprResult Result = BuildExpressionTrait(ET, KWLoc, Queried, RParen);
1974
1975 return Result;
1976}
1977
1979 switch (ET) {
1980 case ET_IsLValueExpr:
1981 return E->isLValue();
1982 case ET_IsRValueExpr:
1983 return E->isPRValue();
1984 }
1985 llvm_unreachable("Expression trait not covered by switch");
1986}
1987
1989 Expr *Queried, SourceLocation RParen) {
1990 if (Queried->isTypeDependent()) {
1991 // Delay type-checking for type-dependent expressions.
1992 } else if (Queried->hasPlaceholderType()) {
1993 ExprResult PE = CheckPlaceholderExpr(Queried);
1994 if (PE.isInvalid())
1995 return ExprError();
1996 return BuildExpressionTrait(ET, KWLoc, PE.get(), RParen);
1997 }
1998
1999 bool Value = EvaluateExpressionTrait(ET, Queried);
2000
2001 return new (Context)
2002 ExpressionTraitExpr(KWLoc, ET, Queried, Value, RParen, Context.BoolTy);
2003}
2004
2005static std::optional<TypeTrait> StdNameToTypeTrait(StringRef Name) {
2006 return llvm::StringSwitch<std::optional<TypeTrait>>(Name)
2007 .Case("is_trivially_relocatable",
2008 TypeTrait::UTT_IsCppTriviallyRelocatable)
2009 .Case("is_replaceable", TypeTrait::UTT_IsReplaceable)
2010 .Case("is_trivially_copyable", TypeTrait::UTT_IsTriviallyCopyable)
2011 .Case("is_assignable", TypeTrait::BTT_IsAssignable)
2012 .Case("is_empty", TypeTrait::UTT_IsEmpty)
2013 .Case("is_standard_layout", TypeTrait::UTT_IsStandardLayout)
2014 .Case("is_aggregate", TypeTrait::UTT_IsAggregate)
2015 .Case("is_constructible", TypeTrait::TT_IsConstructible)
2016 .Case("is_final", TypeTrait::UTT_IsFinal)
2017 .Case("is_abstract", TypeTrait::UTT_IsAbstract)
2018 .Default(std::nullopt);
2019}
2020
2022 std::optional<std::pair<TypeTrait, llvm::SmallVector<QualType, 1>>>;
2023
2024// Recognize type traits that are builting type traits, or known standard
2025// type traits in <type_traits>. Note that at this point we assume the
2026// trait evaluated to false, so we need only to recognize the shape of the
2027// outer-most symbol.
2030 std::optional<TypeTrait> Trait;
2031
2032 // builtins
2033 if (const auto *TraitExpr = dyn_cast<TypeTraitExpr>(E)) {
2034 Trait = TraitExpr->getTrait();
2035 for (const auto *Arg : TraitExpr->getArgs())
2036 Args.push_back(Arg->getType());
2037 return {{Trait.value(), std::move(Args)}};
2038 }
2039 const auto *Ref = dyn_cast<DeclRefExpr>(E);
2040 if (!Ref)
2041 return std::nullopt;
2042
2043 // std::is_xxx_v<>
2044 if (const auto *VD =
2045 dyn_cast<VarTemplateSpecializationDecl>(Ref->getDecl())) {
2046 if (!VD->isInStdNamespace())
2047 return std::nullopt;
2048 StringRef Name = VD->getIdentifier()->getName();
2049 if (!Name.consume_back("_v"))
2050 return std::nullopt;
2051 Trait = StdNameToTypeTrait(Name);
2052 if (!Trait)
2053 return std::nullopt;
2054 for (const auto &Arg : VD->getTemplateArgs().asArray()) {
2055 if (Arg.getKind() == TemplateArgument::ArgKind::Pack) {
2056 for (const auto &InnerArg : Arg.pack_elements())
2057 Args.push_back(InnerArg.getAsType());
2058 } else if (Arg.getKind() == TemplateArgument::ArgKind::Type) {
2059 Args.push_back(Arg.getAsType());
2060 } else {
2061 llvm_unreachable("Unexpected kind");
2062 }
2063 }
2064 return {{Trait.value(), std::move(Args)}};
2065 }
2066
2067 // std::is_xxx<>::value
2068 if (const auto *VD = dyn_cast<VarDecl>(Ref->getDecl());
2069 Ref->hasQualifier() && VD && VD->getIdentifier()->isStr("value")) {
2070 NestedNameSpecifier Qualifier = Ref->getQualifier();
2071 if (Qualifier.getKind() != NestedNameSpecifier::Kind::Type)
2072 return std::nullopt;
2073 const auto *Ts = Qualifier.getAsType()->getAs<TemplateSpecializationType>();
2074 if (!Ts)
2075 return std::nullopt;
2076 const TemplateDecl *D = Ts->getTemplateName().getAsTemplateDecl();
2077 if (!D || !D->isInStdNamespace())
2078 return std::nullopt;
2079 Trait = StdNameToTypeTrait(D->getIdentifier()->getName());
2080 if (!Trait)
2081 return std::nullopt;
2082 for (const auto &Arg : Ts->template_arguments())
2083 Args.push_back(Arg.getAsType());
2084 return {{Trait.value(), std::move(Args)}};
2085 }
2086 return std::nullopt;
2087}
2088
2090 const CXXRecordDecl *D) {
2091 if (D->isUnion()) {
2092 auto DiagSPM = [&](CXXSpecialMemberKind K, bool Has) {
2093 if (Has)
2094 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2095 << diag::TraitNotSatisfiedReason::UnionWithUserDeclaredSMF << K;
2096 };
2105 return;
2106 }
2107
2109 const auto *Decl = cast_or_null<CXXConstructorDecl>(
2110 LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/false));
2111 if (Decl && Decl->isUserProvided())
2112 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2113 << diag::TraitNotSatisfiedReason::UserProvidedCtr
2114 << Decl->isMoveConstructor() << Decl->getSourceRange();
2115 }
2118 LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/true);
2119 if (Decl && Decl->isUserProvided())
2120 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2121 << diag::TraitNotSatisfiedReason::UserProvidedAssign
2122 << Decl->isMoveAssignmentOperator() << Decl->getSourceRange();
2123 }
2124 if (CXXDestructorDecl *Dtr = D->getDestructor()) {
2125 Dtr = Dtr->getCanonicalDecl();
2126 if (Dtr->isUserProvided() && !Dtr->isDefaulted())
2127 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2128 << diag::TraitNotSatisfiedReason::DeletedDtr << /*User Provided*/ 1
2129 << Dtr->getSourceRange();
2130 }
2131}
2132
2134 SourceLocation Loc,
2135 const CXXRecordDecl *D) {
2136 for (const CXXBaseSpecifier &B : D->bases()) {
2137 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2138 if (B.isVirtual())
2139 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2140 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2141 << B.getSourceRange();
2142 if (!SemaRef.IsCXXTriviallyRelocatableType(B.getType()))
2143 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2144 << diag::TraitNotSatisfiedReason::NTRBase << B.getType()
2145 << B.getSourceRange();
2146 }
2147 for (const FieldDecl *Field : D->fields()) {
2148 if (!Field->getType()->isReferenceType() &&
2149 !SemaRef.IsCXXTriviallyRelocatableType(Field->getType()))
2150 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2151 << diag::TraitNotSatisfiedReason::NTRField << Field
2152 << Field->getType() << Field->getSourceRange();
2153 }
2154 if (D->hasDeletedDestructor())
2155 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2156 << diag::TraitNotSatisfiedReason::DeletedDtr << /*Deleted*/ 0
2157 << D->getDestructor()->getSourceRange();
2158
2159 if (D->hasAttr<TriviallyRelocatableAttr>())
2160 return;
2161 DiagnoseNonDefaultMovable(SemaRef, Loc, D);
2162}
2163
2165 SourceLocation Loc,
2166 QualType T) {
2167 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2168 << T << diag::TraitName::TriviallyRelocatable;
2169 if (T->isVariablyModifiedType())
2170 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2171 << diag::TraitNotSatisfiedReason::VLA;
2172
2173 if (T->isReferenceType())
2174 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2175 << diag::TraitNotSatisfiedReason::Ref;
2176 T = T.getNonReferenceType();
2177
2178 if (T.hasNonTrivialObjCLifetime())
2179 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2180 << diag::TraitNotSatisfiedReason::HasArcLifetime;
2181
2182 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2183 if (!D || D->isInvalidDecl())
2184 return;
2185
2186 if (D->hasDefinition())
2188
2189 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2190}
2191
2193 const CXXRecordDecl *D) {
2194 for (const CXXBaseSpecifier &B : D->bases()) {
2195 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2196 if (!SemaRef.IsCXXReplaceableType(B.getType()))
2197 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2198 << diag::TraitNotSatisfiedReason::NonReplaceableBase << B.getType()
2199 << B.getSourceRange();
2200 }
2201 for (const FieldDecl *Field : D->fields()) {
2202 if (!SemaRef.IsCXXReplaceableType(Field->getType()))
2203 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2204 << diag::TraitNotSatisfiedReason::NonReplaceableField << Field
2205 << Field->getType() << Field->getSourceRange();
2206 }
2207 if (D->hasDeletedDestructor())
2208 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2209 << diag::TraitNotSatisfiedReason::DeletedDtr << /*Deleted*/ 0
2210 << D->getDestructor()->getSourceRange();
2211
2213 const auto *Decl = cast<CXXConstructorDecl>(
2214 LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/false));
2215 if (Decl && Decl->isDeleted())
2216 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2217 << diag::TraitNotSatisfiedReason::DeletedCtr
2218 << Decl->isMoveConstructor() << Decl->getSourceRange();
2219 }
2222 LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/true);
2223 if (Decl && Decl->isDeleted())
2224 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2225 << diag::TraitNotSatisfiedReason::DeletedAssign
2226 << Decl->isMoveAssignmentOperator() << Decl->getSourceRange();
2227 }
2228
2229 if (D->hasAttr<ReplaceableAttr>())
2230 return;
2231 DiagnoseNonDefaultMovable(SemaRef, Loc, D);
2232}
2233
2235 QualType T) {
2236 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2237 << T << diag::TraitName::Replaceable;
2238
2239 if (T->isVariablyModifiedType())
2240 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2241 << diag::TraitNotSatisfiedReason::VLA;
2242
2243 if (T->isReferenceType())
2244 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2245 << diag::TraitNotSatisfiedReason::Ref;
2246 T = T.getNonReferenceType();
2247
2248 if (T.isConstQualified())
2249 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2250 << diag::TraitNotSatisfiedReason::Const;
2251
2252 if (T.isVolatileQualified())
2253 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2254 << diag::TraitNotSatisfiedReason::Volatile;
2255
2256 bool IsArray = T->isArrayType();
2257 T = SemaRef.getASTContext().getBaseElementType(T.getUnqualifiedType());
2258
2259 if (T->isScalarType())
2260 return;
2261
2262 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2263 if (!D) {
2264 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2265 << diag::TraitNotSatisfiedReason::NotScalarOrClass << IsArray;
2266 return;
2267 }
2268
2269 if (D->isInvalidDecl())
2270 return;
2271
2272 if (D->hasDefinition())
2273 DiagnoseNonReplaceableReason(SemaRef, Loc, D);
2274
2275 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2276}
2277
2279 SourceLocation Loc,
2280 const CXXRecordDecl *D) {
2281 for (const CXXBaseSpecifier &B : D->bases()) {
2282 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2283 if (B.isVirtual())
2284 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2285 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2286 << B.getSourceRange();
2287 if (!B.getType().isTriviallyCopyableType(D->getASTContext())) {
2288 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2289 << diag::TraitNotSatisfiedReason::NTCBase << B.getType()
2290 << B.getSourceRange();
2291 }
2292 }
2293 for (const FieldDecl *Field : D->fields()) {
2294 if (!Field->getType().isTriviallyCopyableType(Field->getASTContext()))
2295 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2296 << diag::TraitNotSatisfiedReason::NTCField << Field
2297 << Field->getType() << Field->getSourceRange();
2298 }
2299 CXXDestructorDecl *Dtr = D->getDestructor();
2300 if (D->hasDeletedDestructor() || (Dtr && !Dtr->isTrivial()))
2301 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2302 << diag::TraitNotSatisfiedReason::DeletedDtr
2304
2305 for (const CXXMethodDecl *Method : D->methods()) {
2306 if (Method->isTrivial() || !Method->isUserProvided()) {
2307 continue;
2308 }
2309 auto SpecialMemberKind =
2310 SemaRef.getDefaultedFunctionKind(Method).asSpecialMember();
2311 switch (SpecialMemberKind) {
2316 bool IsAssignment =
2317 SpecialMemberKind == CXXSpecialMemberKind::CopyAssignment ||
2318 SpecialMemberKind == CXXSpecialMemberKind::MoveAssignment;
2319 bool IsMove =
2320 SpecialMemberKind == CXXSpecialMemberKind::MoveConstructor ||
2321 SpecialMemberKind == CXXSpecialMemberKind::MoveAssignment;
2322
2323 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2324 << (IsAssignment ? diag::TraitNotSatisfiedReason::UserProvidedAssign
2325 : diag::TraitNotSatisfiedReason::UserProvidedCtr)
2326 << IsMove << Method->getSourceRange();
2327 break;
2328 }
2329 default:
2330 break;
2331 }
2332 }
2333}
2334
2336 Sema &SemaRef, SourceLocation Loc,
2338 if (Ts.empty()) {
2339 return;
2340 }
2341
2342 bool ContainsVoid = false;
2343 for (const QualType &ArgTy : Ts) {
2344 ContainsVoid |= ArgTy->isVoidType();
2345 }
2346
2347 if (ContainsVoid)
2348 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2349 << diag::TraitNotSatisfiedReason::CVVoidType;
2350
2351 QualType T = Ts[0];
2352 if (T->isFunctionType())
2353 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2354 << diag::TraitNotSatisfiedReason::FunctionType;
2355
2356 if (T->isIncompleteArrayType())
2357 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2358 << diag::TraitNotSatisfiedReason::IncompleteArrayType;
2359
2360 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2361 if (!D || D->isInvalidDecl() || !D->hasDefinition())
2362 return;
2363
2364 llvm::BumpPtrAllocator OpaqueExprAllocator;
2365 SmallVector<Expr *, 2> ArgExprs;
2366 ArgExprs.reserve(Ts.size() - 1);
2367 for (unsigned I = 1, N = Ts.size(); I != N; ++I) {
2368 QualType ArgTy = Ts[I];
2369 if (ArgTy->isObjectType() || ArgTy->isFunctionType())
2370 ArgTy = SemaRef.Context.getRValueReferenceType(ArgTy);
2371 ArgExprs.push_back(
2372 new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
2373 OpaqueValueExpr(Loc, ArgTy.getNonLValueExprType(SemaRef.Context),
2375 }
2376
2379 Sema::ContextRAII TUContext(SemaRef,
2383 InitializationSequence Init(SemaRef, To, InitKind, ArgExprs);
2384
2385 Init.Diagnose(SemaRef, To, InitKind, ArgExprs);
2386 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2387}
2388
2390 SourceLocation Loc, QualType T) {
2391 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2392 << T << diag::TraitName::TriviallyCopyable;
2393
2394 if (T->isReferenceType())
2395 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2396 << diag::TraitNotSatisfiedReason::Ref;
2397
2398 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2399 if (!D || D->isInvalidDecl())
2400 return;
2401
2402 if (D->hasDefinition())
2403 DiagnoseNonTriviallyCopyableReason(SemaRef, Loc, D);
2404
2405 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2406}
2407
2409 QualType T, QualType U) {
2410 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2411
2412 auto createDeclValExpr = [&](QualType Ty) -> OpaqueValueExpr {
2413 if (Ty->isObjectType() || Ty->isFunctionType())
2414 Ty = SemaRef.Context.getRValueReferenceType(Ty);
2415 return {Loc, Ty.getNonLValueExprType(SemaRef.Context),
2417 };
2418
2419 auto LHS = createDeclValExpr(T);
2420 auto RHS = createDeclValExpr(U);
2421
2424 Sema::ContextRAII TUContext(SemaRef,
2426 SemaRef.BuildBinOp(/*S=*/nullptr, Loc, BO_Assign, &LHS, &RHS);
2427
2428 if (!D || D->isInvalidDecl())
2429 return;
2430
2431 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2432}
2433
2435 const CXXRecordDecl *D) {
2436 // Non-static data members (ignore zero-width bit‐fields).
2437 for (const auto *Field : D->fields()) {
2438 if (Field->isZeroLengthBitField())
2439 continue;
2440 if (Field->isBitField()) {
2441 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2442 << diag::TraitNotSatisfiedReason::NonZeroLengthField << Field
2443 << Field->getSourceRange();
2444 continue;
2445 }
2446 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2447 << diag::TraitNotSatisfiedReason::NonEmptyMember << Field
2448 << Field->getType() << Field->getSourceRange();
2449 }
2450
2451 // Virtual functions.
2452 for (const auto *M : D->methods()) {
2453 if (M->isVirtual()) {
2454 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2455 << diag::TraitNotSatisfiedReason::VirtualFunction << M
2456 << M->getSourceRange();
2457 break;
2458 }
2459 }
2460
2461 // Virtual bases and non-empty bases.
2462 for (const auto &B : D->bases()) {
2463 const auto *BR = B.getType()->getAsCXXRecordDecl();
2464 if (!BR || BR->isInvalidDecl())
2465 continue;
2466 if (B.isVirtual()) {
2467 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2468 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2469 << B.getSourceRange();
2470 }
2471 if (!BR->isEmpty()) {
2472 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2473 << diag::TraitNotSatisfiedReason::NonEmptyBase << B.getType()
2474 << B.getSourceRange();
2475 }
2476 }
2477}
2478
2480 // Emit primary "not empty" diagnostic.
2481 S.Diag(Loc, diag::note_unsatisfied_trait) << T << diag::TraitName::Empty;
2482
2483 // While diagnosing is_empty<T>, we want to look at the actual type, not a
2484 // reference or an array of it. So we need to massage the QualType param to
2485 // strip refs and arrays.
2486 if (T->isReferenceType())
2487 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2488 << diag::TraitNotSatisfiedReason::Ref;
2489 T = T.getNonReferenceType();
2490
2491 if (auto *AT = S.Context.getAsArrayType(T))
2492 T = AT->getElementType();
2493
2494 if (auto *D = T->getAsCXXRecordDecl()) {
2495 if (D->hasDefinition()) {
2496 DiagnoseIsEmptyReason(S, Loc, D);
2497 S.Diag(D->getLocation(), diag::note_defined_here) << D;
2498 }
2499 }
2500}
2501
2503 const CXXRecordDecl *D) {
2504 if (!D || D->isInvalidDecl())
2505 return;
2506
2507 // Complete record but not 'final'.
2508 if (!D->isEffectivelyFinal()) {
2509 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2510 << diag::TraitNotSatisfiedReason::NotMarkedFinal;
2511 S.Diag(D->getLocation(), diag::note_defined_here) << D;
2512 return;
2513 }
2514}
2515
2517 // Primary: “%0 is not final”
2518 S.Diag(Loc, diag::note_unsatisfied_trait) << T << diag::TraitName::Final;
2519 if (T->isReferenceType()) {
2520 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2521 << diag::TraitNotSatisfiedReason::Ref;
2522 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2523 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2524 return;
2525 }
2526 // Arrays / functions / non-records → not a class/union.
2527 if (S.Context.getAsArrayType(T)) {
2528 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2529 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2530 return;
2531 }
2532 if (T->isFunctionType()) {
2533 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2534 << diag::TraitNotSatisfiedReason::FunctionType;
2535 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2536 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2537 return;
2538 }
2539 if (!T->isRecordType()) {
2540 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2541 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2542 return;
2543 }
2544 if (const auto *D = T->getAsCXXRecordDecl())
2545 DiagnoseIsFinalReason(S, Loc, D);
2546}
2547
2549 int NumBasesWithFields = 0;
2550 for (const CXXBaseSpecifier &Base : D->bases()) {
2551 const CXXRecordDecl *BaseRD = Base.getType()->getAsCXXRecordDecl();
2552 if (!BaseRD || BaseRD->isInvalidDecl())
2553 continue;
2554
2555 for (const FieldDecl *Field : BaseRD->fields()) {
2556 if (!Field->isUnnamedBitField()) {
2557 if (++NumBasesWithFields > 1)
2558 return true; // found more than one base class with fields
2559 break; // no need to check further fields in this base class
2560 }
2561 }
2562 }
2563 return false;
2564}
2565
2567 const CXXRecordDecl *D) {
2568 for (const CXXBaseSpecifier &B : D->bases()) {
2569 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2570 if (B.isVirtual()) {
2571 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2572 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2573 << B.getSourceRange();
2574 }
2575 if (!B.getType()->isStandardLayoutType()) {
2576 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2577 << diag::TraitNotSatisfiedReason::NonStandardLayoutBase << B.getType()
2578 << B.getSourceRange();
2579 }
2580 }
2581 // Check for mixed access specifiers in fields.
2582 const FieldDecl *FirstField = nullptr;
2583 AccessSpecifier FirstAccess = AS_none;
2584
2585 for (const FieldDecl *Field : D->fields()) {
2586 if (Field->isUnnamedBitField())
2587 continue;
2588
2589 // Record the first field we see
2590 if (!FirstField) {
2591 FirstField = Field;
2592 FirstAccess = Field->getAccess();
2593 continue;
2594 }
2595
2596 // Check if the field has a different access specifier than the first one.
2597 if (Field->getAccess() != FirstAccess) {
2598 // Emit a diagnostic about mixed access specifiers.
2599 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2600 << diag::TraitNotSatisfiedReason::MixedAccess;
2601
2602 SemaRef.Diag(FirstField->getLocation(), diag::note_defined_here)
2603 << FirstField;
2604
2605 SemaRef.Diag(Field->getLocation(), diag::note_unsatisfied_trait_reason)
2606 << diag::TraitNotSatisfiedReason::MixedAccessField << Field
2607 << FirstField;
2608
2609 // No need to check further fields, as we already found mixed access.
2610 break;
2611 }
2612 }
2614 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2615 << diag::TraitNotSatisfiedReason::MultipleDataBase;
2616 }
2617 if (D->isPolymorphic()) {
2618 // Find the best location to point “defined here” at.
2619 const CXXMethodDecl *VirtualMD = nullptr;
2620 // First, look for a virtual method.
2621 for (const auto *M : D->methods()) {
2622 if (M->isVirtual()) {
2623 VirtualMD = M;
2624 break;
2625 }
2626 }
2627 if (VirtualMD) {
2628 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2629 << diag::TraitNotSatisfiedReason::VirtualFunction << VirtualMD;
2630 SemaRef.Diag(VirtualMD->getLocation(), diag::note_defined_here)
2631 << VirtualMD;
2632 } else {
2633 // If no virtual method, point to the record declaration itself.
2634 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2635 << diag::TraitNotSatisfiedReason::VirtualFunction << D;
2636 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2637 }
2638 }
2639 for (const FieldDecl *Field : D->fields()) {
2640 if (!Field->getType()->isStandardLayoutType()) {
2641 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2642 << diag::TraitNotSatisfiedReason::NonStandardLayoutMember << Field
2643 << Field->getType() << Field->getSourceRange();
2644 }
2645 }
2646 // Find any indirect base classes that have fields.
2647 if (D->hasDirectFields()) {
2648 const CXXRecordDecl *Indirect = nullptr;
2649 D->forallBases([&](const CXXRecordDecl *BaseDef) {
2650 if (BaseDef->hasDirectFields()) {
2651 Indirect = BaseDef;
2652 return false; // stop traversal
2653 }
2654 return true; // continue to the next base
2655 });
2656 if (Indirect) {
2657 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2658 << diag::TraitNotSatisfiedReason::IndirectBaseWithFields << Indirect
2659 << Indirect->getSourceRange();
2660 }
2661 }
2662}
2663
2665 QualType T) {
2666 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2667 << T << diag::TraitName::StandardLayout;
2668
2669 // Check type-level exclusion first.
2670 if (T->isVariablyModifiedType()) {
2671 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2672 << diag::TraitNotSatisfiedReason::VLA;
2673 return;
2674 }
2675
2676 if (T->isReferenceType()) {
2677 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2678 << diag::TraitNotSatisfiedReason::Ref;
2679 return;
2680 }
2681 T = T.getNonReferenceType();
2682 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2683 if (!D || D->isInvalidDecl())
2684 return;
2685
2686 if (D->hasDefinition())
2687 DiagnoseNonStandardLayoutReason(SemaRef, Loc, D);
2688
2689 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2690}
2691
2693 const CXXRecordDecl *D) {
2694 for (const CXXConstructorDecl *Ctor : D->ctors()) {
2695 if (Ctor->isUserProvided())
2696 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2697 << diag::TraitNotSatisfiedReason::UserDeclaredCtr;
2698 if (Ctor->isInheritingConstructor())
2699 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2700 << diag::TraitNotSatisfiedReason::InheritedCtr;
2701 }
2702
2703 if (llvm::any_of(D->decls(), [](auto const *Sub) {
2704 return isa<ConstructorUsingShadowDecl>(Sub);
2705 })) {
2706 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2707 << diag::TraitNotSatisfiedReason::InheritedCtr;
2708 }
2709
2710 if (D->isPolymorphic())
2711 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2712 << diag::TraitNotSatisfiedReason::PolymorphicType
2713 << D->getSourceRange();
2714
2715 for (const CXXBaseSpecifier &B : D->bases()) {
2716 if (B.isVirtual()) {
2717 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2718 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2719 << B.getSourceRange();
2720 continue;
2721 }
2722 auto AccessSpecifier = B.getAccessSpecifier();
2723 switch (AccessSpecifier) {
2724 case AS_private:
2725 case AS_protected:
2726 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2727 << diag::TraitNotSatisfiedReason::PrivateProtectedDirectBase
2729 break;
2730 default:
2731 break;
2732 }
2733 }
2734
2735 for (const CXXMethodDecl *Method : D->methods()) {
2736 if (Method->isVirtual()) {
2737 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2738 << diag::TraitNotSatisfiedReason::VirtualFunction << Method
2739 << Method->getSourceRange();
2740 }
2741 }
2742
2743 for (const FieldDecl *Field : D->fields()) {
2744 auto AccessSpecifier = Field->getAccess();
2745 switch (AccessSpecifier) {
2746 case AS_private:
2747 case AS_protected:
2748 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2749 << diag::TraitNotSatisfiedReason::PrivateProtectedDirectDataMember
2751 break;
2752 default:
2753 break;
2754 }
2755 }
2756
2757 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2758}
2759
2761 QualType T) {
2762 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2763 << T << diag::TraitName::Aggregate;
2764
2765 if (T->isVoidType())
2766 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2767 << diag::TraitNotSatisfiedReason::CVVoidType;
2768
2769 T = T.getNonReferenceType();
2770 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2771 if (!D || D->isInvalidDecl())
2772 return;
2773
2774 if (D->hasDefinition())
2775 DiagnoseNonAggregateReason(SemaRef, Loc, D);
2776}
2777
2779 const CXXRecordDecl *D) {
2780 // If this type has any abstract base classes, their respective virtual
2781 // functions must have been overridden.
2782 for (const CXXBaseSpecifier &B : D->bases()) {
2783 if (B.getType()->castAsCXXRecordDecl()->isAbstract()) {
2784 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2785 << diag::TraitNotSatisfiedReason::OverridesAllPureVirtual
2786 << B.getType() << B.getSourceRange();
2787 }
2788 }
2789}
2790
2792 QualType T) {
2793 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2794 << T << diag::TraitName::Abstract;
2795
2796 if (T->isReferenceType()) {
2797 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2798 << diag::TraitNotSatisfiedReason::Ref;
2799 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2800 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2801 return;
2802 }
2803
2804 if (T->isUnionType()) {
2805 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2806 << diag::TraitNotSatisfiedReason::UnionType;
2807 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2808 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2809 return;
2810 }
2811
2812 if (SemaRef.Context.getAsArrayType(T)) {
2813 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2814 << diag::TraitNotSatisfiedReason::ArrayType;
2815 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2816 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2817 return;
2818 }
2819
2820 if (T->isFunctionType()) {
2821 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2822 << diag::TraitNotSatisfiedReason::FunctionType;
2823 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2824 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2825 return;
2826 }
2827
2828 if (T->isPointerType()) {
2829 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2830 << diag::TraitNotSatisfiedReason::PointerType;
2831 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2832 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2833 return;
2834 }
2835
2836 if (!T->isStructureOrClassType()) {
2837 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2838 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2839 return;
2840 }
2841
2842 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2843 if (D->hasDefinition())
2844 DiagnoseNonAbstractReason(SemaRef, Loc, D);
2845}
2846
2848 E = E->IgnoreParenImpCasts();
2849 if (E->containsErrors())
2850 return;
2851
2853 if (!TraitInfo)
2854 return;
2855
2856 const auto &[Trait, Args] = TraitInfo.value();
2857 switch (Trait) {
2858 case UTT_IsCppTriviallyRelocatable:
2860 break;
2861 case UTT_IsReplaceable:
2862 DiagnoseNonReplaceableReason(*this, E->getBeginLoc(), Args[0]);
2863 break;
2864 case UTT_IsTriviallyCopyable:
2865 DiagnoseNonTriviallyCopyableReason(*this, E->getBeginLoc(), Args[0]);
2866 break;
2867 case BTT_IsAssignable:
2868 DiagnoseNonAssignableReason(*this, E->getBeginLoc(), Args[0], Args[1]);
2869 break;
2870 case UTT_IsEmpty:
2871 DiagnoseIsEmptyReason(*this, E->getBeginLoc(), Args[0]);
2872 break;
2873 case UTT_IsStandardLayout:
2874 DiagnoseNonStandardLayoutReason(*this, E->getBeginLoc(), Args[0]);
2875 break;
2876 case TT_IsConstructible:
2878 break;
2879 case UTT_IsAggregate:
2880 DiagnoseNonAggregateReason(*this, E->getBeginLoc(), Args[0]);
2881 break;
2882 case UTT_IsFinal: {
2883 QualType QT = Args[0];
2884 if (QT->isDependentType())
2885 break;
2886 const auto *RD = QT->getAsCXXRecordDecl();
2887 if (!RD || !RD->isEffectivelyFinal())
2888 DiagnoseIsFinalReason(*this, E->getBeginLoc(), QT); // unsatisfied
2889 break;
2890 }
2891 case UTT_IsAbstract:
2892 DiagnoseNonAbstractReason(*this, E->getBeginLoc(), Args[0]);
2893 break;
2894 default:
2895 break;
2896 }
2897}
static CanQualType GetReturnType(QualType RetTy)
Returns the "extra-canonicalized" return type, which discards qualifiers on the return type.
Definition CGCall.cpp:151
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the Diagnostic IDs-related interfaces.
TokenType getType() const
Returns the token's type, e.g.
This file declares semantic analysis for HLSL constructs.
static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, const TypeSourceInfo *Lhs, const TypeSourceInfo *Rhs, SourceLocation KeyLoc)
static bool HasNonDeletedDefaultedEqualityComparison(Sema &S, const CXXRecordDecl *Decl, SourceLocation KeyLoc)
static void DiagnoseNonAbstractReason(Sema &SemaRef, SourceLocation Loc, const CXXRecordDecl *D)
static APValue EvaluateSizeTTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, ArrayRef< TypeSourceInfo * > Args, SourceLocation RParenLoc, bool IsDependent)
static bool DiagnoseVLAInCXXTypeTrait(Sema &S, const TypeSourceInfo *T, clang::tok::TokenKind TypeTraitID)
Checks that type T is not a VLA.
static bool HasNoThrowOperator(CXXRecordDecl *RD, OverloadedOperatorKind Op, Sema &Self, SourceLocation KeyLoc, ASTContext &C, bool(CXXRecordDecl::*HasTrivial)() const, bool(CXXRecordDecl::*HasNonTrivial)() const, bool(CXXMethodDecl::*IsDesiredOp)() const)
static std::optional< TypeTrait > StdNameToTypeTrait(StringRef Name)
static void DiagnoseNonConstructibleReason(Sema &SemaRef, SourceLocation Loc, const llvm::SmallVector< clang::QualType, 1 > &Ts)
static bool IsEligibleForTrivialRelocation(Sema &SemaRef, const CXXRecordDecl *D)
static CXXMethodDecl * LookupSpecialMemberFromXValue(Sema &SemaRef, const CXXRecordDecl *RD, bool Assign)
static bool hasSuitableMoveAssignmentOperatorForRelocation(Sema &SemaRef, const CXXRecordDecl *D, bool AllowUserDefined)
static bool DiagnoseAtomicInCXXTypeTrait(Sema &S, const TypeSourceInfo *T, clang::tok::TokenKind TypeTraitID)
Checks that type T is not an atomic type (_Atomic).
static 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 IsEligibleForReplacement(Sema &SemaRef, 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 DiagnoseNonReplaceableReason(Sema &SemaRef, SourceLocation Loc, const CXXRecordDecl *D)
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 IsCXXReplaceableType(Sema &S, const CXXRecordDecl *RD)
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:188
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:741
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:642
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.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
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
std::optional< CXXRecordDeclRelocationInfo > getRelocationInfoForCXXRecord(const CXXRecordDecl *) const
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:2990
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition TypeBase.h:3720
Represents a base class of a C++ class.
Definition DeclCXX.h:146
Represents a C++ constructor within a class.
Definition DeclCXX.h:2604
Represents a C++ destructor within a class.
Definition DeclCXX.h:2869
CXXDestructorDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition DeclCXX.h:2921
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2129
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
Definition DeclCXX.cpp:2735
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
Definition DeclCXX.cpp:2714
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:1341
bool hasNonTrivialCopyAssignment() const
Determine whether this class has a non-trivial copy assignment operator (C++ [class....
Definition DeclCXX.h:1334
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
Definition DeclCXX.cpp:2325
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:1240
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
Definition DeclCXX.h:1366
bool hasUserDeclaredDestructor() const
Determine whether this class has a user-declared destructor.
Definition DeclCXX.h:1001
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:2140
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:1301
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:1278
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
Definition DeclCXX.h:1214
bool hasTrivialCopyAssignment() const
Determine whether this class has a trivial copy assignment operator (C++ [class.copy]p11,...
Definition DeclCXX.h:1328
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 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:1313
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:2121
bool hasNonTrivialMoveAssignment() const
Determine whether this class has a non-trivial move assignment operator (C++11 [class....
Definition DeclCXX.h:1348
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:1247
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:1288
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:2877
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition Expr.h:3060
Represents the canonical version of C arrays with a specified constant size.
Definition TypeBase.h:3758
A POD class for pairing a NamedDecl* with an access specifier.
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
DeclContextLookupResult lookup_result
Definition DeclBase.h:2577
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition DeclBase.h:2373
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
bool isInStdNamespace() const
Definition DeclBase.cpp:427
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:524
bool isInvalidDecl() const
Definition DeclBase.h:588
SourceLocation getLocation() const
Definition DeclBase.h:439
AccessSpecifier getAccess() const
Definition DeclBase.h:507
bool hasAttr() const
Definition DeclBase.h:577
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Definition DeclBase.h:427
DeclarationName getCXXOperatorName(OverloadedOperatorKind Op)
Get the name of the overloadable C++ operator corresponding to Op.
DeclarationName getCXXConstructorName(CanQualType Ty)
Returns the name of a C++ constructor for the given Type.
The name of a declaration.
RAII object that enters a new expression evaluation context.
The return type of classify().
Definition Expr.h:337
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:3085
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:412
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
Definition Expr.h:523
static ExprValueKind getValueKindForType(QualType T)
getValueKindForType - Given a formal return or parameter type, give its value kind.
Definition Expr.h:434
An expression trait intrinsic.
Definition ExprCXX.h:3063
Represents a member of a struct/union/class.
Definition Decl.h:3157
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition Decl.h:2376
bool isDeleted() const
Whether this function has been deleted.
Definition Decl.h:2539
bool isDefaulted() const
Whether this function is defaulted.
Definition Decl.h:2384
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4490
bool isUserProvided() const
True if this method is user-declared and was not deleted or defaulted on its first declaration.
Definition Decl.h:2409
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5264
unsigned getNumParams() const
Definition TypeBase.h:5542
bool isNothrow(bool ResultIfDependent=false) const
Determine whether this function type has a non-throwing exception specification.
Definition TypeBase.h:5663
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:273
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
Definition Decl.h:486
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:294
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:1178
OverloadCandidateSet - A set of overload candidates, used in C++ overload resolution (C++ 13....
Definition Overload.h:1153
@ CSK_Normal
Normal lookup.
Definition Overload.h:1157
SmallVectorImpl< OverloadCandidate >::iterator iterator
Definition Overload.h:1369
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:2867
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type.
Definition Type.cpp:3556
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:8470
bool hasNonTrivialObjCLifetime() const
Definition TypeBase.h:1442
@ PCK_Trivial
The type does not fall into any of the following categories.
Definition TypeBase.h:1493
@ PCK_ARCStrong
The type is an Objective-C retainable pointer type that is qualified with the ARC __strong qualifier.
Definition TypeBase.h:1502
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:4446
field_range fields() const
Definition Decl.h:4512
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition SemaBase.cpp:61
A RAII object to temporarily push a declaration context.
Definition Sema.h:3476
CXXSpecialMemberKind asSpecialMember() const
Definition Sema.h:6350
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
Definition Sema.h:12367
bool hasErrorOccurred() const
Determine whether any SFINAE errors have been trapped.
Definition Sema.h:12400
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:854
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:9291
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:1283
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:925
ASTContext::CXXRecordDeclRelocationInfo CheckCXX2CRelocatableAndReplaceable(const clang::CXXRecordDecl *D)
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:918
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)
bool IsCXXReplaceableType(QualType T)
Determines if a type is replaceable according to the C++26 rules.
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:6675
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:1246
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:334
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Stmt.cpp:346
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4834
bool isUnion() const
Definition Decl.h:3919
bool isDependentType() const
Whether this declaration declares a type that is dependent, i.e., a type that somehow depends on temp...
Definition Decl.h:3854
@ 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:8256
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition TypeLoc.h:272
QualType getType() const
Return the type wrapped by this type source info.
Definition TypeBase.h:8267
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:1833
bool isVoidType() const
Definition TypeBase.h:8878
bool isIncompleteArrayType() const
Definition TypeBase.h:8629
bool isRValueReferenceType() const
Definition TypeBase.h:8554
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:8621
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9165
bool isEnumeralType() const
Definition TypeBase.h:8653
bool isScalarType() const
Definition TypeBase.h:8980
bool isVariableArrayType() const
Definition TypeBase.h:8633
bool isLValueReferenceType() const
Definition TypeBase.h:8550
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition TypeBase.h:2782
bool isAggregateType() const
Determines whether the type is a C++ aggregate type or C aggregate or union type.
Definition Type.cpp:2411
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
Definition TypeBase.h:9051
bool isObjectType() const
Determine whether this type is an object type.
Definition TypeBase.h:2510
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
Definition Type.cpp:2436
bool isFunctionType() const
Definition TypeBase.h:8518
bool isStructureOrClassType() const
Definition Type.cpp:706
bool isVectorType() const
Definition TypeBase.h:8661
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition TypeBase.h:2921
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9098
A set of unresolved declarations.
QualType getType() const
Definition Decl.h:722
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.
@ OR_Deleted
Succeeded, but refers to a deleted function.
Definition Overload.h:61
@ OR_Success
Overload resolution succeeded.
Definition Overload.h:52
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition Specifiers.h:123
@ AS_public
Definition Specifiers.h:124
@ AS_protected
Definition Specifiers.h:125
@ AS_none
Definition Specifiers.h:127
@ AS_private
Definition Specifiers.h:126
@ Dependent
Parse the block as a dependent block, which may be used in some template instantiations but not other...
Definition Parser.h:142
@ Result
The result type of a method or function.
Definition TypeBase.h:905
const FunctionProtoType * T
ExprResult ExprError()
Definition Ownership.h:265
CXXSpecialMemberKind
Kinds of C++ special members.
Definition Sema.h:424
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
Definition Specifiers.h:132
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
Definition Specifiers.h:135
@ VK_XValue
An x-value expression is a reference to an object with independent storage but which can be "moved",...
Definition Specifiers.h:144
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Definition Specifiers.h:139
const char * getTraitSpelling(ExpressionTrait T) LLVM_READONLY
Return the spelling of the type trait TT. Never null.
@ Success
Template argument deduction was successful.
Definition Sema.h:368
U cast(CodeGen::Address addr)
Definition Address.h:327
ConstructorInfo getConstructorInfo(NamedDecl *ND)
Definition Overload.h:1512
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...