29#include "llvm/ADT/SmallVector.h"
30#include "llvm/ADT/StringExtras.h"
60 struct CastOperation {
62 : Self(S), SrcExpr(src), DestType(destType),
65 Kind(CK_Dependent), IsARCUnbridgedCast(
false) {
79 !DestType->isArrayType() && !DestType.getPointerAuth()) {
80 DestType = DestType.getAtomicUnqualifiedType();
85 PlaceholderKind = placeholder->getKind();
99 bool IsARCUnbridgedCast;
106 : Locations{
Begin, LParen, RParen} {}
108 OpRangeType() =
default;
122 return SourceRange(getLParenLoc(), getRParenLoc());
134 void CheckConstCast();
135 void CheckReinterpretCast();
136 void CheckStaticCast();
137 void CheckDynamicCast();
138 void CheckCXXCStyleCast(
bool FunctionalCast,
bool ListInitialization);
140 void CheckCStyleCast();
141 void CheckBuiltinBitCast();
142 void CheckAddrspaceCast();
144 void updatePartOfExplicitCastFlags(
CastExpr *CE) {
148 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(CE->
getSubExpr()); CE = ICE)
149 ICE->setIsPartOfExplicitCast(
true);
157 if (IsARCUnbridgedCast) {
159 Self.Context, Self.Context.ARCUnbridgedCastTy, CK_Dependent,
161 Self.CurFPFeatureOverrides());
163 updatePartOfExplicitCastFlags(
castExpr);
173 if (PlaceholderKind != K)
return false;
179 bool isPlaceholder()
const {
180 return PlaceholderKind != 0;
183 return PlaceholderKind == K;
189 void checkCastAlign() {
190 Self.CheckCastAlign(SrcExpr.
get(), DestType, OpRange);
194 bool IsReinterpretCast =
false) {
195 assert(Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers());
198 if (Self.ObjC().CheckObjCConversion(
199 OpRange, DestType, src, CCK,
true,
false, BO_PtrMemD,
201 IsARCUnbridgedCast =
true;
205 void checkQualifiedDestType() {
208 Self.Diag(DestRange.
getBegin(), diag::err_ptrauth_qualifier_cast)
209 << DestType << DestRange;
214 void checkNonOverloadPlaceholders() {
215 if (!isPlaceholder() || isPlaceholder(BuiltinType::Overload))
218 SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.
get());
227 if (
const auto *PtrType = dyn_cast<PointerType>(FromType)) {
228 if (PtrType->getPointeeType()->hasAttr(attr::NoDeref)) {
229 if (
const auto *DestType = dyn_cast<PointerType>(ToType)) {
230 if (!DestType->getPointeeType()->hasAttr(attr::NoDeref)) {
231 S.
Diag(OpLoc, diag::warn_noderef_to_dereferenceable_pointer);
238 struct CheckNoDerefRAII {
239 CheckNoDerefRAII(CastOperation &Op) : Op(Op) {}
240 ~CheckNoDerefRAII() {
241 if (!Op.SrcExpr.isInvalid())
242 CheckNoDeref(Op.Self, Op.SrcExpr.get()->getType(), Op.ResultType,
243 Op.OpRange.getBegin());
271 bool CStyle, CastOperation::OpRangeType OpRange,
276 bool CStyle, CastOperation::OpRangeType OpRange,
280 CastOperation::OpRangeType OpRange,
282 QualType OrigDestType,
unsigned &msg,
287 CastOperation::OpRangeType OpRange,
unsigned &msg,
293 CastOperation::OpRangeType OpRange,
295 bool ListInitialization);
298 CastOperation::OpRangeType OpRange,
301 bool ListInitialization);
307 CastOperation::OpRangeType OpRange,
320 assert(!
D.isInvalidType());
323 if (
D.isInvalidType())
347 CastOperation Op(*
this, DestType,
E);
349 CastOperation::OpRangeType(OpLoc,
Parens.getBegin(),
Parens.getEnd());
350 Op.DestRange = AngleBrackets;
352 Op.checkQualifiedDestType();
355 default: llvm_unreachable(
"Unknown C++ cast!");
357 case tok::kw_addrspace_cast:
358 if (!TypeDependent) {
359 Op.CheckAddrspaceCast();
360 if (Op.SrcExpr.isInvalid())
364 Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
365 DestTInfo, OpLoc,
Parens.getEnd(), AngleBrackets));
367 case tok::kw_const_cast:
368 if (!TypeDependent) {
370 if (Op.SrcExpr.isInvalid())
375 Op.ValueKind, Op.SrcExpr.get(), DestTInfo,
379 case tok::kw_dynamic_cast: {
382 return ExprError(
Diag(OpLoc, diag::err_openclcxx_not_supported)
386 if (!TypeDependent) {
387 Op.CheckDynamicCast();
388 if (Op.SrcExpr.isInvalid())
392 Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
393 &Op.BasePath, DestTInfo,
397 case tok::kw_reinterpret_cast: {
398 if (!TypeDependent) {
399 Op.CheckReinterpretCast();
400 if (Op.SrcExpr.isInvalid())
405 Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
406 nullptr, DestTInfo, OpLoc,
410 case tok::kw_static_cast: {
411 if (!TypeDependent) {
412 Op.CheckStaticCast();
413 if (Op.SrcExpr.isInvalid())
419 Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
421 Parens.getEnd(), AngleBrackets));
429 assert(!
D.isInvalidType());
432 if (
D.isInvalidType())
441 CastOperation Op(*
this, TSI->
getType(), Operand);
442 Op.OpRange = CastOperation::OpRangeType(KWLoc, KWLoc, RParenLoc);
447 Op.CheckBuiltinBitCast();
448 if (Op.SrcExpr.isInvalid())
454 Op.SrcExpr.get(), TSI, KWLoc, RParenLoc);
455 return Op.complete(BCE);
461 CastOperation::OpRangeType range,
463 bool listInitialization) {
486 range.getBegin(), range, listInitialization)
489 range.getBegin(), range.getParenRange(), listInitialization)
500 default:
return false;
532 case OR_Success: llvm_unreachable(
"successful failed overload");
534 if (candidates.
empty())
535 msg = diag::err_ovl_no_conversion_in_cast;
537 msg = diag::err_ovl_no_viable_conversion_in_cast;
542 msg = diag::err_ovl_ambiguous_conversion_in_cast;
550 assert(Res ==
OR_Deleted &&
"Inconsistent overload resolution");
555 S.
PDiag(diag::err_ovl_deleted_conversion_in_cast)
556 << CT << srcType << destType << (Msg !=
nullptr)
557 << (Msg ? Msg->
getString() : StringRef())
566 S.
PDiag(msg) << CT << srcType << destType << range
568 S, howManyCandidates, src);
575 CastOperation::OpRangeType opRange,
Expr *src,
576 QualType destType,
bool listInitialization) {
577 if (msg == diag::err_bad_cxx_cast_generic &&
582 S.
Diag(opRange.getBegin(), msg) << castType
586 int DifferentPtrness = 0;
597 if (!DifferentPtrness) {
600 DeclFrom && DeclTo) {
601 if (!DeclFrom->isCompleteDefinition())
602 S.
Diag(DeclFrom->getLocation(), diag::note_type_incomplete) << DeclFrom;
603 if (!DeclTo->isCompleteDefinition())
604 S.
Diag(DeclTo->getLocation(), diag::note_type_incomplete) << DeclTo;
612enum CastAwayConstnessKind {
619 CACK_SimilarKind = 2,
638static CastAwayConstnessKind
640 enum {
None, Ptr, MemPtr, BlockPtr, Array };
653 return AT->getElementType();
657 CastAwayConstnessKind Kind;
665 Kind = CastAwayConstnessKind::CACK_Similar;
667 Kind = CastAwayConstnessKind::CACK_Similar;
670 int T1Class = Classify(T1);
672 return CastAwayConstnessKind::CACK_None;
674 int T2Class = Classify(T2);
676 return CastAwayConstnessKind::CACK_None;
680 Kind = T1Class == T2Class ? CastAwayConstnessKind::CACK_SimilarKind
681 : CastAwayConstnessKind::CACK_Incoherent;
691 if (Classify(T1) != Array)
694 auto T2Class = Classify(T2);
698 if (T2Class != Array)
699 Kind = CastAwayConstnessKind::CACK_Incoherent;
700 else if (Kind != CastAwayConstnessKind::CACK_Incoherent)
701 Kind = CastAwayConstnessKind::CACK_SimilarKind;
716static CastAwayConstnessKind
718 bool CheckCVR,
bool CheckObjCLifetime,
719 QualType *TheOffendingSrcType =
nullptr,
720 QualType *TheOffendingDestType =
nullptr,
724 if (!CheckCVR && CheckObjCLifetime && !
Self.Context.getLangOpts().ObjC)
725 return CastAwayConstnessKind::CACK_None;
730 "Source type is not pointer or pointer to member.");
733 "Destination type is not pointer or pointer to member.");
736 QualType UnwrappedSrcType =
Self.Context.getCanonicalType(SrcType),
737 UnwrappedDestType =
Self.Context.getCanonicalType(DestType);
742 QualType PrevUnwrappedSrcType = UnwrappedSrcType;
743 QualType PrevUnwrappedDestType = UnwrappedDestType;
744 auto WorstKind = CastAwayConstnessKind::CACK_Similar;
745 bool AllConstSoFar =
true;
747 Self.Context, UnwrappedSrcType, UnwrappedDestType)) {
750 if (Kind > WorstKind)
755 Self.Context.getUnqualifiedArrayType(UnwrappedSrcType, SrcQuals);
756 Self.Context.getUnqualifiedArrayType(UnwrappedDestType, DestQuals);
762 UnwrappedDestType->isObjCObjectType())
771 if (SrcCvrQuals != DestCvrQuals) {
772 if (CastAwayQualifiers)
773 *CastAwayQualifiers = SrcCvrQuals - DestCvrQuals;
776 if (!DestCvrQuals.compatiblyIncludes(SrcCvrQuals,
777 Self.getASTContext())) {
778 if (TheOffendingSrcType)
779 *TheOffendingSrcType = PrevUnwrappedSrcType;
780 if (TheOffendingDestType)
781 *TheOffendingDestType = PrevUnwrappedDestType;
792 if (CheckObjCLifetime &&
798 if (AllConstSoFar && !DestQuals.
hasConst()) {
799 AllConstSoFar =
false;
800 if (TheOffendingSrcType)
801 *TheOffendingSrcType = PrevUnwrappedSrcType;
802 if (TheOffendingDestType)
803 *TheOffendingDestType = PrevUnwrappedDestType;
806 PrevUnwrappedSrcType = UnwrappedSrcType;
807 PrevUnwrappedDestType = UnwrappedDestType;
810 return CastAwayConstnessKind::CACK_None;
816 case CastAwayConstnessKind::CACK_None:
817 llvm_unreachable(
"did not cast away constness");
819 case CastAwayConstnessKind::CACK_Similar:
821 case CastAwayConstnessKind::CACK_SimilarKind:
822 DiagID = diag::err_bad_cxx_cast_qualifiers_away;
825 case CastAwayConstnessKind::CACK_Incoherent:
826 DiagID = diag::ext_bad_cxx_cast_qualifiers_away_incoherent;
830 llvm_unreachable(
"unexpected cast away constness kind");
836void CastOperation::CheckDynamicCast() {
837 CheckNoDerefRAII NoderefCheck(*
this);
840 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
841 else if (isPlaceholder())
842 SrcExpr =
Self.CheckPlaceholderExpr(SrcExpr.get());
843 if (SrcExpr.isInvalid())
846 QualType OrigSrcType = SrcExpr.get()->getType();
847 QualType DestType =
Self.Context.getCanonicalType(this->DestType);
860 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ref_or_ptr)
861 << this->DestType << DestRange;
868 assert(DestPointer &&
"Reference to void is not possible");
869 }
else if (DestRecord) {
870 if (
Self.RequireCompleteType(OpRange.getBegin(), DestPointee,
871 diag::err_bad_cast_incomplete,
877 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
887 QualType SrcType =
Self.Context.getCanonicalType(OrigSrcType);
893 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ptr)
894 << OrigSrcType << this->DestType << SrcExpr.get()->getSourceRange();
898 }
else if (DestReference->isLValueReferenceType()) {
899 if (!SrcExpr.get()->isLValue()) {
900 Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_rvalue)
901 <<
CT_Dynamic << OrigSrcType << this->DestType << OpRange;
903 SrcPointee = SrcType;
907 if (SrcExpr.get()->isPRValue())
908 SrcExpr =
Self.CreateMaterializeTemporaryExpr(
909 SrcType, SrcExpr.get(),
false);
910 SrcPointee = SrcType;
915 if (
Self.RequireCompleteType(OpRange.getBegin(), SrcPointee,
916 diag::err_bad_cast_incomplete,
922 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
928 assert((DestPointer || DestReference) &&
929 "Bad destination non-ptr/ref slipped through.");
930 assert((DestRecord || DestPointee->
isVoidType()) &&
931 "Bad destination pointee slipped through.");
932 assert(SrcRecord &&
"Bad source pointee slipped through.");
936 Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_qualifiers_away)
937 <<
CT_Dynamic << OrigSrcType << this->DestType << OpRange;
944 if (DestRecord == SrcRecord) {
952 Self.IsDerivedFrom(OpRange.getBegin(), SrcPointee, DestPointee)) {
953 if (
Self.CheckDerivedToBaseConversion(SrcPointee, DestPointee,
954 OpRange.getBegin(), OpRange,
960 Kind = CK_DerivedToBase;
966 assert(SrcDecl &&
"Definition missing");
967 if (!cast<CXXRecordDecl>(SrcDecl)->isPolymorphic()) {
968 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_polymorphic)
977 Self.Diag(OpRange.getBegin(), diag::err_no_dynamic_cast_with_fno_rtti);
983 if (!
Self.getLangOpts().RTTIData) {
985 Self.getASTContext().getTargetInfo().getCXXABI().isMicrosoft();
986 bool isClangCL =
Self.getDiagnostics().getDiagnosticOptions().getFormat() ==
988 if (MicrosoftABI || !DestPointee->
isVoidType())
989 Self.Diag(OpRange.getBegin(),
990 diag::warn_no_dynamic_cast_with_rtti_disabled)
997 auto *DestDecl = DestRecord->getAsCXXRecordDecl();
998 if (DestDecl->isEffectivelyFinal())
999 Self.MarkVTableUsed(OpRange.getBegin(), DestDecl);
1011void CastOperation::CheckConstCast() {
1012 CheckNoDerefRAII NoderefCheck(*
this);
1015 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
1016 else if (isPlaceholder())
1017 SrcExpr =
Self.CheckPlaceholderExpr(SrcExpr.get());
1018 if (SrcExpr.isInvalid())
1021 unsigned msg = diag::err_bad_cxx_cast_generic;
1025 << SrcExpr.get()->getType() << DestType << OpRange;
1031void CastOperation::CheckAddrspaceCast() {
1032 unsigned msg = diag::err_bad_cxx_cast_generic;
1036 Self.Diag(OpRange.getBegin(), msg)
1037 <<
CT_Addrspace << SrcExpr.get()->getType() << DestType << OpRange;
1047 CastOperation::OpRangeType OpRange) {
1074 ReinterpretKind = ReinterpretUpcast;
1076 ReinterpretKind = ReinterpretDowncast;
1081 bool NonZeroOffset =
false;
1083 E = BasePaths.
end();
1087 bool IsVirtual =
false;
1088 for (CXXBasePath::const_iterator IElem =
Path.begin(), EElem =
Path.end();
1089 IElem != EElem; ++IElem) {
1090 IsVirtual = IElem->Base->isVirtual();
1093 const CXXRecordDecl *BaseRD = IElem->Base->getType()->getAsCXXRecordDecl();
1094 assert(BaseRD &&
"Base type should be a valid unqualified class type");
1098 *ClassDefinition =
Class->getDefinition();
1099 if (
Class->isInvalidDecl() || !ClassDefinition ||
1100 !ClassDefinition->isCompleteDefinition())
1109 if (Offset.isZero())
1113 NonZeroOffset =
true;
1118 (void) NonZeroOffset;
1120 "Should have returned if has non-virtual base with zero offset");
1123 ReinterpretKind == ReinterpretUpcast? DestType : SrcType;
1125 ReinterpretKind == ReinterpretUpcast? SrcType : DestType;
1128 Self.Diag(BeginLoc, diag::warn_reinterpret_different_from_static)
1129 << DerivedType << BaseType << !
VirtualBase <<
int(ReinterpretKind)
1131 Self.Diag(BeginLoc, diag::note_reinterpret_updowncast_use_static)
1132 <<
int(ReinterpretKind)
1153 unsigned int DiagID = 0;
1154 const unsigned int DiagList[] = {diag::warn_cast_function_type_strict,
1155 diag::warn_cast_function_type};
1180 assert(SrcFTy && DstFTy);
1182 if (
Self.Context.hasSameType(SrcFTy, DstFTy))
1186 if (DiagID == diag::warn_cast_function_type_strict)
1193 return !PT->isVariadic() && PT->getNumParams() == 0;
1209 return !PT->isVariadic() && PT->getNumParams() == 0;
1214 if (IsVoidVoid(SrcFTy) || IsVoidVoid(DstFTy))
1220 if (
Self.getASTContext().getTargetInfo().getTriple().isOSWindows() &&
1235 const auto *SrcFPTy = cast<FunctionProtoType>(SrcFTy);
1236 const auto *DstFPTy = cast<FunctionProtoType>(DstFTy);
1240 unsigned NumParams = SrcFPTy->getNumParams();
1241 unsigned DstNumParams = DstFPTy->getNumParams();
1242 if (NumParams > DstNumParams) {
1243 if (!DstFPTy->isVariadic())
1245 NumParams = DstNumParams;
1246 }
else if (NumParams < DstNumParams) {
1247 if (!SrcFPTy->isVariadic())
1251 for (
unsigned i = 0; i < NumParams; ++i)
1253 DstFPTy->getParamType(i),
Self.Context))
1264void CastOperation::CheckReinterpretCast() {
1265 if (ValueKind ==
VK_PRValue && !isPlaceholder(BuiltinType::Overload))
1266 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
1268 checkNonOverloadPlaceholders();
1269 if (SrcExpr.isInvalid())
1272 unsigned msg = diag::err_bad_cxx_cast_generic;
1275 false, OpRange, msg, Kind);
1277 if (SrcExpr.isInvalid())
1279 if (SrcExpr.get()->getType() ==
Self.Context.OverloadTy) {
1281 Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_overload)
1283 << DestType << OpRange;
1284 Self.NoteAllOverloadCandidates(SrcExpr.get());
1293 if (
Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())
1299 Self.Diag(OpRange.getBegin(), DiagID)
1300 << SrcExpr.get()->getType() << DestType << OpRange;
1310void CastOperation::CheckStaticCast() {
1311 CheckNoDerefRAII NoderefCheck(*
this);
1313 if (isPlaceholder()) {
1314 checkNonOverloadPlaceholders();
1315 if (SrcExpr.isInvalid())
1325 if (claimPlaceholder(BuiltinType::Overload)) {
1326 Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr,
1329 OpRange, DestType, diag::err_bad_static_cast_overload);
1330 if (SrcExpr.isInvalid())
1334 SrcExpr =
Self.IgnoredValueConversions(SrcExpr.get());
1339 !isPlaceholder(BuiltinType::Overload)) {
1340 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
1341 if (SrcExpr.isInvalid())
1345 unsigned msg = diag::err_bad_cxx_cast_generic;
1348 OpRange, msg, Kind, BasePath,
false);
1350 if (SrcExpr.isInvalid())
1352 if (SrcExpr.get()->getType() ==
Self.Context.OverloadTy) {
1354 Self.Diag(OpRange.getBegin(), diag::err_bad_static_cast_overload)
1355 << oe->
getName() << DestType << OpRange
1357 Self.NoteAllOverloadCandidates(SrcExpr.get());
1365 if (Kind == CK_BitCast)
1367 if (
Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())
1382 DestPtrType->getPointeeType().getAddressSpace();
1390 CastOperation::OpRangeType OpRange,
1393 bool ListInitialization) {
1419 OpRange, msg, Kind, BasePath);
1427 Kind, BasePath, msg);
1434 Kind, ListInitialization);
1455 if (
const EnumType *
Enum = dyn_cast<EnumType>(SrcType)) {
1456 if (
Enum->getOriginalDecl()->isScoped()) {
1458 Kind = CK_IntegralToBoolean;
1461 Kind = CK_IntegralCast;
1464 Kind = CK_IntegralToFloating;
1479 if (
Self.RequireCompleteType(OpRange.getBegin(), DestType,
1480 diag::err_bad_cast_incomplete)) {
1488 Kind = ED->isFixed() && ED->getIntegerType()->isBooleanType()
1489 ? CK_IntegralToBoolean
1493 Kind = CK_FloatingToIntegral;
1509 OpRange, msg, Kind, BasePath);
1532 if (DestPointeeQuals != SrcPointeeQuals &&
1534 Self.getASTContext())) {
1535 msg = diag::err_bad_cxx_cast_qualifiers_away;
1540 ? CK_AddressSpaceConversion
1547 if (!CStyle &&
Self.getLangOpts().MSVCCompat &&
1549 Self.Diag(OpRange.getBegin(), diag::ext_ms_cast_fn_obj) << OpRange;
1557 Kind = CK_CPointerToObjCPointerCast;
1562 Kind = CK_AnyPointerToBlockPointerCast;
1576 Self.ObjC().CheckTollFreeBridgeStaticCast(DestType, SrcExpr.
get(), Kind))
1583 if (SrcPointer->getPointeeType()->isRecordType() &&
1585 msg = diag::err_bad_cxx_cast_unrelated_class;
1588 if (
Self.CheckMatrixCast(OpRange, DestType, SrcType, Kind)) {
1625 SrcExpr->
getBeginLoc(), ToType, FromType, &RefConv);
1632 msg = SrcExpr->
isLValue() ? diag::err_bad_lvalue_to_rvalue_cast
1633 : diag::err_bad_rvalue_to_rvalue_cast;
1637 if (RefConv & Sema::ReferenceConversions::DerivedToBase) {
1638 Kind = CK_DerivedToBase;
1639 if (
Self.CheckDerivedToBaseConversion(FromType, ToType,
1641 &BasePath, CStyle)) {
1654 CastOperation::OpRangeType OpRange,
1667 if (!DestReference) {
1671 if (!RValueRef && !SrcExpr->
isLValue()) {
1673 msg = diag::err_bad_cxx_cast_rvalue;
1683 Self.Context.getCanonicalType(SrcExpr->
getType()),
1684 Self.Context.getCanonicalType(DestPointee), CStyle,
1685 OpRange, SrcExpr->
getType(), DestType, msg, Kind,
1692 CastOperation::OpRangeType OpRange,
1710 msg = diag::err_bad_static_cast_pointer_nonpointer;
1717 CStyle, OpRange, SrcType, DestType, msg, Kind,
1726 CastOperation::OpRangeType OpRange,
1731 if (!
Self.isCompleteType(OpRange.getBegin(), SrcType) ||
1732 !
Self.isCompleteType(OpRange.getBegin(), DestType))
1742 if (!
Self.IsDerivedFrom(OpRange.getBegin(), DestType, SrcType, Paths)) {
1767 msg = diag::err_bad_cxx_cast_qualifiers_away;
1776 if (!Paths.isRecordingPaths()) {
1778 Paths.setRecordingPaths(
true);
1779 Self.IsDerivedFrom(OpRange.getBegin(), DestType, SrcType, Paths);
1781 std::string PathDisplayStr;
1782 std::set<unsigned> DisplayedPaths;
1784 if (DisplayedPaths.insert(
Path.back().SubobjectNumber).second) {
1787 PathDisplayStr +=
"\n ";
1789 PathDisplayStr += PE.Base->getType().getAsString() +
" -> ";
1794 Self.Diag(OpRange.getBegin(), diag::err_ambiguous_base_to_derived_cast)
1797 << PathDisplayStr << OpRange;
1802 if (Paths.getDetectedVirtual() !=
nullptr) {
1804 Self.Diag(OpRange.getBegin(), diag::err_static_downcast_via_virtual)
1805 << OrigSrcType << OrigDestType <<
VirtualBase << OpRange;
1811 switch (
Self.CheckBaseClassAccess(OpRange.getBegin(),
1814 diag::err_downcast_from_inaccessible_base)) {
1826 Self.BuildBasePathArray(Paths, BasePath);
1827 Kind = CK_BaseToDerived;
1841 CastOperation::OpRangeType OpRange,
1848 bool WasOverloadedFunction =
false;
1852 =
Self.ResolveAddressOfOverloadedFunction(SrcExpr.
get(), DestType,
false,
1855 SrcType =
Self.Context.getMemberPointerType(
1856 Fn->getType(), std::nullopt, M->
getParent());
1857 WasOverloadedFunction =
true;
1861 switch (
Self.CheckMemberPointerConversion(
1862 SrcType, DestMemPtr, Kind, BasePath, OpRange.getBegin(), OpRange, CStyle,
1865 if (Kind == CK_NullToMemberPointer) {
1866 msg = diag::err_bad_static_cast_member_pointer_nonmp;
1880 if (WasOverloadedFunction) {
1892 SrcExpr =
Self.FixOverloadedFunctionReference(SrcExpr, FoundOverload, Fn);
1909 CastOperation::OpRangeType OpRange,
1911 bool ListInitialization) {
1913 if (
Self.RequireCompleteType(OpRange.getBegin(), DestType,
1914 diag::err_bad_cast_incomplete) ||
1915 Self.RequireNonAbstractType(OpRange.getBegin(), DestType,
1916 diag::err_allocation_of_abstract_type)) {
1929 OpRange.getBegin(), OpRange.getParenRange(), ListInitialization)
1931 Expr *SrcExprRaw = SrcExpr.
get();
1948 if (
Result.isInvalid()) {
1954 Kind = CK_ConstructorConversion;
1967 DestType =
Self.Context.getCanonicalType(DestType);
1969 bool NeedToMaterializeTemporary =
false;
1983 if (isa<LValueReferenceType>(DestTypeTmp) && !SrcExpr.
get()->
isLValue()) {
1987 msg = diag::err_bad_cxx_cast_rvalue;
1991 if (isa<RValueReferenceType>(DestTypeTmp) && SrcExpr.
get()->
isPRValue()) {
1995 msg = diag::err_bad_cxx_cast_rvalue;
2001 NeedToMaterializeTemporary =
true;
2010 msg = diag::err_bad_cxx_cast_bitfield;
2014 DestType =
Self.Context.getPointerType(DestTypeTmp->getPointeeType());
2015 SrcType =
Self.Context.getPointerType(SrcType);
2030 msg = diag::err_bad_const_cast_dest;
2039 msg = diag::err_bad_const_cast_dest;
2049 if (!
Self.Context.hasCvrSimilarType(SrcType, DestType))
2052 if (NeedToMaterializeTemporary)
2055 SrcExpr =
Self.CreateMaterializeTemporaryExpr(SrcExpr.
get()->
getType(),
2070 unsigned DiagID = IsDereference ?
2071 diag::warn_pointer_indirection_from_incompatible_type :
2072 diag::warn_undefined_reinterpret_cast;
2078 if (IsDereference) {
2124 if (
Self.Context.hasSameType(SrcType, DestType))
2127 if (SrcPtrTy->isObjCSelType()) {
2129 if (isa<PointerType>(DestType))
2133 diag::warn_cast_pointer_from_sel)
2142 CastOperation::OpRangeType OpRange) {
2146 if (
Self.Context.hasSameType(SrcType, DstType) ||
2149 const auto *SrcFTy =
2151 const auto *DstFTy =
2161 if (
auto *UO = dyn_cast<UnaryOperator>(Src))
2162 if (UO->getOpcode() == UO_AddrOf)
2164 auto *DRE = dyn_cast<DeclRefExpr>(Src);
2167 auto *FD = dyn_cast<FunctionDecl>(DRE->getDecl());
2175 CallingConv DefaultCC =
Self.getASTContext().getDefaultCallingConvention(
2176 FD->isVariadic(), FD->isCXXInstanceMember());
2177 if (DstCC == DefaultCC || SrcCC != DefaultCC)
2183 Self.Diag(OpRange.getBegin(), diag::warn_cast_calling_conv)
2184 << SrcCCName << DstCCName << OpRange;
2189 if (
Self.Diags.isIgnored(diag::warn_cast_calling_conv, OpRange.getBegin()))
2196 SourceLocation NameLoc = FD->getFirstDecl()->getNameInfo().getLoc();
2200 llvm::raw_svector_ostream OS(CCAttrText);
2201 if (
Self.getLangOpts().MicrosoftExt) {
2203 OS <<
"__" << DstCCName;
2210 OS <<
"__attribute__((" << DstCCName <<
"))";
2211 AttrTokens.push_back(tok::kw___attribute);
2212 AttrTokens.push_back(tok::l_paren);
2213 AttrTokens.push_back(tok::l_paren);
2218 AttrTokens.push_back(tok::r_paren);
2219 AttrTokens.push_back(tok::r_paren);
2222 if (!AttrSpelling.empty())
2223 CCAttrText = AttrSpelling;
2225 Self.Diag(NameLoc, diag::note_change_calling_conv_fixit)
2241 &&
Self.Context.getTypeSize(DestType) >
2242 Self.Context.getTypeSize(SrcType)) {
2249 diag::warn_int_to_void_pointer_cast
2250 : diag::warn_int_to_pointer_cast;
2266 if (
Self.ResolveAndFixSingleFunctionTemplateSpecialization(
2277 if (!
Self.resolveAndFixAddressOfSingleOverloadCandidate(
2280 return Result.isUsable();
2285 CastOperation::OpRangeType OpRange,
2287 bool IsLValueCast =
false;
2289 DestType =
Self.Context.getCanonicalType(DestType);
2294 if (SrcType ==
Self.Context.OverloadTy) {
2299 assert(FixedExpr.
isUsable() &&
"Invalid result fixing overloaded expr");
2300 SrcExpr = FixedExpr;
2308 msg = diag::err_bad_cxx_cast_rvalue;
2313 Self.CheckCompatibleReinterpretCast(SrcType, DestType,
2321 const char *inappropriate =
nullptr;
2326 msg = diag::err_bad_cxx_cast_bitfield;
2331 inappropriate =
"matrix element";
2334 case OK_ObjCSubscript: inappropriate =
"container subscripting expression";
2337 if (inappropriate) {
2338 Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_reference)
2339 << inappropriate << DestType
2346 DestType =
Self.Context.getPointerType(DestTypeTmp->getPointeeType());
2347 SrcType =
Self.Context.getPointerType(SrcType);
2349 IsLValueCast =
true;
2353 SrcType =
Self.Context.getCanonicalType(SrcType);
2357 if (DestMemPtr && SrcMemPtr) {
2363 SrcMemPtr->isMemberFunctionPointer())
2366 if (
Self.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
2369 (void)
Self.isCompleteType(OpRange.getBegin(), SrcType);
2370 (void)
Self.isCompleteType(OpRange.getBegin(), DestType);
2374 if (
Self.Context.getTypeSize(DestMemPtr) !=
2375 Self.Context.getTypeSize(SrcMemPtr)) {
2376 msg = diag::err_bad_cxx_cast_member_pointer_size;
2390 assert(!IsLValueCast);
2391 Kind = CK_ReinterpretMemberPointer;
2401 if (
Self.Context.getTypeSize(SrcType) >
2402 Self.Context.getTypeSize(DestType)) {
2403 msg = diag::err_bad_reinterpret_cast_small_int;
2406 Kind = CK_PointerToIntegral;
2414 if (srcIsVector || destIsVector) {
2416 if (
Self.isValidSveBitcast(SrcType, DestType)) {
2422 if (
Self.RISCV().isValidRVVBitcast(SrcType, DestType)) {
2436 if (
Self.areLaxCompatibleVectorTypes(SrcType, DestType)) {
2441 if (
Self.LangOpts.OpenCL && !CStyle) {
2444 if (
Self.areVectorTypesSameSize(SrcType, DestType)) {
2453 msg = diag::err_bad_cxx_cast_vector_to_scalar_different_size;
2454 else if (!srcIsVector)
2455 msg = diag::err_bad_cxx_cast_scalar_to_vector_different_size;
2457 msg = diag::err_bad_cxx_cast_vector_to_vector_different_size;
2462 if (SrcType == DestType) {
2486 if (!destIsPtr && !srcIsPtr) {
2493 assert(srcIsPtr &&
"One type must be a pointer");
2497 if ((
Self.Context.getTypeSize(SrcType) >
2498 Self.Context.getTypeSize(DestType))) {
2499 bool MicrosoftException =
2501 if (MicrosoftException) {
2503 ? diag::warn_void_pointer_to_int_cast
2504 : diag::warn_pointer_to_int_cast;
2505 Self.Diag(OpRange.getBegin(),
Diag) << SrcType << DestType << OpRange;
2507 msg = diag::err_bad_reinterpret_cast_small_int;
2511 Kind = CK_PointerToIntegral;
2516 assert(destIsPtr &&
"One type must be a pointer");
2522 Kind = CK_IntegralToPointer;
2526 if (!destIsPtr || !srcIsPtr) {
2546 Kind = CK_AddressSpaceConversion;
2553 }
else if (IsLValueCast) {
2554 Kind = CK_LValueBitCast;
2556 Kind =
Self.ObjC().PrepareCastToObjCObjectPointer(SrcExpr);
2559 Kind = CK_AnyPointerToBlockPointerCast;
2570 return SuccessResult;
2584 return SuccessResult;
2593 Self.Diag(OpRange.getBegin(),
2594 Self.getLangOpts().CPlusPlus11 ?
2595 diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)
2597 return SuccessResult;
2602 Self.Diag(OpRange.getBegin(),
2603 Self.getLangOpts().CPlusPlus11 ?
2604 diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)
2606 return SuccessResult;
2618 Self.Diag(OpRange.getBegin(),
2619 diag::warn_bad_cxx_cast_nested_pointer_addr_space)
2632 return SuccessResult;
2638 if (!
Self.getLangOpts().OpenCL && !
Self.getLangOpts().SYCLIsDevice)
2655 auto SrcPointeeType = SrcPtrType->getPointeeType();
2656 auto DestPointeeType = DestPtrType->getPointeeType();
2657 if (!DestPointeeType.isAddressSpaceOverlapping(SrcPointeeType,
2658 Self.getASTContext())) {
2659 msg = diag::err_bad_cxx_cast_addr_space_mismatch;
2662 auto SrcPointeeTypeWithoutAS =
2663 Self.Context.removeAddrSpaceQualType(SrcPointeeType.getCanonicalType());
2664 auto DestPointeeTypeWithoutAS =
2665 Self.Context.removeAddrSpaceQualType(DestPointeeType.getCanonicalType());
2666 if (
Self.Context.hasSameType(SrcPointeeTypeWithoutAS,
2667 DestPointeeTypeWithoutAS)) {
2668 Kind = SrcPointeeType.getAddressSpace() == DestPointeeType.getAddressSpace()
2670 : CK_AddressSpaceConversion;
2677void CastOperation::checkAddressSpaceCast(
QualType SrcType,
QualType DestType) {
2689 if (
Self.getLangOpts().OpenCL) {
2690 const Type *DestPtr, *SrcPtr;
2691 bool Nested =
false;
2692 unsigned DiagID = diag::err_typecheck_incompatible_address_space;
2693 DestPtr =
Self.getASTContext().getCanonicalType(DestType.
getTypePtr()),
2694 SrcPtr =
Self.getASTContext().getCanonicalType(SrcType.
getTypePtr());
2696 while (isa<PointerType>(DestPtr) && isa<PointerType>(SrcPtr)) {
2697 const PointerType *DestPPtr = cast<PointerType>(DestPtr);
2698 const PointerType *SrcPPtr = cast<PointerType>(SrcPtr);
2704 Self.getASTContext())) {
2705 Self.Diag(OpRange.getBegin(), DiagID)
2707 << SrcExpr.get()->getSourceRange();
2716 DiagID = diag::ext_nested_pointer_qualifier_mismatch;
2722 bool SrcCompatXL = this->
getLangOpts().getAltivecSrcCompat() ==
2736 bool SrcCompatGCC = this->
getLangOpts().getAltivecSrcCompat() ==
2738 if (this->
getLangOpts().AltiVec && SrcCompatGCC) {
2740 diag::err_invalid_conversion_between_vector_and_integer)
2741 << VecTy << SrcTy << R;
2747void CastOperation::CheckCXXCStyleCast(
bool FunctionalStyle,
2748 bool ListInitialization) {
2749 assert(
Self.getLangOpts().CPlusPlus);
2752 if (isPlaceholder()) {
2754 if (claimPlaceholder(BuiltinType::UnknownAny)) {
2755 SrcExpr =
Self.checkUnknownAnyCast(DestRange, DestType,
2756 SrcExpr.get(), Kind,
2757 ValueKind, BasePath);
2761 checkNonOverloadPlaceholders();
2762 if (SrcExpr.isInvalid())
2772 if (claimPlaceholder(BuiltinType::Overload)) {
2773 Self.ResolveAndFixSingleFunctionTemplateSpecialization(
2775 true, DestRange, DestType,
2776 diag::err_bad_cstyle_cast_overload);
2777 if (SrcExpr.isInvalid())
2781 SrcExpr =
Self.IgnoredValueConversions(SrcExpr.get());
2786 if (DestType->
isDependentType() || SrcExpr.get()->isTypeDependent() ||
2787 SrcExpr.get()->isValueDependent()) {
2788 assert(Kind == CK_Dependent);
2795 if (
Self.getLangOpts().HLSL) {
2796 if (CheckHLSLCStyleCast(CCK))
2801 !isPlaceholder(BuiltinType::Overload)) {
2802 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
2803 if (SrcExpr.isInvalid())
2809 if (
Self.CheckAltivecInitFromScalar(OpRange, DestType,
2810 SrcExpr.get()->getType())) {
2814 if (
Self.ShouldSplatAltivecScalarInCast(vecTy) &&
2815 (SrcExpr.get()->getType()->isIntegerType() ||
2816 SrcExpr.get()->getType()->isFloatingType())) {
2817 Kind = CK_VectorSplat;
2818 SrcExpr =
Self.prepareVectorSplat(DestType, SrcExpr.get());
2824 QualType SrcType = SrcExpr.get()->getType();
2826 Self.Diag(OpRange.getBegin(), diag::err_wasm_cast_table)
2827 << 1 << SrcExpr.get()->getSourceRange();
2844 unsigned msg = diag::err_bad_cxx_cast_generic;
2847 if (SrcExpr.isInvalid())
2855 if (SrcExpr.isInvalid())
2862 BasePath, ListInitialization);
2863 if (SrcExpr.isInvalid())
2869 OpRange, msg, Kind);
2870 if (SrcExpr.isInvalid())
2876 if (
Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&
2878 checkObjCConversion(CCK);
2881 if (SrcExpr.get()->getType() ==
Self.Context.OverloadTy) {
2892 Self.Diag(OpRange.getBegin(), diag::err_bad_cstyle_cast_overload)
2893 << OE->
getName() << DestType << OpRange
2895 Self.NoteAllOverloadCandidates(SrcExpr.get());
2899 OpRange, SrcExpr.get(), DestType, ListInitialization);
2904 if (Kind == CK_BitCast)
2908 Self.Diag(OpRange.getBegin(), DiagID)
2909 << SrcExpr.get()->getType() << DestType << OpRange;
2920 assert(
Self.getLangOpts().HLSL &&
"Must be HLSL!");
2921 QualType SrcTy = SrcExpr.get()->getType();
2925 if (
Self.HLSL().CanPerformElementwiseCast(SrcExpr.get(), DestType)) {
2927 SrcExpr =
Self.ImpCastExprToType(
2928 SrcExpr.get(),
Self.Context.getArrayParameterType(SrcTy),
2929 CK_HLSLArrayRValue,
VK_PRValue,
nullptr, CCK);
2930 Kind = CK_HLSLElementwiseCast;
2937 if (
Self.HLSL().CanPerformAggregateSplatCast(SrcExpr.get(), DestType)) {
2941 SrcExpr =
Self.ImpCastExprToType(
2943 SrcExpr.get()->getValueKind(),
nullptr, CCK);
2947 SrcExpr =
Self.ImpCastExprToType(
2948 SrcExpr.get(), DVT->getElementType(),
2949 Self.PrepareScalarCast(SrcExpr, DVT->getElementType()),
2950 SrcExpr.get()->getValueKind(),
nullptr, CCK);
2951 Kind = CK_HLSLAggregateSplatCast;
2958 Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_generic)
2959 << 4 << SrcTy << DestType;
2971 if (
Self.Diags.isIgnored(diag::warn_bad_function_cast,
2975 if (!isa<CallExpr>(SrcExpr.
get()))
3000 diag::warn_bad_function_cast)
3005void CastOperation::CheckCStyleCast() {
3006 assert(!
Self.getLangOpts().CPlusPlus);
3009 if (claimPlaceholder(BuiltinType::UnknownAny)) {
3010 SrcExpr =
Self.checkUnknownAnyCast(DestRange, DestType,
3011 SrcExpr.get(), Kind,
3012 ValueKind, BasePath);
3020 SrcExpr =
Self.IgnoredValueConversions(SrcExpr.get());
3021 if (SrcExpr.isInvalid())
3030 if (
Self.getASTContext().isDependenceAllowed() &&
3032 SrcExpr.get()->isValueDependent())) {
3033 assert((DestType->
containsErrors() || SrcExpr.get()->containsErrors() ||
3034 SrcExpr.get()->containsErrors()) &&
3035 "should only occur in error-recovery path.");
3036 assert(Kind == CK_Dependent);
3041 if (SrcExpr.get()->getType() ==
Self.Context.OverloadTy) {
3044 SrcExpr.get(), DestType,
true, DAP))
3045 SrcExpr =
Self.FixOverloadedFunctionReference(SrcExpr.get(), DAP, FD);
3048 assert(SrcExpr.isUsable());
3050 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
3051 if (SrcExpr.isInvalid())
3053 QualType SrcType = SrcExpr.get()->getType();
3056 Self.Diag(OpRange.getBegin(), diag::err_wasm_cast_table)
3057 << 1 << SrcExpr.get()->getSourceRange();
3064 checkAddressSpaceCast(SrcType, DestType);
3065 if (SrcExpr.isInvalid())
3068 if (
Self.RequireCompleteType(OpRange.getBegin(), DestType,
3069 diag::err_typecheck_cast_to_incomplete)) {
3076 Self.Context.hasSameUnqualifiedType(DestType, SrcType)) {
3083 Self.isValidSveBitcast(SrcType, DestType)) {
3090 Self.RISCV().isValidRVVBitcast(SrcType, DestType)) {
3099 if (
Self.Context.hasSameUnqualifiedType(DestType, SrcType)) {
3101 Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_nonscalar)
3102 << DestType << SrcExpr.get()->getSourceRange();
3111 Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_to_union)
3112 << SrcExpr.get()->getSourceRange();
3116 Self.Diag(OpRange.getBegin(), diag::err_typecheck_cast_to_union_no_type)
3117 << SrcType << SrcExpr.get()->getSourceRange();
3124 if (
Self.getLangOpts().OpenCL && DestType->
isEventT()) {
3126 if (SrcExpr.get()->EvaluateAsInt(
Result,
Self.Context)) {
3127 llvm::APSInt CastInt =
Result.Val.getInt();
3129 Kind = CK_ZeroToOCLOpaqueType;
3132 Self.Diag(OpRange.getBegin(),
3133 diag::err_opencl_cast_non_zero_to_event_t)
3134 <<
toString(CastInt, 10) << SrcExpr.get()->getSourceRange();
3141 Self.Diag(OpRange.getBegin(), diag::err_typecheck_cond_expect_scalar)
3142 << DestType << SrcExpr.get()->getSourceRange();
3152 Self.Diag(SrcExpr.get()->getExprLoc(),
3153 diag::err_typecheck_expect_scalar_operand)
3154 << SrcType << SrcExpr.get()->getSourceRange();
3169 Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_nullptr_cast)
3176 Self.Context, DestType, CK_PointerToBoolean, SrcExpr.get(),
nullptr,
3185 Self.CurFPFeatureOverrides());
3190 if (!SrcExpr.get()->isNullPointerConstant(
Self.Context,
3192 Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_nullptr_cast)
3201 Self.CurFPFeatureOverrides());
3205 SrcExpr =
Self.CheckExtVectorCast(OpRange, DestType, SrcExpr.get(), Kind);
3210 if (
Self.CheckMatrixCast(OpRange, DestType, SrcType, Kind))
3216 if (
Self.CheckAltivecInitFromScalar(OpRange, DestType, SrcType)) {
3220 if (
Self.ShouldSplatAltivecScalarInCast(DestVecTy) &&
3222 Kind = CK_VectorSplat;
3223 SrcExpr =
Self.prepareVectorSplat(DestType, SrcExpr.get());
3224 }
else if (
Self.CheckVectorCast(OpRange, DestType, SrcType, Kind)) {
3231 if (
Self.CheckVectorCast(OpRange, SrcType, DestType, Kind))
3241 if (isa<ObjCSelectorExpr>(SrcExpr.get())) {
3242 Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_cast_selector_expr);
3251 Self.Diag(SrcExpr.get()->getExprLoc(),
3252 diag::err_cast_pointer_from_non_pointer_int)
3253 << SrcType << SrcExpr.get()->getSourceRange();
3262 Self.Diag(SrcExpr.get()->getBeginLoc(),
3263 diag::err_cast_pointer_to_non_pointer_int)
3264 << DestType << SrcExpr.get()->getSourceRange();
3269 if ((
Self.Context.getTypeSize(SrcType) >
3270 Self.Context.getTypeSize(DestType)) &&
3280 : diag::warn_void_pointer_to_int_cast;
3282 Diag = diag::warn_pointer_to_enum_cast;
3284 Diag = diag::warn_pointer_to_int_cast;
3285 Self.Diag(OpRange.getBegin(),
Diag) << SrcType << DestType << OpRange;
3289 if (
Self.getLangOpts().OpenCL && !
Self.getOpenCLOptions().isAvailableOption(
3290 "cl_khr_fp16",
Self.getLangOpts())) {
3292 Self.Diag(SrcExpr.get()->getBeginLoc(), diag::err_opencl_cast_to_half)
3293 << DestType << SrcExpr.get()->getSourceRange();
3300 if (
Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) {
3302 if (SrcExpr.isInvalid())
3306 if (
Self.getLangOpts().ObjCAutoRefCount && CastPtr) {
3309 Qualifiers ExprQuals = ExprPtr->getPointeeType().getQualifiers();
3311 ExprPtr->getPointeeType()->isObjCLifetimeType() &&
3313 Self.Diag(SrcExpr.get()->getBeginLoc(),
3314 diag::err_typecheck_incompatible_ownership)
3316 << SrcExpr.get()->getSourceRange();
3320 }
else if (!
Self.ObjC().CheckObjCARCUnavailableWeakConversion(DestType,
3322 Self.Diag(SrcExpr.get()->getBeginLoc(),
3323 diag::err_arc_convesion_of_weak_unavailable)
3324 << 1 << SrcType << DestType << SrcExpr.get()->getSourceRange();
3331 Self.Diag(OpRange.getBegin(), DiagID) << SrcType << DestType << OpRange;
3333 if (isa<PointerType>(SrcType) && isa<PointerType>(DestType)) {
3340 if (SrcRD && DestRD && SrcRD->
hasAttr<RandomizeLayoutAttr>() &&
3343 Self.Diag(OpRange.getBegin(), diag::err_cast_from_randomized_struct)
3344 << SrcType << DestType;
3353 Kind =
Self.PrepareScalarCast(SrcExpr, DestType);
3354 if (SrcExpr.isInvalid())
3357 if (Kind == CK_BitCast)
3361void CastOperation::CheckBuiltinBitCast() {
3362 QualType SrcType = SrcExpr.get()->getType();
3364 if (
Self.RequireCompleteType(OpRange.getBegin(), DestType,
3365 diag::err_typecheck_cast_to_incomplete) ||
3366 Self.RequireCompleteType(OpRange.getBegin(), SrcType,
3367 diag::err_incomplete_type)) {
3372 if (SrcExpr.get()->isPRValue())
3373 SrcExpr =
Self.CreateMaterializeTemporaryExpr(SrcType, SrcExpr.get(),
3376 CharUnits DestSize =
Self.Context.getTypeSizeInChars(DestType);
3377 CharUnits SourceSize =
Self.Context.getTypeSizeInChars(SrcType);
3378 if (DestSize != SourceSize) {
3379 Self.Diag(OpRange.getBegin(), diag::err_bit_cast_type_size_mismatch)
3387 Self.Diag(OpRange.getBegin(), diag::err_bit_cast_non_trivially_copyable)
3394 Self.Diag(OpRange.getBegin(), diag::err_bit_cast_non_trivially_copyable)
3400 Kind = CK_LValueToRValueBitCast;
3415 QualType TheOffendingSrcType, TheOffendingDestType;
3418 &TheOffendingSrcType, &TheOffendingDestType,
3419 &CastAwayQualifiers) !=
3420 CastAwayConstnessKind::CACK_Similar)
3424 int qualifiers = -1;
3427 }
else if (CastAwayQualifiers.
hasConst()) {
3433 if (qualifiers == -1)
3435 << SrcType << DestType;
3438 << TheOffendingSrcType << TheOffendingDestType << qualifiers;
3450 Op.CheckCXXCStyleCast(
false,
3453 Op.CheckCStyleCast();
3456 if (Op.SrcExpr.isInvalid())
3462 Op.checkQualifiedDestType();
3465 Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
3474 assert(LPLoc.
isValid() &&
"List-initialization shouldn't get here.");
3478 CastOperation::OpRangeType(Op.DestRange.getBegin(), LPLoc, RPLoc);
3480 Op.CheckCXXCStyleCast(
true,
false);
3481 if (Op.SrcExpr.isInvalid())
3484 Op.checkQualifiedDestType();
3490 Context, Op.ResultType, Op.ValueKind, CastTypeInfo, Op.Kind,
Defines the clang::ASTContext interface.
Defines the clang::Expr interface and subclasses for C++ expressions.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
Defines the clang::Preprocessor interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
static TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType, bool CStyle, CastOperation::OpRangeType OpRange, QualType OrigSrcType, QualType OrigDestType, unsigned &msg, CastKind &Kind, CXXCastPath &BasePath)
TryStaticDowncast - Common functionality of TryStaticReferenceDowncast and TryStaticPointerDowncast.
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
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
void UnwrapSimilarArrayTypes(QualType &T1, QualType &T2, bool AllowPiMismatch=true) const
Attempt to unwrap two types that may both be array types with the same bound (or both be array types ...
bool UnwrapSimilarTypes(QualType &T1, QualType &T2, bool AllowPiMismatch=true) const
Attempt to unwrap two types that may be similar (C++ [conv.qual]).
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.
This class is used for builtin types like 'int'.
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...
std::list< CXXBasePath >::const_iterator const_paths_iterator
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.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
static CXXReinterpretCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets)
static CXXStaticCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written, FPOptionsOverride FPO, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets)
bool isAtLeastAsQualifiedAs(CanQual< T > Other, const ASTContext &Ctx) const
Determines whether this canonical type is at least as qualified as the Other canonical type.
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
CanProxy< U > getAs() const
Retrieve a canonical type pointer with a different static type, upcasting or downcasting as needed.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
static const FieldDecl * getTargetFieldForToUnionCast(QualType unionType, QualType opType)
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
A POD class for pairing a NamedDecl* with an access specifier.
bool isInvalidDecl() const
Information about one declarator, including the parsed type information and the identifier.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
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)
PointerAuthQualifier getPointerAuth() const
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.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Base for LValueReferenceType and RValueReferenceType.
QualType getPointeeType() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial 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)
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.
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
The streaming interface shared between DiagnosticBuilder and PartialDiagnostic.
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 isIncompleteArrayType() 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.
The JSON file list parser is used to communicate input to InstallAPI.
OverloadingResult
OverloadingResult - Capture the result of performing overload resolution.
@ OR_Deleted
Succeeded, but refers to a deleted function.
@ OR_Success
Overload resolution succeeded.
@ OR_Ambiguous
Ambiguous candidates found.
@ OR_No_Viable_Function
No viable function found.
OverloadCandidateDisplayKind
@ OCD_AmbiguousCandidates
Requests that only tied-for-best candidates be shown.
@ OCD_ViableCandidates
Requests that only viable candidates be shown.
@ OCD_AllCandidates
Requests that all candidates be shown.
@ OK_VectorComponent
A vector component is an element or range of elements on a vector.
@ OK_ObjCProperty
An Objective-C property is a logical field of an Objective-C object which is read and written via Obj...
@ OK_ObjCSubscript
An Objective-C array/dictionary subscripting which reads an object or writes at the subscripted array...
@ OK_Ordinary
An ordinary object is located at an address in memory.
@ OK_BitField
A bitfield object is a bitfield on a C or C++ record.
@ OK_MatrixComponent
A matrix component is a single element of a matrix.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ASTContext::SectionInfo &Section)
Insertion operator for diagnostics.
@ Result
The result type of a method or function.
CastKind
CastKind - The kind of operation required for a conversion.
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.
const FunctionProtoType * T
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ AltiVecBool
is AltiVec 'vector bool ...'
@ AltiVecVector
is AltiVec vector
@ AltiVecPixel
is AltiVec 'vector Pixel'
@ None
The alignment was not explicit in code.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
@ 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
ReferenceConversions
The conversions that would be performed on an lvalue of type T2 when binding a reference of type T1 t...