26 #include "llvm/ADT/SmallVector.h"
28 using namespace clang;
49 struct CastOperation {
51 : Self(S), SrcExpr(src), DestType(destType),
57 src.
get()->getType()->getAsPlaceholderType()) {
58 PlaceholderKind = placeholder->getKind();
72 bool IsARCUnbridgedCast;
78 void CheckConstCast();
79 void CheckReinterpretCast();
80 void CheckStaticCast();
81 void CheckDynamicCast();
82 void CheckCXXCStyleCast(
bool FunctionalCast,
bool ListInitialization);
83 void CheckCStyleCast();
90 if (IsARCUnbridgedCast) {
92 Self.Context.ARCUnbridgedCastTy,
105 if (PlaceholderKind != K)
return false;
111 bool isPlaceholder()
const {
112 return PlaceholderKind != 0;
115 return PlaceholderKind == K;
118 void checkCastAlign() {
119 Self.CheckCastAlign(SrcExpr.get(), DestType, OpRange);
123 assert(Self.getLangOpts().ObjCAutoRefCount);
126 if (Self.CheckObjCARCConversion(OpRange, DestType, src, CCK) ==
128 IsARCUnbridgedCast =
true;
133 void checkNonOverloadPlaceholders() {
134 if (!isPlaceholder() || isPlaceholder(BuiltinType::Overload))
137 SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());
138 if (SrcExpr.isInvalid())
177 QualType OrigDestType,
unsigned &msg,
193 bool ListInitialization);
200 bool ListInitialization);
246 CastOperation Op(*
this, DestType, E);
248 Op.DestRange = AngleBrackets;
251 default: llvm_unreachable(
"Unknown C++ cast!");
253 case tok::kw_const_cast:
254 if (!TypeDependent) {
256 if (Op.SrcExpr.isInvalid())
260 Op.ValueKind, Op.SrcExpr.get(), DestTInfo,
264 case tok::kw_dynamic_cast: {
265 if (!TypeDependent) {
266 Op.CheckDynamicCast();
267 if (Op.SrcExpr.isInvalid())
271 Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
272 &Op.BasePath, DestTInfo,
276 case tok::kw_reinterpret_cast: {
277 if (!TypeDependent) {
278 Op.CheckReinterpretCast();
279 if (Op.SrcExpr.isInvalid())
283 Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
284 nullptr, DestTInfo, OpLoc,
288 case tok::kw_static_cast: {
289 if (!TypeDependent) {
290 Op.CheckStaticCast();
291 if (Op.SrcExpr.isInvalid())
296 Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
297 &Op.BasePath, DestTInfo,
309 bool listInitialization) {
331 range, listInitialization)
337 assert(sequence.
Failed() &&
"initialization succeeded on second try?");
339 default:
return false;
352 case OR_Success: llvm_unreachable(
"successful failed overload");
354 if (candidates.
empty())
355 msg = diag::err_ovl_no_conversion_in_cast;
357 msg = diag::err_ovl_no_viable_conversion_in_cast;
362 msg = diag::err_ovl_ambiguous_conversion_in_cast;
367 msg = diag::err_ovl_deleted_conversion_in_cast;
373 << CT << srcType << destType
374 << range << src->getSourceRange();
384 bool listInitialization) {
385 if (msg == diag::err_bad_cxx_cast_generic &&
391 << src->
getType() << destType << opRange << src->getSourceRange();
394 int DifferentPtrness = 0;
405 if (!DifferentPtrness) {
408 if (RecFrom && RecTo) {
410 if (!DeclFrom->isCompleteDefinition())
411 S.
Diag(DeclFrom->getLocation(), diag::note_type_incomplete)
412 << DeclFrom->getDeclName();
414 if (!DeclTo->isCompleteDefinition())
415 S.
Diag(DeclTo->getLocation(), diag::note_type_incomplete)
416 << DeclTo->getDeclName();
429 if (T1PtrType && T2PtrType) {
444 else if (T2PtrType) {
450 else if (T2ObjCPtrType) {
460 if (T1MPType && T2MPType) {
468 if (T1BPType && T2BPType) {
487 bool CheckCVR,
bool CheckObjCLifetime,
488 QualType *TheOffendingSrcType =
nullptr,
489 QualType *TheOffendingDestType =
nullptr,
493 if (!CheckCVR && CheckObjCLifetime &&
503 "Source type is not pointer or pointer to member.");
506 "Destination type is not pointer or pointer to member.");
515 QualType PrevUnwrappedSrcType = UnwrappedSrcType;
516 QualType PrevUnwrappedDestType = UnwrappedDestType;
523 Qualifiers RetainedSrcQuals, RetainedDestQuals;
528 if (RetainedSrcQuals != RetainedDestQuals && TheOffendingSrcType &&
529 TheOffendingDestType && CastAwayQualifiers) {
530 *TheOffendingSrcType = PrevUnwrappedSrcType;
531 *TheOffendingDestType = PrevUnwrappedDestType;
532 *CastAwayQualifiers = RetainedSrcQuals - RetainedDestQuals;
536 if (CheckObjCLifetime &&
540 cv1.push_back(RetainedSrcQuals);
541 cv2.push_back(RetainedDestQuals);
543 PrevUnwrappedSrcType = UnwrappedSrcType;
544 PrevUnwrappedDestType = UnwrappedDestType;
556 i1 != cv1.rend(); ++i1, ++i2) {
564 bool ObjCLifetimeConversion;
565 return SrcConstruct != DestConstruct &&
567 ObjCLifetimeConversion);
573 void CastOperation::CheckDynamicCast() {
575 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
576 else if (isPlaceholder())
577 SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());
578 if (SrcExpr.isInvalid())
581 QualType OrigSrcType = SrcExpr.get()->getType();
595 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ref_or_ptr)
596 << this->DestType << DestRange;
603 assert(DestPointer &&
"Reference to void is not possible");
604 }
else if (DestRecord) {
605 if (Self.RequireCompleteType(OpRange.getBegin(), DestPointee,
606 diag::err_bad_dynamic_cast_incomplete,
612 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
628 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ptr)
629 << OrigSrcType << SrcExpr.get()->getSourceRange();
633 }
else if (DestReference->isLValueReferenceType()) {
634 if (!SrcExpr.get()->isLValue()) {
635 Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_rvalue)
636 <<
CT_Dynamic << OrigSrcType << this->DestType << OpRange;
638 SrcPointee = SrcType;
642 if (SrcExpr.get()->isRValue())
644 SrcType, SrcExpr.get(),
false);
645 SrcPointee = SrcType;
650 if (Self.RequireCompleteType(OpRange.getBegin(), SrcPointee,
651 diag::err_bad_dynamic_cast_incomplete,
657 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
663 assert((DestPointer || DestReference) &&
664 "Bad destination non-ptr/ref slipped through.");
665 assert((DestRecord || DestPointee->
isVoidType()) &&
666 "Bad destination pointee slipped through.");
667 assert(SrcRecord &&
"Bad source pointee slipped through.");
671 Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_qualifiers_away)
672 <<
CT_Dynamic << OrigSrcType << this->DestType << OpRange;
679 if (DestRecord == SrcRecord) {
686 if (DestRecord && Self.IsDerivedFrom(SrcPointee, DestPointee)) {
687 if (Self.CheckDerivedToBaseConversion(SrcPointee, DestPointee,
688 OpRange.getBegin(), OpRange,
700 assert(SrcDecl &&
"Definition missing");
701 if (!cast<CXXRecordDecl>(SrcDecl)->isPolymorphic()) {
702 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_polymorphic)
710 if (!Self.getLangOpts().RTTI && !DestPointee->
isVoidType()) {
711 Self.Diag(OpRange.getBegin(), diag::err_no_dynamic_cast_with_fno_rtti);
725 void CastOperation::CheckConstCast() {
727 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
728 else if (isPlaceholder())
729 SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());
730 if (SrcExpr.isInvalid())
733 unsigned msg = diag::err_bad_cxx_cast_generic;
736 Self.Diag(OpRange.getBegin(), msg) <<
CT_Const
737 << SrcExpr.get()->getType() << DestType << OpRange;
773 ReinterpretKind = ReinterpretUpcast;
775 ReinterpretKind = ReinterpretDowncast;
779 bool VirtualBase =
true;
780 bool NonZeroOffset =
false;
786 bool IsVirtual =
false;
787 for (CXXBasePath::const_iterator IElem = Path.begin(), EElem = Path.end();
788 IElem != EElem; ++IElem) {
789 IsVirtual = IElem->Base->isVirtual();
792 const CXXRecordDecl *BaseRD = IElem->Base->getType()->getAsCXXRecordDecl();
793 assert(BaseRD &&
"Base type should be a valid unqualified class type");
799 !ClassDefinition->isCompleteDefinition())
812 NonZeroOffset =
true;
814 VirtualBase = VirtualBase && IsVirtual;
817 (void) NonZeroOffset;
818 assert((VirtualBase || NonZeroOffset) &&
819 "Should have returned if has non-virtual base with zero offset");
822 ReinterpretKind == ReinterpretUpcast? DestType : SrcType;
824 ReinterpretKind == ReinterpretUpcast? SrcType : DestType;
827 Self.
Diag(BeginLoc, diag::warn_reinterpret_different_from_static)
828 << DerivedType << BaseType << !VirtualBase << int(ReinterpretKind)
830 Self.
Diag(BeginLoc, diag::note_reinterpret_updowncast_use_static)
831 << int(ReinterpretKind)
840 void CastOperation::CheckReinterpretCast() {
841 if (ValueKind ==
VK_RValue && !isPlaceholder(BuiltinType::Overload))
842 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
844 checkNonOverloadPlaceholders();
845 if (SrcExpr.isInvalid())
848 unsigned msg = diag::err_bad_cxx_cast_generic;
851 false, OpRange, msg,
Kind);
854 if (SrcExpr.isInvalid())
856 if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
858 Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_overload)
860 << DestType << OpRange;
861 Self.NoteAllOverloadCandidates(SrcExpr.get());
869 if (Self.getLangOpts().ObjCAutoRefCount)
879 void CastOperation::CheckStaticCast() {
880 if (isPlaceholder()) {
881 checkNonOverloadPlaceholders();
882 if (SrcExpr.isInvalid())
892 if (claimPlaceholder(BuiltinType::Overload)) {
893 Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr,
896 OpRange, DestType, diag::err_bad_static_cast_overload);
897 if (SrcExpr.isInvalid())
901 SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());
906 !isPlaceholder(BuiltinType::Overload)) {
907 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
908 if (SrcExpr.isInvalid())
912 unsigned msg = diag::err_bad_cxx_cast_generic;
915 Kind, BasePath,
false);
917 if (SrcExpr.isInvalid())
919 if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
921 Self.Diag(OpRange.getBegin(), diag::err_bad_static_cast_overload)
922 << oe->
getName() << DestType << OpRange
924 Self.NoteAllOverloadCandidates(SrcExpr.get());
933 if (Self.getLangOpts().ObjCAutoRefCount)
948 bool ListInitialization) {
974 OpRange, msg,
Kind, BasePath);
989 Kind, ListInitialization);
1009 if (Enum->getDecl()->isScoped()) {
1052 OpRange, msg, Kind, BasePath);
1075 if (DestPointeeQuals != SrcPointeeQuals &&
1077 msg = diag::err_bad_cxx_cast_qualifiers_away;
1089 Self.
Diag(OpRange.getBegin(), diag::ext_ms_cast_fn_obj) << OpRange;
1123 if (SrcPointer->getPointeeType()->getAs<
RecordType>() &&
1125 msg = diag::err_bad_cxx_cast_unrelated_class;
1150 bool ObjCConversion;
1151 bool ObjCLifetimeConversion;
1161 DerivedToBase, ObjCConversion,
1162 ObjCLifetimeConversion)
1166 msg = diag::err_bad_lvalue_to_rvalue_cast;
1170 if (DerivedToBase) {
1200 if (!DestReference) {
1204 if (!RValueRef && !SrcExpr->
isLValue()) {
1206 msg = diag::err_bad_cxx_cast_rvalue;
1243 msg = diag::err_bad_static_cast_pointer_nonpointer;
1250 CStyle, OpRange, SrcType, DestType, msg, Kind,
1260 QualType OrigDestType,
unsigned &msg,
1298 msg = diag::err_bad_cxx_cast_qualifiers_away;
1312 std::string PathDisplayStr;
1313 std::set<unsigned> DisplayedPaths;
1316 if (DisplayedPaths.insert(PI->back().SubobjectNumber).second) {
1319 PathDisplayStr +=
"\n ";
1320 for (CXXBasePath::const_reverse_iterator EI = PI->rbegin(),
1323 PathDisplayStr += EI->Base->getType().getAsString() +
" -> ";
1328 Self.
Diag(OpRange.
getBegin(), diag::err_ambiguous_base_to_derived_cast)
1331 << PathDisplayStr << OpRange;
1338 Self.
Diag(OpRange.
getBegin(), diag::err_static_downcast_via_virtual)
1339 << OrigSrcType << OrigDestType << VirtualBase << OpRange;
1348 diag::err_downcast_from_inaccessible_base)) {
1382 bool WasOverloadedFunction =
false;
1391 WasOverloadedFunction =
true;
1397 msg = diag::err_bad_static_cast_member_pointer_nonmp;
1419 Paths.setRecordingPaths(
true);
1420 bool StillOkay = Self.
IsDerivedFrom(SrcClass, DestClass, Paths);
1424 Self.
Diag(OpRange.
getBegin(), diag::err_ambiguous_memptr_conv)
1425 << 1 << SrcClass << DestClass << PathDisplayStr << OpRange;
1430 if (
const RecordType *VBase = Paths.getDetectedVirtual()) {
1431 Self.
Diag(OpRange.
getBegin(), diag::err_memptr_conv_via_virtual)
1432 << SrcClass << DestClass <<
QualType(VBase, 0) << OpRange;
1439 DestClass, SrcClass,
1441 diag::err_upcast_to_inaccessible_base)) {
1455 if (WasOverloadedFunction) {
1491 diag::err_bad_dynamic_cast_incomplete) ||
1493 diag::err_allocation_of_abstract_type)) {
1511 Expr *SrcExprRaw = SrcExpr.
get();
1546 bool NeedToMaterializeTemporary =
false;
1560 if (isa<LValueReferenceType>(DestTypeTmp) && !SrcExpr.
get()->isLValue()) {
1564 msg = diag::err_bad_cxx_cast_rvalue;
1568 if (isa<RValueReferenceType>(DestTypeTmp) && SrcExpr.
get()->isRValue()) {
1572 msg = diag::err_bad_cxx_cast_rvalue;
1578 NeedToMaterializeTemporary =
true;
1586 if (SrcExpr.
get()->refersToBitField()) {
1587 msg = diag::err_bad_cxx_cast_bitfield;
1607 msg = diag::err_bad_const_cast_dest;
1616 msg = diag::err_bad_const_cast_dest;
1626 while (SrcType != DestType &&
1636 if (SrcQuals != DestQuals)
1641 if (SrcType != DestType)
1644 if (NeedToMaterializeTemporary)
1648 SrcType, SrcExpr.
get(),
false);
1661 unsigned DiagID = IsDereference ?
1662 diag::warn_pointer_indirection_from_incompatible_type :
1663 diag::warn_undefined_reinterpret_cast;
1669 if (IsDereference) {
1705 Diag(Range.
getBegin(), DiagID) << SrcType << DestType << Range;
1714 if (SrcPtrTy->isObjCSelType()) {
1716 if (isa<PointerType>(DestType))
1719 Self.
Diag(SrcExpr.
get()->getExprLoc(),
1720 diag::warn_cast_pointer_from_sel)
1721 << SrcType << DestType << SrcExpr.
get()->getSourceRange();
1745 diag::warn_int_to_void_pointer_cast
1746 : diag::warn_int_to_pointer_cast;
1747 Self.
Diag(Loc, Diag) << SrcType << DestType;
1756 bool IsLValueCast =
false;
1771 ) && SingleFunctionExpr.
isUsable()) {
1772 SrcExpr = SingleFunctionExpr;
1773 SrcType = SrcExpr.
get()->getType();
1780 if (!SrcExpr.
get()->isGLValue()) {
1783 msg = diag::err_bad_cxx_cast_rvalue;
1796 const char *inappropriate =
nullptr;
1797 switch (SrcExpr.
get()->getObjectKind()) {
1800 case OK_BitField: inappropriate =
"bit-field";
break;
1803 case OK_ObjCSubscript: inappropriate =
"container subscripting expression";
1806 if (inappropriate) {
1807 Self.
Diag(OpRange.
getBegin(), diag::err_bad_reinterpret_cast_reference)
1808 << inappropriate << DestType
1809 << OpRange << SrcExpr.
get()->getSourceRange();
1818 IsLValueCast =
true;
1826 if (DestMemPtr && SrcMemPtr) {
1832 SrcMemPtr->isMemberFunctionPointer())
1841 msg = diag::err_bad_cxx_cast_qualifiers_away;
1855 msg = diag::err_bad_cxx_cast_member_pointer_size;
1860 assert(!IsLValueCast);
1873 msg = diag::err_bad_reinterpret_cast_small_int;
1882 if (srcIsVector || destIsVector) {
1888 if (!(srcIsScalar && destIsVector) && !(srcIsVector && destIsScalar) &&
1889 !(srcIsVector && destIsVector))
1900 msg = diag::err_bad_cxx_cast_vector_to_scalar_different_size;
1901 else if (srcIsScalar)
1902 msg = diag::err_bad_cxx_cast_scalar_to_vector_different_size;
1904 msg = diag::err_bad_cxx_cast_vector_to_vector_different_size;
1909 if (SrcType == DestType) {
1933 if (!destIsPtr && !srcIsPtr) {
1940 assert(srcIsPtr &&
"One type must be a pointer");
1944 bool MicrosoftException = Self.
getLangOpts().MicrosoftExt &&
1948 !MicrosoftException) {
1949 msg = diag::err_bad_reinterpret_cast_small_int;
1957 assert(destIsPtr &&
"One type must be a pointer");
1968 if (!destIsPtr || !srcIsPtr) {
1978 msg = diag::err_bad_cxx_cast_qualifiers_away;
2027 diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)
2036 diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)
2049 void CastOperation::CheckCXXCStyleCast(
bool FunctionalStyle,
2050 bool ListInitialization) {
2052 if (isPlaceholder()) {
2054 if (claimPlaceholder(BuiltinType::UnknownAny)) {
2055 SrcExpr = Self.checkUnknownAnyCast(DestRange, DestType,
2056 SrcExpr.get(),
Kind,
2057 ValueKind, BasePath);
2061 checkNonOverloadPlaceholders();
2062 if (SrcExpr.isInvalid())
2072 if (claimPlaceholder(BuiltinType::Overload)) {
2073 Self.ResolveAndFixSingleFunctionTemplateSpecialization(
2075 true, DestRange, DestType,
2076 diag::err_bad_cstyle_cast_overload);
2077 if (SrcExpr.isInvalid())
2081 SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());
2086 if (DestType->
isDependentType() || SrcExpr.get()->isTypeDependent() ||
2087 SrcExpr.get()->isValueDependent()) {
2093 !isPlaceholder(BuiltinType::Overload)) {
2094 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
2095 if (SrcExpr.isInvalid())
2102 && (SrcExpr.get()->getType()->isIntegerType()
2103 || SrcExpr.get()->getType()->isFloatingType())) {
2119 unsigned msg = diag::err_bad_cxx_cast_generic;
2122 if (SrcExpr.isInvalid())
2133 msg,
Kind, BasePath, ListInitialization);
2134 if (SrcExpr.isInvalid())
2140 OpRange, msg,
Kind);
2141 if (SrcExpr.isInvalid())
2146 if (Self.getLangOpts().ObjCAutoRefCount && tcr ==
TC_Success)
2147 checkObjCARCConversion(CCK);
2150 if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
2152 FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(),
2161 Self.Diag(OpRange.getBegin(), diag::err_bad_cstyle_cast_overload)
2162 << OE->
getName() << DestType << OpRange
2164 Self.NoteAllOverloadCandidates(SrcExpr.get());
2168 OpRange, SrcExpr.get(), DestType, ListInitialization);
2185 SrcExpr.
get()->getExprLoc()))
2188 if (!isa<CallExpr>(SrcExpr.
get()))
2210 Self.
Diag(SrcExpr.
get()->getExprLoc(),
2211 diag::warn_bad_function_cast)
2212 << SrcType << DestType << SrcExpr.
get()->getSourceRange();
2216 void CastOperation::CheckCStyleCast() {
2217 assert(!Self.getLangOpts().CPlusPlus);
2220 if (claimPlaceholder(BuiltinType::UnknownAny)) {
2221 SrcExpr = Self.checkUnknownAnyCast(DestRange, DestType,
2222 SrcExpr.get(),
Kind,
2223 ValueKind, BasePath);
2231 SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());
2232 if (SrcExpr.isInvalid())
2240 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
2241 if (SrcExpr.isInvalid())
2243 QualType SrcType = SrcExpr.get()->getType();
2249 if (Self.getLangOpts().OpenCL && DestType->
isPointerType() &&
2253 Self.Diag(OpRange.getBegin(),
2254 diag::err_typecheck_incompatible_address_space)
2256 << SrcExpr.get()->getSourceRange();
2262 if (Self.RequireCompleteType(OpRange.getBegin(), DestType,
2263 diag::err_typecheck_cast_to_incomplete)) {
2271 if (DestRecordTy && Self.Context.hasSameUnqualifiedType(DestType, SrcType)){
2273 Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_nonscalar)
2274 << DestType << SrcExpr.get()->getSourceRange();
2284 Field != FieldEnd; ++Field) {
2285 if (Self.Context.hasSameUnqualifiedType(Field->getType(), SrcType) &&
2286 !Field->isUnnamedBitfield()) {
2287 Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_to_union)
2288 << SrcExpr.get()->getSourceRange();
2292 if (Field == FieldEnd) {
2293 Self.Diag(OpRange.getBegin(), diag::err_typecheck_cast_to_union_no_type)
2294 << SrcType << SrcExpr.get()->getSourceRange();
2303 Self.Diag(OpRange.getBegin(), diag::err_typecheck_cond_expect_scalar)
2304 << DestType << SrcExpr.get()->getSourceRange();
2313 Self.Diag(SrcExpr.get()->getExprLoc(),
2314 diag::err_typecheck_expect_scalar_operand)
2315 << SrcType << SrcExpr.get()->getSourceRange();
2321 SrcExpr = Self.CheckExtVectorCast(OpRange, DestType, SrcExpr.get(),
Kind);
2329 }
else if (Self.CheckVectorCast(OpRange, DestType, SrcType,
Kind)) {
2336 if (Self.CheckVectorCast(OpRange, SrcType, DestType,
Kind))
2346 if (isa<ObjCSelectorExpr>(SrcExpr.get())) {
2347 Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_cast_selector_expr);
2356 Self.Diag(SrcExpr.get()->getExprLoc(),
2357 diag::err_cast_pointer_from_non_pointer_int)
2358 << SrcType << SrcExpr.get()->getSourceRange();
2367 Self.Diag(SrcExpr.get()->getLocStart(),
2368 diag::err_cast_pointer_to_non_pointer_int)
2369 << DestType << SrcExpr.get()->getSourceRange();
2375 if (Self.getLangOpts().OpenCL && !Self.getOpenCLOptions().cl_khr_fp16) {
2377 Self.Diag(SrcExpr.get()->getLocStart(), diag::err_opencl_cast_to_half)
2378 << DestType << SrcExpr.get()->getSourceRange();
2385 if (Self.getLangOpts().ObjCAutoRefCount) {
2387 if (SrcExpr.isInvalid())
2392 Qualifiers CastQuals = CastPtr->getPointeeType().getQualifiers();
2393 Qualifiers ExprQuals = ExprPtr->getPointeeType().getQualifiers();
2394 if (CastPtr->getPointeeType()->isObjCLifetimeType() &&
2395 ExprPtr->getPointeeType()->isObjCLifetimeType() &&
2397 Self.Diag(SrcExpr.get()->getLocStart(),
2398 diag::err_typecheck_incompatible_ownership)
2400 << SrcExpr.get()->getSourceRange();
2405 else if (!Self.CheckObjCARCUnavailableWeakConversion(DestType, SrcType)) {
2406 Self.Diag(SrcExpr.get()->getLocStart(),
2407 diag::err_arc_convesion_of_weak_unavailable)
2408 << 1 << SrcType << DestType << SrcExpr.get()->getSourceRange();
2416 Kind = Self.PrepareScalarCast(SrcExpr, DestType);
2417 if (SrcExpr.isInvalid())
2424 QualType TheOffendingSrcType, TheOffendingDestType;
2428 &TheOffendingSrcType, &TheOffendingDestType,
2429 &CastAwayQualifiers)) {
2430 int qualifiers = -1;
2433 }
else if (CastAwayQualifiers.
hasConst()) {
2439 if (qualifiers == -1)
2440 Self.Diag(SrcExpr.get()->getLocStart(), diag::warn_cast_qual2) <<
2441 SrcType << DestType;
2443 Self.Diag(SrcExpr.get()->getLocStart(), diag::warn_cast_qual) <<
2444 TheOffendingSrcType << TheOffendingDestType << qualifiers;
2452 CastOperation Op(*
this, CastTypeInfo->
getType(), CastExpr);
2454 Op.OpRange =
SourceRange(LPLoc, CastExpr->getLocEnd());
2457 Op.CheckCXXCStyleCast(
false,
2458 isa<InitListExpr>(CastExpr));
2460 Op.CheckCStyleCast();
2463 if (Op.SrcExpr.isInvalid())
2467 Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
2468 &Op.BasePath, CastTypeInfo, LPLoc, RPLoc));
2475 assert(LPLoc.
isValid() &&
"List-initialization shouldn't get here.");
2476 CastOperation Op(*
this, CastTypeInfo->
getType(), CastExpr);
2478 Op.OpRange =
SourceRange(Op.DestRange.getBegin(), CastExpr->getLocEnd());
2480 Op.CheckCXXCStyleCast(
true,
false);
2481 if (Op.SrcExpr.isInvalid())
2484 if (
CXXConstructExpr *ConstructExpr = dyn_cast<CXXConstructExpr>(Op.SrcExpr.get()))
2485 ConstructExpr->setParenOrBraceRange(
SourceRange(LPLoc, RPLoc));
2488 Op.ValueKind, CastTypeInfo, Op.Kind,
2489 Op.SrcExpr.get(), &Op.BasePath, LPLoc, RPLoc));
bool compatiblyIncludesObjCLifetime(Qualifiers other) const
Determines if these qualifiers compatibly include another set of qualifiers from the narrow perspecti...
Defines the clang::ASTContext interface.
SourceLocation getEnd() const
static TryCastResult TryStaticPointerDowncast(Sema &Self, QualType SrcType, QualType DestType, bool CStyle, const SourceRange &OpRange, unsigned &msg, CastKind &Kind, CXXCastPath &BasePath)
Tests whether a conversion according to C++ 5.2.9p8 is valid.
bool RequireNonAbstractType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
const RecordType * getDetectedVirtual() const
The virtual base discovered on the path (if we are merely detecting virtuals).
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
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.
bool isNullPtrType() const
bool isAtLeastAsQualifiedAs(QualType Other) const
Determine whether this type is at least as qualified as the other given type, requiring exact equalit...
A cast other than a C-style cast.
bool isMemberPointerType() const
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range covering the entirety of this nested-name-specifier.
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type...
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
const LangOptions & getLangOpts() const
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
bool isAnyCharacterType() const
Determine whether this type is any of the built-in character types.
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)
bool isRecordType() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
The cast method is appropriate and successful.
bool isVoidPointerType() const
bool isEnumeralType() const
std::string getAsString() const
QualType getPointeeType() const
static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, QualType SrcType, QualType DestType, bool CStyle, const SourceRange &OpRange, unsigned &msg, CastKind &Kind, CXXCastPath &BasePath)
Represents a call to a C++ constructor.
static ExprValueKind getValueKindForType(QualType T)
Overloading for a user-defined conversion failed.
Ambiguous candidates found.
bool isBooleanType() const
bool compatiblyIncludes(Qualifiers other) const
Determines if these qualifiers compatibly include another set. Generally this answers the question of...
A container of type source information.
bool isBlockPointerType() const
static CXXFunctionalCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, TypeSourceInfo *Written, CastKind Kind, Expr *Op, const CXXCastPath *Path, SourceLocation LPLoc, SourceLocation RPLoc)
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
Represents a prvalue temporary that is written into memory so that a reference can bind to it...
static TryCastResult TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType, bool CStyle, const SourceRange &OpRange, unsigned &msg, CastKind &Kind, CXXCastPath &BasePath)
Tests whether a conversion according to C++ 5.2.9p5 is valid.
static InitializedEntity InitializeTemporary(QualType Type)
Create the initialization entity for a temporary.
static TryCastResult TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, Sema::CheckedConversionKind CCK, const SourceRange &OpRange, unsigned &msg, CastKind &Kind, bool ListInitialization)
Information about one declarator, including the parsed type information and the identifier.
void removeObjCLifetime()
DiagnosticsEngine & Diags
void clear()
Clear the base-paths results.
field_iterator field_begin() const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CK_Dynamic - A C++ dynamic_cast.
Defines the clang::Expr interface and subclasses for C++ expressions.
std::list< CXXBasePath >::const_iterator const_paths_iterator
Expr * FixOverloadedFunctionReference(Expr *E, DeclAccessPair FoundDecl, FunctionDecl *Fn)
bool isScalarType() const
void setRecordingPaths(bool RP)
Specify whether we should be recording paths or not.
A vector component is an element or range of elements on a vector.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
The cast method is not applicable.
bool isRecordingPaths() const
Whether we are recording paths.
bool isReferenceType() const
bool isCompleteDefinition() const
bool isAnyPointerType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
CXXRecordDecl * getDefinition() const
unsigned getCVRQualifiers() const
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
void CheckExtraCXXDefaultArguments(Declarator &D)
OverloadCandidateDisplayKind
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
static TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType, bool CStyle, const SourceRange &OpRange, QualType OrigSrcType, QualType OrigDestType, unsigned &msg, CastKind &Kind, CXXCastPath &BasePath)
const TargetInfo & getTargetInfo() const
bool UnwrapSimilarPointerTypes(QualType &T1, QualType &T2)
const LangOptions & getLangOpts() const
ReferenceCompareResult CompareReferenceRelationship(SourceLocation Loc, QualType T1, QualType T2, bool &DerivedToBase, bool &ObjCConversion, bool &ObjCLifetimeConversion)
Succeeded, but refers to a deleted function.
CanProxy< U > getAs() const
Retrieve a canonical type pointer with a different static type, upcasting or downcasting as needed...
OverloadCandidateSet & getFailedCandidateSet()
Retrieve a reference to the candidate set when overload resolution fails.
const CXXRecordDecl * getParent() const
RecordDecl * getDecl() const
CheckedConversionKind
The kind of conversion being performed.
bool isUnsignedIntegerType() const
FunctionDecl * ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr, QualType TargetType, bool Complain, DeclAccessPair &Found, bool *pHadMultipleCandidates=nullptr)
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...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
An ordinary object is located at an address in memory.
static bool UnwrapDissimilarPointerTypes(QualType &T1, QualType &T2)
bool isExtVectorType() const
bool isMemberFunctionPointer() const
field_iterator field_end() const
Sema - This implements semantic analysis and AST building for C.
CastKind
CastKind - The kind of operation required for a conversion.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat)
static TryCastResult TryConstCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, bool CStyle, unsigned &msg)
QualType getPointeeType() const
bool isFunctionPointerType() const
bool isRealFloatingType() const
Floating point categories.
static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, bool CStyle, const SourceRange &OpRange, unsigned &msg, CastKind &Kind)
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
QualType getPointeeType() const
static void diagnoseBadCast(Sema &S, unsigned msg, CastType castType, SourceRange opRange, Expr *src, QualType destType, bool listInitialization)
Diagnose a failed cast.
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
static InitializationKind CreateFunctionalCast(SourceRange TypeRange, bool InitList)
Create a direct initialization for a functional cast.
NestedNameSpecifierLoc getQualifierLoc() const
Fetches the nested-name qualifier with source-location information, if one was given.
void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath)
static FindResult find(Expr *E)
Finds the overloaded expression in the given expression E of OverloadTy.
static CXXStaticCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets)
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Overload resolution succeeded.
bool isFloatingType() const
ExprResult BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, TypeSourceInfo *Ty, Expr *E, SourceRange AngleBrackets, SourceRange Parens)
bool RequireCompleteType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
void NoteCandidates(Sema &S, OverloadCandidateDisplayKind OCD, ArrayRef< Expr * > Args, StringRef Opc="", SourceLocation Loc=SourceLocation())
bool isDependentType() const
bool IsDerivedFrom(QualType Derived, QualType Base)
Determine whether the type Derived is a C++ class that is derived from the type Base.
bool isAtLeastAsQualifiedAs(CanQual< T > Other) const
Determines whether this canonical type is at least as qualified as the Other canonical type...
static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, Sema::CheckedConversionKind CCK, const SourceRange &OpRange, unsigned &msg, CastKind &Kind, CXXCastPath &BasePath, bool ListInitialization)
FailureKind getFailureKind() const
Determine why initialization failed.
bool CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, CastKind &Kind)
bool isComplexIntegerType() const
The result type of a method or function.
RecordDecl * getDefinition() const
void removeCVRQualifiers(unsigned mask)
TypeSourceInfo * GetTypeForDeclaratorCast(Declarator &D, QualType FromTy)
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
static CXXConstCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets)
A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr...
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
CastKind PrepareCastToObjCObjectPointer(ExprResult &E)
bool isComplexType() const
bool isValid() const
Return true if this is a valid SourceLocation object.
Represents a static or instance method of a struct/union/class.
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}_cast's.
std::string getAmbiguousPathsDisplayString(CXXBasePaths &Paths)
Builds a string representing ambiguous paths from a specific derived class to different subobjects of...
bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx, SourceLocation *Loc=nullptr, bool isEvaluated=true) const
Represents a canonical, potentially-qualified type.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Describes the kind of initialization being performed, along with location information for tokens rela...
Overloading for initialization by constructor failed.
SourceLocation getBegin() const
bool isTypeDependent() const
bool isVectorType() const
bool isMemberFunctionPointerType() const
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
QualType getType() const
Return the type wrapped by this type source info.
static InitializationKind CreateCast(SourceRange TypeRange)
Create a direct initialization due to a cast that isn't a C-style or functional cast.
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)
QualType getPointeeType() const
QualType getMemberPointerType(QualType T, const Type *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
bool isZero() const
isZero - Test whether the quantity equals zero.
bool isInvalidDecl() const
void CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType, bool IsDereference, SourceRange Range)
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
static void checkIntToPointerCast(bool CStyle, SourceLocation Loc, const Expr *SrcExpr, QualType DestType, Sema &Self)
Requests that only viable candidates be shown.
bool isAmbiguous(CanQualType BaseType)
Determine whether the path from the most-derived type to the given base type is ambiguous (i...
ExprResult BuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo, SourceLocation LParenLoc, Expr *CastExpr, SourceLocation RParenLoc)
void setCVRQualifiers(unsigned mask)
static InitializationKind CreateCStyleCast(SourceLocation StartLoc, SourceRange TypeRange, bool InitList)
Create a direct initialization for a C-style cast.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
static void DiagnoseCastOfObjCSEL(Sema &Self, const ExprResult &SrcExpr, QualType DestType)
bool isRValueReferenceType() const
QualType getPointeeType() const
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT, SourceRange range, Expr *src, QualType destType, bool listInitialization)
bool isAddressSpaceOverlapping(const PointerType &other) const
Returns true if address spaces of pointers overlap. OpenCL v2.0 defines conversion rules for pointers...
QualType getCanonicalType() const
static CStyleCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation R)
bool isFunctionType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
static bool CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType, bool CheckCVR, bool CheckObjCLifetime, QualType *TheOffendingSrcType=nullptr, QualType *TheOffendingDestType=nullptr, Qualifiers *CastAwayQualifiers=nullptr)
static TryCastResult TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType, bool CStyle, CastKind &Kind, CXXCastPath &BasePath, unsigned &msg)
Tests whether a conversion according to N2844 is valid.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream...
A bitfield object is a bitfield on a C or C++ record.
QualType getPointeeType() const
OverloadingResult getFailedOverloadResult() const
Get the overloading result, for when the initialization sequence failed due to a bad overload...
const Type * getClass() const
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang's AST.
bool Failed() const
Determine whether the initialization sequence is invalid.
Describes the sequence of initializations required to initialize a given object or reference with a s...
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Represents a C++ struct/union/class.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
bool isObjCObjectPointerType() const
bool isPlaceholderType() const
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, const CXXBasePath &Path, unsigned DiagID, bool ForceCheck=false, bool ForceUnprivileged=false)
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
Defines the clang::TargetInfo interface.
DeclarationName getName() const
Gets the name looked up.
bool IsQualificationConversion(QualType FromType, QualType ToType, bool CStyle, bool &ObjCLifetimeConversion)
static void DiagnoseBadFunctionCast(Sema &Self, const ExprResult &SrcExpr, QualType DestType)
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
No viable function found.
bool isConstructorInitialization() const
Determine whether this initialization is direct call to a constructor.
A trivial tuple used to represent a source range.
bool isInvalidType() const
bool ResolveAndFixSingleFunctionTemplateSpecialization(ExprResult &SrcExpr, bool DoFunctionPointerConverion=false, bool Complain=false, const SourceRange &OpRangeForComplaining=SourceRange(), QualType DestTypeForComplaining=QualType(), unsigned DiagIDForComplaining=0)
bool isArithmeticType() const
bool isSignedIntegerType() const
Describes an entity that is being initialized.
bool isIntegralType(ASTContext &Ctx) const
Determine whether this type is an integral type.
std::list< CXXBasePath >::iterator paths_iterator
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals)
Return this type as a completely-unqualified array type, capturing the qualifiers in Quals...
static void DiagnoseReinterpretUpDownCast(Sema &Self, const Expr *SrcExpr, QualType DestType, SourceRange OpRange)
bool isIntegerType() const
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
bool isPointerType() const
bool isIncompleteOrObjectType() const