30#include "llvm/ADT/SmallVector.h"
31#include "llvm/ADT/StringExtras.h"
61 struct CastOperation {
62 CastOperation(Sema &S, QualType destType,
ExprResult src)
63 :
Self(S), SrcExpr(src), DestType(destType),
66 Kind(CK_Dependent), IsARCUnbridgedCast(
false) {
80 !DestType->isArrayType() && !DestType.getPointerAuth()) {
81 DestType = DestType.getAtomicUnqualifiedType();
84 if (
const BuiltinType *placeholder =
86 PlaceholderKind = placeholder->getKind();
100 bool IsARCUnbridgedCast;
103 SourceLocation Locations[3];
105 OpRangeType(SourceLocation Begin, SourceLocation LParen,
106 SourceLocation RParen)
107 : Locations{Begin, LParen, RParen} {}
109 OpRangeType() =
default;
111 SourceLocation getBegin()
const {
return Locations[0]; }
113 SourceLocation getLParenLoc()
const {
return Locations[1]; }
115 SourceLocation getRParenLoc()
const {
return Locations[2]; }
117 friend const StreamingDiagnostic &
118 operator<<(
const StreamingDiagnostic &DB, OpRangeType Op) {
119 return DB << SourceRange(Op);
122 SourceRange getParenRange()
const {
123 return SourceRange(getLParenLoc(), getRParenLoc());
126 operator SourceRange()
const {
127 return SourceRange(getBegin(), getRParenLoc());
132 SourceRange DestRange;
135 void CheckConstCast();
136 void CheckReinterpretCast();
137 void CheckStaticCast();
138 void CheckDynamicCast();
139 void CheckCXXCStyleCast(
bool FunctionalCast,
bool ListInitialization);
141 void CheckCStyleCast();
142 void CheckBuiltinBitCast();
143 void CheckAddrspaceCast();
145 void updatePartOfExplicitCastFlags(
CastExpr *CE) {
149 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(CE->
getSubExpr()); CE = ICE)
150 ICE->setIsPartOfExplicitCast(
true);
158 if (IsARCUnbridgedCast) {
160 Self.Context, Self.Context.ARCUnbridgedCastTy, CK_Dependent,
162 Self.CurFPFeatureOverrides());
164 updatePartOfExplicitCastFlags(
castExpr);
174 if (PlaceholderKind != K)
return false;
180 bool isPlaceholder()
const {
181 return PlaceholderKind != 0;
184 return PlaceholderKind == K;
188 void checkAddressSpaceCast(QualType SrcType, QualType DestType);
190 void checkCastAlign() {
191 Self.CheckCastAlign(SrcExpr.get(), DestType, OpRange);
195 bool IsReinterpretCast =
false) {
196 assert(Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers());
198 Expr *src = SrcExpr.
get();
199 if (Self.ObjC().CheckObjCConversion(
200 OpRange, DestType, src, CCK,
true,
false, BO_PtrMemD,
202 IsARCUnbridgedCast =
true;
206 void checkQualifiedDestType() {
208 if (DestType.getPointerAuth()) {
209 Self.Diag(DestRange.getBegin(), diag::err_ptrauth_qualifier_cast)
210 << DestType << DestRange;
215 void checkNonOverloadPlaceholders() {
216 if (!isPlaceholder() || isPlaceholder(BuiltinType::Overload))
219 SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());
220 if (SrcExpr.isInvalid())
228 if (
const auto *PtrType = dyn_cast<PointerType>(FromType)) {
229 if (PtrType->getPointeeType()->hasAttr(attr::NoDeref)) {
230 if (
const auto *DestType = dyn_cast<PointerType>(ToType)) {
231 if (!DestType->getPointeeType()->hasAttr(attr::NoDeref)) {
232 S.
Diag(OpLoc, diag::warn_noderef_to_dereferenceable_pointer);
239 struct CheckNoDerefRAII {
240 CheckNoDerefRAII(CastOperation &Op) : Op(Op) {}
241 ~CheckNoDerefRAII() {
242 if (!Op.SrcExpr.isInvalid())
243 CheckNoDeref(Op.Self, Op.SrcExpr.get()->getType(), Op.ResultType,
244 Op.OpRange.getBegin());
272 bool CStyle, CastOperation::OpRangeType OpRange,
277 bool CStyle, CastOperation::OpRangeType OpRange,
281 CastOperation::OpRangeType OpRange,
283 QualType OrigDestType,
unsigned &msg,
288 CastOperation::OpRangeType OpRange,
unsigned &msg,
294 CastOperation::OpRangeType OpRange,
296 bool ListInitialization);
299 CastOperation::OpRangeType OpRange,
302 bool ListInitialization);
308 CastOperation::OpRangeType OpRange,
348 CastOperation Op(*
this, DestType, E);
350 CastOperation::OpRangeType(OpLoc,
Parens.getBegin(),
Parens.getEnd());
351 Op.DestRange = AngleBrackets;
353 Op.checkQualifiedDestType();
356 default: llvm_unreachable(
"Unknown C++ cast!");
358 case tok::kw_addrspace_cast:
359 if (!TypeDependent) {
360 Op.CheckAddrspaceCast();
365 Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.
get(),
366 DestTInfo, OpLoc,
Parens.getEnd(), AngleBrackets));
368 case tok::kw_const_cast:
369 if (!TypeDependent) {
376 Op.ValueKind, Op.SrcExpr.
get(), DestTInfo,
380 case tok::kw_dynamic_cast: {
383 return ExprError(
Diag(OpLoc, diag::err_openclcxx_not_supported)
387 if (!TypeDependent) {
388 Op.CheckDynamicCast();
393 Op.ValueKind, Op.Kind, Op.SrcExpr.
get(),
394 &Op.BasePath, DestTInfo,
398 case tok::kw_reinterpret_cast: {
399 if (!TypeDependent) {
400 Op.CheckReinterpretCast();
406 Op.ValueKind, Op.Kind, Op.SrcExpr.
get(),
407 nullptr, DestTInfo, OpLoc,
411 case tok::kw_static_cast: {
412 if (!TypeDependent) {
413 Op.CheckStaticCast();
420 Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.
get(),
422 Parens.getEnd(), AngleBrackets));
442 if (Operand->hasPlaceholderType()) {
449 CastOperation Op(*
this, TSI->
getType(), Operand);
450 Op.OpRange = CastOperation::OpRangeType(KWLoc, KWLoc, RParenLoc);
455 Op.CheckBuiltinBitCast();
462 Op.SrcExpr.
get(), TSI, KWLoc, RParenLoc);
463 return Op.complete(BCE);
469 CastOperation::OpRangeType range,
471 bool listInitialization) {
494 range.getBegin(), range, listInitialization)
497 range.getBegin(), range.getParenRange(), listInitialization)
508 default:
return false;
540 case OR_Success: llvm_unreachable(
"successful failed overload");
542 if (candidates.
empty())
543 msg = diag::err_ovl_no_conversion_in_cast;
545 msg = diag::err_ovl_no_viable_conversion_in_cast;
550 msg = diag::err_ovl_ambiguous_conversion_in_cast;
558 assert(Res ==
OR_Deleted &&
"Inconsistent overload resolution");
563 S.
PDiag(diag::err_ovl_deleted_conversion_in_cast)
564 << CT << srcType << destType << (Msg !=
nullptr)
565 << (Msg ? Msg->
getString() : StringRef())
574 S.
PDiag(msg) << CT << srcType << destType << range
576 S, howManyCandidates, src);
583 CastOperation::OpRangeType opRange,
Expr *src,
584 QualType destType,
bool listInitialization) {
585 if (msg == diag::err_bad_cxx_cast_generic &&
590 S.
Diag(opRange.getBegin(), msg) << castType
594 int DifferentPtrness = 0;
597 From = Ptr->getPointeeType();
602 To = Ptr->getPointeeType();
605 if (!DifferentPtrness) {
608 DeclFrom && DeclTo) {
609 if (!DeclFrom->isCompleteDefinition())
610 S.
Diag(DeclFrom->getLocation(), diag::note_type_incomplete) << DeclFrom;
611 if (!DeclTo->isCompleteDefinition())
612 S.
Diag(DeclTo->getLocation(), diag::note_type_incomplete) << DeclTo;
620enum CastAwayConstnessKind {
627 CACK_SimilarKind = 2,
646static CastAwayConstnessKind
648 enum {
None, Ptr, MemPtr, BlockPtr,
Array };
650 if (
T->isAnyPointerType())
return Ptr;
651 if (
T->isMemberPointerType())
return MemPtr;
652 if (
T->isBlockPointerType())
return BlockPtr;
655 if (
T->isConstantArrayType() ||
T->isIncompleteArrayType())
return Array;
660 if (
auto *AT = Context.getAsArrayType(
T))
661 return AT->getElementType();
662 return T->getPointeeType();
665 CastAwayConstnessKind Kind;
673 Kind = CastAwayConstnessKind::CACK_Similar;
674 }
else if (Context.UnwrapSimilarTypes(T1, T2)) {
675 Kind = CastAwayConstnessKind::CACK_Similar;
678 int T1Class = Classify(T1);
680 return CastAwayConstnessKind::CACK_None;
682 int T2Class = Classify(T2);
684 return CastAwayConstnessKind::CACK_None;
688 Kind = T1Class == T2Class ? CastAwayConstnessKind::CACK_SimilarKind
689 : CastAwayConstnessKind::CACK_Incoherent;
697 Context.UnwrapSimilarArrayTypes(T1, T2);
699 if (Classify(T1) !=
Array)
702 auto T2Class = Classify(T2);
706 if (T2Class !=
Array)
707 Kind = CastAwayConstnessKind::CACK_Incoherent;
708 else if (Kind != CastAwayConstnessKind::CACK_Incoherent)
709 Kind = CastAwayConstnessKind::CACK_SimilarKind;
724static CastAwayConstnessKind
726 bool CheckCVR,
bool CheckObjCLifetime,
727 QualType *TheOffendingSrcType =
nullptr,
728 QualType *TheOffendingDestType =
nullptr,
732 if (!CheckCVR && CheckObjCLifetime && !
Self.Context.getLangOpts().ObjC)
733 return CastAwayConstnessKind::CACK_None;
738 "Source type is not pointer or pointer to member.");
741 "Destination type is not pointer or pointer to member.");
744 QualType UnwrappedSrcType =
Self.Context.getCanonicalType(SrcType),
745 UnwrappedDestType =
Self.Context.getCanonicalType(DestType);
750 QualType PrevUnwrappedSrcType = UnwrappedSrcType;
751 QualType PrevUnwrappedDestType = UnwrappedDestType;
752 auto WorstKind = CastAwayConstnessKind::CACK_Similar;
753 bool AllConstSoFar =
true;
755 Self.Context, UnwrappedSrcType, UnwrappedDestType)) {
758 if (Kind > WorstKind)
763 Self.Context.getUnqualifiedArrayType(UnwrappedSrcType, SrcQuals);
764 Self.Context.getUnqualifiedArrayType(UnwrappedDestType, DestQuals);
770 UnwrappedDestType->isObjCObjectType())
779 if (SrcCvrQuals != DestCvrQuals) {
780 if (CastAwayQualifiers)
781 *CastAwayQualifiers = SrcCvrQuals - DestCvrQuals;
784 if (!DestCvrQuals.compatiblyIncludes(SrcCvrQuals,
785 Self.getASTContext())) {
786 if (TheOffendingSrcType)
787 *TheOffendingSrcType = PrevUnwrappedSrcType;
788 if (TheOffendingDestType)
789 *TheOffendingDestType = PrevUnwrappedDestType;
800 if (CheckObjCLifetime &&
806 if (AllConstSoFar && !DestQuals.
hasConst()) {
807 AllConstSoFar =
false;
808 if (TheOffendingSrcType)
809 *TheOffendingSrcType = PrevUnwrappedSrcType;
810 if (TheOffendingDestType)
811 *TheOffendingDestType = PrevUnwrappedDestType;
814 PrevUnwrappedSrcType = UnwrappedSrcType;
815 PrevUnwrappedDestType = UnwrappedDestType;
818 return CastAwayConstnessKind::CACK_None;
824 case CastAwayConstnessKind::CACK_None:
825 llvm_unreachable(
"did not cast away constness");
827 case CastAwayConstnessKind::CACK_Similar:
829 case CastAwayConstnessKind::CACK_SimilarKind:
830 DiagID = diag::err_bad_cxx_cast_qualifiers_away;
833 case CastAwayConstnessKind::CACK_Incoherent:
834 DiagID = diag::ext_bad_cxx_cast_qualifiers_away_incoherent;
838 llvm_unreachable(
"unexpected cast away constness kind");
844void CastOperation::CheckDynamicCast() {
845 CheckNoDerefRAII NoderefCheck(*
this);
848 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
849 else if (isPlaceholder())
850 SrcExpr =
Self.CheckPlaceholderExpr(SrcExpr.get());
851 if (SrcExpr.isInvalid())
854 QualType OrigSrcType = SrcExpr.get()->getType();
855 QualType DestType =
Self.Context.getCanonicalType(this->DestType);
868 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ref_or_ptr)
869 << this->DestType << DestRange;
874 const auto *DestRecord = DestPointee->
getAsCanonical<RecordType>();
876 assert(DestPointer &&
"Reference to void is not possible");
877 }
else if (DestRecord) {
878 if (
Self.RequireCompleteType(OpRange.getBegin(), DestPointee,
879 diag::err_bad_cast_incomplete,
885 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
895 QualType SrcType =
Self.Context.getCanonicalType(OrigSrcType);
901 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ptr)
902 << OrigSrcType << this->DestType << SrcExpr.get()->getSourceRange();
906 }
else if (DestReference->isLValueReferenceType()) {
907 if (!SrcExpr.get()->isLValue()) {
908 Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_rvalue)
909 <<
CT_Dynamic << OrigSrcType << this->DestType << OpRange;
911 SrcPointee = SrcType;
915 if (SrcExpr.get()->isPRValue())
916 SrcExpr =
Self.CreateMaterializeTemporaryExpr(
917 SrcType, SrcExpr.get(),
false);
918 SrcPointee = SrcType;
923 if (
Self.RequireCompleteType(OpRange.getBegin(), SrcPointee,
924 diag::err_bad_cast_incomplete,
930 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
936 assert((DestPointer || DestReference) &&
937 "Bad destination non-ptr/ref slipped through.");
938 assert((DestRecord || DestPointee->
isVoidType()) &&
939 "Bad destination pointee slipped through.");
940 assert(SrcRecord &&
"Bad source pointee slipped through.");
944 Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_qualifiers_away)
945 <<
CT_Dynamic << OrigSrcType << this->DestType << OpRange;
952 if (DestRecord == SrcRecord) {
960 Self.IsDerivedFrom(OpRange.getBegin(), SrcPointee, DestPointee)) {
961 if (
Self.CheckDerivedToBaseConversion(SrcPointee, DestPointee,
962 OpRange.getBegin(), OpRange,
968 Kind = CK_DerivedToBase;
974 assert(SrcDecl &&
"Definition missing");
976 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_polymorphic)
985 Self.Diag(OpRange.getBegin(), diag::err_no_dynamic_cast_with_fno_rtti);
991 if (!
Self.getLangOpts().RTTIData) {
993 Self.getASTContext().getTargetInfo().getCXXABI().isMicrosoft();
994 bool isClangCL =
Self.getDiagnostics().getDiagnosticOptions().getFormat() ==
996 if (MicrosoftABI || !DestPointee->
isVoidType())
997 Self.Diag(OpRange.getBegin(),
998 diag::warn_no_dynamic_cast_with_rtti_disabled)
1005 auto *DestDecl = DestRecord->getAsCXXRecordDecl();
1006 if (DestDecl->isEffectivelyFinal())
1007 Self.MarkVTableUsed(OpRange.getBegin(), DestDecl);
1019void CastOperation::CheckConstCast() {
1020 CheckNoDerefRAII NoderefCheck(*
this);
1023 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
1024 else if (isPlaceholder())
1025 SrcExpr =
Self.CheckPlaceholderExpr(SrcExpr.get());
1026 if (SrcExpr.isInvalid())
1029 unsigned msg = diag::err_bad_cxx_cast_generic;
1033 << SrcExpr.get()->getType() << DestType << OpRange;
1039void CastOperation::CheckAddrspaceCast() {
1040 unsigned msg = diag::err_bad_cxx_cast_generic;
1044 Self.Diag(OpRange.getBegin(), msg)
1045 <<
CT_Addrspace << SrcExpr.get()->getType() << DestType << OpRange;
1055 CastOperation::OpRangeType OpRange) {
1082 ReinterpretKind = ReinterpretUpcast;
1084 ReinterpretKind = ReinterpretDowncast;
1089 bool NonZeroOffset =
false;
1091 E = BasePaths.
end();
1095 bool IsVirtual =
false;
1096 for (CXXBasePath::const_iterator IElem = Path.begin(), EElem = Path.end();
1097 IElem != EElem; ++IElem) {
1098 IsVirtual = IElem->Base->isVirtual();
1101 const CXXRecordDecl *BaseRD = IElem->Base->getType()->getAsCXXRecordDecl();
1102 assert(BaseRD &&
"Base type should be a valid unqualified class type");
1107 if (Class->isInvalidDecl() || !ClassDefinition ||
1108 !ClassDefinition->isCompleteDefinition())
1112 Self.Context.getASTRecordLayout(Class);
1117 if (Offset.isZero())
1121 NonZeroOffset =
true;
1126 (void) NonZeroOffset;
1128 "Should have returned if has non-virtual base with zero offset");
1131 ReinterpretKind == ReinterpretUpcast? DestType : SrcType;
1133 ReinterpretKind == ReinterpretUpcast? SrcType : DestType;
1136 Self.Diag(BeginLoc, diag::warn_reinterpret_different_from_static)
1137 << DerivedType << BaseType << !
VirtualBase <<
int(ReinterpretKind)
1139 Self.Diag(BeginLoc, diag::note_reinterpret_updowncast_use_static)
1140 <<
int(ReinterpretKind)
1152 if (Context.getTypeSizeInChars(SrcType) ==
1153 Context.getTypeSizeInChars(DestType))
1156 return Context.hasSameUnqualifiedType(SrcType, DestType);
1161 unsigned int DiagID = 0;
1162 const unsigned int DiagList[] = {diag::warn_cast_function_type_strict,
1163 diag::warn_cast_function_type};
1188 assert(SrcFTy && DstFTy);
1190 if (
Self.Context.hasSameType(SrcFTy, DstFTy))
1194 if (DiagID == diag::warn_cast_function_type_strict)
1198 if (!
T->getReturnType()->isVoidType())
1201 return !PT->isVariadic() && PT->getNumParams() == 0;
1214 if (!
T->getReturnType()->isIntegerType())
1217 return !PT->isVariadic() && PT->getNumParams() == 0;
1222 if (IsVoidVoid(SrcFTy) || IsVoidVoid(DstFTy))
1228 if (
Self.getASTContext().getTargetInfo().getTriple().isOSWindows() &&
1248 unsigned NumParams = SrcFPTy->getNumParams();
1249 unsigned DstNumParams = DstFPTy->getNumParams();
1250 if (NumParams > DstNumParams) {
1251 if (!DstFPTy->isVariadic())
1253 NumParams = DstNumParams;
1254 }
else if (NumParams < DstNumParams) {
1255 if (!SrcFPTy->isVariadic())
1259 for (
unsigned i = 0; i < NumParams; ++i)
1261 DstFPTy->getParamType(i),
Self.Context))
1272void CastOperation::CheckReinterpretCast() {
1273 if (ValueKind ==
VK_PRValue && !isPlaceholder(BuiltinType::Overload))
1274 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
1276 checkNonOverloadPlaceholders();
1277 if (SrcExpr.isInvalid())
1280 unsigned msg = diag::err_bad_cxx_cast_generic;
1283 false, OpRange, msg, Kind);
1285 if (SrcExpr.isInvalid())
1287 if (SrcExpr.get()->getType() ==
Self.Context.OverloadTy) {
1289 Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_overload)
1291 << DestType << OpRange;
1292 Self.NoteAllOverloadCandidates(SrcExpr.get());
1301 if (
Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())
1307 Self.Diag(OpRange.getBegin(), DiagID)
1308 << SrcExpr.get()->getType() << DestType << OpRange;
1318void CastOperation::CheckStaticCast() {
1319 CheckNoDerefRAII NoderefCheck(*
this);
1321 if (isPlaceholder()) {
1322 checkNonOverloadPlaceholders();
1323 if (SrcExpr.isInvalid())
1333 if (claimPlaceholder(BuiltinType::Overload)) {
1334 Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr,
1337 OpRange, DestType, diag::err_bad_static_cast_overload);
1338 if (SrcExpr.isInvalid())
1342 SrcExpr =
Self.IgnoredValueConversions(SrcExpr.get());
1347 !isPlaceholder(BuiltinType::Overload)) {
1348 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
1349 if (SrcExpr.isInvalid())
1353 unsigned msg = diag::err_bad_cxx_cast_generic;
1356 OpRange, msg, Kind, BasePath,
false);
1358 if (SrcExpr.isInvalid())
1360 if (SrcExpr.get()->getType() ==
Self.Context.OverloadTy) {
1362 Self.Diag(OpRange.getBegin(), diag::err_bad_static_cast_overload)
1363 << oe->
getName() << DestType << OpRange
1365 Self.NoteAllOverloadCandidates(SrcExpr.get());
1373 if (Kind == CK_BitCast)
1375 if (
Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())
1390 DestPtrType->getPointeeType().getAddressSpace();
1398 CastOperation::OpRangeType OpRange,
1401 bool ListInitialization) {
1427 OpRange, msg, Kind, BasePath);
1435 Kind, BasePath, msg);
1442 Kind, ListInitialization);
1463 if (
const EnumType *
Enum = dyn_cast<EnumType>(SrcType)) {
1464 if (
Enum->getDecl()->isScoped()) {
1466 Kind = CK_IntegralToBoolean;
1469 Kind = CK_IntegralCast;
1472 Kind = CK_IntegralToFloating;
1487 if (
Self.RequireCompleteType(OpRange.getBegin(), DestType,
1488 diag::err_bad_cast_incomplete)) {
1498 bool DestIsFixedBoolean =
1499 ED->
isFixed() && ED->getIntegerType()->isBooleanType();
1501 Kind = DestIsFixedBoolean ? CK_IntegralToBoolean : CK_IntegralCast;
1508 Kind = DestIsFixedBoolean ? CK_FloatingToBoolean : CK_FloatingToIntegral;
1524 OpRange, msg, Kind, BasePath);
1547 if (DestPointeeQuals != SrcPointeeQuals &&
1549 Self.getASTContext())) {
1550 msg = diag::err_bad_cxx_cast_qualifiers_away;
1555 ? CK_AddressSpaceConversion
1562 if (!CStyle &&
Self.getLangOpts().MSVCCompat &&
1564 Self.Diag(OpRange.getBegin(), diag::ext_ms_cast_fn_obj) << OpRange;
1572 Kind = CK_CPointerToObjCPointerCast;
1577 Kind = CK_AnyPointerToBlockPointerCast;
1591 Self.ObjC().CheckTollFreeBridgeStaticCast(DestType, SrcExpr.
get(), Kind))
1598 if (SrcPointer->getPointeeType()->isRecordType() &&
1600 msg = diag::err_bad_cxx_cast_unrelated_class;
1603 if (
Self.CheckMatrixCast(OpRange, DestType, SrcType, Kind)) {
1610 if (SrcType ==
Self.Context.AMDGPUFeaturePredicateTy &&
1611 DestType ==
Self.Context.getLogicalOperationType()) {
1612 SrcExpr =
Self.AMDGPU().ExpandAMDGPUPredicateBuiltIn(SrcExpr.
get());
1639 QualType ToType = R->getPointeeType();
1647 SrcExpr->
getBeginLoc(), ToType, FromType, &RefConv);
1654 msg = SrcExpr->
isLValue() ? diag::err_bad_lvalue_to_rvalue_cast
1655 : diag::err_bad_rvalue_to_rvalue_cast;
1659 if (RefConv & Sema::ReferenceConversions::DerivedToBase) {
1660 Kind = CK_DerivedToBase;
1661 if (
Self.CheckDerivedToBaseConversion(FromType, ToType,
1663 &BasePath, CStyle)) {
1676 CastOperation::OpRangeType OpRange,
1689 if (!DestReference) {
1693 if (!RValueRef && !SrcExpr->
isLValue()) {
1695 msg = diag::err_bad_cxx_cast_rvalue;
1705 Self.Context.getCanonicalType(SrcExpr->
getType()),
1706 Self.Context.getCanonicalType(DestPointee), CStyle,
1707 OpRange, SrcExpr->
getType(), DestType, msg, Kind,
1714 CastOperation::OpRangeType OpRange,
1732 msg = diag::err_bad_static_cast_pointer_nonpointer;
1739 CStyle, OpRange, SrcType, DestType, msg, Kind,
1748 CastOperation::OpRangeType OpRange,
1753 if (!
Self.isCompleteType(OpRange.getBegin(), SrcType) ||
1754 !
Self.isCompleteType(OpRange.getBegin(), DestType))
1758 if (!DestType->
getAs<RecordType>() || !SrcType->
getAs<RecordType>()) {
1764 if (!
Self.IsDerivedFrom(OpRange.getBegin(), DestType, SrcType, Paths)) {
1789 msg = diag::err_bad_cxx_cast_qualifiers_away;
1801 Self.IsDerivedFrom(OpRange.getBegin(), DestType, SrcType, Paths);
1803 std::string PathDisplayStr;
1804 std::set<unsigned> DisplayedPaths;
1806 if (DisplayedPaths.insert(Path.back().SubobjectNumber).second) {
1809 PathDisplayStr +=
"\n ";
1811 PathDisplayStr += PE.Base->getType().getAsString() +
" -> ";
1816 Self.Diag(OpRange.getBegin(), diag::err_ambiguous_base_to_derived_cast)
1819 << PathDisplayStr << OpRange;
1826 Self.Diag(OpRange.getBegin(), diag::err_static_downcast_via_virtual)
1827 << OrigSrcType << OrigDestType <<
VirtualBase << OpRange;
1833 switch (
Self.CheckBaseClassAccess(OpRange.getBegin(),
1836 diag::err_downcast_from_inaccessible_base)) {
1848 Self.BuildBasePathArray(Paths, BasePath);
1849 Kind = CK_BaseToDerived;
1863 CastOperation::OpRangeType OpRange,
1870 bool WasOverloadedFunction =
false;
1874 =
Self.ResolveAddressOfOverloadedFunction(SrcExpr.
get(), DestType,
false,
1877 SrcType =
Self.Context.getMemberPointerType(
1878 Fn->getType(), std::nullopt, M->
getParent());
1879 WasOverloadedFunction =
true;
1883 switch (
Self.CheckMemberPointerConversion(
1884 SrcType, DestMemPtr, Kind, BasePath, OpRange.getBegin(), OpRange, CStyle,
1887 if (Kind == CK_NullToMemberPointer) {
1888 msg = diag::err_bad_static_cast_member_pointer_nonmp;
1902 if (WasOverloadedFunction) {
1914 SrcExpr =
Self.FixOverloadedFunctionReference(SrcExpr, FoundOverload, Fn);
1931 CastOperation::OpRangeType OpRange,
1933 bool ListInitialization) {
1935 if (
Self.RequireCompleteType(OpRange.getBegin(), DestType,
1936 diag::err_bad_cast_incomplete) ||
1937 Self.RequireNonAbstractType(OpRange.getBegin(), DestType,
1938 diag::err_allocation_of_abstract_type)) {
1951 OpRange.getBegin(), OpRange.getParenRange(), ListInitialization)
1953 Expr *SrcExprRaw = SrcExpr.
get();
1970 if (
Result.isInvalid()) {
1976 Kind = CK_ConstructorConversion;
1989 DestType =
Self.Context.getCanonicalType(DestType);
1991 bool NeedToMaterializeTemporary =
false;
2009 msg = diag::err_bad_cxx_cast_rvalue;
2017 msg = diag::err_bad_cxx_cast_rvalue;
2023 NeedToMaterializeTemporary =
true;
2032 msg = diag::err_bad_cxx_cast_bitfield;
2036 DestType =
Self.Context.getPointerType(DestTypeTmp->getPointeeType());
2037 SrcType =
Self.Context.getPointerType(SrcType);
2052 msg = diag::err_bad_const_cast_dest;
2061 msg = diag::err_bad_const_cast_dest;
2071 if (!
Self.Context.hasCvrSimilarType(SrcType, DestType))
2074 if (NeedToMaterializeTemporary)
2077 SrcExpr =
Self.CreateMaterializeTemporaryExpr(SrcExpr.
get()->
getType(),
2092 unsigned DiagID = IsDereference ?
2093 diag::warn_pointer_indirection_from_incompatible_type :
2094 diag::warn_undefined_reinterpret_cast;
2096 if (
Diags.isIgnored(DiagID, Range.getBegin()))
2100 if (IsDereference) {
2115 if (
Context.hasSameUnqualifiedType(DestTy, SrcTy)) {
2140 Diag(Range.getBegin(), DiagID) << SrcType << DestType << Range;
2146 if (
Self.Context.hasSameType(SrcType, DestType))
2149 if (SrcPtrTy->isObjCSelType()) {
2155 diag::warn_cast_pointer_from_sel)
2164 CastOperation::OpRangeType OpRange) {
2168 if (
Self.Context.hasSameType(SrcType, DstType) ||
2171 const auto *SrcFTy =
2173 const auto *DstFTy =
2183 if (
auto *UO = dyn_cast<UnaryOperator>(Src))
2184 if (UO->getOpcode() == UO_AddrOf)
2186 auto *DRE = dyn_cast<DeclRefExpr>(Src);
2189 auto *FD = dyn_cast<FunctionDecl>(DRE->getDecl());
2197 CallingConv DefaultCC =
Self.getASTContext().getDefaultCallingConvention(
2198 FD->isVariadic(), FD->isCXXInstanceMember());
2199 if (DstCC == DefaultCC || SrcCC != DefaultCC)
2205 Self.Diag(OpRange.getBegin(), diag::warn_cast_calling_conv)
2206 << SrcCCName << DstCCName << OpRange;
2211 if (
Self.Diags.isIgnored(diag::warn_cast_calling_conv, OpRange.getBegin()))
2218 SourceLocation NameLoc = FD->getFirstDecl()->getNameInfo().getLoc();
2222 llvm::raw_svector_ostream OS(CCAttrText);
2223 if (
Self.getLangOpts().MicrosoftExt) {
2225 OS <<
"__" << DstCCName;
2232 OS <<
"__attribute__((" << DstCCName <<
"))";
2233 AttrTokens.push_back(tok::kw___attribute);
2234 AttrTokens.push_back(tok::l_paren);
2235 AttrTokens.push_back(tok::l_paren);
2240 AttrTokens.push_back(tok::r_paren);
2241 AttrTokens.push_back(tok::r_paren);
2244 if (!AttrSpelling.empty())
2245 CCAttrText = AttrSpelling;
2247 Self.Diag(NameLoc, diag::note_change_calling_conv_fixit)
2263 &&
Self.Context.getTypeSize(DestType) >
2264 Self.Context.getTypeSize(SrcType)) {
2271 diag::warn_int_to_void_pointer_cast
2272 : diag::warn_int_to_pointer_cast;
2288 if (
Self.ResolveAndFixSingleFunctionTemplateSpecialization(
2299 if (!
Self.resolveAndFixAddressOfSingleOverloadCandidate(
2302 return Result.isUsable();
2307 CastOperation::OpRangeType OpRange,
2309 bool IsLValueCast =
false;
2311 DestType =
Self.Context.getCanonicalType(DestType);
2316 if (SrcType ==
Self.Context.OverloadTy) {
2321 assert(FixedExpr.
isUsable() &&
"Invalid result fixing overloaded expr");
2322 SrcExpr = FixedExpr;
2330 msg = diag::err_bad_cxx_cast_rvalue;
2335 Self.CheckCompatibleReinterpretCast(SrcType, DestType,
2343 const char *inappropriate =
nullptr;
2348 msg = diag::err_bad_cxx_cast_bitfield;
2353 inappropriate =
"matrix element";
2356 case OK_ObjCSubscript: inappropriate =
"container subscripting expression";
2359 if (inappropriate) {
2360 Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_reference)
2361 << inappropriate << DestType
2368 DestType =
Self.Context.getPointerType(DestTypeTmp->getPointeeType());
2369 SrcType =
Self.Context.getPointerType(SrcType);
2371 IsLValueCast =
true;
2375 SrcType =
Self.Context.getCanonicalType(SrcType);
2379 if (DestMemPtr && SrcMemPtr) {
2385 SrcMemPtr->isMemberFunctionPointer())
2388 if (
Self.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
2391 (void)
Self.isCompleteType(OpRange.getBegin(), SrcType);
2392 (void)
Self.isCompleteType(OpRange.getBegin(), DestType);
2396 if (
Self.Context.getTypeSize(DestMemPtr) !=
2397 Self.Context.getTypeSize(SrcMemPtr)) {
2398 msg = diag::err_bad_cxx_cast_member_pointer_size;
2412 assert(!IsLValueCast);
2413 Kind = CK_ReinterpretMemberPointer;
2423 if (
Self.Context.getTypeSize(SrcType) >
2424 Self.Context.getTypeSize(DestType)) {
2425 msg = diag::err_bad_reinterpret_cast_small_int;
2428 Kind = CK_PointerToIntegral;
2436 if (srcIsVector || destIsVector) {
2438 if (
Self.isValidSveBitcast(SrcType, DestType)) {
2444 if (
Self.RISCV().isValidRVVBitcast(SrcType, DestType)) {
2458 if (
Self.areLaxCompatibleVectorTypes(SrcType, DestType)) {
2463 if (
Self.LangOpts.OpenCL && !CStyle) {
2466 if (
Self.areVectorTypesSameSize(SrcType, DestType)) {
2475 msg = diag::err_bad_cxx_cast_vector_to_scalar_different_size;
2476 else if (!srcIsVector)
2477 msg = diag::err_bad_cxx_cast_scalar_to_vector_different_size;
2479 msg = diag::err_bad_cxx_cast_vector_to_vector_different_size;
2484 if (SrcType == DestType) {
2508 if (!destIsPtr && !srcIsPtr) {
2515 assert(srcIsPtr &&
"One type must be a pointer");
2519 if ((
Self.Context.getTypeSize(SrcType) >
2520 Self.Context.getTypeSize(DestType))) {
2521 bool MicrosoftException =
2523 if (MicrosoftException) {
2525 ? diag::warn_void_pointer_to_int_cast
2526 : diag::warn_pointer_to_int_cast;
2527 Self.Diag(OpRange.getBegin(),
Diag) << SrcType << DestType << OpRange;
2529 msg = diag::err_bad_reinterpret_cast_small_int;
2533 Kind = CK_PointerToIntegral;
2538 assert(destIsPtr &&
"One type must be a pointer");
2544 Kind = CK_IntegralToPointer;
2548 if (!destIsPtr || !srcIsPtr) {
2568 Kind = CK_AddressSpaceConversion;
2575 }
else if (IsLValueCast) {
2576 Kind = CK_LValueBitCast;
2578 Kind =
Self.ObjC().PrepareCastToObjCObjectPointer(SrcExpr);
2581 Kind = CK_AnyPointerToBlockPointerCast;
2592 return SuccessResult;
2606 return SuccessResult;
2615 Self.Diag(OpRange.getBegin(),
2616 Self.getLangOpts().CPlusPlus11 ?
2617 diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)
2619 return SuccessResult;
2624 Self.Diag(OpRange.getBegin(),
2625 Self.getLangOpts().CPlusPlus11 ?
2626 diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)
2628 return SuccessResult;
2640 Self.Diag(OpRange.getBegin(),
2641 diag::warn_bad_cxx_cast_nested_pointer_addr_space)
2654 return SuccessResult;
2660 if (!
Self.getLangOpts().OpenCL && !
Self.getLangOpts().SYCLIsDevice)
2677 auto SrcPointeeType = SrcPtrType->getPointeeType();
2678 auto DestPointeeType = DestPtrType->getPointeeType();
2679 if (!DestPointeeType.isAddressSpaceOverlapping(SrcPointeeType,
2680 Self.getASTContext())) {
2681 msg = diag::err_bad_cxx_cast_addr_space_mismatch;
2684 auto SrcPointeeTypeWithoutAS =
2685 Self.Context.removeAddrSpaceQualType(SrcPointeeType.getCanonicalType());
2686 auto DestPointeeTypeWithoutAS =
2687 Self.Context.removeAddrSpaceQualType(DestPointeeType.getCanonicalType());
2688 if (
Self.Context.hasSameType(SrcPointeeTypeWithoutAS,
2689 DestPointeeTypeWithoutAS)) {
2690 Kind = SrcPointeeType.getAddressSpace() == DestPointeeType.getAddressSpace()
2692 : CK_AddressSpaceConversion;
2699void CastOperation::checkAddressSpaceCast(
QualType SrcType,
QualType DestType) {
2711 if (
Self.getLangOpts().OpenCL) {
2712 const Type *DestPtr, *SrcPtr;
2713 bool Nested =
false;
2714 unsigned DiagID = diag::err_typecheck_incompatible_address_space;
2715 DestPtr =
Self.getASTContext().getCanonicalType(DestType.
getTypePtr()),
2716 SrcPtr =
Self.getASTContext().getCanonicalType(SrcType.
getTypePtr());
2726 Self.getASTContext())) {
2727 Self.Diag(OpRange.getBegin(), DiagID)
2729 << SrcExpr.get()->getSourceRange();
2738 DiagID = diag::ext_nested_pointer_qualifier_mismatch;
2744 bool SrcCompatXL = this->
getLangOpts().getAltivecSrcCompat() ==
2758 bool SrcCompatGCC = this->
getLangOpts().getAltivecSrcCompat() ==
2760 if (this->
getLangOpts().AltiVec && SrcCompatGCC) {
2762 diag::err_invalid_conversion_between_vector_and_integer)
2763 << VecTy << SrcTy << R;
2769void CastOperation::CheckCXXCStyleCast(
bool FunctionalStyle,
2770 bool ListInitialization) {
2771 assert(
Self.getLangOpts().CPlusPlus);
2774 if (isPlaceholder()) {
2776 if (claimPlaceholder(BuiltinType::UnknownAny)) {
2777 SrcExpr =
Self.checkUnknownAnyCast(DestRange, DestType,
2778 SrcExpr.get(), Kind,
2779 ValueKind, BasePath);
2783 checkNonOverloadPlaceholders();
2784 if (SrcExpr.isInvalid())
2794 if (claimPlaceholder(BuiltinType::Overload)) {
2795 Self.ResolveAndFixSingleFunctionTemplateSpecialization(
2797 true, DestRange, DestType,
2798 diag::err_bad_cstyle_cast_overload);
2799 if (SrcExpr.isInvalid())
2803 SrcExpr =
Self.IgnoredValueConversions(SrcExpr.get());
2808 if (DestType->
isDependentType() || SrcExpr.get()->isTypeDependent() ||
2809 SrcExpr.get()->isValueDependent()) {
2810 assert(Kind == CK_Dependent);
2817 if (
Self.getLangOpts().HLSL) {
2818 if (CheckHLSLCStyleCast(CCK))
2823 !isPlaceholder(BuiltinType::Overload)) {
2824 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
2825 if (SrcExpr.isInvalid())
2831 if (
Self.CheckAltivecInitFromScalar(OpRange, DestType,
2832 SrcExpr.get()->getType())) {
2836 if (
Self.ShouldSplatAltivecScalarInCast(vecTy) &&
2837 (SrcExpr.get()->getType()->isIntegerType() ||
2838 SrcExpr.get()->getType()->isFloatingType())) {
2839 Kind = CK_VectorSplat;
2840 SrcExpr =
Self.prepareVectorSplat(DestType, SrcExpr.get());
2846 QualType SrcType = SrcExpr.get()->getType();
2848 Self.Diag(OpRange.getBegin(), diag::err_wasm_cast_table)
2849 << 1 << SrcExpr.get()->getSourceRange();
2866 unsigned msg = diag::err_bad_cxx_cast_generic;
2869 if (SrcExpr.isInvalid())
2877 if (SrcExpr.isInvalid())
2884 BasePath, ListInitialization);
2885 if (SrcExpr.isInvalid())
2891 OpRange, msg, Kind);
2892 if (SrcExpr.isInvalid())
2898 if (
Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&
2900 checkObjCConversion(CCK);
2903 if (SrcExpr.get()->getType() ==
Self.Context.OverloadTy) {
2914 Self.Diag(OpRange.getBegin(), diag::err_bad_cstyle_cast_overload)
2915 << OE->
getName() << DestType << OpRange
2917 Self.NoteAllOverloadCandidates(SrcExpr.get());
2921 OpRange, SrcExpr.get(), DestType, ListInitialization);
2926 if (Kind == CK_BitCast)
2930 Self.Diag(OpRange.getBegin(), DiagID)
2931 << SrcExpr.get()->getType() << DestType << OpRange;
2942 assert(
Self.getLangOpts().HLSL &&
"Must be HLSL!");
2943 QualType SrcTy = SrcExpr.get()->getType();
2947 if (
Self.HLSL().CanPerformElementwiseCast(SrcExpr.get(), DestType)) {
2949 SrcExpr =
Self.ImpCastExprToType(
2950 SrcExpr.get(),
Self.Context.getArrayParameterType(SrcTy),
2951 CK_HLSLArrayRValue,
VK_PRValue,
nullptr, CCK);
2953 SrcExpr =
Self.DefaultLvalueConversion(SrcExpr.get());
2954 Kind = CK_HLSLElementwiseCast;
2961 if (
Self.HLSL().CanPerformAggregateSplatCast(SrcExpr.get(), DestType)) {
2962 SrcExpr =
Self.DefaultLvalueConversion(SrcExpr.get());
2967 SrcExpr =
Self.ImpCastExprToType(
2969 SrcExpr.get()->getValueKind(),
nullptr, CCK);
2971 else if (MT && MT->getNumElementsFlattened() == 1)
2972 SrcExpr =
Self.ImpCastExprToType(
2973 SrcExpr.get(), MT->getElementType(), CK_HLSLMatrixTruncation,
2974 SrcExpr.get()->getValueKind(),
nullptr, CCK);
2978 SrcExpr =
Self.ImpCastExprToType(
2979 SrcExpr.get(), DVT->getElementType(),
2980 Self.PrepareScalarCast(SrcExpr, DVT->getElementType()),
2981 SrcExpr.get()->getValueKind(),
nullptr, CCK);
2982 Kind = CK_HLSLAggregateSplatCast;
2989 Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_generic)
2990 << 4 << SrcTy << DestType;
3002 if (
Self.Diags.isIgnored(diag::warn_bad_function_cast,
3031 diag::warn_bad_function_cast)
3036void CastOperation::CheckCStyleCast() {
3037 assert(!
Self.getLangOpts().CPlusPlus);
3040 if (claimPlaceholder(BuiltinType::UnknownAny)) {
3041 SrcExpr =
Self.checkUnknownAnyCast(DestRange, DestType,
3042 SrcExpr.get(), Kind,
3043 ValueKind, BasePath);
3051 SrcExpr =
Self.IgnoredValueConversions(SrcExpr.get());
3052 if (SrcExpr.isInvalid())
3061 if (
Self.getASTContext().isDependenceAllowed() &&
3063 SrcExpr.get()->isValueDependent())) {
3064 assert((DestType->
containsErrors() || SrcExpr.get()->containsErrors() ||
3065 SrcExpr.get()->containsErrors()) &&
3066 "should only occur in error-recovery path.");
3067 assert(Kind == CK_Dependent);
3072 if (SrcExpr.get()->getType() ==
Self.Context.OverloadTy) {
3075 SrcExpr.get(), DestType,
true, DAP))
3076 SrcExpr =
Self.FixOverloadedFunctionReference(SrcExpr.get(), DAP, FD);
3079 assert(SrcExpr.isUsable());
3081 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
3082 if (SrcExpr.isInvalid())
3084 QualType SrcType = SrcExpr.get()->getType();
3087 Self.Diag(OpRange.getBegin(), diag::err_wasm_cast_table)
3088 << 1 << SrcExpr.get()->getSourceRange();
3095 checkAddressSpaceCast(SrcType, DestType);
3096 if (SrcExpr.isInvalid())
3099 if (
Self.RequireCompleteType(OpRange.getBegin(), DestType,
3100 diag::err_typecheck_cast_to_incomplete)) {
3107 Self.Context.hasSameUnqualifiedType(DestType, SrcType)) {
3114 Self.isValidSveBitcast(SrcType, DestType)) {
3121 Self.RISCV().isValidRVVBitcast(SrcType, DestType)) {
3128 if (
const RecordType *DestRecordTy =
3130 if (
Self.Context.hasSameUnqualifiedType(DestType, SrcType)) {
3132 Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_nonscalar)
3133 << DestType << SrcExpr.get()->getSourceRange();
3142 Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_to_union)
3143 << SrcExpr.get()->getSourceRange();
3147 Self.Diag(OpRange.getBegin(), diag::err_typecheck_cast_to_union_no_type)
3148 << SrcType << SrcExpr.get()->getSourceRange();
3155 if (
Self.getLangOpts().OpenCL && DestType->
isEventT()) {
3157 if (SrcExpr.get()->EvaluateAsInt(
Result,
Self.Context)) {
3158 llvm::APSInt CastInt =
Result.Val.getInt();
3160 Kind = CK_ZeroToOCLOpaqueType;
3163 Self.Diag(OpRange.getBegin(),
3164 diag::err_opencl_cast_non_zero_to_event_t)
3165 <<
toString(CastInt, 10) << SrcExpr.get()->getSourceRange();
3172 Self.Diag(OpRange.getBegin(), diag::err_typecheck_cond_expect_scalar)
3173 << DestType << SrcExpr.get()->getSourceRange();
3183 Self.Diag(SrcExpr.get()->getExprLoc(),
3184 diag::err_typecheck_expect_scalar_operand)
3185 << SrcType << SrcExpr.get()->getSourceRange();
3200 Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_nullptr_cast)
3207 Self.Context, DestType, CK_PointerToBoolean, SrcExpr.get(),
nullptr,
3216 Self.CurFPFeatureOverrides());
3221 if (!SrcExpr.get()->isNullPointerConstant(
Self.Context,
3223 Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_nullptr_cast)
3232 Self.CurFPFeatureOverrides());
3236 SrcExpr =
Self.CheckExtVectorCast(OpRange, DestType, SrcExpr.get(), Kind);
3241 if (
Self.CheckMatrixCast(OpRange, DestType, SrcType, Kind))
3247 if (
Self.CheckAltivecInitFromScalar(OpRange, DestType, SrcType)) {
3251 if (
Self.ShouldSplatAltivecScalarInCast(DestVecTy) &&
3253 Kind = CK_VectorSplat;
3254 SrcExpr =
Self.prepareVectorSplat(DestType, SrcExpr.get());
3255 }
else if (
Self.CheckVectorCast(OpRange, DestType, SrcType, Kind)) {
3262 if (
Self.CheckVectorCast(OpRange, SrcType, DestType, Kind))
3273 Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_cast_selector_expr);
3282 Self.Diag(SrcExpr.get()->getExprLoc(),
3283 diag::err_cast_pointer_from_non_pointer_int)
3284 << SrcType << SrcExpr.get()->getSourceRange();
3293 Self.Diag(SrcExpr.get()->getBeginLoc(),
3294 diag::err_cast_pointer_to_non_pointer_int)
3295 << DestType << SrcExpr.get()->getSourceRange();
3300 if ((
Self.Context.getTypeSize(SrcType) >
3301 Self.Context.getTypeSize(DestType)) &&
3311 : diag::warn_void_pointer_to_int_cast;
3313 Diag = diag::warn_pointer_to_enum_cast;
3315 Diag = diag::warn_pointer_to_int_cast;
3316 Self.Diag(OpRange.getBegin(),
Diag) << SrcType << DestType << OpRange;
3320 if (
Self.getLangOpts().OpenCL && !
Self.getOpenCLOptions().isAvailableOption(
3321 "cl_khr_fp16",
Self.getLangOpts())) {
3323 Self.Diag(SrcExpr.get()->getBeginLoc(), diag::err_opencl_cast_to_half)
3324 << DestType << SrcExpr.get()->getSourceRange();
3331 if (
Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) {
3333 if (SrcExpr.isInvalid())
3337 if (
Self.getLangOpts().ObjCAutoRefCount && CastPtr) {
3340 Qualifiers ExprQuals = ExprPtr->getPointeeType().getQualifiers();
3342 ExprPtr->getPointeeType()->isObjCLifetimeType() &&
3344 Self.Diag(SrcExpr.get()->getBeginLoc(),
3345 diag::err_typecheck_incompatible_ownership)
3347 << SrcExpr.get()->getSourceRange();
3351 }
else if (!
Self.ObjC().CheckObjCARCUnavailableWeakConversion(DestType,
3353 Self.Diag(SrcExpr.get()->getBeginLoc(),
3354 diag::err_arc_convesion_of_weak_unavailable)
3355 << 1 << SrcType << DestType << SrcExpr.get()->getSourceRange();
3362 Self.Diag(OpRange.getBegin(), DiagID) << SrcType << DestType << OpRange;
3371 if (SrcRD && DestRD && SrcRD->
hasAttr<RandomizeLayoutAttr>() &&
3374 Self.Diag(OpRange.getBegin(), diag::err_cast_from_randomized_struct)
3375 << SrcType << DestType;
3384 Kind =
Self.PrepareScalarCast(SrcExpr, DestType);
3385 if (SrcExpr.isInvalid())
3388 if (Kind == CK_BitCast)
3392void CastOperation::CheckBuiltinBitCast() {
3393 QualType SrcType = SrcExpr.get()->getType();
3395 if (
Self.RequireCompleteType(OpRange.getBegin(), DestType,
3396 diag::err_typecheck_cast_to_incomplete) ||
3397 Self.RequireCompleteType(OpRange.getBegin(), SrcType,
3398 diag::err_incomplete_type)) {
3403 if (SrcExpr.get()->isPRValue())
3404 SrcExpr =
Self.CreateMaterializeTemporaryExpr(SrcType, SrcExpr.get(),
3407 CharUnits DestSize =
Self.Context.getTypeSizeInChars(DestType);
3408 CharUnits SourceSize =
Self.Context.getTypeSizeInChars(SrcType);
3409 if (DestSize != SourceSize) {
3410 Self.Diag(OpRange.getBegin(), diag::err_bit_cast_type_size_mismatch)
3418 Self.Diag(OpRange.getBegin(), diag::err_bit_cast_non_trivially_copyable)
3425 Self.Diag(OpRange.getBegin(), diag::err_bit_cast_non_trivially_copyable)
3431 Kind = CK_LValueToRValueBitCast;
3446 QualType TheOffendingSrcType, TheOffendingDestType;
3449 &TheOffendingSrcType, &TheOffendingDestType,
3450 &CastAwayQualifiers) !=
3451 CastAwayConstnessKind::CACK_Similar)
3455 int qualifiers = -1;
3458 }
else if (CastAwayQualifiers.
hasConst()) {
3464 if (qualifiers == -1)
3466 << SrcType << DestType;
3469 << TheOffendingSrcType << TheOffendingDestType << qualifiers;
3481 Op.CheckCXXCStyleCast(
false,
3484 Op.CheckCStyleCast();
3493 Op.checkQualifiedDestType();
3496 Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.
get(),
3505 assert(LPLoc.
isValid() &&
"List-initialization shouldn't get here.");
3509 CastOperation::OpRangeType(Op.DestRange.
getBegin(), LPLoc, RPLoc);
3511 Op.CheckCXXCStyleCast(
true,
false);
3515 Op.checkQualifiedDestType();
3521 Context, Op.ResultType, Op.ValueKind, CastTypeInfo, Op.Kind,
Defines the clang::ASTContext interface.
Defines the clang::Expr interface and subclasses for C++ expressions.
Result
Implement __builtin_bit_cast and related operations.
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.
This file declares semantic analysis functions specific to AMDGPU.
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.
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...
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.
static TryCastResult getCastAwayConstnessCastKind(CastAwayConstnessKind CACK, unsigned &DiagID)
static bool IsAddressSpaceConversion(QualType SrcType, QualType DestType)
@ CT_Reinterpret
reinterpret_cast
@ CT_Functional
Type(expr)
@ CT_Addrspace
addrspace_cast
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.
static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, bool CStyle, CastOperation::OpRangeType OpRange, unsigned &msg, CastKind &Kind)
static bool isValidCast(TryCastResult TCR)
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.
static bool argTypeIsABIEquivalent(QualType SrcType, QualType DestType, ASTContext &Context)
static unsigned int checkCastFunctionType(Sema &Self, const ExprResult &SrcExpr, QualType DestType)
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.
@ TC_Success
The cast method is appropriate and successful.
@ TC_Extension
The cast method is appropriate and accepted as a language extension.
@ TC_Failed
The cast method is appropriate, but failed.
@ TC_NotApplicable
The cast method is not applicable.
static void DiagnoseReinterpretUpDownCast(Sema &Self, const Expr *SrcExpr, QualType DestType, CastOperation::OpRangeType OpRange)
Check that a reinterpret_cast<DestType>(SrcExpr) is not used as upcast or downcast between respective...
static void DiagnoseCastQual(Sema &Self, const ExprResult &SrcExpr, QualType DestType)
DiagnoseCastQual - Warn whenever casts discards a qualifiers, be it either const, volatile or both.
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:
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...
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.
static void DiagnoseCastOfObjCSEL(Sema &Self, const ExprResult &SrcExpr, QualType DestType)
static void DiagnoseBadFunctionCast(Sema &Self, const ExprResult &SrcExpr, QualType DestType)
DiagnoseBadFunctionCast - Warn whenever a function call is cast to a non-matching type.
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:
static bool fixOverloadedReinterpretCastExpr(Sema &Self, QualType DestType, ExprResult &Result)
static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT, CastOperation::OpRangeType range, Expr *src, QualType destType, bool listInitialization)
Try to diagnose a failed overloaded cast.
static void diagnoseBadCast(Sema &S, unsigned msg, CastType castType, CastOperation::OpRangeType opRange, Expr *src, QualType destType, bool listInitialization)
Diagnose a failed cast.
static CastAwayConstnessKind unwrapCastAwayConstnessLevel(ASTContext &Context, QualType &T1, QualType &T2)
Unwrap one level of types for CastsAwayConstness.
static void checkIntToPointerCast(bool CStyle, const SourceRange &OpRange, const Expr *SrcExpr, QualType DestType, Sema &Self)
static TryCastResult TryAddressSpaceCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, bool CStyle, unsigned &msg, CastKind &Kind)
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.
Represents a concrete matrix type with constant number of rows and columns.
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)
ExprResult BuildBuiltinBitCastExpr(SourceLocation KWLoc, TypeSourceInfo *TSI, Expr *Operand, SourceLocation RParenLoc)
FPOptionsOverride CurFPFeatureOverrides()
bool ShouldSplatAltivecScalarInCast(const VectorType *VecTy)
ExprResult ActOnBuiltinBitCastExpr(SourceLocation KWLoc, Declarator &Dcl, ExprResult Operand, SourceLocation RParenLoc)
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)
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.
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
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)
TypeSourceInfo * GetTypeForDeclaratorCast(Declarator &D, QualType FromTy)
DiagnosticsEngine & Diags
ExprResult BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, TypeSourceInfo *Ty, Expr *E, SourceRange AngleBrackets, SourceRange Parens)
bool CheckAltivecInitFromScalar(SourceRange R, QualType VecTy, QualType SrcTy)
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<specific type>.
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<specific type>'.
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.
Top level wrappers for InstallAPI frontend operations.
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 of 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 or range of elements 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