Thanks to visit codestin.com
Credit goes to clang.llvm.org

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