clang: lib/Sema/SemaCast.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
29#include "llvm/ADT/SmallVector.h"
30#include "llvm/ADT/StringExtras.h"
31#include
32using namespace clang;
33
34
35
44
48
58
59namespace {
60 struct CastOperation {
61 CastOperation(Sema &S, QualType destType, ExprResult src)
62 : Self(S), SrcExpr(src), DestType(destType),
65 Kind(CK_Dependent), IsARCUnbridgedCast(false) {
66
67
68
69
70
71
72
73
74
75
76
77
79 !DestType->isArrayType() && !DestType.getPointerAuth()) {
80 DestType = DestType.getAtomicUnqualifiedType();
81 }
82
83 if (const BuiltinType *placeholder =
85 PlaceholderKind = placeholder->getKind();
86 } else {
88 }
89 }
90
91 Sema &Self;
93 QualType DestType;
94 QualType ResultType;
99 bool IsARCUnbridgedCast;
100
101 struct OpRangeType {
102 SourceLocation Locations[3];
103
104 OpRangeType(SourceLocation Begin, SourceLocation LParen,
105 SourceLocation RParen)
106 : Locations{Begin, LParen, RParen} {}
107
108 OpRangeType() = default;
109
110 SourceLocation getBegin() const { return Locations[0]; }
111
112 SourceLocation getLParenLoc() const { return Locations[1]; }
113
114 SourceLocation getRParenLoc() const { return Locations[2]; }
115
116 friend const StreamingDiagnostic &
117 operator<<(const StreamingDiagnostic &DB, OpRangeType Op) {
118 return DB << SourceRange(Op);
119 }
120
121 SourceRange getParenRange() const {
122 return SourceRange(getLParenLoc(), getRParenLoc());
123 }
124
125 operator SourceRange() const {
126 return SourceRange(getBegin(), getRParenLoc());
127 }
128 };
129
130 OpRangeType OpRange;
131 SourceRange DestRange;
132
133
134 void CheckConstCast();
135 void CheckReinterpretCast();
136 void CheckStaticCast();
137 void CheckDynamicCast();
138 void CheckCXXCStyleCast(bool FunctionalCast, bool ListInitialization);
140 void CheckCStyleCast();
141 void CheckBuiltinBitCast();
142 void CheckAddrspaceCast();
143
144 void updatePartOfExplicitCastFlags(CastExpr *CE) {
145
146
147
148 for (; auto *ICE = dyn_cast(CE->getSubExpr()); CE = ICE)
149 ICE->setIsPartOfExplicitCast(true);
150 }
151
152
153
155
156
157 if (IsARCUnbridgedCast) {
159 Self.Context, Self.Context.ARCUnbridgedCastTy, CK_Dependent,
161 Self.CurFPFeatureOverrides());
162 }
163 updatePartOfExplicitCastFlags(castExpr);
165 }
166
167
168
169
170
171
173 if (PlaceholderKind != K) return false;
174
176 return true;
177 }
178
179 bool isPlaceholder() const {
180 return PlaceholderKind != 0;
181 }
183 return PlaceholderKind == K;
184 }
185
186
187 void checkAddressSpaceCast(QualType SrcType, QualType DestType);
188
189 void checkCastAlign() {
190 Self.CheckCastAlign(SrcExpr.get(), DestType, OpRange);
191 }
192
194 bool IsReinterpretCast = false) {
195 assert(Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers());
196
197 Expr *src = SrcExpr.get();
198 if (Self.ObjC().CheckObjCConversion(
199 OpRange, DestType, src, CCK, true, false, BO_PtrMemD,
201 IsARCUnbridgedCast = true;
202 SrcExpr = src;
203 }
204
205 void checkQualifiedDestType() {
206
207 if (DestType.getPointerAuth()) {
208 Self.Diag(DestRange.getBegin(), diag::err_ptrauth_qualifier_cast)
209 << DestType << DestRange;
210 }
211 }
212
213
214 void checkNonOverloadPlaceholders() {
215 if (!isPlaceholder() || isPlaceholder(BuiltinType::Overload))
216 return;
217
218 SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());
219 if (SrcExpr.isInvalid())
220 return;
222 }
223 };
224
227 if (const auto *PtrType = dyn_cast(FromType)) {
228 if (PtrType->getPointeeType()->hasAttr(attr::NoDeref)) {
229 if (const auto *DestType = dyn_cast(ToType)) {
230 if (!DestType->getPointeeType()->hasAttr(attr::NoDeref)) {
231 S.Diag(OpLoc, diag::warn_noderef_to_dereferenceable_pointer);
232 }
233 }
234 }
235 }
236 }
237
238 struct CheckNoDerefRAII {
239 CheckNoDerefRAII(CastOperation &Op) : Op(Op) {}
240 ~CheckNoDerefRAII() {
241 if (!Op.SrcExpr.isInvalid())
242 CheckNoDeref(Op.Self, Op.SrcExpr.get()->getType(), Op.ResultType,
243 Op.OpRange.getBegin());
244 }
245
246 CastOperation &Op;
247 };
248}
249
252
253
254
255
256
257
258
259
260
261
262
263
265 QualType DestType, bool CStyle,
268 unsigned &msg);
271 bool CStyle, CastOperation::OpRangeType OpRange,
272 unsigned &msg, CastKind &Kind,
276 bool CStyle, CastOperation::OpRangeType OpRange,
280 CastOperation::OpRangeType OpRange,
282 QualType OrigDestType, unsigned &msg,
286 QualType DestType, bool CStyle,
287 CastOperation::OpRangeType OpRange, unsigned &msg,
289
293 CastOperation::OpRangeType OpRange,
294 unsigned &msg, CastKind &Kind,
295 bool ListInitialization);
298 CastOperation::OpRangeType OpRange,
299 unsigned &msg, CastKind &Kind,
301 bool ListInitialization);
303 QualType DestType, bool CStyle,
304 unsigned &msg);
306 QualType DestType, bool CStyle,
307 CastOperation::OpRangeType OpRange,
308 unsigned &msg, CastKind &Kind);
310 QualType DestType, bool CStyle,
311 unsigned &msg, CastKind &Kind);
312
319
321
325
327
329 }
330
332 SourceRange(LAngleBracketLoc, RAngleBracketLoc),
334}
335
342
343
344 bool TypeDependent =
346
347 CastOperation Op(*this, DestType, E);
348 Op.OpRange =
349 CastOperation::OpRangeType(OpLoc, Parens.getBegin(), Parens.getEnd());
350 Op.DestRange = AngleBrackets;
351
352 Op.checkQualifiedDestType();
353
354 switch (Kind) {
355 default: llvm_unreachable("Unknown C++ cast!");
356
357 case tok::kw_addrspace_cast:
358 if (!TypeDependent) {
359 Op.CheckAddrspaceCast();
362 }
364 Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
365 DestTInfo, OpLoc, Parens.getEnd(), AngleBrackets));
366
367 case tok::kw_const_cast:
368 if (!TypeDependent) {
369 Op.CheckConstCast();
373 }
375 Op.ValueKind, Op.SrcExpr.get(), DestTInfo,
376 OpLoc, Parens.getEnd(),
377 AngleBrackets));
378
379 case tok::kw_dynamic_cast: {
380
382 return ExprError(Diag(OpLoc, diag::err_openclcxx_not_supported)
383 << "dynamic_cast");
384 }
385
386 if (!TypeDependent) {
387 Op.CheckDynamicCast();
390 }
392 Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
393 &Op.BasePath, DestTInfo,
394 OpLoc, Parens.getEnd(),
395 AngleBrackets));
396 }
397 case tok::kw_reinterpret_cast: {
398 if (!TypeDependent) {
399 Op.CheckReinterpretCast();
403 }
405 Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
406 nullptr, DestTInfo, OpLoc,
408 AngleBrackets));
409 }
410 case tok::kw_static_cast: {
411 if (!TypeDependent) {
412 Op.CheckStaticCast();
416 }
417
419 Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
421 Parens.getEnd(), AngleBrackets));
422 }
423 }
424}
425
437
441 CastOperation Op(*this, TSI->getType(), Operand);
442 Op.OpRange = CastOperation::OpRangeType(KWLoc, KWLoc, RParenLoc);
445
447 Op.CheckBuiltinBitCast();
450 }
451
454 Op.SrcExpr.get(), TSI, KWLoc, RParenLoc);
455 return Op.complete(BCE);
456}
457
458
459
461 CastOperation::OpRangeType range,
463 bool listInitialization) {
464 switch (CT) {
465
470 return false;
471
472
476 break;
477 }
478
481 return false;
482
486 range.getBegin(), range, listInitialization)
489 range.getBegin(), range.getParenRange(), listInitialization)
492
493
494
495
496 if (!sequence.Failed())
497 return false;
498
500 default: return false;
501
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
519 return false;
520 break;
523 break;
524 }
525
527
528 unsigned msg = 0;
530
532 case OR_Success: llvm_unreachable("successful failed overload");
534 if (candidates.empty())
535 msg = diag::err_ovl_no_conversion_in_cast;
536 else
537 msg = diag::err_ovl_no_viable_conversion_in_cast;
539 break;
540
542 msg = diag::err_ovl_ambiguous_conversion_in_cast;
544 break;
545
550 assert(Res == OR_Deleted && "Inconsistent overload resolution");
551
552 StringLiteral *Msg = Best->Function->getDeletedMessage();
555 S.PDiag(diag::err_ovl_deleted_conversion_in_cast)
556 << CT << srcType << destType << (Msg != nullptr)
557 << (Msg ? Msg->getString() : StringRef())
560 return true;
561 }
562 }
563
566 S.PDiag(msg) << CT << srcType << destType << range
568 S, howManyCandidates, src);
569
570 return true;
571}
572
573
575 CastOperation::OpRangeType opRange, Expr *src,
576 QualType destType, bool listInitialization) {
577 if (msg == diag::err_bad_cxx_cast_generic &&
579 listInitialization))
580 return;
581
582 S.Diag(opRange.getBegin(), msg) << castType
584
585
586 int DifferentPtrness = 0;
590 DifferentPtrness++;
591 }
595 DifferentPtrness--;
596 }
597 if (!DifferentPtrness) {
600 DeclFrom && DeclTo) {
601 if (!DeclFrom->isCompleteDefinition())
602 S.Diag(DeclFrom->getLocation(), diag::note_type_incomplete) << DeclFrom;
603 if (!DeclTo->isCompleteDefinition())
604 S.Diag(DeclTo->getLocation(), diag::note_type_incomplete) << DeclTo;
605 }
606 }
607}
608
609namespace {
610
611
612enum CastAwayConstnessKind {
613
614 CACK_None = 0,
615
616 CACK_Similar = 1,
617
618
619 CACK_SimilarKind = 2,
620
621
622 CACK_Incoherent = 3,
623};
624}
625
626
627
628
629
630
631
632
633
634
635
636
637
638static CastAwayConstnessKind
640 enum { None, Ptr, MemPtr, BlockPtr, Array };
642 if (T->isAnyPointerType()) return Ptr;
643 if (T->isMemberPointerType()) return MemPtr;
644 if (T->isBlockPointerType()) return BlockPtr;
645
646
647 if (T->isConstantArrayType() || T->isIncompleteArrayType()) return Array;
649 };
650
652 if (auto *AT = Context.getAsArrayType(T))
653 return AT->getElementType();
654 return T->getPointeeType();
655 };
656
657 CastAwayConstnessKind Kind;
658
660
661
662
663
665 Kind = CastAwayConstnessKind::CACK_Similar;
666 } else if (Context.UnwrapSimilarTypes(T1, T2)) {
667 Kind = CastAwayConstnessKind::CACK_Similar;
668 } else {
669
670 int T1Class = Classify(T1);
671 if (T1Class == None)
672 return CastAwayConstnessKind::CACK_None;
673
674 int T2Class = Classify(T2);
675 if (T2Class == None)
676 return CastAwayConstnessKind::CACK_None;
677
678 T1 = Unwrap(T1);
679 T2 = Unwrap(T2);
680 Kind = T1Class == T2Class ? CastAwayConstnessKind::CACK_SimilarKind
681 : CastAwayConstnessKind::CACK_Incoherent;
682 }
683
684
685
686
687
688 while (true) {
689 Context.UnwrapSimilarArrayTypes(T1, T2);
690
691 if (Classify(T1) != Array)
692 break;
693
694 auto T2Class = Classify(T2);
695 if (T2Class == None)
696 break;
697
698 if (T2Class != Array)
699 Kind = CastAwayConstnessKind::CACK_Incoherent;
700 else if (Kind != CastAwayConstnessKind::CACK_Incoherent)
701 Kind = CastAwayConstnessKind::CACK_SimilarKind;
702
703 T1 = Unwrap(T1);
705 }
706
707 return Kind;
708}
709
710
711
712
713
714
715
716static CastAwayConstnessKind
718 bool CheckCVR, bool CheckObjCLifetime,
719 QualType *TheOffendingSrcType = nullptr,
720 QualType *TheOffendingDestType = nullptr,
721 Qualifiers *CastAwayQualifiers = nullptr) {
722
723
724 if (!CheckCVR && CheckObjCLifetime && .Context.getLangOpts().ObjC)
725 return CastAwayConstnessKind::CACK_None;
726
730 "Source type is not pointer or pointer to member.");
733 "Destination type is not pointer or pointer to member.");
734 }
735
736 QualType UnwrappedSrcType = Self.Context.getCanonicalType(SrcType),
737 UnwrappedDestType = Self.Context.getCanonicalType(DestType);
738
739
740
741
742 QualType PrevUnwrappedSrcType = UnwrappedSrcType;
743 QualType PrevUnwrappedDestType = UnwrappedDestType;
744 auto WorstKind = CastAwayConstnessKind::CACK_Similar;
745 bool AllConstSoFar = true;
747 Self.Context, UnwrappedSrcType, UnwrappedDestType)) {
748
749
750 if (Kind > WorstKind)
751 WorstKind = Kind;
752
753
755 Self.Context.getUnqualifiedArrayType(UnwrappedSrcType, SrcQuals);
756 Self.Context.getUnqualifiedArrayType(UnwrappedDestType, DestQuals);
757
758
759
760
762 UnwrappedDestType->isObjCObjectType())
764
765 if (CheckCVR) {
770
771 if (SrcCvrQuals != DestCvrQuals) {
772 if (CastAwayQualifiers)
773 *CastAwayQualifiers = SrcCvrQuals - DestCvrQuals;
774
775
776 if (!DestCvrQuals.compatiblyIncludes(SrcCvrQuals,
777 Self.getASTContext())) {
778 if (TheOffendingSrcType)
779 *TheOffendingSrcType = PrevUnwrappedSrcType;
780 if (TheOffendingDestType)
781 *TheOffendingDestType = PrevUnwrappedDestType;
782 return WorstKind;
783 }
784
785
786
787 if (!AllConstSoFar)
788 return WorstKind;
789 }
790 }
791
792 if (CheckObjCLifetime &&
794 return WorstKind;
795
796
797
798 if (AllConstSoFar && !DestQuals.hasConst()) {
799 AllConstSoFar = false;
800 if (TheOffendingSrcType)
801 *TheOffendingSrcType = PrevUnwrappedSrcType;
802 if (TheOffendingDestType)
803 *TheOffendingDestType = PrevUnwrappedDestType;
804 }
805
806 PrevUnwrappedSrcType = UnwrappedSrcType;
807 PrevUnwrappedDestType = UnwrappedDestType;
808 }
809
810 return CastAwayConstnessKind::CACK_None;
811}
812
814 unsigned &DiagID) {
815 switch (CACK) {
816 case CastAwayConstnessKind::CACK_None:
817 llvm_unreachable("did not cast away constness");
818
819 case CastAwayConstnessKind::CACK_Similar:
820
821 case CastAwayConstnessKind::CACK_SimilarKind:
822 DiagID = diag::err_bad_cxx_cast_qualifiers_away;
824
825 case CastAwayConstnessKind::CACK_Incoherent:
826 DiagID = diag::ext_bad_cxx_cast_qualifiers_away_incoherent;
828 }
829
830 llvm_unreachable("unexpected cast away constness kind");
831}
832
833
834
835
836void CastOperation::CheckDynamicCast() {
837 CheckNoDerefRAII NoderefCheck(*this);
838
840 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
841 else if (isPlaceholder())
842 SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());
843 if (SrcExpr.isInvalid())
844 return;
845
846 QualType OrigSrcType = SrcExpr.get()->getType();
847 QualType DestType = Self.Context.getCanonicalType(this->DestType);
848
849
850
851
855 if (DestPointer) {
859 } else {
860 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ref_or_ptr)
861 << this->DestType << DestRange;
863 return;
864 }
865
866 const auto *DestRecord = DestPointee->getAsCanonical();
868 assert(DestPointer && "Reference to void is not possible");
869 } else if (DestRecord) {
870 if (Self.RequireCompleteType(OpRange.getBegin(), DestPointee,
871 diag::err_bad_cast_incomplete,
872 DestRange)) {
874 return;
875 }
876 } else {
877 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
880 return;
881 }
882
883
884
885
886
887 QualType SrcType = Self.Context.getCanonicalType(OrigSrcType);
889 if (DestPointer) {
892 } else {
893 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ptr)
894 << OrigSrcType << this->DestType << SrcExpr.get()->getSourceRange();
896 return;
897 }
898 } else if (DestReference->isLValueReferenceType()) {
899 if (!SrcExpr.get()->isLValue()) {
900 Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_rvalue)
901 << CT_Dynamic << OrigSrcType << this->DestType << OpRange;
902 }
903 SrcPointee = SrcType;
904 } else {
905
906
907 if (SrcExpr.get()->isPRValue())
908 SrcExpr = Self.CreateMaterializeTemporaryExpr(
909 SrcType, SrcExpr.get(), false);
910 SrcPointee = SrcType;
911 }
912
913 const auto *SrcRecord = SrcPointee->getAsCanonical();
914 if (SrcRecord) {
915 if (Self.RequireCompleteType(OpRange.getBegin(), SrcPointee,
916 diag::err_bad_cast_incomplete,
917 SrcExpr.get())) {
919 return;
920 }
921 } else {
922 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
923 << SrcPointee.getUnqualifiedType() << SrcExpr.get()->getSourceRange();
925 return;
926 }
927
928 assert((DestPointer || DestReference) &&
929 "Bad destination non-ptr/ref slipped through.");
930 assert((DestRecord || DestPointee->isVoidType()) &&
931 "Bad destination pointee slipped through.");
932 assert(SrcRecord && "Bad source pointee slipped through.");
933
934
936 Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_qualifiers_away)
937 << CT_Dynamic << OrigSrcType << this->DestType << OpRange;
939 return;
940 }
941
942
943
944 if (DestRecord == SrcRecord) {
945 Kind = CK_NoOp;
946 return;
947 }
948
949
950
951 if (DestRecord &&
952 Self.IsDerivedFrom(OpRange.getBegin(), SrcPointee, DestPointee)) {
953 if (Self.CheckDerivedToBaseConversion(SrcPointee, DestPointee,
954 OpRange.getBegin(), OpRange,
955 &BasePath)) {
957 return;
958 }
959
960 Kind = CK_DerivedToBase;
961 return;
962 }
963
964
966 assert(SrcDecl && "Definition missing");
968 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_polymorphic)
969 << SrcPointee.getUnqualifiedType() << SrcExpr.get()->getSourceRange();
971 }
972
973
974
975
976 if (.getLangOpts().RTTI && !DestPointee->isVoidType()) {
977 Self.Diag(OpRange.getBegin(), diag::err_no_dynamic_cast_with_fno_rtti);
979 return;
980 }
981
982
983 if (.getLangOpts().RTTIData) {
984 bool MicrosoftABI =
985 Self.getASTContext().getTargetInfo().getCXXABI().isMicrosoft();
986 bool isClangCL = Self.getDiagnostics().getDiagnosticOptions().getFormat() ==
988 if (MicrosoftABI || !DestPointee->isVoidType())
989 Self.Diag(OpRange.getBegin(),
990 diag::warn_no_dynamic_cast_with_rtti_disabled)
991 << isClangCL;
992 }
993
994
995
996 if (DestRecord) {
997 auto *DestDecl = DestRecord->getAsCXXRecordDecl();
998 if (DestDecl->isEffectivelyFinal())
999 Self.MarkVTableUsed(OpRange.getBegin(), DestDecl);
1000 }
1001
1002
1003 Kind = CK_Dynamic;
1004}
1005
1006
1007
1008
1009
1010
1011void CastOperation::CheckConstCast() {
1012 CheckNoDerefRAII NoderefCheck(*this);
1013
1015 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
1016 else if (isPlaceholder())
1017 SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());
1018 if (SrcExpr.isInvalid())
1019 return;
1020
1021 unsigned msg = diag::err_bad_cxx_cast_generic;
1022 auto TCR = TryConstCast(Self, SrcExpr, DestType, false, msg);
1023 if (TCR != TC_Success && msg != 0) {
1024 Self.Diag(OpRange.getBegin(), msg) << CT_Const
1025 << SrcExpr.get()->getType() << DestType << OpRange;
1026 }
1029}
1030
1031void CastOperation::CheckAddrspaceCast() {
1032 unsigned msg = diag::err_bad_cxx_cast_generic;
1033 auto TCR =
1035 if (TCR != TC_Success && msg != 0) {
1036 Self.Diag(OpRange.getBegin(), msg)
1037 << CT_Addrspace << SrcExpr.get()->getType() << DestType << OpRange;
1038 }
1041}
1042
1043
1044
1047 CastOperation::OpRangeType OpRange) {
1049
1050
1054
1055
1056
1057
1059 return;
1060
1062
1064 return;
1065
1066 enum {
1067 ReinterpretUpcast,
1068 ReinterpretDowncast
1069 } ReinterpretKind;
1070
1072
1074 ReinterpretKind = ReinterpretUpcast;
1075 else if (DestRD->isDerivedFrom(SrcRD, BasePaths))
1076 ReinterpretKind = ReinterpretDowncast;
1077 else
1078 return;
1079
1081 bool NonZeroOffset = false;
1083 E = BasePaths.end();
1084 I != E; ++I) {
1087 bool IsVirtual = false;
1088 for (CXXBasePath::const_iterator IElem = Path.begin(), EElem = Path.end();
1089 IElem != EElem; ++IElem) {
1090 IsVirtual = IElem->Base->isVirtual();
1091 if (IsVirtual)
1092 break;
1093 const CXXRecordDecl *BaseRD = IElem->Base->getType()->getAsCXXRecordDecl();
1094 assert(BaseRD && "Base type should be a valid unqualified class type");
1095
1096
1099 if (Class->isInvalidDecl() || !ClassDefinition ||
1100 !ClassDefinition->isCompleteDefinition())
1101 return;
1102
1104 Self.Context.getASTRecordLayout(Class);
1106 }
1107 if (!IsVirtual) {
1108
1109 if (Offset.isZero())
1110 return;
1111
1112 else
1113 NonZeroOffset = true;
1114 }
1116 }
1117
1118 (void) NonZeroOffset;
1119 assert((VirtualBase || NonZeroOffset) &&
1120 "Should have returned if has non-virtual base with zero offset");
1121
1123 ReinterpretKind == ReinterpretUpcast? DestType : SrcType;
1125 ReinterpretKind == ReinterpretUpcast? SrcType : DestType;
1126
1128 Self.Diag(BeginLoc, diag::warn_reinterpret_different_from_static)
1129 << DerivedType << BaseType << << int(ReinterpretKind)
1130 << OpRange;
1131 Self.Diag(BeginLoc, diag::note_reinterpret_updowncast_use_static)
1132 << int(ReinterpretKind)
1134}
1135
1139 return true;
1140
1141
1144 if (Context.getTypeSizeInChars(SrcType) ==
1145 Context.getTypeSizeInChars(DestType))
1146 return true;
1147
1148 return Context.hasSameUnqualifiedType(SrcType, DestType);
1149}
1150
1153 unsigned int DiagID = 0;
1154 const unsigned int DiagList[] = {diag::warn_cast_function_type_strict,
1155 diag::warn_cast_function_type};
1158 DiagID = ID;
1159 break;
1160 }
1161 }
1162 if (!DiagID)
1163 return 0;
1164
1177 } else {
1178 return 0;
1179 }
1180 assert(SrcFTy && DstFTy);
1181
1182 if (Self.Context.hasSameType(SrcFTy, DstFTy))
1183 return 0;
1184
1185
1186 if (DiagID == diag::warn_cast_function_type_strict)
1187 return DiagID;
1188
1190 if (->getReturnType()->isVoidType())
1191 return false;
1193 return !PT->isVariadic() && PT->getNumParams() == 0;
1194 return false;
1195 };
1196
1198
1199
1200
1201
1202
1203
1204
1205
1206 if (->getReturnType()->isIntegerType())
1207 return false;
1209 return !PT->isVariadic() && PT->getNumParams() == 0;
1210 return true;
1211 };
1212
1213
1214 if (IsVoidVoid(SrcFTy) || IsVoidVoid(DstFTy))
1215 return 0;
1216
1217
1218
1219
1220 if (Self.getASTContext().getTargetInfo().getTriple().isOSWindows() &&
1221 IsFarProc(SrcFTy))
1222 return 0;
1223
1224
1226 Self.Context))
1227 return DiagID;
1228
1229
1231 return 0;
1232
1233
1234
1237
1238
1239
1240 unsigned NumParams = SrcFPTy->getNumParams();
1241 unsigned DstNumParams = DstFPTy->getNumParams();
1242 if (NumParams > DstNumParams) {
1243 if (!DstFPTy->isVariadic())
1244 return DiagID;
1245 NumParams = DstNumParams;
1246 } else if (NumParams < DstNumParams) {
1247 if (!SrcFPTy->isVariadic())
1248 return DiagID;
1249 }
1250
1251 for (unsigned i = 0; i < NumParams; ++i)
1253 DstFPTy->getParamType(i), Self.Context))
1254 return DiagID;
1255
1256 return 0;
1257}
1258
1259
1260
1261
1262
1263
1264void CastOperation::CheckReinterpretCast() {
1265 if (ValueKind == VK_PRValue && !isPlaceholder(BuiltinType::Overload))
1266 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
1267 else
1268 checkNonOverloadPlaceholders();
1269 if (SrcExpr.isInvalid())
1270 return;
1271
1272 unsigned msg = diag::err_bad_cxx_cast_generic;
1275 false, OpRange, msg, Kind);
1276 if (tcr != TC_Success && msg != 0) {
1277 if (SrcExpr.isInvalid())
1278 return;
1279 if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
1280
1281 Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_overload)
1283 << DestType << OpRange;
1284 Self.NoteAllOverloadCandidates(SrcExpr.get());
1285
1286 } else {
1288 DestType, false);
1289 }
1290 }
1291
1293 if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())
1295 true);
1297
1299 Self.Diag(OpRange.getBegin(), DiagID)
1300 << SrcExpr.get()->getType() << DestType << OpRange;
1301 } else {
1303 }
1304}
1305
1306
1307
1308
1309
1310void CastOperation::CheckStaticCast() {
1311 CheckNoDerefRAII NoderefCheck(*this);
1312
1313 if (isPlaceholder()) {
1314 checkNonOverloadPlaceholders();
1315 if (SrcExpr.isInvalid())
1316 return;
1317 }
1318
1319
1320
1321
1323 Kind = CK_ToVoid;
1324
1325 if (claimPlaceholder(BuiltinType::Overload)) {
1326 Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr,
1327 false,
1328 true,
1329 OpRange, DestType, diag::err_bad_static_cast_overload);
1330 if (SrcExpr.isInvalid())
1331 return;
1332 }
1333
1334 SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());
1335 return;
1336 }
1337
1339 !isPlaceholder(BuiltinType::Overload)) {
1340 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
1341 if (SrcExpr.isInvalid())
1342 return;
1343 }
1344
1345 unsigned msg = diag::err_bad_cxx_cast_generic;
1348 OpRange, msg, Kind, BasePath, false);
1349 if (tcr != TC_Success && msg != 0) {
1350 if (SrcExpr.isInvalid())
1351 return;
1352 if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
1354 Self.Diag(OpRange.getBegin(), diag::err_bad_static_cast_overload)
1355 << oe->getName() << DestType << OpRange
1357 Self.NoteAllOverloadCandidates(SrcExpr.get());
1358 } else {
1360 false);
1361 }
1362 }
1363
1365 if (Kind == CK_BitCast)
1366 checkCastAlign();
1367 if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())
1369 } else {
1371 }
1372}
1373
1376 if (!SrcPtrType)
1377 return false;
1379 if (!DestPtrType)
1380 return false;
1382 DestPtrType->getPointeeType().getAddressSpace();
1383}
1384
1385
1386
1387
1390 CastOperation::OpRangeType OpRange,
1391 unsigned &msg, CastKind &Kind,
1393 bool ListInitialization) {
1394
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1414
1415
1416
1417
1419 OpRange, msg, Kind, BasePath);
1421 return tcr;
1422
1423
1424
1425
1427 Kind, BasePath, msg);
1429 return tcr;
1430
1431
1432
1434 Kind, ListInitialization);
1438 return tcr;
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1451
1452
1453
1454
1455 if (const EnumType *Enum = dyn_cast(SrcType)) {
1456 if (Enum->getDecl()->isScoped()) {
1458 Kind = CK_IntegralToBoolean;
1461 Kind = CK_IntegralCast;
1464 Kind = CK_IntegralToFloating;
1466 }
1467 }
1468 }
1469
1470
1471
1472
1473
1474
1475
1476
1477
1479 if (Self.RequireCompleteType(OpRange.getBegin(), DestType,
1480 diag::err_bad_cast_incomplete)) {
1483 }
1485
1486
1488 Kind = ED->isFixed() && ED->getIntegerType()->isBooleanType()
1489 ? CK_IntegralToBoolean
1490 : CK_IntegralCast;
1493 Kind = CK_FloatingToIntegral;
1495 }
1496 }
1497
1498
1499
1501 Kind, BasePath);
1503 return tcr;
1504
1505
1506
1507
1509 OpRange, msg, Kind, BasePath);
1511 return tcr;
1512
1513
1514
1515
1522
1523
1524
1525 if (!CStyle) {
1532 if (DestPointeeQuals != SrcPointeeQuals &&
1534 Self.getASTContext())) {
1535 msg = diag::err_bad_cxx_cast_qualifiers_away;
1537 }
1538 }
1540 ? CK_AddressSpaceConversion
1541 : CK_BitCast;
1543 }
1544
1545
1546
1547 if (!CStyle && Self.getLangOpts().MSVCCompat &&
1549 Self.Diag(OpRange.getBegin(), diag::ext_ms_cast_fn_obj) << OpRange;
1550 Kind = CK_BitCast;
1552 }
1553 }
1555
1556
1557 Kind = CK_CPointerToObjCPointerCast;
1559 }
1561
1562 Kind = CK_AnyPointerToBlockPointerCast;
1564 }
1565 }
1566 }
1567
1570 Kind = CK_BitCast;
1572 }
1573
1574
1575 if (!CStyle &&
1576 Self.ObjC().CheckTollFreeBridgeStaticCast(DestType, SrcExpr.get(), Kind))
1578
1579
1580
1582 if (const auto *DestPointer = DestType->getAs<PointerType>())
1583 if (SrcPointer->getPointeeType()->isRecordType() &&
1585 msg = diag::err_bad_cxx_cast_unrelated_class;
1586
1588 if (Self.CheckMatrixCast(OpRange, DestType, SrcType, Kind)) {
1591 }
1593 }
1594
1595
1597}
1598
1599
1601 QualType DestType, bool CStyle,
1604
1605
1606
1608 if (!R)
1610
1613
1614
1615
1618 if (CStyle) {
1621 }
1622
1625 SrcExpr->getBeginLoc(), ToType, FromType, &RefConv);
1629
1630
1631
1632 msg = SrcExpr->isLValue() ? diag::err_bad_lvalue_to_rvalue_cast
1633 : diag::err_bad_rvalue_to_rvalue_cast;
1635 }
1636
1637 if (RefConv & Sema::ReferenceConversions::DerivedToBase) {
1638 Kind = CK_DerivedToBase;
1639 if (Self.CheckDerivedToBaseConversion(FromType, ToType,
1641 &BasePath, CStyle)) {
1642 msg = 0;
1644 }
1645 } else
1646 Kind = CK_NoOp;
1647
1649}
1650
1651
1653 QualType DestType, bool CStyle,
1654 CastOperation::OpRangeType OpRange,
1655 unsigned &msg, CastKind &Kind,
1657
1658
1659
1660
1661
1662
1663
1664
1665
1667 if (!DestReference) {
1669 }
1671 if (!RValueRef && !SrcExpr->isLValue()) {
1672
1673 msg = diag::err_bad_cxx_cast_rvalue;
1675 }
1676
1678
1679
1680
1681
1683 Self.Context.getCanonicalType(SrcExpr->getType()),
1684 Self.Context.getCanonicalType(DestPointee), CStyle,
1685 OpRange, SrcExpr->getType(), DestType, msg, Kind,
1686 BasePath);
1687}
1688
1689
1691 QualType DestType, bool CStyle,
1692 CastOperation::OpRangeType OpRange,
1693 unsigned &msg, CastKind &Kind,
1695
1696
1697
1698
1699
1700
1701
1702
1704 if (!DestPointer) {
1706 }
1707
1709 if (!SrcPointer) {
1710 msg = diag::err_bad_static_cast_pointer_nonpointer;
1712 }
1713
1717 CStyle, OpRange, SrcType, DestType, msg, Kind,
1718 BasePath);
1719}
1720
1721
1722
1723
1726 CastOperation::OpRangeType OpRange,
1728 unsigned &msg, CastKind &Kind,
1730
1731 if (.isCompleteType(OpRange.getBegin(), SrcType) ||
1732 .isCompleteType(OpRange.getBegin(), DestType))
1734
1735
1736 if (!DestType->getAs() || !SrcType->getAs()) {
1738 }
1739
1740 CXXBasePaths Paths(true, true,
1741 true);
1742 if (.IsDerivedFrom(OpRange.getBegin(), DestType, SrcType, Paths)) {
1744 }
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765 if (!CStyle &&
1767 msg = diag::err_bad_cxx_cast_qualifiers_away;
1769 }
1770
1772
1773
1774
1775
1779 Self.IsDerivedFrom(OpRange.getBegin(), DestType, SrcType, Paths);
1780 }
1781 std::string PathDisplayStr;
1782 std::set DisplayedPaths;
1784 if (DisplayedPaths.insert(Path.back().SubobjectNumber).second) {
1785
1786
1787 PathDisplayStr += "\n ";
1789 PathDisplayStr += PE.Base->getType().getAsString() + " -> ";
1791 }
1792 }
1793
1794 Self.Diag(OpRange.getBegin(), diag::err_ambiguous_base_to_derived_cast)
1797 << PathDisplayStr << OpRange;
1798 msg = 0;
1800 }
1801
1804 Self.Diag(OpRange.getBegin(), diag::err_static_downcast_via_virtual)
1805 << OrigSrcType << OrigDestType << VirtualBase << OpRange;
1806 msg = 0;
1808 }
1809
1810 if (!CStyle) {
1811 switch (Self.CheckBaseClassAccess(OpRange.getBegin(),
1812 SrcType, DestType,
1814 diag::err_downcast_from_inaccessible_base)) {
1818 break;
1819
1821 msg = 0;
1823 }
1824 }
1825
1826 Self.BuildBasePathArray(Paths, BasePath);
1827 Kind = CK_BaseToDerived;
1829}
1830
1831
1832
1833
1834
1835
1836
1837
1840 bool CStyle,
1841 CastOperation::OpRangeType OpRange,
1842 unsigned &msg, CastKind &Kind,
1845 if (!DestMemPtr)
1847
1848 bool WasOverloadedFunction = false;
1850 if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
1852 = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(), DestType, false,
1853 FoundOverload)) {
1855 SrcType = Self.Context.getMemberPointerType(
1856 Fn->getType(), std::nullopt, M->getParent());
1857 WasOverloadedFunction = true;
1858 }
1859 }
1860
1861 switch (Self.CheckMemberPointerConversion(
1862 SrcType, DestMemPtr, Kind, BasePath, OpRange.getBegin(), OpRange, CStyle,
1865 if (Kind == CK_NullToMemberPointer) {
1866 msg = diag::err_bad_static_cast_member_pointer_nonmp;
1868 }
1869 break;
1876 msg = 0;
1878 }
1879
1880 if (WasOverloadedFunction) {
1881
1882
1883 FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(),
1884 DestType,
1885 true,
1886 FoundOverload);
1887 if (!Fn) {
1888 msg = 0;
1890 }
1891
1892 SrcExpr = Self.FixOverloadedFunctionReference(SrcExpr, FoundOverload, Fn);
1894 msg = 0;
1896 }
1897 }
1899}
1900
1901
1902
1903
1904
1905
1909 CastOperation::OpRangeType OpRange,
1910 unsigned &msg, CastKind &Kind,
1911 bool ListInitialization) {
1913 if (Self.RequireCompleteType(OpRange.getBegin(), DestType,
1914 diag::err_bad_cast_incomplete) ||
1915 Self.RequireNonAbstractType(OpRange.getBegin(), DestType,
1916 diag::err_allocation_of_abstract_type)) {
1917 msg = 0;
1919 }
1920 }
1921
1926 ListInitialization)
1929 OpRange.getBegin(), OpRange.getParenRange(), ListInitialization)
1931 Expr *SrcExprRaw = SrcExpr.get();
1932
1933
1934
1936
1937
1938
1939
1940
1941
1946
1948 if (Result.isInvalid()) {
1949 msg = 0;
1951 }
1952
1954 Kind = CK_ConstructorConversion;
1955 else
1956 Kind = CK_NoOp;
1957
1958 SrcExpr = Result;
1960}
1961
1962
1963
1965 QualType DestType, bool CStyle,
1966 unsigned &msg) {
1967 DestType = Self.Context.getCanonicalType(DestType);
1969 bool NeedToMaterializeTemporary = false;
1970
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1984
1985
1986
1987 msg = diag::err_bad_cxx_cast_rvalue;
1989 }
1990
1993
1994
1995 msg = diag::err_bad_cxx_cast_rvalue;
1997 }
1998
1999
2000
2001 NeedToMaterializeTemporary = true;
2002 }
2003
2004
2005
2006
2007
2008
2010 msg = diag::err_bad_cxx_cast_bitfield;
2012 }
2013
2014 DestType = Self.Context.getPointerType(DestTypeTmp->getPointeeType());
2015 SrcType = Self.Context.getPointerType(SrcType);
2016 }
2017
2018
2019
2020
2024
2025
2026
2027
2028
2029 if (!CStyle)
2030 msg = diag::err_bad_const_cast_dest;
2032 }
2035
2036
2037
2038 if (!CStyle)
2039 msg = diag::err_bad_const_cast_dest;
2041 }
2042
2043
2044
2045
2046
2047
2048
2049 if (.Context.hasCvrSimilarType(SrcType, DestType))
2051
2052 if (NeedToMaterializeTemporary)
2053
2054
2055 SrcExpr = Self.CreateMaterializeTemporaryExpr(SrcExpr.get()->getType(),
2056 SrcExpr.get(),
2057 false);
2058
2060}
2061
2062
2063
2064
2065
2066
2068 bool IsDereference,
2070 unsigned DiagID = IsDereference ?
2071 diag::warn_pointer_indirection_from_incompatible_type :
2072 diag::warn_undefined_reinterpret_cast;
2073
2074 if (Diags.isIgnored(DiagID, Range.getBegin()))
2075 return;
2076
2078 if (IsDereference) {
2080 return;
2081 }
2084 } else {
2086 return;
2087 }
2088 SrcTy = SrcType;
2090 }
2091
2092
2093 if (Context.hasSameUnqualifiedType(DestTy, SrcTy)) {
2094 return;
2095 }
2096
2099 return;
2100 }
2101
2104 return;
2105
2106
2109 if (Context.getTypeSize(DestTy) == Context.getTypeSize(SrcTy)) {
2110 return;
2111 }
2112 }
2113
2115 return;
2116 }
2117
2118 Diag(Range.getBegin(), DiagID) << SrcType << DestType << Range;
2119}
2120
2124 if (Self.Context.hasSameType(SrcType, DestType))
2125 return;
2127 if (SrcPtrTy->isObjCSelType()) {
2133 diag::warn_cast_pointer_from_sel)
2135 }
2136}
2137
2138
2139
2142 CastOperation::OpRangeType OpRange) {
2143
2144
2146 if (Self.Context.hasSameType(SrcType, DstType) ||
2148 return;
2149 const auto *SrcFTy =
2151 const auto *DstFTy =
2153 CallingConv SrcCC = SrcFTy->getCallConv();
2155 if (SrcCC == DstCC)
2156 return;
2157
2158
2159
2161 if (auto *UO = dyn_cast(Src))
2162 if (UO->getOpcode() == UO_AddrOf)
2164 auto *DRE = dyn_cast(Src);
2165 if (!DRE)
2166 return;
2167 auto *FD = dyn_cast(DRE->getDecl());
2168 if (!FD)
2169 return;
2170
2171
2172
2173
2174
2175 CallingConv DefaultCC = Self.getASTContext().getDefaultCallingConvention(
2176 FD->isVariadic(), FD->isCXXInstanceMember());
2177 if (DstCC == DefaultCC || SrcCC != DefaultCC)
2178 return;
2179
2180
2183 Self.Diag(OpRange.getBegin(), diag::warn_cast_calling_conv)
2184 << SrcCCName << DstCCName << OpRange;
2185
2186
2187
2188
2189 if (Self.Diags.isIgnored(diag::warn_cast_calling_conv, OpRange.getBegin()))
2190 return;
2191
2192
2193
2194
2195
2196 SourceLocation NameLoc = FD->getFirstDecl()->getNameInfo().getLoc();
2200 llvm::raw_svector_ostream OS(CCAttrText);
2201 if (Self.getLangOpts().MicrosoftExt) {
2202
2203 OS << "__" << DstCCName;
2205 AttrTokens.push_back(II->isKeyword(Self.getLangOpts())
2208 } else {
2209
2210 OS << "__attribute__((" << DstCCName << "))";
2211 AttrTokens.push_back(tok::kw___attribute);
2212 AttrTokens.push_back(tok::l_paren);
2213 AttrTokens.push_back(tok::l_paren);
2215 AttrTokens.push_back(II->isKeyword(Self.getLangOpts())
2218 AttrTokens.push_back(tok::r_paren);
2219 AttrTokens.push_back(tok::r_paren);
2220 }
2222 if (!AttrSpelling.empty())
2223 CCAttrText = AttrSpelling;
2224 OS << ' ';
2225 Self.Diag(NameLoc, diag::note_change_calling_conv_fixit)
2227}
2228
2233
2234
2235
2236
2241 && Self.Context.getTypeSize(DestType) >
2242 Self.Context.getTypeSize(SrcType)) {
2243
2244
2245
2246
2247
2249 diag::warn_int_to_void_pointer_cast
2250 : diag::warn_int_to_pointer_cast;
2251 Self.Diag(OpRange.getBegin(), Diag) << SrcType << DestType << OpRange;
2252 }
2253}
2254
2257
2258
2259
2260
2261
2262
2263 Expr *E = Result.get();
2264
2265
2266 if (Self.ResolveAndFixSingleFunctionTemplateSpecialization(
2267 Result,
2270 ) &&
2271 Result.isUsable())
2272 return true;
2273
2274
2275
2276 Result = E;
2277 if (.resolveAndFixAddressOfSingleOverloadCandidate(
2278 Result, true))
2279 return false;
2280 return Result.isUsable();
2281}
2282
2284 QualType DestType, bool CStyle,
2285 CastOperation::OpRangeType OpRange,
2286 unsigned &msg, CastKind &Kind) {
2287 bool IsLValueCast = false;
2288
2289 DestType = Self.Context.getCanonicalType(DestType);
2291
2292
2293
2294 if (SrcType == Self.Context.OverloadTy) {
2298
2299 assert(FixedExpr.isUsable() && "Invalid result fixing overloaded expr");
2300 SrcExpr = FixedExpr;
2302 }
2303
2306
2307
2308 msg = diag::err_bad_cxx_cast_rvalue;
2310 }
2311
2312 if (!CStyle) {
2313 Self.CheckCompatibleReinterpretCast(SrcType, DestType,
2314 false, OpRange);
2315 }
2316
2317
2318
2319
2320
2321 const char *inappropriate = nullptr;
2324 break;
2326 msg = diag::err_bad_cxx_cast_bitfield;
2328
2331 inappropriate = "matrix element";
2332 break;
2333 case OK_ObjCProperty: inappropriate = "property expression"; break;
2334 case OK_ObjCSubscript: inappropriate = "container subscripting expression";
2335 break;
2336 }
2337 if (inappropriate) {
2338 Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_reference)
2339 << inappropriate << DestType
2343 }
2344
2345
2346 DestType = Self.Context.getPointerType(DestTypeTmp->getPointeeType());
2347 SrcType = Self.Context.getPointerType(SrcType);
2348
2349 IsLValueCast = true;
2350 }
2351
2352
2353 SrcType = Self.Context.getCanonicalType(SrcType);
2354
2357 if (DestMemPtr && SrcMemPtr) {
2358
2359
2360
2361
2363 SrcMemPtr->isMemberFunctionPointer())
2365
2366 if (Self.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
2367
2368
2369 (void)Self.isCompleteType(OpRange.getBegin(), SrcType);
2370 (void)Self.isCompleteType(OpRange.getBegin(), DestType);
2371 }
2372
2373
2374 if (Self.Context.getTypeSize(DestMemPtr) !=
2375 Self.Context.getTypeSize(SrcMemPtr)) {
2376 msg = diag::err_bad_cxx_cast_member_pointer_size;
2378 }
2379
2380
2381
2382
2383
2384 if (auto CACK =
2386 CStyle))
2388
2389
2390 assert(!IsLValueCast);
2391 Kind = CK_ReinterpretMemberPointer;
2393 }
2394
2395
2397
2398
2399
2400
2401 if (Self.Context.getTypeSize(SrcType) >
2402 Self.Context.getTypeSize(DestType)) {
2403 msg = diag::err_bad_reinterpret_cast_small_int;
2405 }
2406 Kind = CK_PointerToIntegral;
2408 }
2409
2410
2411
2412 bool destIsVector = DestType->isVectorType();
2414 if (srcIsVector || destIsVector) {
2415
2416 if (Self.isValidSveBitcast(SrcType, DestType)) {
2417 Kind = CK_BitCast;
2419 }
2420
2421
2422 if (Self.RISCV().isValidRVVBitcast(SrcType, DestType)) {
2423 Kind = CK_BitCast;
2425 }
2426
2427
2428
2429
2433
2434
2435
2436 if (Self.areLaxCompatibleVectorTypes(SrcType, DestType)) {
2437 Kind = CK_BitCast;
2439 }
2440
2441 if (Self.LangOpts.OpenCL && !CStyle) {
2443
2444 if (Self.areVectorTypesSameSize(SrcType, DestType)) {
2445 Kind = CK_BitCast;
2447 }
2448 }
2449 }
2450
2451
2452 if (!destIsVector)
2453 msg = diag::err_bad_cxx_cast_vector_to_scalar_different_size;
2454 else if (!srcIsVector)
2455 msg = diag::err_bad_cxx_cast_scalar_to_vector_different_size;
2456 else
2457 msg = diag::err_bad_cxx_cast_vector_to_vector_different_size;
2458
2460 }
2461
2462 if (SrcType == DestType) {
2463
2464
2465
2466
2467
2468
2469
2470
2471 Kind = CK_NoOp;
2478 }
2479 return Result;
2480 }
2481
2486 if (!destIsPtr && !srcIsPtr) {
2487
2488
2490 }
2491
2493 assert(srcIsPtr && "One type must be a pointer");
2494
2495
2496
2497 if ((Self.Context.getTypeSize(SrcType) >
2498 Self.Context.getTypeSize(DestType))) {
2499 bool MicrosoftException =
2501 if (MicrosoftException) {
2503 ? diag::warn_void_pointer_to_int_cast
2504 : diag::warn_pointer_to_int_cast;
2505 Self.Diag(OpRange.getBegin(), Diag) << SrcType << DestType << OpRange;
2506 } else {
2507 msg = diag::err_bad_reinterpret_cast_small_int;
2509 }
2510 }
2511 Kind = CK_PointerToIntegral;
2513 }
2514
2516 assert(destIsPtr && "One type must be a pointer");
2518
2519
2520
2521
2522 Kind = CK_IntegralToPointer;
2524 }
2525
2526 if (!destIsPtr || !srcIsPtr) {
2527
2528
2530 }
2531
2532
2536
2537
2538
2540 if (auto CACK =
2542 CStyle))
2544
2546 Kind = CK_AddressSpaceConversion;
2548 if (!CStyle &&
2552 }
2553 } else if (IsLValueCast) {
2554 Kind = CK_LValueBitCast;
2556 Kind = Self.ObjC().PrepareCastToObjCObjectPointer(SrcExpr);
2559 Kind = CK_AnyPointerToBlockPointerCast;
2560 } else {
2561 Kind = CK_BitCast;
2562 }
2563 } else {
2564 Kind = CK_BitCast;
2565 }
2566
2567
2568
2570 return SuccessResult;
2571 }
2572 if (CStyle)
2574
2576
2577
2578
2579
2582
2583
2584 return SuccessResult;
2585 }
2586
2587
2588
2589
2590
2591
2592
2593 Self.Diag(OpRange.getBegin(),
2594 Self.getLangOpts().CPlusPlus11 ?
2595 diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)
2596 << OpRange;
2597 return SuccessResult;
2598 }
2599
2601
2602 Self.Diag(OpRange.getBegin(),
2603 Self.getLangOpts().CPlusPlus11 ?
2604 diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)
2605 << OpRange;
2606 return SuccessResult;
2607 }
2608
2609
2616 while (!DestPtee.isNull() && !SrcPtee.isNull()) {
2618 Self.Diag(OpRange.getBegin(),
2619 diag::warn_bad_cxx_cast_nested_pointer_addr_space)
2620 << CStyle << SrcType << DestType << SrcExpr.get()->getSourceRange();
2621 break;
2622 }
2625 }
2626
2627
2628
2629
2630
2631
2632 return SuccessResult;
2633}
2634
2636 QualType DestType, bool CStyle,
2637 unsigned &msg, CastKind &Kind) {
2638 if (.getLangOpts().OpenCL &&
.getLangOpts().SYCLIsDevice)
2639
2640
2642
2643
2644
2645 auto SrcType = SrcExpr.get()->getType();
2646
2647
2648
2650 if (!SrcPtrType)
2653 if (!DestPtrType)
2655 auto SrcPointeeType = SrcPtrType->getPointeeType();
2656 auto DestPointeeType = DestPtrType->getPointeeType();
2657 if (!DestPointeeType.isAddressSpaceOverlapping(SrcPointeeType,
2658 Self.getASTContext())) {
2659 msg = diag::err_bad_cxx_cast_addr_space_mismatch;
2661 }
2662 auto SrcPointeeTypeWithoutAS =
2663 Self.Context.removeAddrSpaceQualType(SrcPointeeType.getCanonicalType());
2664 auto DestPointeeTypeWithoutAS =
2665 Self.Context.removeAddrSpaceQualType(DestPointeeType.getCanonicalType());
2666 if (Self.Context.hasSameType(SrcPointeeTypeWithoutAS,
2667 DestPointeeTypeWithoutAS)) {
2668 Kind = SrcPointeeType.getAddressSpace() == DestPointeeType.getAddressSpace()
2669 ? CK_NoOp
2670 : CK_AddressSpaceConversion;
2672 } else {
2674 }
2675}
2676
2677void CastOperation::checkAddressSpaceCast(QualType SrcType, QualType DestType) {
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689 if (Self.getLangOpts().OpenCL) {
2690 const Type *DestPtr, *SrcPtr;
2691 bool Nested = false;
2692 unsigned DiagID = diag::err_typecheck_incompatible_address_space;
2693 DestPtr = Self.getASTContext().getCanonicalType(DestType.getTypePtr()),
2694 SrcPtr = Self.getASTContext().getCanonicalType(SrcType.getTypePtr());
2695
2701 if (Nested
2704 Self.getASTContext())) {
2705 Self.Diag(OpRange.getBegin(), DiagID)
2707 << SrcExpr.get()->getSourceRange();
2708 if (!Nested)
2710 return;
2711 }
2712
2715 Nested = true;
2716 DiagID = diag::ext_nested_pointer_qualifier_mismatch;
2717 }
2718 }
2719}
2720
2722 bool SrcCompatXL = this->getLangOpts().getAltivecSrcCompat() ==
2725
2729 return true;
2730 }
2731 return false;
2732}
2733
2736 bool SrcCompatGCC = this->getLangOpts().getAltivecSrcCompat() ==
2738 if (this->getLangOpts().AltiVec && SrcCompatGCC) {
2740 diag::err_invalid_conversion_between_vector_and_integer)
2741 << VecTy << SrcTy << R;
2742 return true;
2743 }
2744 return false;
2745}
2746
2747void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,
2748 bool ListInitialization) {
2749 assert(Self.getLangOpts().CPlusPlus);
2750
2751
2752 if (isPlaceholder()) {
2753
2754 if (claimPlaceholder(BuiltinType::UnknownAny)) {
2755 SrcExpr = Self.checkUnknownAnyCast(DestRange, DestType,
2756 SrcExpr.get(), Kind,
2757 ValueKind, BasePath);
2758 return;
2759 }
2760
2761 checkNonOverloadPlaceholders();
2762 if (SrcExpr.isInvalid())
2763 return;
2764 }
2765
2766
2767
2768
2770 Kind = CK_ToVoid;
2771
2772 if (claimPlaceholder(BuiltinType::Overload)) {
2773 Self.ResolveAndFixSingleFunctionTemplateSpecialization(
2774 SrcExpr, false,
2775 true, DestRange, DestType,
2776 diag::err_bad_cstyle_cast_overload);
2777 if (SrcExpr.isInvalid())
2778 return;
2779 }
2780
2781 SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());
2782 return;
2783 }
2784
2785
2786 if (DestType->isDependentType() || SrcExpr.get()->isTypeDependent() ||
2787 SrcExpr.get()->isValueDependent()) {
2788 assert(Kind == CK_Dependent);
2789 return;
2790 }
2791
2795 if (Self.getLangOpts().HLSL) {
2796 if (CheckHLSLCStyleCast(CCK))
2797 return;
2798 }
2799
2801 !isPlaceholder(BuiltinType::Overload)) {
2802 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
2803 if (SrcExpr.isInvalid())
2804 return;
2805 }
2806
2807
2809 if (Self.CheckAltivecInitFromScalar(OpRange, DestType,
2810 SrcExpr.get()->getType())) {
2812 return;
2813 }
2814 if (Self.ShouldSplatAltivecScalarInCast(vecTy) &&
2815 (SrcExpr.get()->getType()->isIntegerType() ||
2816 SrcExpr.get()->getType()->isFloatingType())) {
2817 Kind = CK_VectorSplat;
2818 SrcExpr = Self.prepareVectorSplat(DestType, SrcExpr.get());
2819 return;
2820 }
2821 }
2822
2823
2824 QualType SrcType = SrcExpr.get()->getType();
2826 Self.Diag(OpRange.getBegin(), diag::err_wasm_cast_table)
2827 << 1 << SrcExpr.get()->getSourceRange();
2829 return;
2830 }
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844 unsigned msg = diag::err_bad_cxx_cast_generic;
2846 true, msg);
2847 if (SrcExpr.isInvalid())
2848 return;
2850 Kind = CK_NoOp;
2851
2854 Kind);
2855 if (SrcExpr.isInvalid())
2856 return;
2857
2859
2860
2861 tcr = TryStaticCast(Self, SrcExpr, DestType, CCK, OpRange, msg, Kind,
2862 BasePath, ListInitialization);
2863 if (SrcExpr.isInvalid())
2864 return;
2865
2867
2869 OpRange, msg, Kind);
2870 if (SrcExpr.isInvalid())
2871 return;
2872 }
2873 }
2874 }
2875
2876 if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&
2878 checkObjCConversion(CCK);
2879
2880 if (tcr != TC_Success && msg != 0) {
2881 if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
2883 FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(),
2884 DestType,
2885 true,
2887 if (Fn) {
2888
2889
2890
2892 Self.Diag(OpRange.getBegin(), diag::err_bad_cstyle_cast_overload)
2893 << OE->getName() << DestType << OpRange
2895 Self.NoteAllOverloadCandidates(SrcExpr.get());
2896 }
2897 } else {
2899 OpRange, SrcExpr.get(), DestType, ListInitialization);
2900 }
2901 }
2902
2904 if (Kind == CK_BitCast)
2905 checkCastAlign();
2906
2908 Self.Diag(OpRange.getBegin(), DiagID)
2909 << SrcExpr.get()->getType() << DestType << OpRange;
2910
2911 } else {
2913 }
2914}
2915
2916
2917
2918
2920 assert(Self.getLangOpts().HLSL && "Must be HLSL!");
2921 QualType SrcTy = SrcExpr.get()->getType();
2922
2923
2924
2925 if (Self.HLSL().CanPerformElementwiseCast(SrcExpr.get(), DestType)) {
2927 SrcExpr = Self.ImpCastExprToType(
2928 SrcExpr.get(), Self.Context.getArrayParameterType(SrcTy),
2929 CK_HLSLArrayRValue, VK_PRValue, nullptr, CCK);
2930 else
2931 SrcExpr = Self.DefaultLvalueConversion(SrcExpr.get());
2932 Kind = CK_HLSLElementwiseCast;
2933 return true;
2934 }
2935
2936
2937
2938
2939 if (Self.HLSL().CanPerformAggregateSplatCast(SrcExpr.get(), DestType)) {
2940 SrcExpr = Self.DefaultLvalueConversion(SrcExpr.get());
2942
2944 SrcExpr = Self.ImpCastExprToType(
2945 SrcExpr.get(), VT->getElementType(), CK_HLSLVectorTruncation,
2946 SrcExpr.get()->getValueKind(), nullptr, CCK);
2947
2948
2950 SrcExpr = Self.ImpCastExprToType(
2951 SrcExpr.get(), DVT->getElementType(),
2952 Self.PrepareScalarCast(SrcExpr, DVT->getElementType()),
2953 SrcExpr.get()->getValueKind(), nullptr, CCK);
2954 Kind = CK_HLSLAggregateSplatCast;
2955 return true;
2956 }
2957
2958
2959
2961 Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_generic)
2962 << 4 << SrcTy << DestType;
2964 return true;
2965 }
2966 return false;
2967}
2968
2969
2970
2971
2974 if (Self.Diags.isIgnored(diag::warn_bad_function_cast,
2976 return;
2977
2979 return;
2980
2983 return;
2986 return;
2990 return;
2992 return;
2994 return;
2996 return;
2998 return;
3000 return;
3001
3003 diag::warn_bad_function_cast)
3005}
3006
3007
3008void CastOperation::CheckCStyleCast() {
3009 assert(.getLangOpts().CPlusPlus);
3010
3011
3012 if (claimPlaceholder(BuiltinType::UnknownAny)) {
3013 SrcExpr = Self.checkUnknownAnyCast(DestRange, DestType,
3014 SrcExpr.get(), Kind,
3015 ValueKind, BasePath);
3016 return;
3017 }
3018
3019
3020
3022
3023 SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());
3024 if (SrcExpr.isInvalid())
3025 return;
3026
3027
3028 Kind = CK_ToVoid;
3029 return;
3030 }
3031
3032
3033 if (Self.getASTContext().isDependenceAllowed() &&
3034 (DestType->isDependentType() || SrcExpr.get()->isTypeDependent() ||
3035 SrcExpr.get()->isValueDependent())) {
3036 assert((DestType->containsErrors() || SrcExpr.get()->containsErrors() ||
3037 SrcExpr.get()->containsErrors()) &&
3038 "should only occur in error-recovery path.");
3039 assert(Kind == CK_Dependent);
3040 return;
3041 }
3042
3043
3044 if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
3046 if (FunctionDecl *FD = Self.ResolveAddressOfOverloadedFunction(
3047 SrcExpr.get(), DestType, true, DAP))
3048 SrcExpr = Self.FixOverloadedFunctionReference(SrcExpr.get(), DAP, FD);
3049 else
3050 return;
3051 assert(SrcExpr.isUsable());
3052 }
3053 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
3054 if (SrcExpr.isInvalid())
3055 return;
3056 QualType SrcType = SrcExpr.get()->getType();
3057
3059 Self.Diag(OpRange.getBegin(), diag::err_wasm_cast_table)
3060 << 1 << SrcExpr.get()->getSourceRange();
3062 return;
3063 }
3064
3066
3067 checkAddressSpaceCast(SrcType, DestType);
3068 if (SrcExpr.isInvalid())
3069 return;
3070
3071 if (Self.RequireCompleteType(OpRange.getBegin(), DestType,
3072 diag::err_typecheck_cast_to_incomplete)) {
3074 return;
3075 }
3076
3077
3079 Self.Context.hasSameUnqualifiedType(DestType, SrcType)) {
3080 Kind = CK_NoOp;
3081 return;
3082 }
3083
3084
3086 Self.isValidSveBitcast(SrcType, DestType)) {
3087 Kind = CK_BitCast;
3088 return;
3089 }
3090
3091
3093 Self.RISCV().isValidRVVBitcast(SrcType, DestType)) {
3094 Kind = CK_BitCast;
3095 return;
3096 }
3097
3100 if (const RecordType *DestRecordTy =
3102 if (Self.Context.hasSameUnqualifiedType(DestType, SrcType)) {
3103
3104 Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_nonscalar)
3105 << DestType << SrcExpr.get()->getSourceRange();
3106 Kind = CK_NoOp;
3107 return;
3108 }
3109
3110
3113 SrcType)) {
3114 Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_to_union)
3115 << SrcExpr.get()->getSourceRange();
3116 Kind = CK_ToUnion;
3117 return;
3118 }
3119 Self.Diag(OpRange.getBegin(), diag::err_typecheck_cast_to_union_no_type)
3120 << SrcType << SrcExpr.get()->getSourceRange();
3122 return;
3123 }
3124 }
3125
3126
3127 if (Self.getLangOpts().OpenCL && DestType->isEventT()) {
3129 if (SrcExpr.get()->EvaluateAsInt(Result, Self.Context)) {
3130 llvm::APSInt CastInt = Result.Val.getInt();
3131 if (0 == CastInt) {
3132 Kind = CK_ZeroToOCLOpaqueType;
3133 return;
3134 }
3135 Self.Diag(OpRange.getBegin(),
3136 diag::err_opencl_cast_non_zero_to_event_t)
3137 << toString(CastInt, 10) << SrcExpr.get()->getSourceRange();
3139 return;
3140 }
3141 }
3142
3143
3144 Self.Diag(OpRange.getBegin(), diag::err_typecheck_cond_expect_scalar)
3145 << DestType << SrcExpr.get()->getSourceRange();
3147 return;
3148 }
3149
3150
3151
3152
3155 Self.Diag(SrcExpr.get()->getExprLoc(),
3156 diag::err_typecheck_expect_scalar_operand)
3157 << SrcType << SrcExpr.get()->getSourceRange();
3159 return;
3160 }
3161
3162
3163
3164
3165
3167
3168
3169
3172 Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_nullptr_cast)
3173 << 0 << DestType;
3175 return;
3176 }
3179 Self.Context, DestType, CK_PointerToBoolean, SrcExpr.get(), nullptr,
3181
3183
3184
3188 Self.CurFPFeatureOverrides());
3189 }
3190 }
3191
3193 if (!SrcExpr.get()->isNullPointerConstant(Self.Context,
3195 Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_nullptr_cast)
3196 << 1 << SrcType;
3198 return;
3199 }
3200
3201
3204 Self.CurFPFeatureOverrides());
3205 }
3206
3208 SrcExpr = Self.CheckExtVectorCast(OpRange, DestType, SrcExpr.get(), Kind);
3209 return;
3210 }
3211
3213 if (Self.CheckMatrixCast(OpRange, DestType, SrcType, Kind))
3215 return;
3216 }
3217
3219 if (Self.CheckAltivecInitFromScalar(OpRange, DestType, SrcType)) {
3221 return;
3222 }
3223 if (Self.ShouldSplatAltivecScalarInCast(DestVecTy) &&
3225 Kind = CK_VectorSplat;
3226 SrcExpr = Self.prepareVectorSplat(DestType, SrcExpr.get());
3227 } else if (Self.CheckVectorCast(OpRange, DestType, SrcType, Kind)) {
3229 }
3230 return;
3231 }
3232
3234 if (Self.CheckVectorCast(OpRange, SrcType, DestType, Kind))
3236 return;
3237 }
3238
3239
3240
3241
3242
3243
3245 Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_cast_selector_expr);
3247 return;
3248 }
3249
3250
3251
3254 Self.Diag(SrcExpr.get()->getExprLoc(),
3255 diag::err_cast_pointer_from_non_pointer_int)
3256 << SrcType << SrcExpr.get()->getSourceRange();
3258 return;
3259 }
3265 Self.Diag(SrcExpr.get()->getBeginLoc(),
3266 diag::err_cast_pointer_to_non_pointer_int)
3267 << DestType << SrcExpr.get()->getSourceRange();
3269 return;
3270 }
3271
3272 if ((Self.Context.getTypeSize(SrcType) >
3273 Self.Context.getTypeSize(DestType)) &&
3275
3276
3277
3278
3279
3280 unsigned Diag;
3282 Diag = DestType->isEnumeralType() ? diag::warn_void_pointer_to_enum_cast
3283 : diag::warn_void_pointer_to_int_cast;
3285 Diag = diag::warn_pointer_to_enum_cast;
3286 else
3287 Diag = diag::warn_pointer_to_int_cast;
3288 Self.Diag(OpRange.getBegin(), Diag) << SrcType << DestType << OpRange;
3289 }
3290 }
3291
3292 if (Self.getLangOpts().OpenCL && .getOpenCLOptions().isAvailableOption(
3293 "cl_khr_fp16", Self.getLangOpts())) {
3295 Self.Diag(SrcExpr.get()->getBeginLoc(), diag::err_opencl_cast_to_half)
3296 << DestType << SrcExpr.get()->getSourceRange();
3298 return;
3299 }
3300 }
3301
3302
3303 if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) {
3305 if (SrcExpr.isInvalid())
3306 return;
3307
3309 if (Self.getLangOpts().ObjCAutoRefCount && CastPtr) {
3312 Qualifiers ExprQuals = ExprPtr->getPointeeType().getQualifiers();
3314 ExprPtr->getPointeeType()->isObjCLifetimeType() &&
3316 Self.Diag(SrcExpr.get()->getBeginLoc(),
3317 diag::err_typecheck_incompatible_ownership)
3319 << SrcExpr.get()->getSourceRange();
3320 return;
3321 }
3322 }
3323 } else if (.ObjC().CheckObjCARCUnavailableWeakConversion(DestType,
3324 SrcType)) {
3325 Self.Diag(SrcExpr.get()->getBeginLoc(),
3326 diag::err_arc_convesion_of_weak_unavailable)
3327 << 1 << SrcType << DestType << SrcExpr.get()->getSourceRange();
3329 return;
3330 }
3331 }
3332
3334 Self.Diag(OpRange.getBegin(), DiagID) << SrcType << DestType << OpRange;
3335
3339
3342
3343 if (SrcRD && DestRD && SrcRD->hasAttr() &&
3344 SrcRD != DestRD) {
3345
3346 Self.Diag(OpRange.getBegin(), diag::err_cast_from_randomized_struct)
3347 << SrcType << DestType;
3349 return;
3350 }
3351 }
3352
3356 Kind = Self.PrepareScalarCast(SrcExpr, DestType);
3357 if (SrcExpr.isInvalid())
3358 return;
3359
3360 if (Kind == CK_BitCast)
3361 checkCastAlign();
3362}
3363
3364void CastOperation::CheckBuiltinBitCast() {
3365 QualType SrcType = SrcExpr.get()->getType();
3366
3367 if (Self.RequireCompleteType(OpRange.getBegin(), DestType,
3368 diag::err_typecheck_cast_to_incomplete) ||
3369 Self.RequireCompleteType(OpRange.getBegin(), SrcType,
3370 diag::err_incomplete_type)) {
3372 return;
3373 }
3374
3375 if (SrcExpr.get()->isPRValue())
3376 SrcExpr = Self.CreateMaterializeTemporaryExpr(SrcType, SrcExpr.get(),
3377 false);
3378
3379 CharUnits DestSize = Self.Context.getTypeSizeInChars(DestType);
3380 CharUnits SourceSize = Self.Context.getTypeSizeInChars(SrcType);
3381 if (DestSize != SourceSize) {
3382 Self.Diag(OpRange.getBegin(), diag::err_bit_cast_type_size_mismatch)
3383 << SrcType << DestType << (int)SourceSize.getQuantity()
3386 return;
3387 }
3388
3390 Self.Diag(OpRange.getBegin(), diag::err_bit_cast_non_trivially_copyable)
3391 << 1;
3393 return;
3394 }
3395
3397 Self.Diag(OpRange.getBegin(), diag::err_bit_cast_non_trivially_copyable)
3398 << 0;
3400 return;
3401 }
3402
3403 Kind = CK_LValueToRValueBitCast;
3404}
3405
3406
3407
3411 return;
3412
3416 return;
3417
3418 QualType TheOffendingSrcType, TheOffendingDestType;
3421 &TheOffendingSrcType, &TheOffendingDestType,
3422 &CastAwayQualifiers) !=
3423 CastAwayConstnessKind::CACK_Similar)
3424 return;
3425
3426
3427 int qualifiers = -1;
3428 if (CastAwayQualifiers.hasConst() && CastAwayQualifiers.hasVolatile()) {
3429 qualifiers = 0;
3430 } else if (CastAwayQualifiers.hasConst()) {
3431 qualifiers = 1;
3432 } else if (CastAwayQualifiers.hasVolatile()) {
3433 qualifiers = 2;
3434 }
3435
3436 if (qualifiers == -1)
3438 << SrcType << DestType;
3439 else
3441 << TheOffendingSrcType << TheOffendingDestType << qualifiers;
3442}
3443
3448 CastOperation Op(*this, CastTypeInfo->getType(), CastExpr);
3450 Op.OpRange = CastOperation::OpRangeType(LPLoc, LPLoc, CastExpr->getEndLoc());
3451
3453 Op.CheckCXXCStyleCast( false,
3455 } else {
3456 Op.CheckCStyleCast();
3457 }
3458
3461
3462
3464
3465 Op.checkQualifiedDestType();
3466
3468 Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
3470}
3471
3477 assert(LPLoc.isValid() && "List-initialization shouldn't get here.");
3480 Op.OpRange =
3481 CastOperation::OpRangeType(Op.DestRange.getBegin(), LPLoc, RPLoc);
3482
3483 Op.CheckCXXCStyleCast(true, false);
3486
3487 Op.checkQualifiedDestType();
3488
3489
3491
3493 Context, Op.ResultType, Op.ValueKind, CastTypeInfo, Op.Kind,
3495}
Defines the clang::ASTContext interface.
Defines the clang::Expr interface and subclasses for C++ expressions.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
Defines the clang::Preprocessor interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
static TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType, bool CStyle, CastOperation::OpRangeType OpRange, QualType OrigSrcType, QualType OrigDestType, unsigned &msg, CastKind &Kind, CXXCastPath &BasePath)
TryStaticDowncast - Common functionality of TryStaticReferenceDowncast and TryStaticPointerDowncast.
Definition SemaCast.cpp:1724
static CastAwayConstnessKind CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType, bool CheckCVR, bool CheckObjCLifetime, QualType *TheOffendingSrcType=nullptr, QualType *TheOffendingDestType=nullptr, Qualifiers *CastAwayQualifiers=nullptr)
Check if the pointer conversion from SrcType to DestType casts away constness as defined in C++ [expr...
Definition SemaCast.cpp:717
static TryCastResult TryStaticPointerDowncast(Sema &Self, QualType SrcType, QualType DestType, bool CStyle, CastOperation::OpRangeType OpRange, unsigned &msg, CastKind &Kind, CXXCastPath &BasePath)
Tests whether a conversion according to C++ 5.2.9p8 is valid.
Definition SemaCast.cpp:1690
static TryCastResult getCastAwayConstnessCastKind(CastAwayConstnessKind CACK, unsigned &DiagID)
Definition SemaCast.cpp:813
static bool IsAddressSpaceConversion(QualType SrcType, QualType DestType)
Definition SemaCast.cpp:1374
CastType
Definition SemaCast.cpp:49
@ CT_Reinterpret
reinterpret_cast
Definition SemaCast.cpp:52
@ CT_Functional
Type(expr)
Definition SemaCast.cpp:55
@ CT_Dynamic
dynamic_cast
Definition SemaCast.cpp:53
@ CT_Const
const_cast
Definition SemaCast.cpp:50
@ CT_CStyle
(Type)expr
Definition SemaCast.cpp:54
@ CT_Addrspace
addrspace_cast
Definition SemaCast.cpp:56
@ CT_Static
static_cast
Definition SemaCast.cpp:51
static TryCastResult TryConstCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, bool CStyle, unsigned &msg)
TryConstCast - See if a const_cast from source to destination is allowed, and perform it if it is.
Definition SemaCast.cpp:1964
static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, bool CStyle, CastOperation::OpRangeType OpRange, unsigned &msg, CastKind &Kind)
Definition SemaCast.cpp:2283
static bool isValidCast(TryCastResult TCR)
Definition SemaCast.cpp:45
static TryCastResult TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType, bool CStyle, CastOperation::OpRangeType OpRange, unsigned &msg, CastKind &Kind, CXXCastPath &BasePath)
Tests whether a conversion according to C++ 5.2.9p5 is valid.
Definition SemaCast.cpp:1652
static bool argTypeIsABIEquivalent(QualType SrcType, QualType DestType, ASTContext &Context)
Definition SemaCast.cpp:1136
static unsigned int checkCastFunctionType(Sema &Self, const ExprResult &SrcExpr, QualType DestType)
Definition SemaCast.cpp:1151
static TryCastResult TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType, bool CStyle, SourceRange OpRange, CastKind &Kind, CXXCastPath &BasePath, unsigned &msg)
Tests whether a conversion according to N2844 is valid.
Definition SemaCast.cpp:1600
TryCastResult
Definition SemaCast.cpp:36
@ TC_Success
The cast method is appropriate and successful.
Definition SemaCast.cpp:38
@ TC_Extension
The cast method is appropriate and accepted as a language extension.
Definition SemaCast.cpp:39
@ TC_Failed
The cast method is appropriate, but failed.
Definition SemaCast.cpp:41
@ TC_NotApplicable
The cast method is not applicable.
Definition SemaCast.cpp:37
static void DiagnoseReinterpretUpDownCast(Sema &Self, const Expr *SrcExpr, QualType DestType, CastOperation::OpRangeType OpRange)
Check that a reinterpret_cast(SrcExpr) is not used as upcast or downcast between respective...
Definition SemaCast.cpp:1045
static void DiagnoseCastQual(Sema &Self, const ExprResult &SrcExpr, QualType DestType)
DiagnoseCastQual - Warn whenever casts discards a qualifiers, be it either const, volatile or both.
Definition SemaCast.cpp:3408
static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, QualType SrcType, QualType DestType, bool CStyle, CastOperation::OpRangeType OpRange, unsigned &msg, CastKind &Kind, CXXCastPath &BasePath)
TryStaticMemberPointerUpcast - Tests whether a conversion according to C++ 5.2.9p9 is valid:
Definition SemaCast.cpp:1838
static void DiagnoseCallingConvCast(Sema &Self, const ExprResult &SrcExpr, QualType DstType, CastOperation::OpRangeType OpRange)
Diagnose casts that change the calling convention of a pointer to a function defined in the current T...
Definition SemaCast.cpp:2140
static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, CheckedConversionKind CCK, CastOperation::OpRangeType OpRange, unsigned &msg, CastKind &Kind, CXXCastPath &BasePath, bool ListInitialization)
TryStaticCast - Check if a static cast can be performed, and do so if possible.
Definition SemaCast.cpp:1388
static void DiagnoseCastOfObjCSEL(Sema &Self, const ExprResult &SrcExpr, QualType DestType)
Definition SemaCast.cpp:2121
static void DiagnoseBadFunctionCast(Sema &Self, const ExprResult &SrcExpr, QualType DestType)
DiagnoseBadFunctionCast - Warn whenever a function call is cast to a non-matching type.
Definition SemaCast.cpp:2972
static TryCastResult TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, CheckedConversionKind CCK, CastOperation::OpRangeType OpRange, unsigned &msg, CastKind &Kind, bool ListInitialization)
TryStaticImplicitCast - Tests whether a conversion according to C++ 5.2.9p2 is valid:
Definition SemaCast.cpp:1906
static bool fixOverloadedReinterpretCastExpr(Sema &Self, QualType DestType, ExprResult &Result)
Definition SemaCast.cpp:2255
static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT, CastOperation::OpRangeType range, Expr *src, QualType destType, bool listInitialization)
Try to diagnose a failed overloaded cast.
Definition SemaCast.cpp:460
static void diagnoseBadCast(Sema &S, unsigned msg, CastType castType, CastOperation::OpRangeType opRange, Expr *src, QualType destType, bool listInitialization)
Diagnose a failed cast.
Definition SemaCast.cpp:574
static CastAwayConstnessKind unwrapCastAwayConstnessLevel(ASTContext &Context, QualType &T1, QualType &T2)
Unwrap one level of types for CastsAwayConstness.
Definition SemaCast.cpp:639
static void checkIntToPointerCast(bool CStyle, const SourceRange &OpRange, const Expr *SrcExpr, QualType DestType, Sema &Self)
Definition SemaCast.cpp:2229
static TryCastResult TryAddressSpaceCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, bool CStyle, unsigned &msg, CastKind &Kind)
Definition SemaCast.cpp:2635
This file declares semantic analysis for HLSL constructs.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis functions specific to RISC-V.
static QualType getPointeeType(const MemRegion *R)
TextDiagnosticBuffer::DiagList DiagList
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const LangOptions & getLangOpts() const
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Represents a C++2a __builtin_bit_cast(T, v) expression.
static CStyleCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, FPOptionsOverride FPO, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation R)
static CXXAddrspaceCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind, Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets)
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
const RecordType * getDetectedVirtual() const
The virtual base discovered on the path (if we are merely detecting virtuals).
bool isRecordingPaths() const
Whether we are recording paths.
void setRecordingPaths(bool RP)
Specify whether we should be recording paths or not.
void clear()
Clear the base-paths results.
std::list< CXXBasePath >::const_iterator const_paths_iterator
bool isAmbiguous(CanQualType BaseType) const
Determine whether the path from the most-derived type to the given base type is ambiguous (i....
static CXXConstCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets)
static CXXDynamicCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets)
static CXXFunctionalCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, TypeSourceInfo *Written, CastKind Kind, Expr *Op, const CXXCastPath *Path, FPOptionsOverride FPO, SourceLocation LPLoc, SourceLocation RPLoc)
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Represents a C++ struct/union/class.
CXXRecordDecl * getDefinition() const
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
static CXXReinterpretCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets)
static CXXStaticCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written, FPOptionsOverride FPO, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets)
bool isAtLeastAsQualifiedAs(CanQual< T > Other, const ASTContext &Ctx) const
Determines whether this canonical type is at least as qualified as the Other canonical type.
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
CanProxy< U > getAs() const
Retrieve a canonical type pointer with a different static type, upcasting or downcasting as needed.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
static const FieldDecl * getTargetFieldForToUnionCast(QualType unionType, QualType opType)
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
A POD class for pairing a NamedDecl* with an access specifier.
bool isInvalidDecl() const
Information about one declarator, including the parsed type information and the identifier.
bool isInvalidType() const
bool isFixed() const
Returns true if this is an Objective-C, C++11, or Microsoft-style enumeration with a fixed underlying...
This represents one expression.
bool isIntegerConstantExpr(const ASTContext &Ctx) const
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
@ NPC_NeverValueDependent
Specifies that the expression should never be value-dependent.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
static ExprValueKind getValueKindForType(QualType T)
getValueKindForType - Given a formal return or parameter type, give its value kind.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
Represents a function declaration or definition.
Represents a prototype with parameter type info, e.g.
FunctionType - C99 6.7.5.3 - Function Declarators.
static StringRef getNameForCallConv(CallingConv CC)
CallingConv getCallConv() const
QualType getReturnType() const
One of these records is kept for each identifier that is lexed.
tok::TokenKind getTokenID() const
If this is a source-language token (e.g.
bool isKeyword(const LangOptions &LangOpts) const
Return true if this token is a keyword in the specified language.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
Describes the kind of initialization being performed, along with location information for tokens rela...
static InitializationKind CreateCast(SourceRange TypeRange)
Create a direct initialization due to a cast that isn't a C-style or functional cast.
static InitializationKind CreateFunctionalCast(SourceLocation StartLoc, SourceRange ParenRange, bool InitList)
Create a direct initialization for a functional cast.
static InitializationKind CreateCStyleCast(SourceLocation StartLoc, SourceRange TypeRange, bool InitList)
Create a direct initialization for a C-style cast.
Describes the sequence of initializations required to initialize a given object or reference with a s...
ExprResult Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType *ResultType=nullptr)
Perform the actual initialization of the given entity based on the computed initialization sequence.
FailureKind getFailureKind() const
Determine why initialization failed.
OverloadingResult getFailedOverloadResult() const
Get the overloading result, for when the initialization sequence failed due to a bad overload.
bool Failed() const
Determine whether the initialization sequence is invalid.
@ FK_UserConversionOverloadFailed
Overloading for a user-defined conversion failed.
@ FK_ConstructorOverloadFailed
Overloading for initialization by constructor failed.
@ FK_ParenthesizedListInitFailed
Parenthesized list initialization failed at some point.
bool isConstructorInitialization() const
Determine whether this initialization is direct call to a constructor.
OverloadCandidateSet & getFailedCandidateSet()
Retrieve a reference to the candidate set when overload resolution fails.
Describes an entity that is being initialized.
static InitializedEntity InitializeTemporary(QualType Type)
Create the initialization entity for a temporary.
Represents a matrix type, as defined in the Matrix Types clang extensions.
A pointer to member type per C++ 8.3.3 - Pointers to members.
bool isMemberFunctionPointer() const
Returns true if the member type (i.e.
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range covering the entirety of this nested-name-specifier.
OverloadCandidateSet - A set of overload candidates, used in C++ overload resolution (C++ 13....
SmallVectorImpl< OverloadCandidate >::iterator iterator
void NoteCandidates(PartialDiagnosticAt PA, Sema &S, OverloadCandidateDisplayKind OCD, ArrayRef< Expr * > Args, StringRef Opc="", SourceLocation Loc=SourceLocation(), llvm::function_ref< bool(OverloadCandidate &)> Filter=[](OverloadCandidate &) { return true;})
When overload resolution fails, prints diagnostic messages containing the candidates in the candidate...
OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc, OverloadCandidateSet::iterator &Best)
Find the best viable function on this overload set, if it exists.
A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr.
static FindResult find(Expr *E)
Finds the overloaded expression in the given expression E of OverloadTy.
NestedNameSpecifierLoc getQualifierLoc() const
Fetches the nested-name qualifier with source-location information, if one was given.
DeclarationName getName() const
Gets the name looked up.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
StringRef getLastMacroWithSpelling(SourceLocation Loc, ArrayRef< TokenValue > Tokens) const
Return the name of the macro defined before Loc that has spelling Tokens.
A (possibly-)qualified type.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type.
bool isAddressSpaceOverlapping(QualType T, const ASTContext &Ctx) const
Returns true if address space qualifiers overlap with T address space qualifiers.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
QualType withCVRQualifiers(unsigned CVR) const
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
bool isAtLeastAsQualifiedAs(QualType Other, const ASTContext &Ctx) const
Determine whether this type is at least as qualified as the other given type, requiring exact equalit...
The collection of all-type qualifiers we support.
unsigned getCVRQualifiers() const
void removeObjCLifetime()
bool compatiblyIncludes(Qualifiers other, const ASTContext &Ctx) const
Determines if these qualifiers compatibly include another set.
static bool isAddressSpaceSupersetOf(LangAS A, LangAS B, const ASTContext &Ctx)
Returns true if address space A is equal to or a superset of B.
static Qualifiers fromCVRMask(unsigned CVR)
bool compatiblyIncludesObjCLifetime(Qualifiers other) const
Determines if these qualifiers compatibly include another set of qualifiers from the narrow perspecti...
An rvalue reference type, per C++11 [dcl.ref].
Represents a struct/union/class.
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
Base for LValueReferenceType and RValueReferenceType.
QualType getPointeeType() const
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Sema - This implements semantic analysis and AST building for C.
ReferenceCompareResult
ReferenceCompareResult - Expresses the result of comparing two types (cv1 T1 and cv2 T2) to determine...
@ Ref_Incompatible
Ref_Incompatible - The two types are incompatible, so direct reference binding is not possible.
@ Ref_Compatible
Ref_Compatible - The two types are reference-compatible.
ExprResult BuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo, QualType Type, SourceLocation LParenLoc, Expr *CastExpr, SourceLocation RParenLoc)
Definition SemaCast.cpp:3472
ExprResult BuildBuiltinBitCastExpr(SourceLocation KWLoc, TypeSourceInfo *TSI, Expr *Operand, SourceLocation RParenLoc)
Definition SemaCast.cpp:438
FPOptionsOverride CurFPFeatureOverrides()
bool ShouldSplatAltivecScalarInCast(const VectorType *VecTy)
Definition SemaCast.cpp:2721
ExprResult ActOnBuiltinBitCastExpr(SourceLocation KWLoc, Declarator &Dcl, ExprResult Operand, SourceLocation RParenLoc)
Definition SemaCast.cpp:426
const LangOptions & getLangOpts() const
void CheckExtraCXXDefaultArguments(Declarator &D)
CheckExtraCXXDefaultArguments - Check for any extra default arguments in the declarator,...
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
Definition SemaCast.cpp:3444
ReferenceConversionsScope::ReferenceConversions ReferenceConversions
ExprResult ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, SourceLocation LAngleBracketLoc, Declarator &D, SourceLocation RAngleBracketLoc, SourceLocation LParenLoc, Expr *E, SourceLocation RParenLoc)
ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const,addrspace}_cast's.
Definition SemaCast.cpp:314
void DiscardMisalignedMemberAddress(const Type *T, Expr *E)
This function checks if the expression is in the sef of potentially misaligned members and it is conv...
void CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType, bool IsDereference, SourceRange Range)
Definition SemaCast.cpp:2067
TypeSourceInfo * GetTypeForDeclaratorCast(Declarator &D, QualType FromTy)
DiagnosticsEngine & Diags
ExprResult BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, TypeSourceInfo *Ty, Expr *E, SourceRange AngleBrackets, SourceRange Parens)
Definition SemaCast.cpp:337
bool CheckAltivecInitFromScalar(SourceRange R, QualType VecTy, QualType SrcTy)
Definition SemaCast.cpp:2734
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
SourceLocation getEndLoc() const LLVM_READONLY
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
StringRef getString() const
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Stores token information for comparing actual tokens with predefined values.
Base wrapper for a particular "section" of type source info.
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
SourceLocation getEndLoc() const
Get the end source location.
SourceLocation getBeginLoc() const
Get the begin source location.
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
bool isIncompleteOrObjectType() const
Return true if this is an incomplete or object type, in other words, not a function type.
bool isBlockPointerType() const
bool isBooleanType() const
bool isFunctionReferenceType() const
bool isPlaceholderType() const
Test for a type which does not represent an actual type-system type but is instead used as a placehol...
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
bool isRValueReferenceType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isConstantArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isVoidPointerType() const
bool isFunctionPointerType() const
bool isArithmeticType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs.
bool isReferenceType() const
bool isEnumeralType() const
bool isScalarType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isSizelessBuiltinType() const
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isExtVectorType() const
bool isAnyCharacterType() const
Determine whether this type is any of the built-in character types.
bool isLValueReferenceType() const
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
const BuiltinType * getAsPlaceholderType() const
bool isWebAssemblyTableType() const
Returns true if this is a WebAssembly table type: either an array of reference types,...
bool containsErrors() const
Whether this type is an error type.
bool isMemberPointerType() const
bool isMatrixType() const
EnumDecl * castAsEnumDecl() const
bool isComplexIntegerType() const
bool isObjCObjectType() const
bool isObjCLifetimeType() const
Returns true if objects of this type have lifetime semantics under ARC.
bool isFunctionType() const
bool isObjCObjectPointerType() const
bool isMemberFunctionPointerType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
bool isAnyPointerType() const
const T * getAs() const
Member-template getAs'.
bool isNullPtrType() const
bool isRecordType() const
bool isFunctionNoProtoType() const
Represents a GCC generic vector type.
unsigned getNumElements() const
VectorKind getVectorKind() const
QualType getElementType() const
Defines the clang::TargetInfo interface.
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang's AST.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
OverloadingResult
OverloadingResult - Capture the result of performing overload resolution.
@ OR_Deleted
Succeeded, but refers to a deleted function.
@ OR_Success
Overload resolution succeeded.
@ OR_Ambiguous
Ambiguous candidates found.
@ OR_No_Viable_Function
No viable function found.
OverloadCandidateDisplayKind
@ OCD_AmbiguousCandidates
Requests that only tied-for-best candidates be shown.
@ OCD_ViableCandidates
Requests that only viable candidates be shown.
@ OCD_AllCandidates
Requests that all candidates be shown.
@ OK_VectorComponent
A vector component is an element or range of elements on a vector.
@ OK_ObjCProperty
An Objective-C property is a logical field of an Objective-C object which is read and written via Obj...
@ OK_ObjCSubscript
An Objective-C array/dictionary subscripting which reads an object or writes at the subscripted array...
@ OK_Ordinary
An ordinary object is located at an address in memory.
@ OK_BitField
A bitfield object is a bitfield on a C or C++ record.
@ OK_MatrixComponent
A matrix component is a single element of a matrix.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ Result
The result type of a method or function.
const FunctionProtoType * T
CastKind
CastKind - The kind of operation required for a conversion.
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
SmallVector< CXXBaseSpecifier *, 4 > CXXCastPath
A simple array of base specifiers.
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ConceptReference *C)
Insertion operator for diagnostics.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ AltiVecBool
is AltiVec 'vector bool ...'
@ AltiVecVector
is AltiVec vector
@ AltiVecPixel
is AltiVec 'vector Pixel'
U cast(CodeGen::Address addr)
@ None
The alignment was not explicit in code.
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
ActionResult< Expr * > ExprResult
@ Parens
New-expression has a C++98 paren-delimited initializer.
CheckedConversionKind
The kind of conversion being performed.
@ CStyleCast
A C-style cast.
@ OtherCast
A cast other than a C-style cast.
@ FunctionalCast
A functional-style cast.
Represents an element in a path from a derived class to a base class.
EvalResult is a struct with detailed info about an evaluated expression.
OverloadExpr * Expression