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()) {
1080 return true;
1081
1082 bool FoundConstructor = false;
1083 for (const auto *ND : Self.LookupConstructors(RD)) {
1084 // FIXME: In C++0x, a constructor template can be a default constructor.
1085 if (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl()))
1086 continue;
1087 // UsingDecl itself is not a constructor
1088 if (isa<UsingDecl>(ND))
1089 continue;
1090 auto *Constructor = cast<CXXConstructorDecl>(ND->getUnderlyingDecl());
1091 if (Constructor->isDefaultConstructor()) {
1092 FoundConstructor = true;
1093 auto *CPT = Constructor->getType()->castAs<FunctionProtoType>();
1094 CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
1095 if (!CPT)
1096 return false;
1097 // FIXME: check whether evaluating default arguments can throw.
1098 // For now, we'll be conservative and assume that they can throw.
1099 if (!CPT->isNothrow() || CPT->getNumParams() > 0)
1100 return false;
1101 }
1102 }
1103 return FoundConstructor;
1104 }
1105 return false;
1106 case UTT_HasVirtualDestructor:
1107 // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
1108 // If type is a class type with a virtual destructor ([class.dtor])
1109 // then the trait is true, else it is false.
1110 if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
1111 if (CXXDestructorDecl *Destructor = Self.LookupDestructor(RD))
1112 return Destructor->isVirtual();
1113 return false;
1114
1115 // These type trait expressions are modeled on the specifications for the
1116 // Embarcadero C++0x type trait functions:
1117 // http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index
1118 case UTT_IsCompleteType:
1119 // http://docwiki.embarcadero.com/RADStudio/XE/en/Is_complete_type_(typename_T_):
1120 // Returns True if and only if T is a complete type at the point of the
1121 // function call.
1122 return !T->isIncompleteType();
1123 case UTT_HasUniqueObjectRepresentations:
1124 return C.hasUniqueObjectRepresentations(T);
1125 case UTT_IsTriviallyRelocatable:
1127 case UTT_IsBitwiseCloneable:
1128 return T.isBitwiseCloneableType(C);
1129 case UTT_IsCppTriviallyRelocatable:
1130 return Self.IsCXXTriviallyRelocatableType(T);
1131 case UTT_IsReplaceable:
1132 return Self.IsCXXReplaceableType(T);
1133 case UTT_CanPassInRegs:
1134 if (CXXRecordDecl *RD = T->getAsCXXRecordDecl(); RD && !T.hasQualifiers())
1135 return RD->canPassInRegisters();
1136 Self.Diag(KeyLoc, diag::err_builtin_pass_in_regs_non_class) << T;
1137 return false;
1138 case UTT_IsTriviallyEqualityComparable:
1139 return isTriviallyEqualityComparableType(Self, T, KeyLoc);
1140 case UTT_IsImplicitLifetime: {
1142 tok::kw___builtin_is_implicit_lifetime);
1144 tok::kw___builtin_is_implicit_lifetime);
1145
1146 // [basic.types.general] p9
1147 // Scalar types, implicit-lifetime class types ([class.prop]),
1148 // array types, and cv-qualified versions of these types
1149 // are collectively called implicit-lifetime types.
1150 QualType UnqualT = T->getCanonicalTypeUnqualified();
1151 if (UnqualT->isScalarType())
1152 return true;
1153 if (UnqualT->isArrayType() || UnqualT->isVectorType())
1154 return true;
1155 const CXXRecordDecl *RD = UnqualT->getAsCXXRecordDecl();
1156 if (!RD)
1157 return false;
1158
1159 // [class.prop] p9
1160 // A class S is an implicit-lifetime class if
1161 // - it is an aggregate whose destructor is not user-provided or
1162 // - it has at least one trivial eligible constructor and a trivial,
1163 // non-deleted destructor.
1164 const CXXDestructorDecl *Dtor = RD->getDestructor();
1165 if (UnqualT->isAggregateType() && (!Dtor || !Dtor->isUserProvided()))
1166 return true;
1167 bool HasTrivialNonDeletedDtr =
1168 RD->hasTrivialDestructor() && (!Dtor || !Dtor->isDeleted());
1169 if (!HasTrivialNonDeletedDtr)
1170 return false;
1171 for (CXXConstructorDecl *Ctr : RD->ctors()) {
1172 if (Ctr->isIneligibleOrNotSelected() || Ctr->isDeleted())
1173 continue;
1174 if (Ctr->isTrivial())
1175 return true;
1176 }
1180 return true;
1183 return true;
1186 return true;
1187 return false;
1188 }
1189 case UTT_IsIntangibleType:
1190 assert(Self.getLangOpts().HLSL && "intangible types are HLSL-only feature");
1191 if (!T->isVoidType() && !T->isIncompleteArrayType())
1192 if (Self.RequireCompleteType(TInfo->getTypeLoc().getBeginLoc(), T,
1193 diag::err_incomplete_type))
1194 return false;
1196 tok::kw___builtin_hlsl_is_intangible))
1197 return false;
1198 return T->isHLSLIntangibleType();
1199
1200 case UTT_IsTypedResourceElementCompatible:
1201 assert(Self.getLangOpts().HLSL &&
1202 "typed resource element compatible types are an HLSL-only feature");
1203 if (T->isIncompleteType())
1204 return false;
1205
1206 return Self.HLSL().IsTypedResourceElementCompatible(T);
1207 }
1208}
1209
1210static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT,
1211 const TypeSourceInfo *Lhs,
1212 const TypeSourceInfo *Rhs,
1213 SourceLocation KeyLoc);
1214
1216 Sema &Self, const TypeSourceInfo *Lhs, const TypeSourceInfo *Rhs,
1217 SourceLocation KeyLoc, llvm::BumpPtrAllocator &OpaqueExprAllocator) {
1218
1219 QualType LhsT = Lhs->getType();
1220 QualType RhsT = Rhs->getType();
1221
1222 // C++0x [meta.rel]p4:
1223 // Given the following function prototype:
1224 //
1225 // template <class T>
1226 // typename add_rvalue_reference<T>::type create();
1227 //
1228 // the predicate condition for a template specialization
1229 // is_convertible<From, To> shall be satisfied if and only if
1230 // the return expression in the following code would be
1231 // well-formed, including any implicit conversions to the return
1232 // type of the function:
1233 //
1234 // To test() {
1235 // return create<From>();
1236 // }
1237 //
1238 // Access checking is performed as if in a context unrelated to To and
1239 // From. Only the validity of the immediate context of the expression
1240 // of the return-statement (including conversions to the return type)
1241 // is considered.
1242 //
1243 // We model the initialization as a copy-initialization of a temporary
1244 // of the appropriate type, which for this expression is identical to the
1245 // return statement (since NRVO doesn't apply).
1246
1247 // Functions aren't allowed to return function or array types.
1248 if (RhsT->isFunctionType() || RhsT->isArrayType())
1249 return ExprError();
1250
1251 // A function definition requires a complete, non-abstract return type.
1252 if (!Self.isCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT) ||
1253 Self.isAbstractType(Rhs->getTypeLoc().getBeginLoc(), RhsT))
1254 return ExprError();
1255
1256 // Compute the result of add_rvalue_reference.
1257 if (LhsT->isObjectType() || LhsT->isFunctionType())
1258 LhsT = Self.Context.getRValueReferenceType(LhsT);
1259
1260 // Build a fake source and destination for initialization.
1262 Expr *From = new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
1263 OpaqueValueExpr(KeyLoc, LhsT.getNonLValueExprType(Self.Context),
1265 InitializationKind Kind =
1267
1268 // Perform the initialization in an unevaluated context within a SFINAE
1269 // trap at translation unit scope.
1272 Sema::SFINAETrap SFINAE(Self, /*ForValidityCheck=*/true);
1273 Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
1274 InitializationSequence Init(Self, To, Kind, From);
1275 if (Init.Failed())
1276 return ExprError();
1277
1278 ExprResult Result = Init.Perform(Self, To, Kind, From);
1279 if (Result.isInvalid() || SFINAE.hasErrorOccurred())
1280 return ExprError();
1281
1282 return Result;
1283}
1284
1286 SourceLocation KWLoc,
1288 SourceLocation RParenLoc,
1289 bool IsDependent) {
1290 if (IsDependent)
1291 return APValue();
1292
1293 switch (Kind) {
1294 case TypeTrait::UTT_StructuredBindingSize: {
1295 QualType T = Args[0]->getType();
1296 SourceRange ArgRange = Args[0]->getTypeLoc().getSourceRange();
1297 UnsignedOrNone Size =
1299 if (!Size) {
1300 S.Diag(KWLoc, diag::err_arg_is_not_destructurable) << T << ArgRange;
1301 return APValue();
1302 }
1303 return APValue(
1305 break;
1306 }
1307 default:
1308 llvm_unreachable("Not a SizeT type trait");
1309 }
1310}
1311
1313 SourceLocation KWLoc,
1315 SourceLocation RParenLoc,
1316 bool IsDependent) {
1317 if (IsDependent)
1318 return false;
1319
1320 if (Kind <= UTT_Last)
1321 return EvaluateUnaryTypeTrait(S, Kind, KWLoc, Args[0]);
1322
1323 // Evaluate ReferenceBindsToTemporary and ReferenceConstructsFromTemporary
1324 // alongside the IsConstructible traits to avoid duplication.
1325 if (Kind <= BTT_Last && Kind != BTT_ReferenceBindsToTemporary &&
1326 Kind != BTT_ReferenceConstructsFromTemporary &&
1327 Kind != BTT_ReferenceConvertsFromTemporary)
1328 return EvaluateBinaryTypeTrait(S, Kind, Args[0], Args[1], RParenLoc);
1329
1330 switch (Kind) {
1331 case clang::BTT_ReferenceBindsToTemporary:
1332 case clang::BTT_ReferenceConstructsFromTemporary:
1333 case clang::BTT_ReferenceConvertsFromTemporary:
1334 case clang::TT_IsConstructible:
1335 case clang::TT_IsNothrowConstructible:
1336 case clang::TT_IsTriviallyConstructible: {
1337 // C++11 [meta.unary.prop]:
1338 // is_trivially_constructible is defined as:
1339 //
1340 // is_constructible<T, Args...>::value is true and the variable
1341 // definition for is_constructible, as defined below, is known to call
1342 // no operation that is not trivial.
1343 //
1344 // The predicate condition for a template specialization
1345 // is_constructible<T, Args...> shall be satisfied if and only if the
1346 // following variable definition would be well-formed for some invented
1347 // variable t:
1348 //
1349 // T t(create<Args>()...);
1350 assert(!Args.empty());
1351
1352 // Precondition: T and all types in the parameter pack Args shall be
1353 // complete types, (possibly cv-qualified) void, or arrays of
1354 // unknown bound.
1355 for (const auto *TSI : Args) {
1356 QualType ArgTy = TSI->getType();
1357 if (ArgTy->isVoidType() || ArgTy->isIncompleteArrayType())
1358 continue;
1359
1360 if (S.RequireCompleteType(
1361 KWLoc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr))
1362 return false;
1363 }
1364
1365 // Make sure the first argument is not incomplete nor a function type.
1366 QualType T = Args[0]->getType();
1367 if (T->isIncompleteType() || T->isFunctionType())
1368 return false;
1369
1370 // Make sure the first argument is not an abstract type.
1371 CXXRecordDecl *RD = T->getAsCXXRecordDecl();
1372 if (RD && RD->isAbstract())
1373 return false;
1374
1375 // LWG3819: For reference_meows_from_temporary traits, && is not added to
1376 // the source object type.
1377 // Otherwise, compute the result of add_rvalue_reference_t.
1378 bool UseRawObjectType =
1379 Kind == clang::BTT_ReferenceBindsToTemporary ||
1380 Kind == clang::BTT_ReferenceConstructsFromTemporary ||
1381 Kind == clang::BTT_ReferenceConvertsFromTemporary;
1382
1383 llvm::BumpPtrAllocator OpaqueExprAllocator;
1384 SmallVector<Expr *, 2> ArgExprs;
1385 ArgExprs.reserve(Args.size() - 1);
1386 for (unsigned I = 1, N = Args.size(); I != N; ++I) {
1387 QualType ArgTy = Args[I]->getType();
1388 if ((ArgTy->isObjectType() && !UseRawObjectType) ||
1389 ArgTy->isFunctionType())
1390 ArgTy = S.Context.getRValueReferenceType(ArgTy);
1391 ArgExprs.push_back(
1392 new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
1393 OpaqueValueExpr(Args[I]->getTypeLoc().getBeginLoc(),
1396 }
1397
1398 // Perform the initialization in an unevaluated context within a SFINAE
1399 // trap at translation unit scope.
1402 Sema::SFINAETrap SFINAE(S, /*ForValidityCheck=*/true);
1406 InitializationKind InitKind(
1407 Kind == clang::BTT_ReferenceConvertsFromTemporary
1408 ? InitializationKind::CreateCopy(KWLoc, KWLoc)
1409 : InitializationKind::CreateDirect(KWLoc, KWLoc, RParenLoc));
1410 InitializationSequence Init(S, To, InitKind, ArgExprs);
1411 if (Init.Failed())
1412 return false;
1413
1414 ExprResult Result = Init.Perform(S, To, InitKind, ArgExprs);
1415 if (Result.isInvalid() || SFINAE.hasErrorOccurred())
1416 return false;
1417
1418 if (Kind == clang::TT_IsConstructible)
1419 return true;
1420
1421 if (Kind == clang::BTT_ReferenceBindsToTemporary ||
1422 Kind == clang::BTT_ReferenceConstructsFromTemporary ||
1423 Kind == clang::BTT_ReferenceConvertsFromTemporary) {
1424 if (!T->isReferenceType())
1425 return false;
1426
1427 // A function reference never binds to a temporary object.
1428 if (T.getNonReferenceType()->isFunctionType())
1429 return false;
1430
1431 if (!Init.isDirectReferenceBinding())
1432 return true;
1433
1434 if (Kind == clang::BTT_ReferenceBindsToTemporary)
1435 return false;
1436
1437 QualType U = Args[1]->getType();
1438 if (U->isReferenceType())
1439 return false;
1440
1442 S.Context.getPointerType(T.getNonReferenceType()));
1444 S.Context.getPointerType(U.getNonReferenceType()));
1445 return !CheckConvertibilityForTypeTraits(S, UPtr, TPtr, RParenLoc,
1446 OpaqueExprAllocator)
1447 .isInvalid();
1448 }
1449
1450 if (Kind == clang::TT_IsNothrowConstructible)
1451 return S.canThrow(Result.get()) == CT_Cannot;
1452
1453 if (Kind == clang::TT_IsTriviallyConstructible) {
1454 // Under Objective-C ARC and Weak, if the destination has non-trivial
1455 // Objective-C lifetime, this is a non-trivial construction.
1456 if (T.getNonReferenceType().hasNonTrivialObjCLifetime())
1457 return false;
1458
1459 // The initialization succeeded; now make sure there are no non-trivial
1460 // calls.
1461 return !Result.get()->hasNonTrivialCall(S.Context);
1462 }
1463
1464 llvm_unreachable("unhandled type trait");
1465 return false;
1466 }
1467 default:
1468 llvm_unreachable("not a TT");
1469 }
1470
1471 return false;
1472}
1473
1474namespace {
1475void DiagnoseBuiltinDeprecation(Sema &S, TypeTrait Kind, SourceLocation KWLoc) {
1476 TypeTrait Replacement;
1477 switch (Kind) {
1478 case UTT_HasNothrowAssign:
1479 case UTT_HasNothrowMoveAssign:
1480 Replacement = BTT_IsNothrowAssignable;
1481 break;
1482 case UTT_HasNothrowCopy:
1483 case UTT_HasNothrowConstructor:
1484 Replacement = TT_IsNothrowConstructible;
1485 break;
1486 case UTT_HasTrivialAssign:
1487 case UTT_HasTrivialMoveAssign:
1488 Replacement = BTT_IsTriviallyAssignable;
1489 break;
1490 case UTT_HasTrivialCopy:
1491 Replacement = UTT_IsTriviallyCopyable;
1492 break;
1493 case UTT_HasTrivialDefaultConstructor:
1494 case UTT_HasTrivialMoveConstructor:
1495 Replacement = TT_IsTriviallyConstructible;
1496 break;
1497 case UTT_HasTrivialDestructor:
1498 Replacement = UTT_IsTriviallyDestructible;
1499 break;
1500 case UTT_IsTriviallyRelocatable:
1501 Replacement = clang::UTT_IsCppTriviallyRelocatable;
1502 break;
1503 case BTT_ReferenceBindsToTemporary:
1504 Replacement = clang::BTT_ReferenceConstructsFromTemporary;
1505 break;
1506 default:
1507 return;
1508 }
1509 S.Diag(KWLoc, diag::warn_deprecated_builtin)
1510 << getTraitSpelling(Kind) << getTraitSpelling(Replacement);
1511}
1512} // namespace
1513
1514bool Sema::CheckTypeTraitArity(unsigned Arity, SourceLocation Loc, size_t N) {
1515 if (Arity && N != Arity) {
1516 Diag(Loc, diag::err_type_trait_arity)
1517 << Arity << 0 << (Arity > 1) << (int)N << SourceRange(Loc);
1518 return false;
1519 }
1520
1521 if (!Arity && N == 0) {
1522 Diag(Loc, diag::err_type_trait_arity)
1523 << 1 << 1 << 1 << (int)N << SourceRange(Loc);
1524 return false;
1525 }
1526 return true;
1527}
1528
1533
1535 if (Kind == TypeTrait::UTT_StructuredBindingSize)
1538}
1539
1542 SourceLocation RParenLoc) {
1543 if (!CheckTypeTraitArity(getTypeTraitArity(Kind), KWLoc, Args.size()))
1544 return ExprError();
1545
1547 *this, Kind, KWLoc, Args[0]->getType()))
1548 return ExprError();
1549
1550 DiagnoseBuiltinDeprecation(*this, Kind, KWLoc);
1551
1552 bool Dependent = false;
1553 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
1554 if (Args[I]->getType()->isDependentType()) {
1555 Dependent = true;
1556 break;
1557 }
1558 }
1559
1560 switch (GetReturnType(Kind)) {
1562 bool Result = EvaluateBooleanTypeTrait(*this, Kind, KWLoc, Args, RParenLoc,
1563 Dependent);
1564 return TypeTraitExpr::Create(Context, Context.getLogicalOperationType(),
1565 KWLoc, Kind, Args, RParenLoc, Result);
1566 }
1568 APValue Result =
1569 EvaluateSizeTTypeTrait(*this, Kind, KWLoc, Args, RParenLoc, Dependent);
1570 return TypeTraitExpr::Create(Context, Context.getSizeType(), KWLoc, Kind,
1571 Args, RParenLoc, Result);
1572 }
1573 }
1574 llvm_unreachable("unhandled type trait return type");
1575}
1576
1579 SourceLocation RParenLoc) {
1581 ConvertedArgs.reserve(Args.size());
1582
1583 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
1584 TypeSourceInfo *TInfo;
1585 QualType T = GetTypeFromParser(Args[I], &TInfo);
1586 if (!TInfo)
1587 TInfo = Context.getTrivialTypeSourceInfo(T, KWLoc);
1588
1589 ConvertedArgs.push_back(TInfo);
1590 }
1591
1592 return BuildTypeTrait(Kind, KWLoc, ConvertedArgs, RParenLoc);
1593}
1594
1596 QualType RhsT) {
1597 // C++0x [meta.rel]p2
1598 // Base is a base class of Derived without regard to cv-qualifiers or
1599 // Base and Derived are not unions and name the same class type without
1600 // regard to cv-qualifiers.
1601
1602 const RecordType *lhsRecord = LhsT->getAsCanonical<RecordType>();
1603 const RecordType *rhsRecord = RhsT->getAsCanonical<RecordType>();
1604 if (!rhsRecord || !lhsRecord) {
1605 const ObjCObjectType *LHSObjTy = LhsT->getAs<ObjCObjectType>();
1606 const ObjCObjectType *RHSObjTy = RhsT->getAs<ObjCObjectType>();
1607 if (!LHSObjTy || !RHSObjTy)
1608 return false;
1609
1610 ObjCInterfaceDecl *BaseInterface = LHSObjTy->getInterface();
1611 ObjCInterfaceDecl *DerivedInterface = RHSObjTy->getInterface();
1612 if (!BaseInterface || !DerivedInterface)
1613 return false;
1614
1615 if (RequireCompleteType(RhsTLoc, RhsT,
1616 diag::err_incomplete_type_used_in_type_trait_expr))
1617 return false;
1618
1619 return BaseInterface->isSuperClassOf(DerivedInterface);
1620 }
1621
1622 assert(Context.hasSameUnqualifiedType(LhsT, RhsT) ==
1623 (lhsRecord == rhsRecord));
1624
1625 // Unions are never base classes, and never have base classes.
1626 // It doesn't matter if they are complete or not. See PR#41843
1627 if (lhsRecord && lhsRecord->getDecl()->isUnion())
1628 return false;
1629 if (rhsRecord && rhsRecord->getDecl()->isUnion())
1630 return false;
1631
1632 if (lhsRecord == rhsRecord)
1633 return true;
1634
1635 // C++0x [meta.rel]p2:
1636 // If Base and Derived are class types and are different types
1637 // (ignoring possible cv-qualifiers) then Derived shall be a
1638 // complete type.
1639 if (RequireCompleteType(RhsTLoc, RhsT,
1640 diag::err_incomplete_type_used_in_type_trait_expr))
1641 return false;
1642
1643 return cast<CXXRecordDecl>(rhsRecord->getDecl())
1644 ->isDerivedFrom(cast<CXXRecordDecl>(lhsRecord->getDecl()));
1645}
1646
1648 const TypeSourceInfo *Lhs,
1649 const TypeSourceInfo *Rhs,
1650 SourceLocation KeyLoc) {
1651 QualType LhsT = Lhs->getType();
1652 QualType RhsT = Rhs->getType();
1653
1654 assert(!LhsT->isDependentType() && !RhsT->isDependentType() &&
1655 "Cannot evaluate traits of dependent types");
1656
1657 switch (BTT) {
1658 case BTT_IsBaseOf:
1659 return Self.BuiltinIsBaseOf(Rhs->getTypeLoc().getBeginLoc(), LhsT, RhsT);
1660
1661 case BTT_IsVirtualBaseOf: {
1662 const RecordType *BaseRecord = LhsT->getAsCanonical<RecordType>();
1663 const RecordType *DerivedRecord = RhsT->getAsCanonical<RecordType>();
1664
1665 if (!BaseRecord || !DerivedRecord) {
1667 tok::kw___builtin_is_virtual_base_of);
1669 tok::kw___builtin_is_virtual_base_of);
1670 return false;
1671 }
1672
1673 if (BaseRecord->isUnionType() || DerivedRecord->isUnionType())
1674 return false;
1675
1676 if (!BaseRecord->isStructureOrClassType() ||
1677 !DerivedRecord->isStructureOrClassType())
1678 return false;
1679
1680 if (Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1681 diag::err_incomplete_type))
1682 return false;
1683
1684 return cast<CXXRecordDecl>(DerivedRecord->getDecl())
1685 ->isVirtuallyDerivedFrom(cast<CXXRecordDecl>(BaseRecord->getDecl()));
1686 }
1687 case BTT_IsSame:
1688 return Self.Context.hasSameType(LhsT, RhsT);
1689 case BTT_TypeCompatible: {
1690 // GCC ignores cv-qualifiers on arrays for this builtin.
1691 Qualifiers LhsQuals, RhsQuals;
1692 QualType Lhs = Self.getASTContext().getUnqualifiedArrayType(LhsT, LhsQuals);
1693 QualType Rhs = Self.getASTContext().getUnqualifiedArrayType(RhsT, RhsQuals);
1694 return Self.Context.typesAreCompatible(Lhs, Rhs);
1695 }
1696 case BTT_IsConvertible:
1697 case BTT_IsConvertibleTo:
1698 case BTT_IsNothrowConvertible: {
1699 if (RhsT->isVoidType())
1700 return LhsT->isVoidType();
1701 llvm::BumpPtrAllocator OpaqueExprAllocator;
1702 ExprResult Result = CheckConvertibilityForTypeTraits(Self, Lhs, Rhs, KeyLoc,
1703 OpaqueExprAllocator);
1704 if (Result.isInvalid())
1705 return false;
1706
1707 if (BTT != BTT_IsNothrowConvertible)
1708 return true;
1709
1710 return Self.canThrow(Result.get()) == CT_Cannot;
1711 }
1712
1713 case BTT_IsAssignable:
1714 case BTT_IsNothrowAssignable:
1715 case BTT_IsTriviallyAssignable: {
1716 // C++11 [meta.unary.prop]p3:
1717 // is_trivially_assignable is defined as:
1718 // is_assignable<T, U>::value is true and the assignment, as defined by
1719 // is_assignable, is known to call no operation that is not trivial
1720 //
1721 // is_assignable is defined as:
1722 // The expression declval<T>() = declval<U>() is well-formed when
1723 // treated as an unevaluated operand (Clause 5).
1724 //
1725 // For both, T and U shall be complete types, (possibly cv-qualified)
1726 // void, or arrays of unknown bound.
1727 if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType() &&
1728 Self.RequireCompleteType(
1729 Lhs->getTypeLoc().getBeginLoc(), LhsT,
1730 diag::err_incomplete_type_used_in_type_trait_expr))
1731 return false;
1732 if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType() &&
1733 Self.RequireCompleteType(
1734 Rhs->getTypeLoc().getBeginLoc(), RhsT,
1735 diag::err_incomplete_type_used_in_type_trait_expr))
1736 return false;
1737
1738 // cv void is never assignable.
1739 if (LhsT->isVoidType() || RhsT->isVoidType())
1740 return false;
1741
1742 // Build expressions that emulate the effect of declval<T>() and
1743 // declval<U>().
1744 auto createDeclValExpr = [&](QualType Ty) -> OpaqueValueExpr {
1745 if (Ty->isObjectType() || Ty->isFunctionType())
1746 Ty = Self.Context.getRValueReferenceType(Ty);
1747 return {KeyLoc, Ty.getNonLValueExprType(Self.Context),
1749 };
1750
1751 auto Lhs = createDeclValExpr(LhsT);
1752 auto Rhs = createDeclValExpr(RhsT);
1753
1754 // Attempt the assignment in an unevaluated context within a SFINAE
1755 // trap at translation unit scope.
1758 Sema::SFINAETrap SFINAE(Self, /*ForValidityCheck=*/true);
1759 Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
1760 ExprResult Result =
1761 Self.BuildBinOp(/*S=*/nullptr, KeyLoc, BO_Assign, &Lhs, &Rhs);
1762 if (Result.isInvalid())
1763 return false;
1764
1765 // Treat the assignment as unused for the purpose of -Wdeprecated-volatile.
1766 Self.CheckUnusedVolatileAssignment(Result.get());
1767
1768 if (SFINAE.hasErrorOccurred())
1769 return false;
1770
1771 if (BTT == BTT_IsAssignable)
1772 return true;
1773
1774 if (BTT == BTT_IsNothrowAssignable)
1775 return Self.canThrow(Result.get()) == CT_Cannot;
1776
1777 if (BTT == BTT_IsTriviallyAssignable) {
1778 // Under Objective-C ARC and Weak, if the destination has non-trivial
1779 // Objective-C lifetime, this is a non-trivial assignment.
1781 return false;
1782 const ASTContext &Context = Self.getASTContext();
1783 if (Context.containsAddressDiscriminatedPointerAuth(LhsT) ||
1784 Context.containsAddressDiscriminatedPointerAuth(RhsT))
1785 return false;
1786 return !Result.get()->hasNonTrivialCall(Self.Context);
1787 }
1788
1789 llvm_unreachable("unhandled type trait");
1790 return false;
1791 }
1792 case BTT_IsLayoutCompatible: {
1793 if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType())
1794 Self.RequireCompleteType(Lhs->getTypeLoc().getBeginLoc(), LhsT,
1795 diag::err_incomplete_type);
1796 if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType())
1797 Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1798 diag::err_incomplete_type);
1799
1800 DiagnoseVLAInCXXTypeTrait(Self, Lhs, tok::kw___is_layout_compatible);
1801 DiagnoseVLAInCXXTypeTrait(Self, Rhs, tok::kw___is_layout_compatible);
1802
1803 return Self.IsLayoutCompatible(LhsT, RhsT);
1804 }
1805 case BTT_IsPointerInterconvertibleBaseOf: {
1806 if (LhsT->isStructureOrClassType() && RhsT->isStructureOrClassType() &&
1807 !Self.getASTContext().hasSameUnqualifiedType(LhsT, RhsT)) {
1808 Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1809 diag::err_incomplete_type);
1810 }
1811
1813 tok::kw___is_pointer_interconvertible_base_of);
1815 tok::kw___is_pointer_interconvertible_base_of);
1816
1817 return Self.IsPointerInterconvertibleBaseOf(Lhs, Rhs);
1818 }
1819 case BTT_IsDeducible: {
1820 const auto *TSTToBeDeduced = cast<DeducedTemplateSpecializationType>(LhsT);
1821 sema::TemplateDeductionInfo Info(KeyLoc);
1822 return Self.DeduceTemplateArgumentsFromType(
1823 TSTToBeDeduced->getTemplateName().getAsTemplateDecl(), RhsT,
1825 }
1826 case BTT_IsScalarizedLayoutCompatible: {
1827 if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType() &&
1828 Self.RequireCompleteType(Lhs->getTypeLoc().getBeginLoc(), LhsT,
1829 diag::err_incomplete_type))
1830 return true;
1831 if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType() &&
1832 Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1833 diag::err_incomplete_type))
1834 return true;
1835
1837 Self, Lhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1839 Self, Rhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1840
1841 return Self.HLSL().IsScalarizedLayoutCompatible(LhsT, RhsT);
1842 }
1843 case BTT_LtSynthesizesFromSpaceship:
1844 case BTT_LeSynthesizesFromSpaceship:
1845 case BTT_GtSynthesizesFromSpaceship:
1846 case BTT_GeSynthesizesFromSpaceship: {
1847 EnterExpressionEvaluationContext UnevaluatedContext(
1849 Sema::SFINAETrap SFINAE(Self, /*ForValidityCheck=*/true);
1850 Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
1851
1852 OpaqueValueExpr LHS(KeyLoc, LhsT.getNonReferenceType(),
1854 : LhsT->isRValueReferenceType()
1857 OpaqueValueExpr RHS(KeyLoc, RhsT.getNonReferenceType(),
1859 : RhsT->isRValueReferenceType()
1862
1863 auto OpKind = [&] {
1864 switch (BTT) {
1865 case BTT_LtSynthesizesFromSpaceship:
1866 return BinaryOperatorKind::BO_LT;
1867 case BTT_LeSynthesizesFromSpaceship:
1868 return BinaryOperatorKind::BO_LE;
1869 case BTT_GtSynthesizesFromSpaceship:
1870 return BinaryOperatorKind::BO_GT;
1871 case BTT_GeSynthesizesFromSpaceship:
1872 return BinaryOperatorKind::BO_GE;
1873 default:
1874 llvm_unreachable("Trying to Synthesize non-comparison operator?");
1875 }
1876 }();
1877
1878 UnresolvedSet<16> Functions;
1879 Self.LookupBinOp(Self.TUScope, KeyLoc, OpKind, Functions);
1880
1881 ExprResult Result =
1882 Self.CreateOverloadedBinOp(KeyLoc, OpKind, Functions, &LHS, &RHS);
1883 if (Result.isInvalid() || SFINAE.hasErrorOccurred())
1884 return false;
1885
1886 return isa<CXXRewrittenBinaryOperator>(Result.get());
1887 }
1888 default:
1889 llvm_unreachable("not a BTT");
1890 }
1891 llvm_unreachable("Unknown type trait or not implemented");
1892}
1893
1895 ParsedType Ty, Expr *DimExpr,
1896 SourceLocation RParen) {
1897 TypeSourceInfo *TSInfo;
1898 QualType T = GetTypeFromParser(Ty, &TSInfo);
1899 if (!TSInfo)
1900 TSInfo = Context.getTrivialTypeSourceInfo(T);
1901
1902 return BuildArrayTypeTrait(ATT, KWLoc, TSInfo, DimExpr, RParen);
1903}
1904
1906 QualType T, Expr *DimExpr,
1907 SourceLocation KeyLoc) {
1908 assert(!T->isDependentType() && "Cannot evaluate traits of dependent type");
1909
1910 switch (ATT) {
1911 case ATT_ArrayRank:
1912 if (T->isArrayType()) {
1913 unsigned Dim = 0;
1914 while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {
1915 ++Dim;
1916 T = AT->getElementType();
1917 }
1918 return Dim;
1919 }
1920 return 0;
1921
1922 case ATT_ArrayExtent: {
1923 llvm::APSInt Value;
1924 uint64_t Dim;
1925 if (Self.VerifyIntegerConstantExpression(
1926 DimExpr, &Value, diag::err_dimension_expr_not_constant_integer)
1927 .isInvalid())
1928 return 0;
1929 if (Value.isSigned() && Value.isNegative()) {
1930 Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer)
1931 << DimExpr->getSourceRange();
1932 return 0;
1933 }
1934 Dim = Value.getLimitedValue();
1935
1936 if (T->isArrayType()) {
1937 unsigned D = 0;
1938 bool Matched = false;
1939 while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {
1940 if (Dim == D) {
1941 Matched = true;
1942 break;
1943 }
1944 ++D;
1945 T = AT->getElementType();
1946 }
1947
1948 if (Matched && T->isArrayType()) {
1949 if (const ConstantArrayType *CAT =
1950 Self.Context.getAsConstantArrayType(T))
1951 return CAT->getLimitedSize();
1952 }
1953 }
1954 return 0;
1955 }
1956 }
1957 llvm_unreachable("Unknown type trait or not implemented");
1958}
1959
1961 TypeSourceInfo *TSInfo, Expr *DimExpr,
1962 SourceLocation RParen) {
1963 QualType T = TSInfo->getType();
1964
1965 // FIXME: This should likely be tracked as an APInt to remove any host
1966 // assumptions about the width of size_t on the target.
1967 uint64_t Value = 0;
1968 if (!T->isDependentType())
1969 Value = EvaluateArrayTypeTrait(*this, ATT, T, DimExpr, KWLoc);
1970
1971 // While the specification for these traits from the Embarcadero C++
1972 // compiler's documentation says the return type is 'unsigned int', Clang
1973 // returns 'size_t'. On Windows, the primary platform for the Embarcadero
1974 // compiler, there is no difference. On several other platforms this is an
1975 // important distinction.
1976 return new (Context) ArrayTypeTraitExpr(KWLoc, ATT, TSInfo, Value, DimExpr,
1977 RParen, Context.getSizeType());
1978}
1979
1981 Expr *Queried, SourceLocation RParen) {
1982 // If error parsing the expression, ignore.
1983 if (!Queried)
1984 return ExprError();
1985
1986 ExprResult Result = BuildExpressionTrait(ET, KWLoc, Queried, RParen);
1987
1988 return Result;
1989}
1990
1992 switch (ET) {
1993 case ET_IsLValueExpr:
1994 return E->isLValue();
1995 case ET_IsRValueExpr:
1996 return E->isPRValue();
1997 }
1998 llvm_unreachable("Expression trait not covered by switch");
1999}
2000
2002 Expr *Queried, SourceLocation RParen) {
2003 if (Queried->isTypeDependent()) {
2004 // Delay type-checking for type-dependent expressions.
2005 } else if (Queried->hasPlaceholderType()) {
2006 ExprResult PE = CheckPlaceholderExpr(Queried);
2007 if (PE.isInvalid())
2008 return ExprError();
2009 return BuildExpressionTrait(ET, KWLoc, PE.get(), RParen);
2010 }
2011
2012 bool Value = EvaluateExpressionTrait(ET, Queried);
2013
2014 return new (Context)
2015 ExpressionTraitExpr(KWLoc, ET, Queried, Value, RParen, Context.BoolTy);
2016}
2017
2018static std::optional<TypeTrait> StdNameToTypeTrait(StringRef Name) {
2019 return llvm::StringSwitch<std::optional<TypeTrait>>(Name)
2020 .Case("is_trivially_relocatable",
2021 TypeTrait::UTT_IsCppTriviallyRelocatable)
2022 .Case("is_replaceable", TypeTrait::UTT_IsReplaceable)
2023 .Case("is_trivially_copyable", TypeTrait::UTT_IsTriviallyCopyable)
2024 .Case("is_assignable", TypeTrait::BTT_IsAssignable)
2025 .Case("is_empty", TypeTrait::UTT_IsEmpty)
2026 .Case("is_standard_layout", TypeTrait::UTT_IsStandardLayout)
2027 .Case("is_aggregate", TypeTrait::UTT_IsAggregate)
2028 .Case("is_constructible", TypeTrait::TT_IsConstructible)
2029 .Case("is_final", TypeTrait::UTT_IsFinal)
2030 .Case("is_abstract", TypeTrait::UTT_IsAbstract)
2031 .Default(std::nullopt);
2032}
2033
2035 std::optional<std::pair<TypeTrait, llvm::SmallVector<QualType, 1>>>;
2036
2037// Recognize type traits that are builting type traits, or known standard
2038// type traits in <type_traits>. Note that at this point we assume the
2039// trait evaluated to false, so we need only to recognize the shape of the
2040// outer-most symbol.
2043 std::optional<TypeTrait> Trait;
2044
2045 // builtins
2046 if (const auto *TraitExpr = dyn_cast<TypeTraitExpr>(E)) {
2047 Trait = TraitExpr->getTrait();
2048 for (const auto *Arg : TraitExpr->getArgs())
2049 Args.push_back(Arg->getType());
2050 return {{Trait.value(), std::move(Args)}};
2051 }
2052 const auto *Ref = dyn_cast<DeclRefExpr>(E);
2053 if (!Ref)
2054 return std::nullopt;
2055
2056 // std::is_xxx_v<>
2057 if (const auto *VD =
2058 dyn_cast<VarTemplateSpecializationDecl>(Ref->getDecl())) {
2059 if (!VD->isInStdNamespace())
2060 return std::nullopt;
2061 StringRef Name = VD->getIdentifier()->getName();
2062 if (!Name.consume_back("_v"))
2063 return std::nullopt;
2064 Trait = StdNameToTypeTrait(Name);
2065 if (!Trait)
2066 return std::nullopt;
2067 for (const auto &Arg : VD->getTemplateArgs().asArray()) {
2068 if (Arg.getKind() == TemplateArgument::ArgKind::Pack) {
2069 for (const auto &InnerArg : Arg.pack_elements())
2070 Args.push_back(InnerArg.getAsType());
2071 } else if (Arg.getKind() == TemplateArgument::ArgKind::Type) {
2072 Args.push_back(Arg.getAsType());
2073 } else {
2074 llvm_unreachable("Unexpected kind");
2075 }
2076 }
2077 return {{Trait.value(), std::move(Args)}};
2078 }
2079
2080 // std::is_xxx<>::value
2081 if (const auto *VD = dyn_cast<VarDecl>(Ref->getDecl());
2082 Ref->hasQualifier() && VD && VD->getIdentifier()->isStr("value")) {
2083 NestedNameSpecifier Qualifier = Ref->getQualifier();
2084 if (Qualifier.getKind() != NestedNameSpecifier::Kind::Type)
2085 return std::nullopt;
2086 const auto *Ts = Qualifier.getAsType()->getAs<TemplateSpecializationType>();
2087 if (!Ts)
2088 return std::nullopt;
2089 const TemplateDecl *D = Ts->getTemplateName().getAsTemplateDecl();
2090 if (!D || !D->isInStdNamespace())
2091 return std::nullopt;
2092 Trait = StdNameToTypeTrait(D->getIdentifier()->getName());
2093 if (!Trait)
2094 return std::nullopt;
2095 for (const auto &Arg : Ts->template_arguments())
2096 Args.push_back(Arg.getAsType());
2097 return {{Trait.value(), std::move(Args)}};
2098 }
2099 return std::nullopt;
2100}
2101
2103 const CXXRecordDecl *D) {
2104 if (D->isUnion()) {
2105 auto DiagSPM = [&](CXXSpecialMemberKind K, bool Has) {
2106 if (Has)
2107 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2108 << diag::TraitNotSatisfiedReason::UnionWithUserDeclaredSMF << K;
2109 };
2118 return;
2119 }
2120
2122 const auto *Decl = cast_or_null<CXXConstructorDecl>(
2123 LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/false));
2124 if (Decl && Decl->isUserProvided())
2125 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2126 << diag::TraitNotSatisfiedReason::UserProvidedCtr
2127 << Decl->isMoveConstructor() << Decl->getSourceRange();
2128 }
2131 LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/true);
2132 if (Decl && Decl->isUserProvided())
2133 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2134 << diag::TraitNotSatisfiedReason::UserProvidedAssign
2135 << Decl->isMoveAssignmentOperator() << Decl->getSourceRange();
2136 }
2137 if (CXXDestructorDecl *Dtr = D->getDestructor()) {
2138 Dtr = Dtr->getCanonicalDecl();
2139 if (Dtr->isUserProvided() && !Dtr->isDefaulted())
2140 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2141 << diag::TraitNotSatisfiedReason::DeletedDtr << /*User Provided*/ 1
2142 << Dtr->getSourceRange();
2143 }
2144}
2145
2147 SourceLocation Loc,
2148 const CXXRecordDecl *D) {
2149 for (const CXXBaseSpecifier &B : D->bases()) {
2150 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2151 if (B.isVirtual())
2152 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2153 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2154 << B.getSourceRange();
2155 if (!SemaRef.IsCXXTriviallyRelocatableType(B.getType()))
2156 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2157 << diag::TraitNotSatisfiedReason::NTRBase << B.getType()
2158 << B.getSourceRange();
2159 }
2160 for (const FieldDecl *Field : D->fields()) {
2161 if (!Field->getType()->isReferenceType() &&
2162 !SemaRef.IsCXXTriviallyRelocatableType(Field->getType()))
2163 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2164 << diag::TraitNotSatisfiedReason::NTRField << Field
2165 << Field->getType() << Field->getSourceRange();
2166 }
2167 if (D->hasDeletedDestructor())
2168 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2169 << diag::TraitNotSatisfiedReason::DeletedDtr << /*Deleted*/ 0
2170 << D->getDestructor()->getSourceRange();
2171
2172 if (D->hasAttr<TriviallyRelocatableAttr>())
2173 return;
2174 DiagnoseNonDefaultMovable(SemaRef, Loc, D);
2175}
2176
2178 SourceLocation Loc,
2179 QualType T) {
2180 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2181 << T << diag::TraitName::TriviallyRelocatable;
2182 if (T->isVariablyModifiedType())
2183 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2184 << diag::TraitNotSatisfiedReason::VLA;
2185
2186 if (T->isReferenceType())
2187 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2188 << diag::TraitNotSatisfiedReason::Ref;
2189 T = T.getNonReferenceType();
2190
2191 if (T.hasNonTrivialObjCLifetime())
2192 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2193 << diag::TraitNotSatisfiedReason::HasArcLifetime;
2194
2195 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2196 if (!D || D->isInvalidDecl())
2197 return;
2198
2199 if (D->hasDefinition())
2201
2202 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2203}
2204
2206 const CXXRecordDecl *D) {
2207 for (const CXXBaseSpecifier &B : D->bases()) {
2208 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2209 if (!SemaRef.IsCXXReplaceableType(B.getType()))
2210 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2211 << diag::TraitNotSatisfiedReason::NonReplaceableBase << B.getType()
2212 << B.getSourceRange();
2213 }
2214 for (const FieldDecl *Field : D->fields()) {
2215 if (!SemaRef.IsCXXReplaceableType(Field->getType()))
2216 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2217 << diag::TraitNotSatisfiedReason::NonReplaceableField << Field
2218 << Field->getType() << Field->getSourceRange();
2219 }
2220 if (D->hasDeletedDestructor())
2221 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2222 << diag::TraitNotSatisfiedReason::DeletedDtr << /*Deleted*/ 0
2223 << D->getDestructor()->getSourceRange();
2224
2226 const auto *Decl = cast<CXXConstructorDecl>(
2227 LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/false));
2228 if (Decl && Decl->isDeleted())
2229 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2230 << diag::TraitNotSatisfiedReason::DeletedCtr
2231 << Decl->isMoveConstructor() << Decl->getSourceRange();
2232 }
2235 LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/true);
2236 if (Decl && Decl->isDeleted())
2237 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2238 << diag::TraitNotSatisfiedReason::DeletedAssign
2239 << Decl->isMoveAssignmentOperator() << Decl->getSourceRange();
2240 }
2241
2242 if (D->hasAttr<ReplaceableAttr>())
2243 return;
2244 DiagnoseNonDefaultMovable(SemaRef, Loc, D);
2245}
2246
2248 QualType T) {
2249 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2250 << T << diag::TraitName::Replaceable;
2251
2252 if (T->isVariablyModifiedType())
2253 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2254 << diag::TraitNotSatisfiedReason::VLA;
2255
2256 if (T->isReferenceType())
2257 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2258 << diag::TraitNotSatisfiedReason::Ref;
2259 T = T.getNonReferenceType();
2260
2261 if (T.isConstQualified())
2262 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2263 << diag::TraitNotSatisfiedReason::Const;
2264
2265 if (T.isVolatileQualified())
2266 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2267 << diag::TraitNotSatisfiedReason::Volatile;
2268
2269 bool IsArray = T->isArrayType();
2270 T = SemaRef.getASTContext().getBaseElementType(T.getUnqualifiedType());
2271
2272 if (T->isScalarType())
2273 return;
2274
2275 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2276 if (!D) {
2277 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2278 << diag::TraitNotSatisfiedReason::NotScalarOrClass << IsArray;
2279 return;
2280 }
2281
2282 if (D->isInvalidDecl())
2283 return;
2284
2285 if (D->hasDefinition())
2286 DiagnoseNonReplaceableReason(SemaRef, Loc, D);
2287
2288 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2289}
2290
2292 SourceLocation Loc,
2293 const CXXRecordDecl *D) {
2294 for (const CXXBaseSpecifier &B : D->bases()) {
2295 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2296 if (B.isVirtual())
2297 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2298 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2299 << B.getSourceRange();
2300 if (!B.getType().isTriviallyCopyableType(D->getASTContext())) {
2301 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2302 << diag::TraitNotSatisfiedReason::NTCBase << B.getType()
2303 << B.getSourceRange();
2304 }
2305 }
2306 for (const FieldDecl *Field : D->fields()) {
2307 if (!Field->getType().isTriviallyCopyableType(Field->getASTContext()))
2308 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2309 << diag::TraitNotSatisfiedReason::NTCField << Field
2310 << Field->getType() << Field->getSourceRange();
2311 }
2312 CXXDestructorDecl *Dtr = D->getDestructor();
2313 if (D->hasDeletedDestructor() || (Dtr && !Dtr->isTrivial()))
2314 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2315 << diag::TraitNotSatisfiedReason::DeletedDtr
2317
2318 for (const CXXMethodDecl *Method : D->methods()) {
2319 if (Method->isTrivial() || !Method->isUserProvided()) {
2320 continue;
2321 }
2322 auto SpecialMemberKind =
2323 SemaRef.getDefaultedFunctionKind(Method).asSpecialMember();
2324 switch (SpecialMemberKind) {
2329 bool IsAssignment =
2330 SpecialMemberKind == CXXSpecialMemberKind::CopyAssignment ||
2331 SpecialMemberKind == CXXSpecialMemberKind::MoveAssignment;
2332 bool IsMove =
2333 SpecialMemberKind == CXXSpecialMemberKind::MoveConstructor ||
2334 SpecialMemberKind == CXXSpecialMemberKind::MoveAssignment;
2335
2336 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2337 << (IsAssignment ? diag::TraitNotSatisfiedReason::UserProvidedAssign
2338 : diag::TraitNotSatisfiedReason::UserProvidedCtr)
2339 << IsMove << Method->getSourceRange();
2340 break;
2341 }
2342 default:
2343 break;
2344 }
2345 }
2346}
2347
2349 Sema &SemaRef, SourceLocation Loc,
2351 if (Ts.empty()) {
2352 return;
2353 }
2354
2355 bool ContainsVoid = false;
2356 for (const QualType &ArgTy : Ts) {
2357 ContainsVoid |= ArgTy->isVoidType();
2358 }
2359
2360 if (ContainsVoid)
2361 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2362 << diag::TraitNotSatisfiedReason::CVVoidType;
2363
2364 QualType T = Ts[0];
2365 if (T->isFunctionType())
2366 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2367 << diag::TraitNotSatisfiedReason::FunctionType;
2368
2369 if (T->isIncompleteArrayType())
2370 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2371 << diag::TraitNotSatisfiedReason::IncompleteArrayType;
2372
2373 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2374 if (!D || D->isInvalidDecl() || !D->hasDefinition())
2375 return;
2376
2377 llvm::BumpPtrAllocator OpaqueExprAllocator;
2378 SmallVector<Expr *, 2> ArgExprs;
2379 ArgExprs.reserve(Ts.size() - 1);
2380 for (unsigned I = 1, N = Ts.size(); I != N; ++I) {
2381 QualType ArgTy = Ts[I];
2382 if (ArgTy->isObjectType() || ArgTy->isFunctionType())
2383 ArgTy = SemaRef.Context.getRValueReferenceType(ArgTy);
2384 ArgExprs.push_back(
2385 new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
2386 OpaqueValueExpr(Loc, ArgTy.getNonLValueExprType(SemaRef.Context),
2388 }
2389
2392 Sema::ContextRAII TUContext(SemaRef,
2396 InitializationSequence Init(SemaRef, To, InitKind, ArgExprs);
2397
2398 Init.Diagnose(SemaRef, To, InitKind, ArgExprs);
2399 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2400}
2401
2403 SourceLocation Loc, QualType T) {
2404 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2405 << T << diag::TraitName::TriviallyCopyable;
2406
2407 if (T->isReferenceType())
2408 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2409 << diag::TraitNotSatisfiedReason::Ref;
2410
2411 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2412 if (!D || D->isInvalidDecl())
2413 return;
2414
2415 if (D->hasDefinition())
2416 DiagnoseNonTriviallyCopyableReason(SemaRef, Loc, D);
2417
2418 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2419}
2420
2422 QualType T, QualType U) {
2423 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2424
2425 auto createDeclValExpr = [&](QualType Ty) -> OpaqueValueExpr {
2426 if (Ty->isObjectType() || Ty->isFunctionType())
2427 Ty = SemaRef.Context.getRValueReferenceType(Ty);
2428 return {Loc, Ty.getNonLValueExprType(SemaRef.Context),
2430 };
2431
2432 auto LHS = createDeclValExpr(T);
2433 auto RHS = createDeclValExpr(U);
2434
2437 Sema::ContextRAII TUContext(SemaRef,
2439 SemaRef.BuildBinOp(/*S=*/nullptr, Loc, BO_Assign, &LHS, &RHS);
2440
2441 if (!D || D->isInvalidDecl())
2442 return;
2443
2444 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2445}
2446
2448 const CXXRecordDecl *D) {
2449 // Non-static data members (ignore zero-width bit‐fields).
2450 for (const auto *Field : D->fields()) {
2451 if (Field->isZeroLengthBitField())
2452 continue;
2453 if (Field->isBitField()) {
2454 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2455 << diag::TraitNotSatisfiedReason::NonZeroLengthField << Field
2456 << Field->getSourceRange();
2457 continue;
2458 }
2459 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2460 << diag::TraitNotSatisfiedReason::NonEmptyMember << Field
2461 << Field->getType() << Field->getSourceRange();
2462 }
2463
2464 // Virtual functions.
2465 for (const auto *M : D->methods()) {
2466 if (M->isVirtual()) {
2467 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2468 << diag::TraitNotSatisfiedReason::VirtualFunction << M
2469 << M->getSourceRange();
2470 break;
2471 }
2472 }
2473
2474 // Virtual bases and non-empty bases.
2475 for (const auto &B : D->bases()) {
2476 const auto *BR = B.getType()->getAsCXXRecordDecl();
2477 if (!BR || BR->isInvalidDecl())
2478 continue;
2479 if (B.isVirtual()) {
2480 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2481 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2482 << B.getSourceRange();
2483 }
2484 if (!BR->isEmpty()) {
2485 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2486 << diag::TraitNotSatisfiedReason::NonEmptyBase << B.getType()
2487 << B.getSourceRange();
2488 }
2489 }
2490}
2491
2493 // Emit primary "not empty" diagnostic.
2494 S.Diag(Loc, diag::note_unsatisfied_trait) << T << diag::TraitName::Empty;
2495
2496 // While diagnosing is_empty<T>, we want to look at the actual type, not a
2497 // reference or an array of it. So we need to massage the QualType param to
2498 // strip refs and arrays.
2499 if (T->isReferenceType())
2500 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2501 << diag::TraitNotSatisfiedReason::Ref;
2502 T = T.getNonReferenceType();
2503
2504 if (auto *AT = S.Context.getAsArrayType(T))
2505 T = AT->getElementType();
2506
2507 if (auto *D = T->getAsCXXRecordDecl()) {
2508 if (D->hasDefinition()) {
2509 DiagnoseIsEmptyReason(S, Loc, D);
2510 S.Diag(D->getLocation(), diag::note_defined_here) << D;
2511 }
2512 }
2513}
2514
2516 const CXXRecordDecl *D) {
2517 if (!D || D->isInvalidDecl())
2518 return;
2519
2520 // Complete record but not 'final'.
2521 if (!D->isEffectivelyFinal()) {
2522 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2523 << diag::TraitNotSatisfiedReason::NotMarkedFinal;
2524 S.Diag(D->getLocation(), diag::note_defined_here) << D;
2525 return;
2526 }
2527}
2528
2530 // Primary: “%0 is not final”
2531 S.Diag(Loc, diag::note_unsatisfied_trait) << T << diag::TraitName::Final;
2532 if (T->isReferenceType()) {
2533 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2534 << diag::TraitNotSatisfiedReason::Ref;
2535 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2536 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2537 return;
2538 }
2539 // Arrays / functions / non-records → not a class/union.
2540 if (S.Context.getAsArrayType(T)) {
2541 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2542 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2543 return;
2544 }
2545 if (T->isFunctionType()) {
2546 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2547 << diag::TraitNotSatisfiedReason::FunctionType;
2548 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2549 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2550 return;
2551 }
2552 if (!T->isRecordType()) {
2553 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2554 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2555 return;
2556 }
2557 if (const auto *D = T->getAsCXXRecordDecl())
2558 DiagnoseIsFinalReason(S, Loc, D);
2559}
2560
2562 int NumBasesWithFields = 0;
2563 for (const CXXBaseSpecifier &Base : D->bases()) {
2564 const CXXRecordDecl *BaseRD = Base.getType()->getAsCXXRecordDecl();
2565 if (!BaseRD || BaseRD->isInvalidDecl())
2566 continue;
2567
2568 for (const FieldDecl *Field : BaseRD->fields()) {
2569 if (!Field->isUnnamedBitField()) {
2570 if (++NumBasesWithFields > 1)
2571 return true; // found more than one base class with fields
2572 break; // no need to check further fields in this base class
2573 }
2574 }
2575 }
2576 return false;
2577}
2578
2580 const CXXRecordDecl *D) {
2581 for (const CXXBaseSpecifier &B : D->bases()) {
2582 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2583 if (B.isVirtual()) {
2584 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2585 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2586 << B.getSourceRange();
2587 }
2588 if (!B.getType()->isStandardLayoutType()) {
2589 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2590 << diag::TraitNotSatisfiedReason::NonStandardLayoutBase << B.getType()
2591 << B.getSourceRange();
2592 }
2593 }
2594 // Check for mixed access specifiers in fields.
2595 const FieldDecl *FirstField = nullptr;
2596 AccessSpecifier FirstAccess = AS_none;
2597
2598 for (const FieldDecl *Field : D->fields()) {
2599 if (Field->isUnnamedBitField())
2600 continue;
2601
2602 // Record the first field we see
2603 if (!FirstField) {
2604 FirstField = Field;
2605 FirstAccess = Field->getAccess();
2606 continue;
2607 }
2608
2609 // Check if the field has a different access specifier than the first one.
2610 if (Field->getAccess() != FirstAccess) {
2611 // Emit a diagnostic about mixed access specifiers.
2612 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2613 << diag::TraitNotSatisfiedReason::MixedAccess;
2614
2615 SemaRef.Diag(FirstField->getLocation(), diag::note_defined_here)
2616 << FirstField;
2617
2618 SemaRef.Diag(Field->getLocation(), diag::note_unsatisfied_trait_reason)
2619 << diag::TraitNotSatisfiedReason::MixedAccessField << Field
2620 << FirstField;
2621
2622 // No need to check further fields, as we already found mixed access.
2623 break;
2624 }
2625 }
2627 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2628 << diag::TraitNotSatisfiedReason::MultipleDataBase;
2629 }
2630 if (D->isPolymorphic()) {
2631 // Find the best location to point “defined here” at.
2632 const CXXMethodDecl *VirtualMD = nullptr;
2633 // First, look for a virtual method.
2634 for (const auto *M : D->methods()) {
2635 if (M->isVirtual()) {
2636 VirtualMD = M;
2637 break;
2638 }
2639 }
2640 if (VirtualMD) {
2641 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2642 << diag::TraitNotSatisfiedReason::VirtualFunction << VirtualMD;
2643 SemaRef.Diag(VirtualMD->getLocation(), diag::note_defined_here)
2644 << VirtualMD;
2645 } else {
2646 // If no virtual method, point to the record declaration itself.
2647 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2648 << diag::TraitNotSatisfiedReason::VirtualFunction << D;
2649 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2650 }
2651 }
2652 for (const FieldDecl *Field : D->fields()) {
2653 if (!Field->getType()->isStandardLayoutType()) {
2654 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2655 << diag::TraitNotSatisfiedReason::NonStandardLayoutMember << Field
2656 << Field->getType() << Field->getSourceRange();
2657 }
2658 }
2659 // Find any indirect base classes that have fields.
2660 if (D->hasDirectFields()) {
2661 const CXXRecordDecl *Indirect = nullptr;
2662 D->forallBases([&](const CXXRecordDecl *BaseDef) {
2663 if (BaseDef->hasDirectFields()) {
2664 Indirect = BaseDef;
2665 return false; // stop traversal
2666 }
2667 return true; // continue to the next base
2668 });
2669 if (Indirect) {
2670 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2671 << diag::TraitNotSatisfiedReason::IndirectBaseWithFields << Indirect
2672 << Indirect->getSourceRange();
2673 }
2674 }
2675}
2676
2678 QualType T) {
2679 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2680 << T << diag::TraitName::StandardLayout;
2681
2682 // Check type-level exclusion first.
2683 if (T->isVariablyModifiedType()) {
2684 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2685 << diag::TraitNotSatisfiedReason::VLA;
2686 return;
2687 }
2688
2689 if (T->isReferenceType()) {
2690 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2691 << diag::TraitNotSatisfiedReason::Ref;
2692 return;
2693 }
2694 T = T.getNonReferenceType();
2695 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2696 if (!D || D->isInvalidDecl())
2697 return;
2698
2699 if (D->hasDefinition())
2700 DiagnoseNonStandardLayoutReason(SemaRef, Loc, D);
2701
2702 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2703}
2704
2706 const CXXRecordDecl *D) {
2707 for (const CXXConstructorDecl *Ctor : D->ctors()) {
2708 if (Ctor->isUserProvided())
2709 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2710 << diag::TraitNotSatisfiedReason::UserDeclaredCtr;
2711 if (Ctor->isInheritingConstructor())
2712 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2713 << diag::TraitNotSatisfiedReason::InheritedCtr;
2714 }
2715
2716 if (llvm::any_of(D->decls(), [](auto const *Sub) {
2717 return isa<ConstructorUsingShadowDecl>(Sub);
2718 })) {
2719 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2720 << diag::TraitNotSatisfiedReason::InheritedCtr;
2721 }
2722
2723 if (D->isPolymorphic())
2724 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2725 << diag::TraitNotSatisfiedReason::PolymorphicType
2726 << D->getSourceRange();
2727
2728 for (const CXXBaseSpecifier &B : D->bases()) {
2729 if (B.isVirtual()) {
2730 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2731 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2732 << B.getSourceRange();
2733 continue;
2734 }
2735 auto AccessSpecifier = B.getAccessSpecifier();
2736 switch (AccessSpecifier) {
2737 case AS_private:
2738 case AS_protected:
2739 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2740 << diag::TraitNotSatisfiedReason::PrivateProtectedDirectBase
2742 break;
2743 default:
2744 break;
2745 }
2746 }
2747
2748 for (const CXXMethodDecl *Method : D->methods()) {
2749 if (Method->isVirtual()) {
2750 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2751 << diag::TraitNotSatisfiedReason::VirtualFunction << Method
2752 << Method->getSourceRange();
2753 }
2754 }
2755
2756 for (const FieldDecl *Field : D->fields()) {
2757 auto AccessSpecifier = Field->getAccess();
2758 switch (AccessSpecifier) {
2759 case AS_private:
2760 case AS_protected:
2761 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2762 << diag::TraitNotSatisfiedReason::PrivateProtectedDirectDataMember
2764 break;
2765 default:
2766 break;
2767 }
2768 }
2769
2770 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2771}
2772
2774 QualType T) {
2775 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2776 << T << diag::TraitName::Aggregate;
2777
2778 if (T->isVoidType())
2779 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2780 << diag::TraitNotSatisfiedReason::CVVoidType;
2781
2782 T = T.getNonReferenceType();
2783 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2784 if (!D || D->isInvalidDecl())
2785 return;
2786
2787 if (D->hasDefinition())
2788 DiagnoseNonAggregateReason(SemaRef, Loc, D);
2789}
2790
2792 const CXXRecordDecl *D) {
2793 // If this type has any abstract base classes, their respective virtual
2794 // functions must have been overridden.
2795 for (const CXXBaseSpecifier &B : D->bases()) {
2796 if (B.getType()->castAsCXXRecordDecl()->isAbstract()) {
2797 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2798 << diag::TraitNotSatisfiedReason::OverridesAllPureVirtual
2799 << B.getType() << B.getSourceRange();
2800 }
2801 }
2802}
2803
2805 QualType T) {
2806 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2807 << T << diag::TraitName::Abstract;
2808
2809 if (T->isReferenceType()) {
2810 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2811 << diag::TraitNotSatisfiedReason::Ref;
2812 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2813 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2814 return;
2815 }
2816
2817 if (T->isUnionType()) {
2818 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2819 << diag::TraitNotSatisfiedReason::UnionType;
2820 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2821 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2822 return;
2823 }
2824
2825 if (SemaRef.Context.getAsArrayType(T)) {
2826 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2827 << diag::TraitNotSatisfiedReason::ArrayType;
2828 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2829 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2830 return;
2831 }
2832
2833 if (T->isFunctionType()) {
2834 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2835 << diag::TraitNotSatisfiedReason::FunctionType;
2836 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2837 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2838 return;
2839 }
2840
2841 if (T->isPointerType()) {
2842 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2843 << diag::TraitNotSatisfiedReason::PointerType;
2844 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2845 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2846 return;
2847 }
2848
2849 if (!T->isStructureOrClassType()) {
2850 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2851 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2852 return;
2853 }
2854
2855 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2856 if (D->hasDefinition())
2857 DiagnoseNonAbstractReason(SemaRef, Loc, D);
2858}
2859
2861 E = E->IgnoreParenImpCasts();
2862 if (E->containsErrors())
2863 return;
2864
2866 if (!TraitInfo)
2867 return;
2868
2869 const auto &[Trait, Args] = TraitInfo.value();
2870 switch (Trait) {
2871 case UTT_IsCppTriviallyRelocatable:
2873 break;
2874 case UTT_IsReplaceable:
2875 DiagnoseNonReplaceableReason(*this, E->getBeginLoc(), Args[0]);
2876 break;
2877 case UTT_IsTriviallyCopyable:
2878 DiagnoseNonTriviallyCopyableReason(*this, E->getBeginLoc(), Args[0]);
2879 break;
2880 case BTT_IsAssignable:
2881 DiagnoseNonAssignableReason(*this, E->getBeginLoc(), Args[0], Args[1]);
2882 break;
2883 case UTT_IsEmpty:
2884 DiagnoseIsEmptyReason(*this, E->getBeginLoc(), Args[0]);
2885 break;
2886 case UTT_IsStandardLayout:
2887 DiagnoseNonStandardLayoutReason(*this, E->getBeginLoc(), Args[0]);
2888 break;
2889 case TT_IsConstructible:
2891 break;
2892 case UTT_IsAggregate:
2893 DiagnoseNonAggregateReason(*this, E->getBeginLoc(), Args[0]);
2894 break;
2895 case UTT_IsFinal: {
2896 QualType QT = Args[0];
2897 if (QT->isDependentType())
2898 break;
2899 const auto *RD = QT->getAsCXXRecordDecl();
2900 if (!RD || !RD->isEffectivelyFinal())
2901 DiagnoseIsFinalReason(*this, E->getBeginLoc(), QT); // unsatisfied
2902 break;
2903 }
2904 case UTT_IsAbstract:
2905 DiagnoseNonAbstractReason(*this, E->getBeginLoc(), Args[0]);
2906 break;
2907 default:
2908 break;
2909 }
2910}
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:220
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:776
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:677
bool hasUniqueObjectRepresentations(QualType Ty, bool CheckIfTriviallyCopyable=true) const
Return true if the specified type has unique object representations according to (C++17 [meta....
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
TypeSourceInfo * CreateTypeSourceInfo(QualType T, unsigned Size=0) const
Allocate an uninitialized TypeSourceInfo.
llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const
Make an APSInt of the appropriate width and signedness for the given Value and integer Type.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
CanQualType getCanonicalTagType(const TagDecl *TD) const
std::optional< CXXRecordDeclRelocationInfo > getRelocationInfoForCXXRecord(const CXXRecordDecl *) const
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
PtrTy get() const
Definition Ownership.h:171
bool isInvalid() const
Definition Ownership.h:167
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
Definition ExprCXX.h:2998
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition TypeBase.h:3722
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 defaultedMoveConstructorIsDeleted() const
true if a defaulted move constructor for this class would be deleted.
Definition DeclCXX.h:706
bool hasUserDeclaredMoveAssignment() const
Determine whether this class has had a move assignment declared by the user.
Definition DeclCXX.h:961
bool hasDeletedDestructor() const
Returns the destructor decl for this class.
Definition DeclCXX.cpp: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 needsImplicitDefaultConstructor() const
Determine if we need to declare a default constructor for this class.
Definition DeclCXX.h:766
bool needsImplicitMoveConstructor() const
Determine whether this class should get an implicit move constructor or if any existing special membe...
Definition DeclCXX.h:892
bool hasUserDeclaredCopyAssignment() const
Determine whether this class has a user-declared copy assignment operator.
Definition DeclCXX.h:910
method_range methods() const
Definition DeclCXX.h:650
CXXRecordDecl * getDefinition() const
Definition DeclCXX.h:548
bool hasTrivialCopyConstructor() const
Determine whether this class has a trivial copy constructor (C++ [class.copy]p6, C++11 [class....
Definition DeclCXX.h: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 defaultedCopyConstructorIsDeleted() const
true if a defaulted copy constructor for this class would be deleted.
Definition DeclCXX.h:697
bool hasTrivialCopyAssignment() const
Determine whether this class has a trivial copy assignment operator (C++ [class.copy]p11,...
Definition DeclCXX.h: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 needsImplicitCopyConstructor() const
Determine whether this class needs an implicit copy constructor to be lazily declared.
Definition DeclCXX.h:799
bool hasSimpleMoveAssignment() const
true if we know for sure that this class has a single, accessible, unambiguous move assignment operat...
Definition DeclCXX.h:744
bool hasNonTrivialMoveConstructor() const
Determine whether this class has a non-trivial move constructor (C++11 [class.copy]p12)
Definition DeclCXX.h: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:3760
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:449
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:546
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:3071
Represents a member of a struct/union/class.
Definition Decl.h:3160
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition Decl.h:2377
bool isDeleted() const
Whether this function has been deleted.
Definition Decl.h:2540
bool isDefaulted() const
Whether this function is defaulted.
Definition Decl.h:2385
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4538
bool isUserProvided() const
True if this method is user-declared and was not deleted or defaulted on its first declaration.
Definition Decl.h:2410
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5254
unsigned getNumParams() const
Definition TypeBase.h:5532
bool isNothrow(bool ResultIfDependent=false) const
Determine whether this function type has a non-throwing exception specification.
Definition TypeBase.h:5653
Declaration of a template function.
StringRef getName() const
Return the actual identifier string.
Describes the kind of initialization being performed, along with location information for tokens rela...
static InitializationKind CreateDirect(SourceLocation InitLoc, SourceLocation LParenLoc, SourceLocation RParenLoc)
Create a direct initialization.
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
Describes the sequence of initializations required to initialize a given object or reference with a s...
Describes an entity that is being initialized.
static InitializedEntity InitializeTemporary(QualType Type)
Create the initialization entity for a temporary.
Represents the results of name lookup.
Definition Lookup.h:147
UnresolvedSetImpl::iterator iterator
Definition Lookup.h:154
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
Definition Lookup.h:636
iterator end() const
Definition Lookup.h:359
iterator begin() const
Definition Lookup.h:358
This represents a decl that may have a name.
Definition Decl.h:274
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
Definition Decl.h:487
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:295
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
Represents an ObjC class declaration.
Definition DeclObjC.h:1154
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
Definition DeclObjC.h:1810
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition Expr.h: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:2866
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type.
Definition Type.cpp:3555
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:8463
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:4449
field_range fields() const
Definition Decl.h:4515
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Definition SemaBase.cpp:61
A RAII object to temporarily push a declaration context.
Definition Sema.h:3467
CXXSpecialMemberKind asSpecialMember() const
Definition Sema.h:6356
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
Definition Sema.h:12395
bool hasErrorOccurred() const
Determine whether any SFINAE errors have been trapped.
Definition Sema.h:12428
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:9297
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:6681
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:338
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Stmt.cpp:350
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4882
bool isUnion() const
Definition Decl.h:3922
bool isDependentType() const
Whether this declaration declares a type that is dependent, i.e., a type that somehow depends on temp...
Definition Decl.h:3857
@ 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:8249
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition TypeLoc.h:267
QualType getType() const
Return the type wrapped by this type source info.
Definition TypeBase.h:8260
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:8871
bool isIncompleteArrayType() const
Definition TypeBase.h:8622
bool isRValueReferenceType() const
Definition TypeBase.h:8547
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:8614
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9158
bool isEnumeralType() const
Definition TypeBase.h:8646
bool isScalarType() const
Definition TypeBase.h:8973
bool isVariableArrayType() const
Definition TypeBase.h:8626
bool isLValueReferenceType() const
Definition TypeBase.h:8543
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:9044
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:2435
bool isFunctionType() const
Definition TypeBase.h:8511
bool isStructureOrClassType() const
Definition Type.cpp:706
bool isVectorType() const
Definition TypeBase.h:8654
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:9091
A set of unresolved declarations.
QualType getType() const
Definition Decl.h:723
Provides information about an attempted template argument deduction, whose success or failure was des...
Definition SPIR.cpp:47
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Definition TokenKinds.h:25
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
bool isa(CodeGen::Address addr)
Definition Address.h:330
ArrayTypeTrait
Names for the array type traits.
Definition TypeTraits.h:42
@ CPlusPlus
unsigned getTypeTraitArity(TypeTrait T) LLVM_READONLY
Return the arity of the type trait T.
@ 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:425
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:369
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...