28#include "llvm/ADT/SmallVector.h"
29#include "llvm/ADT/StringExtras.h"
59 struct CastOperation {
61 : Self(S), SrcExpr(src), DestType(destType),
64 Kind(CK_Dependent), IsARCUnbridgedCast(
false) {
75 !DestType->isArrayType()) {
76 DestType = DestType.getAtomicUnqualifiedType();
81 PlaceholderKind = placeholder->getKind();
95 bool IsARCUnbridgedCast;
101 void CheckConstCast();
102 void CheckReinterpretCast();
103 void CheckStaticCast();
104 void CheckDynamicCast();
105 void CheckCXXCStyleCast(
bool FunctionalCast,
bool ListInitialization);
106 void CheckCStyleCast();
107 void CheckBuiltinBitCast();
108 void CheckAddrspaceCast();
110 void updatePartOfExplicitCastFlags(
CastExpr *CE) {
114 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(CE->
getSubExpr()); CE = ICE)
115 ICE->setIsPartOfExplicitCast(
true);
123 if (IsARCUnbridgedCast) {
125 Self.Context, Self.Context.ARCUnbridgedCastTy, CK_Dependent,
127 Self.CurFPFeatureOverrides());
129 updatePartOfExplicitCastFlags(
castExpr);
139 if (PlaceholderKind != K)
return false;
145 bool isPlaceholder()
const {
146 return PlaceholderKind != 0;
149 return PlaceholderKind == K;
155 void checkCastAlign() {
156 Self.CheckCastAlign(SrcExpr.
get(), DestType, OpRange);
160 assert(Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers());
163 if (Self.ObjC().CheckObjCConversion(OpRange, DestType, src, CCK) ==
165 IsARCUnbridgedCast =
true;
170 void checkNonOverloadPlaceholders() {
171 if (!isPlaceholder() || isPlaceholder(BuiltinType::Overload))
174 SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.
get());
183 if (
const auto *PtrType = dyn_cast<PointerType>(FromType)) {
184 if (PtrType->getPointeeType()->hasAttr(attr::NoDeref)) {
185 if (
const auto *DestType = dyn_cast<PointerType>(ToType)) {
186 if (!DestType->getPointeeType()->hasAttr(attr::NoDeref)) {
187 S.
Diag(OpLoc, diag::warn_noderef_to_dereferenceable_pointer);
194 struct CheckNoDerefRAII {
195 CheckNoDerefRAII(CastOperation &Op) : Op(Op) {}
196 ~CheckNoDerefRAII() {
197 if (!Op.SrcExpr.isInvalid())
198 CheckNoDeref(Op.Self, Op.SrcExpr.get()->getType(), Op.ResultType,
199 Op.OpRange.getBegin());
241 QualType OrigDestType,
unsigned &msg,
255 unsigned &msg,
CastKind &Kind,
bool ListInitialization);
260 bool ListInitialization);
279 assert(!
D.isInvalidType());
282 if (
D.isInvalidType())
306 CastOperation Op(*
this, DestType,
E);
308 Op.DestRange = AngleBrackets;
311 default: llvm_unreachable(
"Unknown C++ cast!");
313 case tok::kw_addrspace_cast:
314 if (!TypeDependent) {
315 Op.CheckAddrspaceCast();
316 if (Op.SrcExpr.isInvalid())
320 Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
321 DestTInfo, OpLoc,
Parens.getEnd(), AngleBrackets));
323 case tok::kw_const_cast:
324 if (!TypeDependent) {
326 if (Op.SrcExpr.isInvalid())
331 Op.ValueKind, Op.SrcExpr.get(), DestTInfo,
335 case tok::kw_dynamic_cast: {
338 return ExprError(
Diag(OpLoc, diag::err_openclcxx_not_supported)
342 if (!TypeDependent) {
343 Op.CheckDynamicCast();
344 if (Op.SrcExpr.isInvalid())
348 Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
349 &Op.BasePath, DestTInfo,
353 case tok::kw_reinterpret_cast: {
354 if (!TypeDependent) {
355 Op.CheckReinterpretCast();
356 if (Op.SrcExpr.isInvalid())
361 Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
362 nullptr, DestTInfo, OpLoc,
366 case tok::kw_static_cast: {
367 if (!TypeDependent) {
368 Op.CheckStaticCast();
369 if (Op.SrcExpr.isInvalid())
375 Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
377 Parens.getEnd(), AngleBrackets));
385 assert(!
D.isInvalidType());
388 if (
D.isInvalidType())
397 CastOperation Op(*
this, TSI->
getType(), Operand);
403 Op.CheckBuiltinBitCast();
404 if (Op.SrcExpr.isInvalid())
410 Op.SrcExpr.get(), TSI, KWLoc, RParenLoc);
411 return Op.complete(BCE);
419 bool listInitialization) {
442 range, listInitialization)
455 default:
return false;
487 case OR_Success: llvm_unreachable(
"successful failed overload");
489 if (candidates.
empty())
490 msg = diag::err_ovl_no_conversion_in_cast;
492 msg = diag::err_ovl_no_viable_conversion_in_cast;
497 msg = diag::err_ovl_ambiguous_conversion_in_cast;
505 assert(Res ==
OR_Deleted &&
"Inconsistent overload resolution");
510 S.
PDiag(diag::err_ovl_deleted_conversion_in_cast)
511 << CT << srcType << destType << (Msg !=
nullptr)
512 << (Msg ? Msg->
getString() : StringRef())
521 S.
PDiag(msg) << CT << srcType << destType << range
523 S, howManyCandidates, src);
531 bool listInitialization) {
532 if (msg == diag::err_bad_cxx_cast_generic &&
541 int DifferentPtrness = 0;
552 if (!DifferentPtrness) {
555 if (RecFrom && RecTo) {
557 if (!DeclFrom->isCompleteDefinition())
558 S.
Diag(DeclFrom->getLocation(), diag::note_type_incomplete) << DeclFrom;
560 if (!DeclTo->isCompleteDefinition())
561 S.
Diag(DeclTo->getLocation(), diag::note_type_incomplete) << DeclTo;
569enum CastAwayConstnessKind {
576 CACK_SimilarKind = 2,
595static CastAwayConstnessKind
597 enum {
None, Ptr, MemPtr, BlockPtr, Array };
610 return AT->getElementType();
614 CastAwayConstnessKind Kind;
622 Kind = CastAwayConstnessKind::CACK_Similar;
624 Kind = CastAwayConstnessKind::CACK_Similar;
627 int T1Class = Classify(T1);
629 return CastAwayConstnessKind::CACK_None;
631 int T2Class = Classify(T2);
633 return CastAwayConstnessKind::CACK_None;
637 Kind = T1Class == T2Class ? CastAwayConstnessKind::CACK_SimilarKind
638 : CastAwayConstnessKind::CACK_Incoherent;
648 if (Classify(T1) != Array)
651 auto T2Class = Classify(T2);
655 if (T2Class != Array)
656 Kind = CastAwayConstnessKind::CACK_Incoherent;
657 else if (Kind != CastAwayConstnessKind::CACK_Incoherent)
658 Kind = CastAwayConstnessKind::CACK_SimilarKind;
673static CastAwayConstnessKind
675 bool CheckCVR,
bool CheckObjCLifetime,
676 QualType *TheOffendingSrcType =
nullptr,
677 QualType *TheOffendingDestType =
nullptr,
681 if (!CheckCVR && CheckObjCLifetime && !
Self.Context.getLangOpts().ObjC)
682 return CastAwayConstnessKind::CACK_None;
687 "Source type is not pointer or pointer to member.");
690 "Destination type is not pointer or pointer to member.");
693 QualType UnwrappedSrcType =
Self.Context.getCanonicalType(SrcType),
694 UnwrappedDestType =
Self.Context.getCanonicalType(DestType);
699 QualType PrevUnwrappedSrcType = UnwrappedSrcType;
700 QualType PrevUnwrappedDestType = UnwrappedDestType;
701 auto WorstKind = CastAwayConstnessKind::CACK_Similar;
702 bool AllConstSoFar =
true;
704 Self.Context, UnwrappedSrcType, UnwrappedDestType)) {
707 if (Kind > WorstKind)
712 Self.Context.getUnqualifiedArrayType(UnwrappedSrcType, SrcQuals);
713 Self.Context.getUnqualifiedArrayType(UnwrappedDestType, DestQuals);
719 UnwrappedDestType->isObjCObjectType())
728 if (SrcCvrQuals != DestCvrQuals) {
729 if (CastAwayQualifiers)
730 *CastAwayQualifiers = SrcCvrQuals - DestCvrQuals;
733 if (!DestCvrQuals.compatiblyIncludes(SrcCvrQuals,
734 Self.getASTContext())) {
735 if (TheOffendingSrcType)
736 *TheOffendingSrcType = PrevUnwrappedSrcType;
737 if (TheOffendingDestType)
738 *TheOffendingDestType = PrevUnwrappedDestType;
749 if (CheckObjCLifetime &&
755 if (AllConstSoFar && !DestQuals.
hasConst()) {
756 AllConstSoFar =
false;
757 if (TheOffendingSrcType)
758 *TheOffendingSrcType = PrevUnwrappedSrcType;
759 if (TheOffendingDestType)
760 *TheOffendingDestType = PrevUnwrappedDestType;
763 PrevUnwrappedSrcType = UnwrappedSrcType;
764 PrevUnwrappedDestType = UnwrappedDestType;
767 return CastAwayConstnessKind::CACK_None;
773 case CastAwayConstnessKind::CACK_None:
774 llvm_unreachable(
"did not cast away constness");
776 case CastAwayConstnessKind::CACK_Similar:
778 case CastAwayConstnessKind::CACK_SimilarKind:
779 DiagID = diag::err_bad_cxx_cast_qualifiers_away;
782 case CastAwayConstnessKind::CACK_Incoherent:
783 DiagID = diag::ext_bad_cxx_cast_qualifiers_away_incoherent;
787 llvm_unreachable(
"unexpected cast away constness kind");
793void CastOperation::CheckDynamicCast() {
794 CheckNoDerefRAII NoderefCheck(*
this);
797 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
798 else if (isPlaceholder())
799 SrcExpr =
Self.CheckPlaceholderExpr(SrcExpr.get());
800 if (SrcExpr.isInvalid())
803 QualType OrigSrcType = SrcExpr.get()->getType();
804 QualType DestType =
Self.Context.getCanonicalType(this->DestType);
817 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ref_or_ptr)
818 << this->DestType << DestRange;
825 assert(DestPointer &&
"Reference to void is not possible");
826 }
else if (DestRecord) {
827 if (
Self.RequireCompleteType(OpRange.getBegin(), DestPointee,
828 diag::err_bad_cast_incomplete,
834 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
844 QualType SrcType =
Self.Context.getCanonicalType(OrigSrcType);
850 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ptr)
851 << OrigSrcType << this->DestType << SrcExpr.get()->getSourceRange();
855 }
else if (DestReference->isLValueReferenceType()) {
856 if (!SrcExpr.get()->isLValue()) {
857 Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_rvalue)
858 <<
CT_Dynamic << OrigSrcType << this->DestType << OpRange;
860 SrcPointee = SrcType;
864 if (SrcExpr.get()->isPRValue())
865 SrcExpr =
Self.CreateMaterializeTemporaryExpr(
866 SrcType, SrcExpr.get(),
false);
867 SrcPointee = SrcType;
872 if (
Self.RequireCompleteType(OpRange.getBegin(), SrcPointee,
873 diag::err_bad_cast_incomplete,
879 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
885 assert((DestPointer || DestReference) &&
886 "Bad destination non-ptr/ref slipped through.");
887 assert((DestRecord || DestPointee->
isVoidType()) &&
888 "Bad destination pointee slipped through.");
889 assert(SrcRecord &&
"Bad source pointee slipped through.");
893 Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_qualifiers_away)
894 <<
CT_Dynamic << OrigSrcType << this->DestType << OpRange;
901 if (DestRecord == SrcRecord) {
909 Self.IsDerivedFrom(OpRange.getBegin(), SrcPointee, DestPointee)) {
910 if (
Self.CheckDerivedToBaseConversion(SrcPointee, DestPointee,
911 OpRange.getBegin(), OpRange,
917 Kind = CK_DerivedToBase;
923 assert(SrcDecl &&
"Definition missing");
924 if (!cast<CXXRecordDecl>(SrcDecl)->isPolymorphic()) {
925 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_polymorphic)
934 Self.Diag(OpRange.getBegin(), diag::err_no_dynamic_cast_with_fno_rtti);
940 if (!
Self.getLangOpts().RTTIData) {
942 Self.getASTContext().getTargetInfo().getCXXABI().isMicrosoft();
943 bool isClangCL =
Self.getDiagnostics().getDiagnosticOptions().getFormat() ==
945 if (MicrosoftABI || !DestPointee->
isVoidType())
946 Self.Diag(OpRange.getBegin(),
947 diag::warn_no_dynamic_cast_with_rtti_disabled)
955 if (DestDecl->isEffectivelyFinal())
956 Self.MarkVTableUsed(OpRange.getBegin(), DestDecl);
968void CastOperation::CheckConstCast() {
969 CheckNoDerefRAII NoderefCheck(*
this);
972 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
973 else if (isPlaceholder())
974 SrcExpr =
Self.CheckPlaceholderExpr(SrcExpr.get());
975 if (SrcExpr.isInvalid())
978 unsigned msg = diag::err_bad_cxx_cast_generic;
982 << SrcExpr.get()->getType() << DestType << OpRange;
988void CastOperation::CheckAddrspaceCast() {
989 unsigned msg = diag::err_bad_cxx_cast_generic;
993 Self.Diag(OpRange.getBegin(), msg)
994 <<
CT_Addrspace << SrcExpr.get()->getType() << DestType << OpRange;
1031 ReinterpretKind = ReinterpretUpcast;
1033 ReinterpretKind = ReinterpretDowncast;
1038 bool NonZeroOffset =
false;
1040 E = BasePaths.
end();
1044 bool IsVirtual =
false;
1045 for (CXXBasePath::const_iterator IElem =
Path.begin(), EElem =
Path.end();
1046 IElem != EElem; ++IElem) {
1047 IsVirtual = IElem->Base->isVirtual();
1050 const CXXRecordDecl *BaseRD = IElem->Base->getType()->getAsCXXRecordDecl();
1051 assert(BaseRD &&
"Base type should be a valid unqualified class type");
1055 *ClassDefinition =
Class->getDefinition();
1056 if (
Class->isInvalidDecl() || !ClassDefinition ||
1057 !ClassDefinition->isCompleteDefinition())
1066 if (Offset.isZero())
1070 NonZeroOffset =
true;
1075 (void) NonZeroOffset;
1077 "Should have returned if has non-virtual base with zero offset");
1080 ReinterpretKind == ReinterpretUpcast? DestType : SrcType;
1082 ReinterpretKind == ReinterpretUpcast? SrcType : DestType;
1085 Self.Diag(BeginLoc, diag::warn_reinterpret_different_from_static)
1086 << DerivedType << BaseType << !
VirtualBase <<
int(ReinterpretKind)
1088 Self.Diag(BeginLoc, diag::note_reinterpret_updowncast_use_static)
1089 <<
int(ReinterpretKind)
1110 unsigned int DiagID = 0;
1111 const unsigned int DiagList[] = {diag::warn_cast_function_type_strict,
1112 diag::warn_cast_function_type};
1137 assert(SrcFTy && DstFTy);
1139 if (
Self.Context.hasSameType(SrcFTy, DstFTy))
1143 if (DiagID == diag::warn_cast_function_type_strict)
1150 return !PT->isVariadic() && PT->getNumParams() == 0;
1155 if (IsVoidVoid(SrcFTy) || IsVoidVoid(DstFTy))
1169 const auto *SrcFPTy = cast<FunctionProtoType>(SrcFTy);
1170 const auto *DstFPTy = cast<FunctionProtoType>(DstFTy);
1174 unsigned NumParams = SrcFPTy->getNumParams();
1175 unsigned DstNumParams = DstFPTy->getNumParams();
1176 if (NumParams > DstNumParams) {
1177 if (!DstFPTy->isVariadic())
1179 NumParams = DstNumParams;
1180 }
else if (NumParams < DstNumParams) {
1181 if (!SrcFPTy->isVariadic())
1185 for (
unsigned i = 0; i < NumParams; ++i)
1187 DstFPTy->getParamType(i),
Self.Context))
1198void CastOperation::CheckReinterpretCast() {
1199 if (ValueKind ==
VK_PRValue && !isPlaceholder(BuiltinType::Overload))
1200 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
1202 checkNonOverloadPlaceholders();
1203 if (SrcExpr.isInvalid())
1206 unsigned msg = diag::err_bad_cxx_cast_generic;
1209 false, OpRange, msg, Kind);
1211 if (SrcExpr.isInvalid())
1213 if (SrcExpr.get()->getType() ==
Self.Context.OverloadTy) {
1215 Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_overload)
1217 << DestType << OpRange;
1218 Self.NoteAllOverloadCandidates(SrcExpr.get());
1227 if (
Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())
1232 Self.Diag(OpRange.getBegin(), DiagID)
1233 << SrcExpr.get()->getType() << DestType << OpRange;
1243void CastOperation::CheckStaticCast() {
1244 CheckNoDerefRAII NoderefCheck(*
this);
1246 if (isPlaceholder()) {
1247 checkNonOverloadPlaceholders();
1248 if (SrcExpr.isInvalid())
1258 if (claimPlaceholder(BuiltinType::Overload)) {
1259 Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr,
1262 OpRange, DestType, diag::err_bad_static_cast_overload);
1263 if (SrcExpr.isInvalid())
1267 SrcExpr =
Self.IgnoredValueConversions(SrcExpr.get());
1272 !isPlaceholder(BuiltinType::Overload)) {
1273 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
1274 if (SrcExpr.isInvalid())
1278 unsigned msg = diag::err_bad_cxx_cast_generic;
1281 OpRange, msg, Kind, BasePath,
false);
1283 if (SrcExpr.isInvalid())
1285 if (SrcExpr.get()->getType() ==
Self.Context.OverloadTy) {
1287 Self.Diag(OpRange.getBegin(), diag::err_bad_static_cast_overload)
1288 << oe->
getName() << DestType << OpRange
1290 Self.NoteAllOverloadCandidates(SrcExpr.get());
1298 if (Kind == CK_BitCast)
1300 if (
Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())
1315 DestPtrType->getPointeeType().getAddressSpace();
1325 bool ListInitialization) {
1351 OpRange, msg, Kind, BasePath);
1366 Kind, ListInitialization);
1388 if (
Enum->getDecl()->isScoped()) {
1390 Kind = CK_IntegralToBoolean;
1393 Kind = CK_IntegralCast;
1396 Kind = CK_IntegralToFloating;
1411 if (
Self.RequireCompleteType(OpRange.
getBegin(), DestType,
1412 diag::err_bad_cast_incomplete)) {
1420 Kind =
Enum->getDecl()->isFixed() &&
1421 Enum->getDecl()->getIntegerType()->isBooleanType()
1422 ? CK_IntegralToBoolean
1426 Kind = CK_FloatingToIntegral;
1442 OpRange, msg, Kind, BasePath);
1465 if (DestPointeeQuals != SrcPointeeQuals &&
1467 Self.getASTContext())) {
1468 msg = diag::err_bad_cxx_cast_qualifiers_away;
1473 ? CK_AddressSpaceConversion
1480 if (!CStyle &&
Self.getLangOpts().MSVCCompat &&
1482 Self.Diag(OpRange.
getBegin(), diag::ext_ms_cast_fn_obj) << OpRange;
1490 Kind = CK_CPointerToObjCPointerCast;
1495 Kind = CK_AnyPointerToBlockPointerCast;
1509 Self.ObjC().CheckTollFreeBridgeStaticCast(DestType, SrcExpr.
get(), Kind))
1516 if (SrcPointer->getPointeeType()->getAs<
RecordType>() &&
1518 msg = diag::err_bad_cxx_cast_unrelated_class;
1521 if (
Self.CheckMatrixCast(OpRange, DestType, SrcType, Kind)) {
1559 SrcExpr->
getBeginLoc(), ToType, FromType, &RefConv);
1566 msg = SrcExpr->
isLValue() ? diag::err_bad_lvalue_to_rvalue_cast
1567 : diag::err_bad_rvalue_to_rvalue_cast;
1571 if (RefConv & Sema::ReferenceConversions::DerivedToBase) {
1572 Kind = CK_DerivedToBase;
1579 Self.BuildBasePathArray(Paths, BasePath);
1602 if (!DestReference) {
1606 if (!RValueRef && !SrcExpr->
isLValue()) {
1608 msg = diag::err_bad_cxx_cast_rvalue;
1618 Self.Context.getCanonicalType(SrcExpr->
getType()),
1619 Self.Context.getCanonicalType(DestPointee), CStyle,
1620 OpRange, SrcExpr->
getType(), DestType, msg, Kind,
1645 msg = diag::err_bad_static_cast_pointer_nonpointer;
1652 CStyle, OpRange, SrcType, DestType, msg, Kind,
1662 QualType OrigDestType,
unsigned &msg,
1665 if (!
Self.isCompleteType(OpRange.
getBegin(), SrcType) ||
1676 if (!
Self.IsDerivedFrom(OpRange.
getBegin(), DestType, SrcType, Paths)) {
1701 msg = diag::err_bad_cxx_cast_qualifiers_away;
1710 if (!Paths.isRecordingPaths()) {
1712 Paths.setRecordingPaths(
true);
1713 Self.IsDerivedFrom(OpRange.
getBegin(), DestType, SrcType, Paths);
1715 std::string PathDisplayStr;
1716 std::set<unsigned> DisplayedPaths;
1718 if (DisplayedPaths.insert(
Path.back().SubobjectNumber).second) {
1721 PathDisplayStr +=
"\n ";
1723 PathDisplayStr += PE.Base->getType().getAsString() +
" -> ";
1728 Self.Diag(OpRange.
getBegin(), diag::err_ambiguous_base_to_derived_cast)
1731 << PathDisplayStr << OpRange;
1736 if (Paths.getDetectedVirtual() !=
nullptr) {
1738 Self.Diag(OpRange.
getBegin(), diag::err_static_downcast_via_virtual)
1739 << OrigSrcType << OrigDestType <<
VirtualBase << OpRange;
1748 diag::err_downcast_from_inaccessible_base)) {
1760 Self.BuildBasePathArray(Paths, BasePath);
1761 Kind = CK_BaseToDerived;
1782 bool WasOverloadedFunction =
false;
1786 =
Self.ResolveAddressOfOverloadedFunction(SrcExpr.
get(), DestType,
false,
1789 SrcType =
Self.Context.getMemberPointerType(Fn->getType(),
1791 WasOverloadedFunction =
true;
1797 msg = diag::err_bad_static_cast_member_pointer_nonmp;
1803 if (
Self.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
1804 (void)
Self.isCompleteType(OpRange.
getBegin(), SrcType);
1805 (void)
Self.isCompleteType(OpRange.
getBegin(), DestType);
1818 if (!
Self.IsDerivedFrom(OpRange.
getBegin(), SrcClass, DestClass, Paths))
1822 if (Paths.isAmbiguous(
Self.Context.getCanonicalType(DestClass))) {
1824 Paths.setRecordingPaths(
true);
1826 Self.IsDerivedFrom(OpRange.
getBegin(), SrcClass, DestClass, Paths);
1829 std::string PathDisplayStr =
Self.getAmbiguousPathsDisplayString(Paths);
1830 Self.Diag(OpRange.
getBegin(), diag::err_ambiguous_memptr_conv)
1831 << 1 << SrcClass << DestClass << PathDisplayStr << OpRange;
1836 if (
const RecordType *VBase = Paths.getDetectedVirtual()) {
1837 Self.Diag(OpRange.
getBegin(), diag::err_memptr_conv_via_virtual)
1838 << SrcClass << DestClass <<
QualType(VBase, 0) << OpRange;
1845 DestClass, SrcClass,
1847 diag::err_upcast_to_inaccessible_base)) {
1861 if (WasOverloadedFunction) {
1873 SrcExpr =
Self.FixOverloadedFunctionReference(SrcExpr, FoundOverload, Fn);
1880 Self.BuildBasePathArray(Paths, BasePath);
1881 Kind = CK_DerivedToBaseMemberPointer;
1894 CastKind &Kind,
bool ListInitialization) {
1896 if (
Self.RequireCompleteType(OpRange.
getBegin(), DestType,
1897 diag::err_bad_cast_incomplete) ||
1898 Self.RequireNonAbstractType(OpRange.
getBegin(), DestType,
1899 diag::err_allocation_of_abstract_type)) {
1914 Expr *SrcExprRaw = SrcExpr.
get();
1931 if (
Result.isInvalid()) {
1937 Kind = CK_ConstructorConversion;
1950 DestType =
Self.Context.getCanonicalType(DestType);
1952 bool NeedToMaterializeTemporary =
false;
1966 if (isa<LValueReferenceType>(DestTypeTmp) && !SrcExpr.
get()->
isLValue()) {
1970 msg = diag::err_bad_cxx_cast_rvalue;
1974 if (isa<RValueReferenceType>(DestTypeTmp) && SrcExpr.
get()->
isPRValue()) {
1978 msg = diag::err_bad_cxx_cast_rvalue;
1984 NeedToMaterializeTemporary =
true;
1993 msg = diag::err_bad_cxx_cast_bitfield;
1997 DestType =
Self.Context.getPointerType(DestTypeTmp->getPointeeType());
1998 SrcType =
Self.Context.getPointerType(SrcType);
2013 msg = diag::err_bad_const_cast_dest;
2022 msg = diag::err_bad_const_cast_dest;
2032 if (!
Self.Context.hasCvrSimilarType(SrcType, DestType))
2035 if (NeedToMaterializeTemporary)
2038 SrcExpr =
Self.CreateMaterializeTemporaryExpr(SrcExpr.
get()->
getType(),
2053 unsigned DiagID = IsDereference ?
2054 diag::warn_pointer_indirection_from_incompatible_type :
2055 diag::warn_undefined_reinterpret_cast;
2061 if (IsDereference) {
2103 if (
Self.Context.hasSameType(SrcType, DestType))
2106 if (SrcPtrTy->isObjCSelType()) {
2108 if (isa<PointerType>(DestType))
2112 diag::warn_cast_pointer_from_sel)
2124 if (
Self.Context.hasSameType(SrcType, DstType) ||
2127 const auto *SrcFTy =
2129 const auto *DstFTy =
2139 if (
auto *UO = dyn_cast<UnaryOperator>(Src))
2140 if (UO->getOpcode() == UO_AddrOf)
2142 auto *DRE = dyn_cast<DeclRefExpr>(Src);
2145 auto *FD = dyn_cast<FunctionDecl>(DRE->getDecl());
2153 CallingConv DefaultCC =
Self.getASTContext().getDefaultCallingConvention(
2154 FD->isVariadic(), FD->isCXXInstanceMember());
2155 if (DstCC == DefaultCC || SrcCC != DefaultCC)
2161 Self.Diag(OpRange.
getBegin(), diag::warn_cast_calling_conv)
2162 << SrcCCName << DstCCName << OpRange;
2167 if (
Self.Diags.isIgnored(diag::warn_cast_calling_conv, OpRange.
getBegin()))
2174 SourceLocation NameLoc = FD->getFirstDecl()->getNameInfo().getLoc();
2178 llvm::raw_svector_ostream OS(CCAttrText);
2179 if (
Self.getLangOpts().MicrosoftExt) {
2181 OS <<
"__" << DstCCName;
2188 OS <<
"__attribute__((" << DstCCName <<
"))";
2189 AttrTokens.push_back(tok::kw___attribute);
2190 AttrTokens.push_back(tok::l_paren);
2191 AttrTokens.push_back(tok::l_paren);
2196 AttrTokens.push_back(tok::r_paren);
2197 AttrTokens.push_back(tok::r_paren);
2200 if (!AttrSpelling.empty())
2201 CCAttrText = AttrSpelling;
2203 Self.Diag(NameLoc, diag::note_change_calling_conv_fixit)
2219 &&
Self.Context.getTypeSize(DestType) >
2220 Self.Context.getTypeSize(SrcType)) {
2227 diag::warn_int_to_void_pointer_cast
2228 : diag::warn_int_to_pointer_cast;
2244 if (
Self.ResolveAndFixSingleFunctionTemplateSpecialization(
2255 if (!
Self.resolveAndFixAddressOfSingleOverloadCandidate(
2258 return Result.isUsable();
2266 bool IsLValueCast =
false;
2268 DestType =
Self.Context.getCanonicalType(DestType);
2273 if (SrcType ==
Self.Context.OverloadTy) {
2278 assert(FixedExpr.
isUsable() &&
"Invalid result fixing overloaded expr");
2279 SrcExpr = FixedExpr;
2287 msg = diag::err_bad_cxx_cast_rvalue;
2292 Self.CheckCompatibleReinterpretCast(SrcType, DestType,
2300 const char *inappropriate =
nullptr;
2305 msg = diag::err_bad_cxx_cast_bitfield;
2310 inappropriate =
"matrix element";
2313 case OK_ObjCSubscript: inappropriate =
"container subscripting expression";
2316 if (inappropriate) {
2317 Self.Diag(OpRange.
getBegin(), diag::err_bad_reinterpret_cast_reference)
2318 << inappropriate << DestType
2325 DestType =
Self.Context.getPointerType(DestTypeTmp->getPointeeType());
2326 SrcType =
Self.Context.getPointerType(SrcType);
2328 IsLValueCast =
true;
2332 SrcType =
Self.Context.getCanonicalType(SrcType);
2336 if (DestMemPtr && SrcMemPtr) {
2342 SrcMemPtr->isMemberFunctionPointer())
2345 if (
Self.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
2348 (void)
Self.isCompleteType(OpRange.
getBegin(), SrcType);
2349 (void)
Self.isCompleteType(OpRange.
getBegin(), DestType);
2353 if (
Self.Context.getTypeSize(DestMemPtr) !=
2354 Self.Context.getTypeSize(SrcMemPtr)) {
2355 msg = diag::err_bad_cxx_cast_member_pointer_size;
2369 assert(!IsLValueCast);
2370 Kind = CK_ReinterpretMemberPointer;
2380 if (
Self.Context.getTypeSize(SrcType) >
2381 Self.Context.getTypeSize(DestType)) {
2382 msg = diag::err_bad_reinterpret_cast_small_int;
2385 Kind = CK_PointerToIntegral;
2393 if (srcIsVector || destIsVector) {
2395 if (
Self.isValidSveBitcast(SrcType, DestType)) {
2401 if (
Self.RISCV().isValidRVVBitcast(SrcType, DestType)) {
2415 if (
Self.areLaxCompatibleVectorTypes(SrcType, DestType)) {
2420 if (
Self.LangOpts.OpenCL && !CStyle) {
2423 if (
Self.areVectorTypesSameSize(SrcType, DestType)) {
2432 msg = diag::err_bad_cxx_cast_vector_to_scalar_different_size;
2433 else if (!srcIsVector)
2434 msg = diag::err_bad_cxx_cast_scalar_to_vector_different_size;
2436 msg = diag::err_bad_cxx_cast_vector_to_vector_different_size;
2441 if (SrcType == DestType) {
2465 if (!destIsPtr && !srcIsPtr) {
2472 assert(srcIsPtr &&
"One type must be a pointer");
2476 if ((
Self.Context.getTypeSize(SrcType) >
2477 Self.Context.getTypeSize(DestType))) {
2478 bool MicrosoftException =
2480 if (MicrosoftException) {
2482 ? diag::warn_void_pointer_to_int_cast
2483 : diag::warn_pointer_to_int_cast;
2486 msg = diag::err_bad_reinterpret_cast_small_int;
2490 Kind = CK_PointerToIntegral;
2495 assert(destIsPtr &&
"One type must be a pointer");
2501 Kind = CK_IntegralToPointer;
2505 if (!destIsPtr || !srcIsPtr) {
2525 Kind = CK_AddressSpaceConversion;
2532 }
else if (IsLValueCast) {
2533 Kind = CK_LValueBitCast;
2535 Kind =
Self.ObjC().PrepareCastToObjCObjectPointer(SrcExpr);
2538 Kind = CK_AnyPointerToBlockPointerCast;
2549 return SuccessResult;
2563 return SuccessResult;
2573 Self.getLangOpts().CPlusPlus11 ?
2574 diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)
2576 return SuccessResult;
2582 Self.getLangOpts().CPlusPlus11 ?
2583 diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)
2585 return SuccessResult;
2598 diag::warn_bad_cxx_cast_nested_pointer_addr_space)
2611 return SuccessResult;
2617 if (!
Self.getLangOpts().OpenCL && !
Self.getLangOpts().SYCLIsDevice)
2634 auto SrcPointeeType = SrcPtrType->getPointeeType();
2635 auto DestPointeeType = DestPtrType->getPointeeType();
2636 if (!DestPointeeType.isAddressSpaceOverlapping(SrcPointeeType,
2637 Self.getASTContext())) {
2638 msg = diag::err_bad_cxx_cast_addr_space_mismatch;
2641 auto SrcPointeeTypeWithoutAS =
2642 Self.Context.removeAddrSpaceQualType(SrcPointeeType.getCanonicalType());
2643 auto DestPointeeTypeWithoutAS =
2644 Self.Context.removeAddrSpaceQualType(DestPointeeType.getCanonicalType());
2645 if (
Self.Context.hasSameType(SrcPointeeTypeWithoutAS,
2646 DestPointeeTypeWithoutAS)) {
2647 Kind = SrcPointeeType.getAddressSpace() == DestPointeeType.getAddressSpace()
2649 : CK_AddressSpaceConversion;
2656void CastOperation::checkAddressSpaceCast(
QualType SrcType,
QualType DestType) {
2668 if (
Self.getLangOpts().OpenCL) {
2669 const Type *DestPtr, *SrcPtr;
2670 bool Nested =
false;
2671 unsigned DiagID = diag::err_typecheck_incompatible_address_space;
2672 DestPtr =
Self.getASTContext().getCanonicalType(DestType.
getTypePtr()),
2673 SrcPtr =
Self.getASTContext().getCanonicalType(SrcType.
getTypePtr());
2675 while (isa<PointerType>(DestPtr) && isa<PointerType>(SrcPtr)) {
2676 const PointerType *DestPPtr = cast<PointerType>(DestPtr);
2677 const PointerType *SrcPPtr = cast<PointerType>(SrcPtr);
2683 Self.getASTContext())) {
2684 Self.Diag(OpRange.getBegin(), DiagID)
2686 << SrcExpr.get()->getSourceRange();
2695 DiagID = diag::ext_nested_pointer_qualifier_mismatch;
2701 bool SrcCompatXL = this->
getLangOpts().getAltivecSrcCompat() ==
2715 bool SrcCompatGCC = this->
getLangOpts().getAltivecSrcCompat() ==
2717 if (this->
getLangOpts().AltiVec && SrcCompatGCC) {
2719 diag::err_invalid_conversion_between_vector_and_integer)
2720 << VecTy << SrcTy << R;
2726void CastOperation::CheckCXXCStyleCast(
bool FunctionalStyle,
2727 bool ListInitialization) {
2728 assert(
Self.getLangOpts().CPlusPlus);
2731 if (isPlaceholder()) {
2733 if (claimPlaceholder(BuiltinType::UnknownAny)) {
2734 SrcExpr =
Self.checkUnknownAnyCast(DestRange, DestType,
2735 SrcExpr.get(), Kind,
2736 ValueKind, BasePath);
2740 checkNonOverloadPlaceholders();
2741 if (SrcExpr.isInvalid())
2751 if (claimPlaceholder(BuiltinType::Overload)) {
2752 Self.ResolveAndFixSingleFunctionTemplateSpecialization(
2754 true, DestRange, DestType,
2755 diag::err_bad_cstyle_cast_overload);
2756 if (SrcExpr.isInvalid())
2760 SrcExpr =
Self.IgnoredValueConversions(SrcExpr.get());
2765 if (DestType->
isDependentType() || SrcExpr.get()->isTypeDependent() ||
2766 SrcExpr.get()->isValueDependent()) {
2767 assert(Kind == CK_Dependent);
2772 !isPlaceholder(BuiltinType::Overload)) {
2773 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
2774 if (SrcExpr.isInvalid())
2780 if (
Self.CheckAltivecInitFromScalar(OpRange, DestType,
2781 SrcExpr.get()->getType())) {
2785 if (
Self.ShouldSplatAltivecScalarInCast(vecTy) &&
2786 (SrcExpr.get()->getType()->isIntegerType() ||
2787 SrcExpr.get()->getType()->isFloatingType())) {
2788 Kind = CK_VectorSplat;
2789 SrcExpr =
Self.prepareVectorSplat(DestType, SrcExpr.get());
2795 QualType SrcType = SrcExpr.get()->getType();
2797 Self.Diag(OpRange.getBegin(), diag::err_wasm_cast_table)
2798 << 1 << SrcExpr.get()->getSourceRange();
2815 unsigned msg = diag::err_bad_cxx_cast_generic;
2818 if (SrcExpr.isInvalid())
2829 if (SrcExpr.isInvalid())
2836 BasePath, ListInitialization);
2837 if (SrcExpr.isInvalid())
2843 OpRange, msg, Kind);
2844 if (SrcExpr.isInvalid())
2850 if (
Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&
2852 checkObjCConversion(CCK);
2855 if (SrcExpr.get()->getType() ==
Self.Context.OverloadTy) {
2866 Self.Diag(OpRange.getBegin(), diag::err_bad_cstyle_cast_overload)
2867 << OE->
getName() << DestType << OpRange
2869 Self.NoteAllOverloadCandidates(SrcExpr.get());
2873 OpRange, SrcExpr.get(), DestType, ListInitialization);
2878 if (Kind == CK_BitCast)
2882 Self.Diag(OpRange.getBegin(), DiagID)
2883 << SrcExpr.get()->getType() << DestType << OpRange;
2895 if (
Self.Diags.isIgnored(diag::warn_bad_function_cast,
2899 if (!isa<CallExpr>(SrcExpr.
get()))
2924 diag::warn_bad_function_cast)
2929void CastOperation::CheckCStyleCast() {
2930 assert(!
Self.getLangOpts().CPlusPlus);
2933 if (claimPlaceholder(BuiltinType::UnknownAny)) {
2934 SrcExpr =
Self.checkUnknownAnyCast(DestRange, DestType,
2935 SrcExpr.get(), Kind,
2936 ValueKind, BasePath);
2944 SrcExpr =
Self.IgnoredValueConversions(SrcExpr.get());
2945 if (SrcExpr.isInvalid())
2954 if (
Self.getASTContext().isDependenceAllowed() &&
2956 SrcExpr.get()->isValueDependent())) {
2957 assert((DestType->
containsErrors() || SrcExpr.get()->containsErrors() ||
2958 SrcExpr.get()->containsErrors()) &&
2959 "should only occur in error-recovery path.");
2960 assert(Kind == CK_Dependent);
2965 if (SrcExpr.get()->getType() ==
Self.Context.OverloadTy) {
2968 SrcExpr.get(), DestType,
true, DAP))
2969 SrcExpr =
Self.FixOverloadedFunctionReference(SrcExpr.get(), DAP, FD);
2972 assert(SrcExpr.isUsable());
2974 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
2975 if (SrcExpr.isInvalid())
2977 QualType SrcType = SrcExpr.get()->getType();
2980 Self.Diag(OpRange.getBegin(), diag::err_wasm_cast_table)
2981 << 1 << SrcExpr.get()->getSourceRange();
2988 checkAddressSpaceCast(SrcType, DestType);
2989 if (SrcExpr.isInvalid())
2992 if (
Self.RequireCompleteType(OpRange.getBegin(), DestType,
2993 diag::err_typecheck_cast_to_incomplete)) {
3000 Self.Context.hasSameUnqualifiedType(DestType, SrcType)) {
3007 Self.isValidSveBitcast(SrcType, DestType)) {
3014 Self.RISCV().isValidRVVBitcast(SrcType, DestType)) {
3023 if (DestRecordTy &&
Self.Context.hasSameUnqualifiedType(DestType, SrcType)){
3025 Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_nonscalar)
3026 << DestType << SrcExpr.get()->getSourceRange();
3035 Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_to_union)
3036 << SrcExpr.get()->getSourceRange();
3040 Self.Diag(OpRange.getBegin(), diag::err_typecheck_cast_to_union_no_type)
3041 << SrcType << SrcExpr.get()->getSourceRange();
3048 if (
Self.getLangOpts().OpenCL && DestType->
isEventT()) {
3050 if (SrcExpr.get()->EvaluateAsInt(
Result,
Self.Context)) {
3051 llvm::APSInt CastInt =
Result.Val.getInt();
3053 Kind = CK_ZeroToOCLOpaqueType;
3056 Self.Diag(OpRange.getBegin(),
3057 diag::err_opencl_cast_non_zero_to_event_t)
3058 <<
toString(CastInt, 10) << SrcExpr.get()->getSourceRange();
3065 Self.Diag(OpRange.getBegin(), diag::err_typecheck_cond_expect_scalar)
3066 << DestType << SrcExpr.get()->getSourceRange();
3076 Self.Diag(SrcExpr.get()->getExprLoc(),
3077 diag::err_typecheck_expect_scalar_operand)
3078 << SrcType << SrcExpr.get()->getSourceRange();
3093 Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_nullptr_cast)
3104 Self.CurFPFeatureOverrides());
3108 Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_nullptr_cast)
3115 SrcExpr =
Self.CheckExtVectorCast(OpRange, DestType, SrcExpr.get(), Kind);
3120 if (
Self.CheckMatrixCast(OpRange, DestType, SrcType, Kind))
3126 if (
Self.CheckAltivecInitFromScalar(OpRange, DestType, SrcType)) {
3130 if (
Self.ShouldSplatAltivecScalarInCast(DestVecTy) &&
3132 Kind = CK_VectorSplat;
3133 SrcExpr =
Self.prepareVectorSplat(DestType, SrcExpr.get());
3134 }
else if (
Self.CheckVectorCast(OpRange, DestType, SrcType, Kind)) {
3141 if (
Self.CheckVectorCast(OpRange, SrcType, DestType, Kind))
3151 if (isa<ObjCSelectorExpr>(SrcExpr.get())) {
3152 Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_cast_selector_expr);
3161 Self.Diag(SrcExpr.get()->getExprLoc(),
3162 diag::err_cast_pointer_from_non_pointer_int)
3163 << SrcType << SrcExpr.get()->getSourceRange();
3172 Self.Diag(SrcExpr.get()->getBeginLoc(),
3173 diag::err_cast_pointer_to_non_pointer_int)
3174 << DestType << SrcExpr.get()->getSourceRange();
3179 if ((
Self.Context.getTypeSize(SrcType) >
3180 Self.Context.getTypeSize(DestType)) &&
3190 : diag::warn_void_pointer_to_int_cast;
3192 Diag = diag::warn_pointer_to_enum_cast;
3194 Diag = diag::warn_pointer_to_int_cast;
3195 Self.Diag(OpRange.getBegin(),
Diag) << SrcType << DestType << OpRange;
3199 if (
Self.getLangOpts().OpenCL && !
Self.getOpenCLOptions().isAvailableOption(
3200 "cl_khr_fp16",
Self.getLangOpts())) {
3202 Self.Diag(SrcExpr.get()->getBeginLoc(), diag::err_opencl_cast_to_half)
3203 << DestType << SrcExpr.get()->getSourceRange();
3210 if (
Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) {
3212 if (SrcExpr.isInvalid())
3216 if (
Self.getLangOpts().ObjCAutoRefCount && CastPtr) {
3219 Qualifiers ExprQuals = ExprPtr->getPointeeType().getQualifiers();
3221 ExprPtr->getPointeeType()->isObjCLifetimeType() &&
3223 Self.Diag(SrcExpr.get()->getBeginLoc(),
3224 diag::err_typecheck_incompatible_ownership)
3226 << SrcExpr.get()->getSourceRange();
3230 }
else if (!
Self.ObjC().CheckObjCARCUnavailableWeakConversion(DestType,
3232 Self.Diag(SrcExpr.get()->getBeginLoc(),
3233 diag::err_arc_convesion_of_weak_unavailable)
3234 << 1 << SrcType << DestType << SrcExpr.get()->getSourceRange();
3241 Self.Diag(OpRange.getBegin(), DiagID) << SrcType << DestType << OpRange;
3243 if (isa<PointerType>(SrcType) && isa<PointerType>(DestType)) {
3250 if (SrcRD && DestRD && SrcRD->
hasAttr<RandomizeLayoutAttr>() &&
3253 Self.Diag(OpRange.getBegin(), diag::err_cast_from_randomized_struct)
3254 << SrcType << DestType;
3263 Kind =
Self.PrepareScalarCast(SrcExpr, DestType);
3264 if (SrcExpr.isInvalid())
3267 if (Kind == CK_BitCast)
3271void CastOperation::CheckBuiltinBitCast() {
3272 QualType SrcType = SrcExpr.get()->getType();
3274 if (
Self.RequireCompleteType(OpRange.getBegin(), DestType,
3275 diag::err_typecheck_cast_to_incomplete) ||
3276 Self.RequireCompleteType(OpRange.getBegin(), SrcType,
3277 diag::err_incomplete_type)) {
3282 if (SrcExpr.get()->isPRValue())
3283 SrcExpr =
Self.CreateMaterializeTemporaryExpr(SrcType, SrcExpr.get(),
3286 CharUnits DestSize =
Self.Context.getTypeSizeInChars(DestType);
3287 CharUnits SourceSize =
Self.Context.getTypeSizeInChars(SrcType);
3288 if (DestSize != SourceSize) {
3289 Self.Diag(OpRange.getBegin(), diag::err_bit_cast_type_size_mismatch)
3297 Self.Diag(OpRange.getBegin(), diag::err_bit_cast_non_trivially_copyable)
3304 Self.Diag(OpRange.getBegin(), diag::err_bit_cast_non_trivially_copyable)
3310 Kind = CK_LValueToRValueBitCast;
3325 QualType TheOffendingSrcType, TheOffendingDestType;
3328 &TheOffendingSrcType, &TheOffendingDestType,
3329 &CastAwayQualifiers) !=
3330 CastAwayConstnessKind::CACK_Similar)
3334 int qualifiers = -1;
3337 }
else if (CastAwayQualifiers.
hasConst()) {
3343 if (qualifiers == -1)
3345 << SrcType << DestType;
3348 << TheOffendingSrcType << TheOffendingDestType << qualifiers;
3360 Op.CheckCXXCStyleCast(
false,
3363 Op.CheckCStyleCast();
3366 if (Op.SrcExpr.isInvalid())
3373 Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
3382 assert(LPLoc.
isValid() &&
"List-initialization shouldn't get here.");
3385 Op.OpRange =
SourceRange(Op.DestRange.getBegin(), RPLoc);
3387 Op.CheckCXXCStyleCast(
true,
false);
3388 if (Op.SrcExpr.isInvalid())
3391 auto *SubExpr = Op.SrcExpr.get();
3392 if (
auto *BindExpr = dyn_cast<CXXBindTemporaryExpr>(SubExpr))
3393 SubExpr = BindExpr->getSubExpr();
3394 if (
auto *ConstructExpr = dyn_cast<CXXConstructExpr>(SubExpr))
3395 ConstructExpr->setParenOrBraceRange(
SourceRange(LPLoc, RPLoc));
3401 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 void DiagnoseReinterpretUpDownCast(Sema &Self, const Expr *SrcExpr, QualType DestType, SourceRange OpRange)
Check that a reinterpret_cast<DestType>(SrcExpr) is not used as upcast or downcast between respective...
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 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 bool isValidCast(TryCastResult TCR)
static void diagnoseBadCast(Sema &S, unsigned msg, CastType castType, SourceRange opRange, Expr *src, QualType destType, bool listInitialization)
Diagnose a failed cast.
static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT, SourceRange range, Expr *src, QualType destType, bool listInitialization)
Try to diagnose a failed overloaded cast.
static bool argTypeIsABIEquivalent(QualType SrcType, QualType DestType, ASTContext &Context)
static unsigned int checkCastFunctionType(Sema &Self, const ExprResult &SrcExpr, QualType DestType)
@ 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 TryCastResult TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType, bool CStyle, SourceRange OpRange, unsigned &msg, CastKind &Kind, CXXCastPath &BasePath)
Tests whether a conversion according to C++ 5.2.9p5 is valid.
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 TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, CheckedConversionKind CCK, SourceRange OpRange, unsigned &msg, CastKind &Kind, bool ListInitialization)
TryStaticImplicitCast - Tests whether a conversion according to C++ 5.2.9p2 is valid:
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 TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType, bool CStyle, SourceRange OpRange, QualType OrigSrcType, QualType OrigDestType, unsigned &msg, CastKind &Kind, CXXCastPath &BasePath)
TryStaticDowncast - Common functionality of TryStaticReferenceDowncast and TryStaticPointerDowncast.
static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, bool CStyle, SourceRange OpRange, unsigned &msg, CastKind &Kind)
static bool fixOverloadedReinterpretCastExpr(Sema &Self, QualType DestType, ExprResult &Result)
static CastAwayConstnessKind unwrapCastAwayConstnessLevel(ASTContext &Context, QualType &T1, QualType &T2)
Unwrap one level of types for CastsAwayConstness.
static void DiagnoseCallingConvCast(Sema &Self, const ExprResult &SrcExpr, QualType DstType, SourceRange OpRange)
Diagnose casts that change the calling convention of a pointer to a function defined in the current T...
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.
static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, QualType SrcType, QualType DestType, bool CStyle, SourceRange OpRange, unsigned &msg, CastKind &Kind, CXXCastPath &BasePath)
TryStaticMemberPointerUpcast - Tests whether a conversion according to C++ 5.2.9p9 is valid:
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)
static TryCastResult TryStaticPointerDowncast(Sema &Self, QualType SrcType, QualType DestType, bool CStyle, SourceRange OpRange, unsigned &msg, CastKind &Kind, CXXCastPath &BasePath)
Tests whether a conversion according to C++ 5.2.9p8 is valid.
static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, CheckedConversionKind CCK, SourceRange OpRange, unsigned &msg, CastKind &Kind, CXXCastPath &BasePath, bool ListInitialization)
TryStaticCast - Check if a static cast can be performed, and do so if possible.
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 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.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
bool isIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
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(SourceRange TypeRange, 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.
QualType getPointeeType() const
bool isMemberFunctionPointer() const
Returns true if the member type (i.e.
const Type * getClass() const
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range covering the entirety of this nested-name-specifier.
OverloadCandidateSet - A set of overload candidates, used in C++ overload resolution (C++ 13....
SmallVectorImpl< OverloadCandidate >::iterator iterator
void NoteCandidates(PartialDiagnosticAt PA, Sema &S, OverloadCandidateDisplayKind OCD, ArrayRef< Expr * > Args, StringRef Opc="", SourceLocation Loc=SourceLocation(), llvm::function_ref< bool(OverloadCandidate &)> Filter=[](OverloadCandidate &) { return true;})
When overload resolution fails, prints diagnostic messages containing the candidates in the candidate...
OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc, OverloadCandidateSet::iterator &Best)
Find the best viable function on this overload set, if it exists.
A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr.
static FindResult find(Expr *E)
Finds the overloaded expression in the given expression E of OverloadTy.
NestedNameSpecifierLoc getQualifierLoc() const
Fetches the nested-name qualifier with source-location information, if one was given.
DeclarationName getName() const
Gets the name looked up.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
StringRef getLastMacroWithSpelling(SourceLocation Loc, ArrayRef< TokenValue > Tokens) const
Return the name of the macro defined before Loc that has spelling Tokens.
A (possibly-)qualified type.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type.
bool isAddressSpaceOverlapping(QualType T, const ASTContext &Ctx) const
Returns true if address space qualifiers overlap with T address space qualifiers.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType 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...
RecordDecl * getDecl() const
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
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.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
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
bool isConstantArrayType() const
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
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.
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
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Represents a GCC generic vector type.
VectorKind getVectorKind() 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'.
@ 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...