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) {
76 !DestType->isArrayType()) {
77 DestType = DestType.getAtomicUnqualifiedType();
82 PlaceholderKind = placeholder->getKind();
96 bool IsARCUnbridgedCast;
102 void CheckConstCast();
103 void CheckReinterpretCast();
104 void CheckStaticCast();
105 void CheckDynamicCast();
106 void CheckCXXCStyleCast(
bool FunctionalCast,
bool ListInitialization);
107 void CheckCStyleCast();
108 void CheckBuiltinBitCast();
109 void CheckAddrspaceCast();
111 void updatePartOfExplicitCastFlags(
CastExpr *CE) {
115 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(CE->
getSubExpr()); CE = ICE)
116 ICE->setIsPartOfExplicitCast(
true);
124 if (IsARCUnbridgedCast) {
126 Self.Context, Self.Context.ARCUnbridgedCastTy, CK_Dependent,
128 Self.CurFPFeatureOverrides());
130 updatePartOfExplicitCastFlags(
castExpr);
140 if (PlaceholderKind != K)
return false;
146 bool isPlaceholder()
const {
147 return PlaceholderKind != 0;
150 return PlaceholderKind == K;
156 void checkCastAlign() {
157 Self.CheckCastAlign(SrcExpr.
get(), DestType, OpRange);
161 assert(Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers());
164 if (Self.ObjC().CheckObjCConversion(OpRange, DestType, src, CCK) ==
166 IsARCUnbridgedCast =
true;
171 void checkNonOverloadPlaceholders() {
172 if (!isPlaceholder() || isPlaceholder(BuiltinType::Overload))
175 SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.
get());
184 if (
const auto *PtrType = dyn_cast<PointerType>(FromType)) {
185 if (PtrType->getPointeeType()->hasAttr(attr::NoDeref)) {
186 if (
const auto *DestType = dyn_cast<PointerType>(ToType)) {
187 if (!DestType->getPointeeType()->hasAttr(attr::NoDeref)) {
188 S.
Diag(OpLoc, diag::warn_noderef_to_dereferenceable_pointer);
195 struct CheckNoDerefRAII {
196 CheckNoDerefRAII(CastOperation &Op) : Op(Op) {}
197 ~CheckNoDerefRAII() {
198 if (!Op.SrcExpr.isInvalid())
199 CheckNoDeref(Op.Self, Op.SrcExpr.get()->getType(), Op.ResultType,
200 Op.OpRange.getBegin());
242 QualType OrigDestType,
unsigned &msg,
256 unsigned &msg,
CastKind &Kind,
bool ListInitialization);
261 bool ListInitialization);
280 assert(!
D.isInvalidType());
283 if (
D.isInvalidType())
307 CastOperation Op(*
this, DestType,
E);
309 Op.DestRange = AngleBrackets;
312 default: llvm_unreachable(
"Unknown C++ cast!");
314 case tok::kw_addrspace_cast:
315 if (!TypeDependent) {
316 Op.CheckAddrspaceCast();
317 if (Op.SrcExpr.isInvalid())
321 Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
322 DestTInfo, OpLoc,
Parens.getEnd(), AngleBrackets));
324 case tok::kw_const_cast:
325 if (!TypeDependent) {
327 if (Op.SrcExpr.isInvalid())
332 Op.ValueKind, Op.SrcExpr.get(), DestTInfo,
336 case tok::kw_dynamic_cast: {
339 return ExprError(
Diag(OpLoc, diag::err_openclcxx_not_supported)
343 if (!TypeDependent) {
344 Op.CheckDynamicCast();
345 if (Op.SrcExpr.isInvalid())
349 Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
350 &Op.BasePath, DestTInfo,
354 case tok::kw_reinterpret_cast: {
355 if (!TypeDependent) {
356 Op.CheckReinterpretCast();
357 if (Op.SrcExpr.isInvalid())
362 Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
363 nullptr, DestTInfo, OpLoc,
367 case tok::kw_static_cast: {
368 if (!TypeDependent) {
369 Op.CheckStaticCast();
370 if (Op.SrcExpr.isInvalid())
376 Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
378 Parens.getEnd(), AngleBrackets));
386 assert(!
D.isInvalidType());
389 if (
D.isInvalidType())
398 CastOperation Op(*
this, TSI->
getType(), Operand);
404 Op.CheckBuiltinBitCast();
405 if (Op.SrcExpr.isInvalid())
411 Op.SrcExpr.get(), TSI, KWLoc, RParenLoc);
412 return Op.complete(BCE);
420 bool listInitialization) {
443 range, listInitialization)
449 assert(sequence.
Failed() &&
"initialization succeeded on second try?");
451 default:
return false;
483 case OR_Success: llvm_unreachable(
"successful failed overload");
485 if (candidates.
empty())
486 msg = diag::err_ovl_no_conversion_in_cast;
488 msg = diag::err_ovl_no_viable_conversion_in_cast;
493 msg = diag::err_ovl_ambiguous_conversion_in_cast;
501 assert(Res ==
OR_Deleted &&
"Inconsistent overload resolution");
506 S.
PDiag(diag::err_ovl_deleted_conversion_in_cast)
507 << CT << srcType << destType << (Msg !=
nullptr)
508 << (Msg ? Msg->
getString() : StringRef())
517 S.
PDiag(msg) << CT << srcType << destType << range
519 S, howManyCandidates, src);
527 bool listInitialization) {
528 if (msg == diag::err_bad_cxx_cast_generic &&
537 int DifferentPtrness = 0;
548 if (!DifferentPtrness) {
551 if (RecFrom && RecTo) {
553 if (!DeclFrom->isCompleteDefinition())
554 S.
Diag(DeclFrom->getLocation(), diag::note_type_incomplete) << DeclFrom;
556 if (!DeclTo->isCompleteDefinition())
557 S.
Diag(DeclTo->getLocation(), diag::note_type_incomplete) << DeclTo;
565enum CastAwayConstnessKind {
572 CACK_SimilarKind = 2,
591static CastAwayConstnessKind
593 enum {
None, Ptr, MemPtr, BlockPtr, Array };
606 return AT->getElementType();
610 CastAwayConstnessKind Kind;
618 Kind = CastAwayConstnessKind::CACK_Similar;
620 Kind = CastAwayConstnessKind::CACK_Similar;
623 int T1Class = Classify(T1);
625 return CastAwayConstnessKind::CACK_None;
627 int T2Class = Classify(T2);
629 return CastAwayConstnessKind::CACK_None;
633 Kind = T1Class == T2Class ? CastAwayConstnessKind::CACK_SimilarKind
634 : CastAwayConstnessKind::CACK_Incoherent;
644 if (Classify(T1) != Array)
647 auto T2Class = Classify(T2);
651 if (T2Class != Array)
652 Kind = CastAwayConstnessKind::CACK_Incoherent;
653 else if (Kind != CastAwayConstnessKind::CACK_Incoherent)
654 Kind = CastAwayConstnessKind::CACK_SimilarKind;
669static CastAwayConstnessKind
671 bool CheckCVR,
bool CheckObjCLifetime,
672 QualType *TheOffendingSrcType =
nullptr,
673 QualType *TheOffendingDestType =
nullptr,
677 if (!CheckCVR && CheckObjCLifetime && !
Self.Context.getLangOpts().ObjC)
678 return CastAwayConstnessKind::CACK_None;
683 "Source type is not pointer or pointer to member.");
686 "Destination type is not pointer or pointer to member.");
689 QualType UnwrappedSrcType =
Self.Context.getCanonicalType(SrcType),
690 UnwrappedDestType =
Self.Context.getCanonicalType(DestType);
695 QualType PrevUnwrappedSrcType = UnwrappedSrcType;
696 QualType PrevUnwrappedDestType = UnwrappedDestType;
697 auto WorstKind = CastAwayConstnessKind::CACK_Similar;
698 bool AllConstSoFar =
true;
700 Self.Context, UnwrappedSrcType, UnwrappedDestType)) {
703 if (Kind > WorstKind)
708 Self.Context.getUnqualifiedArrayType(UnwrappedSrcType, SrcQuals);
709 Self.Context.getUnqualifiedArrayType(UnwrappedDestType, DestQuals);
715 UnwrappedDestType->isObjCObjectType())
724 if (SrcCvrQuals != DestCvrQuals) {
725 if (CastAwayQualifiers)
726 *CastAwayQualifiers = SrcCvrQuals - DestCvrQuals;
729 if (!DestCvrQuals.compatiblyIncludes(SrcCvrQuals)) {
730 if (TheOffendingSrcType)
731 *TheOffendingSrcType = PrevUnwrappedSrcType;
732 if (TheOffendingDestType)
733 *TheOffendingDestType = PrevUnwrappedDestType;
744 if (CheckObjCLifetime &&
750 if (AllConstSoFar && !DestQuals.
hasConst()) {
751 AllConstSoFar =
false;
752 if (TheOffendingSrcType)
753 *TheOffendingSrcType = PrevUnwrappedSrcType;
754 if (TheOffendingDestType)
755 *TheOffendingDestType = PrevUnwrappedDestType;
758 PrevUnwrappedSrcType = UnwrappedSrcType;
759 PrevUnwrappedDestType = UnwrappedDestType;
762 return CastAwayConstnessKind::CACK_None;
768 case CastAwayConstnessKind::CACK_None:
769 llvm_unreachable(
"did not cast away constness");
771 case CastAwayConstnessKind::CACK_Similar:
773 case CastAwayConstnessKind::CACK_SimilarKind:
774 DiagID = diag::err_bad_cxx_cast_qualifiers_away;
777 case CastAwayConstnessKind::CACK_Incoherent:
778 DiagID = diag::ext_bad_cxx_cast_qualifiers_away_incoherent;
782 llvm_unreachable(
"unexpected cast away constness kind");
788void CastOperation::CheckDynamicCast() {
789 CheckNoDerefRAII NoderefCheck(*
this);
792 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
793 else if (isPlaceholder())
794 SrcExpr =
Self.CheckPlaceholderExpr(SrcExpr.get());
795 if (SrcExpr.isInvalid())
798 QualType OrigSrcType = SrcExpr.get()->getType();
799 QualType DestType =
Self.Context.getCanonicalType(this->DestType);
812 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ref_or_ptr)
813 << this->DestType << DestRange;
820 assert(DestPointer &&
"Reference to void is not possible");
821 }
else if (DestRecord) {
822 if (
Self.RequireCompleteType(OpRange.getBegin(), DestPointee,
823 diag::err_bad_cast_incomplete,
829 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
839 QualType SrcType =
Self.Context.getCanonicalType(OrigSrcType);
845 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ptr)
846 << OrigSrcType << this->DestType << SrcExpr.get()->getSourceRange();
850 }
else if (DestReference->isLValueReferenceType()) {
851 if (!SrcExpr.get()->isLValue()) {
852 Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_rvalue)
853 <<
CT_Dynamic << OrigSrcType << this->DestType << OpRange;
855 SrcPointee = SrcType;
859 if (SrcExpr.get()->isPRValue())
860 SrcExpr =
Self.CreateMaterializeTemporaryExpr(
861 SrcType, SrcExpr.get(),
false);
862 SrcPointee = SrcType;
867 if (
Self.RequireCompleteType(OpRange.getBegin(), SrcPointee,
868 diag::err_bad_cast_incomplete,
874 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
880 assert((DestPointer || DestReference) &&
881 "Bad destination non-ptr/ref slipped through.");
882 assert((DestRecord || DestPointee->
isVoidType()) &&
883 "Bad destination pointee slipped through.");
884 assert(SrcRecord &&
"Bad source pointee slipped through.");
888 Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_qualifiers_away)
889 <<
CT_Dynamic << OrigSrcType << this->DestType << OpRange;
896 if (DestRecord == SrcRecord) {
904 Self.IsDerivedFrom(OpRange.getBegin(), SrcPointee, DestPointee)) {
905 if (
Self.CheckDerivedToBaseConversion(SrcPointee, DestPointee,
906 OpRange.getBegin(), OpRange,
912 Kind = CK_DerivedToBase;
918 assert(SrcDecl &&
"Definition missing");
919 if (!cast<CXXRecordDecl>(SrcDecl)->isPolymorphic()) {
920 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_polymorphic)
929 Self.Diag(OpRange.getBegin(), diag::err_no_dynamic_cast_with_fno_rtti);
935 if (!
Self.getLangOpts().RTTIData) {
937 Self.getASTContext().getTargetInfo().getCXXABI().isMicrosoft();
938 bool isClangCL =
Self.getDiagnostics().getDiagnosticOptions().getFormat() ==
940 if (MicrosoftABI || !DestPointee->
isVoidType())
941 Self.Diag(OpRange.getBegin(),
942 diag::warn_no_dynamic_cast_with_rtti_disabled)
950 if (DestDecl->isEffectivelyFinal())
951 Self.MarkVTableUsed(OpRange.getBegin(), DestDecl);
963void CastOperation::CheckConstCast() {
964 CheckNoDerefRAII NoderefCheck(*
this);
967 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
968 else if (isPlaceholder())
969 SrcExpr =
Self.CheckPlaceholderExpr(SrcExpr.get());
970 if (SrcExpr.isInvalid())
973 unsigned msg = diag::err_bad_cxx_cast_generic;
977 << SrcExpr.get()->getType() << DestType << OpRange;
983void CastOperation::CheckAddrspaceCast() {
984 unsigned msg = diag::err_bad_cxx_cast_generic;
988 Self.Diag(OpRange.getBegin(), msg)
989 <<
CT_Addrspace << SrcExpr.get()->getType() << DestType << OpRange;
1026 ReinterpretKind = ReinterpretUpcast;
1028 ReinterpretKind = ReinterpretDowncast;
1033 bool NonZeroOffset =
false;
1035 E = BasePaths.
end();
1039 bool IsVirtual =
false;
1040 for (CXXBasePath::const_iterator IElem =
Path.begin(), EElem =
Path.end();
1041 IElem != EElem; ++IElem) {
1042 IsVirtual = IElem->Base->isVirtual();
1045 const CXXRecordDecl *BaseRD = IElem->Base->getType()->getAsCXXRecordDecl();
1046 assert(BaseRD &&
"Base type should be a valid unqualified class type");
1050 *ClassDefinition =
Class->getDefinition();
1051 if (
Class->isInvalidDecl() || !ClassDefinition ||
1052 !ClassDefinition->isCompleteDefinition())
1061 if (Offset.isZero())
1065 NonZeroOffset =
true;
1070 (void) NonZeroOffset;
1072 "Should have returned if has non-virtual base with zero offset");
1075 ReinterpretKind == ReinterpretUpcast? DestType : SrcType;
1077 ReinterpretKind == ReinterpretUpcast? SrcType : DestType;
1080 Self.Diag(BeginLoc, diag::warn_reinterpret_different_from_static)
1081 << DerivedType << BaseType << !
VirtualBase <<
int(ReinterpretKind)
1083 Self.Diag(BeginLoc, diag::note_reinterpret_updowncast_use_static)
1084 <<
int(ReinterpretKind)
1105 unsigned int DiagID = 0;
1106 const unsigned int DiagList[] = {diag::warn_cast_function_type_strict,
1107 diag::warn_cast_function_type};
1132 assert(SrcFTy && DstFTy);
1134 if (
Self.Context.hasSameType(SrcFTy, DstFTy))
1138 if (DiagID == diag::warn_cast_function_type_strict)
1145 return !PT->isVariadic() && PT->getNumParams() == 0;
1150 if (IsVoidVoid(SrcFTy) || IsVoidVoid(DstFTy))
1164 const auto *SrcFPTy = cast<FunctionProtoType>(SrcFTy);
1165 const auto *DstFPTy = cast<FunctionProtoType>(DstFTy);
1169 unsigned NumParams = SrcFPTy->getNumParams();
1170 unsigned DstNumParams = DstFPTy->getNumParams();
1171 if (NumParams > DstNumParams) {
1172 if (!DstFPTy->isVariadic())
1174 NumParams = DstNumParams;
1175 }
else if (NumParams < DstNumParams) {
1176 if (!SrcFPTy->isVariadic())
1180 for (
unsigned i = 0; i < NumParams; ++i)
1182 DstFPTy->getParamType(i),
Self.Context))
1193void CastOperation::CheckReinterpretCast() {
1194 if (ValueKind ==
VK_PRValue && !isPlaceholder(BuiltinType::Overload))
1195 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
1197 checkNonOverloadPlaceholders();
1198 if (SrcExpr.isInvalid())
1201 unsigned msg = diag::err_bad_cxx_cast_generic;
1204 false, OpRange, msg, Kind);
1206 if (SrcExpr.isInvalid())
1208 if (SrcExpr.get()->getType() ==
Self.Context.OverloadTy) {
1210 Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_overload)
1212 << DestType << OpRange;
1213 Self.NoteAllOverloadCandidates(SrcExpr.get());
1222 if (
Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())
1227 Self.Diag(OpRange.getBegin(), DiagID)
1228 << SrcExpr.get()->getType() << DestType << OpRange;
1238void CastOperation::CheckStaticCast() {
1239 CheckNoDerefRAII NoderefCheck(*
this);
1241 if (isPlaceholder()) {
1242 checkNonOverloadPlaceholders();
1243 if (SrcExpr.isInvalid())
1253 if (claimPlaceholder(BuiltinType::Overload)) {
1254 Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr,
1257 OpRange, DestType, diag::err_bad_static_cast_overload);
1258 if (SrcExpr.isInvalid())
1262 SrcExpr =
Self.IgnoredValueConversions(SrcExpr.get());
1267 !isPlaceholder(BuiltinType::Overload)) {
1268 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
1269 if (SrcExpr.isInvalid())
1273 unsigned msg = diag::err_bad_cxx_cast_generic;
1276 OpRange, msg, Kind, BasePath,
false);
1278 if (SrcExpr.isInvalid())
1280 if (SrcExpr.get()->getType() ==
Self.Context.OverloadTy) {
1282 Self.Diag(OpRange.getBegin(), diag::err_bad_static_cast_overload)
1283 << oe->
getName() << DestType << OpRange
1285 Self.NoteAllOverloadCandidates(SrcExpr.get());
1293 if (Kind == CK_BitCast)
1295 if (
Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())
1310 DestPtrType->getPointeeType().getAddressSpace();
1320 bool ListInitialization) {
1346 OpRange, msg, Kind, BasePath);
1361 Kind, ListInitialization);
1383 if (
Enum->getDecl()->isScoped()) {
1385 Kind = CK_IntegralToBoolean;
1388 Kind = CK_IntegralCast;
1391 Kind = CK_IntegralToFloating;
1406 if (
Self.RequireCompleteType(OpRange.
getBegin(), DestType,
1407 diag::err_bad_cast_incomplete)) {
1415 Kind =
Enum->getDecl()->isFixed() &&
1416 Enum->getDecl()->getIntegerType()->isBooleanType()
1417 ? CK_IntegralToBoolean
1421 Kind = CK_FloatingToIntegral;
1437 OpRange, msg, Kind, BasePath);
1460 if (DestPointeeQuals != SrcPointeeQuals &&
1462 msg = diag::err_bad_cxx_cast_qualifiers_away;
1467 ? CK_AddressSpaceConversion
1474 if (!CStyle &&
Self.getLangOpts().MSVCCompat &&
1476 Self.Diag(OpRange.
getBegin(), diag::ext_ms_cast_fn_obj) << OpRange;
1484 Kind = CK_CPointerToObjCPointerCast;
1489 Kind = CK_AnyPointerToBlockPointerCast;
1503 Self.ObjC().CheckTollFreeBridgeStaticCast(DestType, SrcExpr.
get(), Kind))
1510 if (SrcPointer->getPointeeType()->getAs<
RecordType>() &&
1512 msg = diag::err_bad_cxx_cast_unrelated_class;
1515 if (
Self.CheckMatrixCast(OpRange, DestType, SrcType, Kind)) {
1553 SrcExpr->
getBeginLoc(), ToType, FromType, &RefConv);
1560 msg = SrcExpr->
isLValue() ? diag::err_bad_lvalue_to_rvalue_cast
1561 : diag::err_bad_rvalue_to_rvalue_cast;
1565 if (RefConv & Sema::ReferenceConversions::DerivedToBase) {
1566 Kind = CK_DerivedToBase;
1573 Self.BuildBasePathArray(Paths, BasePath);
1596 if (!DestReference) {
1600 if (!RValueRef && !SrcExpr->
isLValue()) {
1602 msg = diag::err_bad_cxx_cast_rvalue;
1612 Self.Context.getCanonicalType(SrcExpr->
getType()),
1613 Self.Context.getCanonicalType(DestPointee), CStyle,
1614 OpRange, SrcExpr->
getType(), DestType, msg, Kind,
1639 msg = diag::err_bad_static_cast_pointer_nonpointer;
1646 CStyle, OpRange, SrcType, DestType, msg, Kind,
1656 QualType OrigDestType,
unsigned &msg,
1659 if (!
Self.isCompleteType(OpRange.
getBegin(), SrcType) ||
1670 if (!
Self.IsDerivedFrom(OpRange.
getBegin(), DestType, SrcType, Paths)) {
1694 msg = diag::err_bad_cxx_cast_qualifiers_away;
1703 if (!Paths.isRecordingPaths()) {
1705 Paths.setRecordingPaths(
true);
1706 Self.IsDerivedFrom(OpRange.
getBegin(), DestType, SrcType, Paths);
1708 std::string PathDisplayStr;
1709 std::set<unsigned> DisplayedPaths;
1711 if (DisplayedPaths.insert(
Path.back().SubobjectNumber).second) {
1714 PathDisplayStr +=
"\n ";
1716 PathDisplayStr += PE.Base->getType().getAsString() +
" -> ";
1721 Self.Diag(OpRange.
getBegin(), diag::err_ambiguous_base_to_derived_cast)
1724 << PathDisplayStr << OpRange;
1729 if (Paths.getDetectedVirtual() !=
nullptr) {
1731 Self.Diag(OpRange.
getBegin(), diag::err_static_downcast_via_virtual)
1732 << OrigSrcType << OrigDestType <<
VirtualBase << OpRange;
1741 diag::err_downcast_from_inaccessible_base)) {
1753 Self.BuildBasePathArray(Paths, BasePath);
1754 Kind = CK_BaseToDerived;
1775 bool WasOverloadedFunction =
false;
1779 =
Self.ResolveAddressOfOverloadedFunction(SrcExpr.
get(), DestType,
false,
1782 SrcType =
Self.Context.getMemberPointerType(Fn->getType(),
1784 WasOverloadedFunction =
true;
1790 msg = diag::err_bad_static_cast_member_pointer_nonmp;
1796 if (
Self.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
1797 (void)
Self.isCompleteType(OpRange.
getBegin(), SrcType);
1798 (void)
Self.isCompleteType(OpRange.
getBegin(), DestType);
1811 if (!
Self.IsDerivedFrom(OpRange.
getBegin(), SrcClass, DestClass, Paths))
1815 if (Paths.isAmbiguous(
Self.Context.getCanonicalType(DestClass))) {
1817 Paths.setRecordingPaths(
true);
1819 Self.IsDerivedFrom(OpRange.
getBegin(), SrcClass, DestClass, Paths);
1822 std::string PathDisplayStr =
Self.getAmbiguousPathsDisplayString(Paths);
1823 Self.Diag(OpRange.
getBegin(), diag::err_ambiguous_memptr_conv)
1824 << 1 << SrcClass << DestClass << PathDisplayStr << OpRange;
1829 if (
const RecordType *VBase = Paths.getDetectedVirtual()) {
1830 Self.Diag(OpRange.
getBegin(), diag::err_memptr_conv_via_virtual)
1831 << SrcClass << DestClass <<
QualType(VBase, 0) << OpRange;
1838 DestClass, SrcClass,
1840 diag::err_upcast_to_inaccessible_base)) {
1854 if (WasOverloadedFunction) {
1866 SrcExpr =
Self.FixOverloadedFunctionReference(SrcExpr, FoundOverload, Fn);
1873 Self.BuildBasePathArray(Paths, BasePath);
1874 Kind = CK_DerivedToBaseMemberPointer;
1887 CastKind &Kind,
bool ListInitialization) {
1889 if (
Self.RequireCompleteType(OpRange.
getBegin(), DestType,
1890 diag::err_bad_cast_incomplete) ||
1891 Self.RequireNonAbstractType(OpRange.
getBegin(), DestType,
1892 diag::err_allocation_of_abstract_type)) {
1907 Expr *SrcExprRaw = SrcExpr.
get();
1924 if (
Result.isInvalid()) {
1930 Kind = CK_ConstructorConversion;
1943 DestType =
Self.Context.getCanonicalType(DestType);
1945 bool NeedToMaterializeTemporary =
false;
1959 if (isa<LValueReferenceType>(DestTypeTmp) && !SrcExpr.
get()->
isLValue()) {
1963 msg = diag::err_bad_cxx_cast_rvalue;
1967 if (isa<RValueReferenceType>(DestTypeTmp) && SrcExpr.
get()->
isPRValue()) {
1971 msg = diag::err_bad_cxx_cast_rvalue;
1977 NeedToMaterializeTemporary =
true;
1986 msg = diag::err_bad_cxx_cast_bitfield;
1990 DestType =
Self.Context.getPointerType(DestTypeTmp->getPointeeType());
1991 SrcType =
Self.Context.getPointerType(SrcType);
2006 msg = diag::err_bad_const_cast_dest;
2015 msg = diag::err_bad_const_cast_dest;
2025 if (!
Self.Context.hasCvrSimilarType(SrcType, DestType))
2028 if (NeedToMaterializeTemporary)
2031 SrcExpr =
Self.CreateMaterializeTemporaryExpr(SrcExpr.
get()->
getType(),
2046 unsigned DiagID = IsDereference ?
2047 diag::warn_pointer_indirection_from_incompatible_type :
2048 diag::warn_undefined_reinterpret_cast;
2054 if (IsDereference) {
2096 if (
Self.Context.hasSameType(SrcType, DestType))
2099 if (SrcPtrTy->isObjCSelType()) {
2101 if (isa<PointerType>(DestType))
2105 diag::warn_cast_pointer_from_sel)
2117 if (
Self.Context.hasSameType(SrcType, DstType) ||
2120 const auto *SrcFTy =
2122 const auto *DstFTy =
2132 if (
auto *UO = dyn_cast<UnaryOperator>(Src))
2133 if (UO->getOpcode() == UO_AddrOf)
2135 auto *DRE = dyn_cast<DeclRefExpr>(Src);
2138 auto *FD = dyn_cast<FunctionDecl>(DRE->getDecl());
2146 CallingConv DefaultCC =
Self.getASTContext().getDefaultCallingConvention(
2147 FD->isVariadic(), FD->isCXXInstanceMember());
2148 if (DstCC == DefaultCC || SrcCC != DefaultCC)
2154 Self.Diag(OpRange.
getBegin(), diag::warn_cast_calling_conv)
2155 << SrcCCName << DstCCName << OpRange;
2160 if (
Self.Diags.isIgnored(diag::warn_cast_calling_conv, OpRange.
getBegin()))
2167 SourceLocation NameLoc = FD->getFirstDecl()->getNameInfo().getLoc();
2171 llvm::raw_svector_ostream OS(CCAttrText);
2172 if (
Self.getLangOpts().MicrosoftExt) {
2174 OS <<
"__" << DstCCName;
2181 OS <<
"__attribute__((" << DstCCName <<
"))";
2182 AttrTokens.push_back(tok::kw___attribute);
2183 AttrTokens.push_back(tok::l_paren);
2184 AttrTokens.push_back(tok::l_paren);
2189 AttrTokens.push_back(tok::r_paren);
2190 AttrTokens.push_back(tok::r_paren);
2193 if (!AttrSpelling.empty())
2194 CCAttrText = AttrSpelling;
2196 Self.Diag(NameLoc, diag::note_change_calling_conv_fixit)
2212 &&
Self.Context.getTypeSize(DestType) >
2213 Self.Context.getTypeSize(SrcType)) {
2220 diag::warn_int_to_void_pointer_cast
2221 : diag::warn_int_to_pointer_cast;
2237 if (
Self.ResolveAndFixSingleFunctionTemplateSpecialization(
2248 if (!
Self.resolveAndFixAddressOfSingleOverloadCandidate(
2251 return Result.isUsable();
2259 bool IsLValueCast =
false;
2261 DestType =
Self.Context.getCanonicalType(DestType);
2266 if (SrcType ==
Self.Context.OverloadTy) {
2271 assert(FixedExpr.
isUsable() &&
"Invalid result fixing overloaded expr");
2272 SrcExpr = FixedExpr;
2280 msg = diag::err_bad_cxx_cast_rvalue;
2285 Self.CheckCompatibleReinterpretCast(SrcType, DestType,
2293 const char *inappropriate =
nullptr;
2298 msg = diag::err_bad_cxx_cast_bitfield;
2303 inappropriate =
"matrix element";
2306 case OK_ObjCSubscript: inappropriate =
"container subscripting expression";
2309 if (inappropriate) {
2310 Self.Diag(OpRange.
getBegin(), diag::err_bad_reinterpret_cast_reference)
2311 << inappropriate << DestType
2318 DestType =
Self.Context.getPointerType(DestTypeTmp->getPointeeType());
2319 SrcType =
Self.Context.getPointerType(SrcType);
2321 IsLValueCast =
true;
2325 SrcType =
Self.Context.getCanonicalType(SrcType);
2329 if (DestMemPtr && SrcMemPtr) {
2335 SrcMemPtr->isMemberFunctionPointer())
2338 if (
Self.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
2341 (void)
Self.isCompleteType(OpRange.
getBegin(), SrcType);
2342 (void)
Self.isCompleteType(OpRange.
getBegin(), DestType);
2346 if (
Self.Context.getTypeSize(DestMemPtr) !=
2347 Self.Context.getTypeSize(SrcMemPtr)) {
2348 msg = diag::err_bad_cxx_cast_member_pointer_size;
2362 assert(!IsLValueCast);
2363 Kind = CK_ReinterpretMemberPointer;
2373 if (
Self.Context.getTypeSize(SrcType) >
2374 Self.Context.getTypeSize(DestType)) {
2375 msg = diag::err_bad_reinterpret_cast_small_int;
2378 Kind = CK_PointerToIntegral;
2386 if (srcIsVector || destIsVector) {
2388 if (
Self.isValidSveBitcast(SrcType, DestType)) {
2394 if (
Self.RISCV().isValidRVVBitcast(SrcType, DestType)) {
2408 if (
Self.areLaxCompatibleVectorTypes(SrcType, DestType)) {
2413 if (
Self.LangOpts.OpenCL && !CStyle) {
2416 if (
Self.areVectorTypesSameSize(SrcType, DestType)) {
2425 msg = diag::err_bad_cxx_cast_vector_to_scalar_different_size;
2426 else if (!srcIsVector)
2427 msg = diag::err_bad_cxx_cast_scalar_to_vector_different_size;
2429 msg = diag::err_bad_cxx_cast_vector_to_vector_different_size;
2434 if (SrcType == DestType) {
2458 if (!destIsPtr && !srcIsPtr) {
2465 assert(srcIsPtr &&
"One type must be a pointer");
2469 if ((
Self.Context.getTypeSize(SrcType) >
2470 Self.Context.getTypeSize(DestType))) {
2471 bool MicrosoftException =
2473 if (MicrosoftException) {
2475 ? diag::warn_void_pointer_to_int_cast
2476 : diag::warn_pointer_to_int_cast;
2479 msg = diag::err_bad_reinterpret_cast_small_int;
2483 Kind = CK_PointerToIntegral;
2488 assert(destIsPtr &&
"One type must be a pointer");
2494 Kind = CK_IntegralToPointer;
2498 if (!destIsPtr || !srcIsPtr) {
2518 Kind = CK_AddressSpaceConversion;
2525 }
else if (IsLValueCast) {
2526 Kind = CK_LValueBitCast;
2528 Kind =
Self.ObjC().PrepareCastToObjCObjectPointer(SrcExpr);
2531 Kind = CK_AnyPointerToBlockPointerCast;
2542 return SuccessResult;
2556 return SuccessResult;
2566 Self.getLangOpts().CPlusPlus11 ?
2567 diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)
2569 return SuccessResult;
2575 Self.getLangOpts().CPlusPlus11 ?
2576 diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)
2578 return SuccessResult;
2591 diag::warn_bad_cxx_cast_nested_pointer_addr_space)
2604 return SuccessResult;
2610 if (!
Self.getLangOpts().OpenCL && !
Self.getLangOpts().SYCLIsDevice)
2627 auto SrcPointeeType = SrcPtrType->getPointeeType();
2628 auto DestPointeeType = DestPtrType->getPointeeType();
2629 if (!DestPointeeType.isAddressSpaceOverlapping(SrcPointeeType)) {
2630 msg = diag::err_bad_cxx_cast_addr_space_mismatch;
2633 auto SrcPointeeTypeWithoutAS =
2634 Self.Context.removeAddrSpaceQualType(SrcPointeeType.getCanonicalType());
2635 auto DestPointeeTypeWithoutAS =
2636 Self.Context.removeAddrSpaceQualType(DestPointeeType.getCanonicalType());
2637 if (
Self.Context.hasSameType(SrcPointeeTypeWithoutAS,
2638 DestPointeeTypeWithoutAS)) {
2639 Kind = SrcPointeeType.getAddressSpace() == DestPointeeType.getAddressSpace()
2641 : CK_AddressSpaceConversion;
2648void CastOperation::checkAddressSpaceCast(
QualType SrcType,
QualType DestType) {
2660 if (
Self.getLangOpts().OpenCL) {
2661 const Type *DestPtr, *SrcPtr;
2662 bool Nested =
false;
2663 unsigned DiagID = diag::err_typecheck_incompatible_address_space;
2664 DestPtr =
Self.getASTContext().getCanonicalType(DestType.
getTypePtr()),
2665 SrcPtr =
Self.getASTContext().getCanonicalType(SrcType.
getTypePtr());
2667 while (isa<PointerType>(DestPtr) && isa<PointerType>(SrcPtr)) {
2668 const PointerType *DestPPtr = cast<PointerType>(DestPtr);
2669 const PointerType *SrcPPtr = cast<PointerType>(SrcPtr);
2675 Self.Diag(OpRange.getBegin(), DiagID)
2677 << SrcExpr.get()->getSourceRange();
2686 DiagID = diag::ext_nested_pointer_qualifier_mismatch;
2692 bool SrcCompatXL = this->
getLangOpts().getAltivecSrcCompat() ==
2706 bool SrcCompatGCC = this->
getLangOpts().getAltivecSrcCompat() ==
2708 if (this->
getLangOpts().AltiVec && SrcCompatGCC) {
2710 diag::err_invalid_conversion_between_vector_and_integer)
2711 << VecTy << SrcTy << R;
2717void CastOperation::CheckCXXCStyleCast(
bool FunctionalStyle,
2718 bool ListInitialization) {
2719 assert(
Self.getLangOpts().CPlusPlus);
2722 if (isPlaceholder()) {
2724 if (claimPlaceholder(BuiltinType::UnknownAny)) {
2725 SrcExpr =
Self.checkUnknownAnyCast(DestRange, DestType,
2726 SrcExpr.get(), Kind,
2727 ValueKind, BasePath);
2731 checkNonOverloadPlaceholders();
2732 if (SrcExpr.isInvalid())
2742 if (claimPlaceholder(BuiltinType::Overload)) {
2743 Self.ResolveAndFixSingleFunctionTemplateSpecialization(
2745 true, DestRange, DestType,
2746 diag::err_bad_cstyle_cast_overload);
2747 if (SrcExpr.isInvalid())
2751 SrcExpr =
Self.IgnoredValueConversions(SrcExpr.get());
2756 if (DestType->
isDependentType() || SrcExpr.get()->isTypeDependent() ||
2757 SrcExpr.get()->isValueDependent()) {
2758 assert(Kind == CK_Dependent);
2763 !isPlaceholder(BuiltinType::Overload)) {
2764 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
2765 if (SrcExpr.isInvalid())
2771 if (
Self.CheckAltivecInitFromScalar(OpRange, DestType,
2772 SrcExpr.get()->getType())) {
2776 if (
Self.ShouldSplatAltivecScalarInCast(vecTy) &&
2777 (SrcExpr.get()->getType()->isIntegerType() ||
2778 SrcExpr.get()->getType()->isFloatingType())) {
2779 Kind = CK_VectorSplat;
2780 SrcExpr =
Self.prepareVectorSplat(DestType, SrcExpr.get());
2786 QualType SrcType = SrcExpr.get()->getType();
2788 Self.Diag(OpRange.getBegin(), diag::err_wasm_cast_table)
2789 << 1 << SrcExpr.get()->getSourceRange();
2806 unsigned msg = diag::err_bad_cxx_cast_generic;
2809 if (SrcExpr.isInvalid())
2820 if (SrcExpr.isInvalid())
2827 BasePath, ListInitialization);
2828 if (SrcExpr.isInvalid())
2834 OpRange, msg, Kind);
2835 if (SrcExpr.isInvalid())
2841 if (
Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&
2843 checkObjCConversion(CCK);
2846 if (SrcExpr.get()->getType() ==
Self.Context.OverloadTy) {
2857 Self.Diag(OpRange.getBegin(), diag::err_bad_cstyle_cast_overload)
2858 << OE->
getName() << DestType << OpRange
2860 Self.NoteAllOverloadCandidates(SrcExpr.get());
2864 OpRange, SrcExpr.get(), DestType, ListInitialization);
2869 if (Kind == CK_BitCast)
2873 Self.Diag(OpRange.getBegin(), DiagID)
2874 << SrcExpr.get()->getType() << DestType << OpRange;
2886 if (
Self.Diags.isIgnored(diag::warn_bad_function_cast,
2890 if (!isa<CallExpr>(SrcExpr.
get()))
2915 diag::warn_bad_function_cast)
2920void CastOperation::CheckCStyleCast() {
2921 assert(!
Self.getLangOpts().CPlusPlus);
2924 if (claimPlaceholder(BuiltinType::UnknownAny)) {
2925 SrcExpr =
Self.checkUnknownAnyCast(DestRange, DestType,
2926 SrcExpr.get(), Kind,
2927 ValueKind, BasePath);
2935 SrcExpr =
Self.IgnoredValueConversions(SrcExpr.get());
2936 if (SrcExpr.isInvalid())
2945 if (
Self.getASTContext().isDependenceAllowed() &&
2947 SrcExpr.get()->isValueDependent())) {
2948 assert((DestType->
containsErrors() || SrcExpr.get()->containsErrors() ||
2949 SrcExpr.get()->containsErrors()) &&
2950 "should only occur in error-recovery path.");
2951 assert(Kind == CK_Dependent);
2956 if (SrcExpr.get()->getType() ==
Self.Context.OverloadTy) {
2959 SrcExpr.get(), DestType,
true, DAP))
2960 SrcExpr =
Self.FixOverloadedFunctionReference(SrcExpr.get(), DAP, FD);
2963 assert(SrcExpr.isUsable());
2965 SrcExpr =
Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
2966 if (SrcExpr.isInvalid())
2968 QualType SrcType = SrcExpr.get()->getType();
2971 Self.Diag(OpRange.getBegin(), diag::err_wasm_cast_table)
2972 << 1 << SrcExpr.get()->getSourceRange();
2979 checkAddressSpaceCast(SrcType, DestType);
2980 if (SrcExpr.isInvalid())
2983 if (
Self.RequireCompleteType(OpRange.getBegin(), DestType,
2984 diag::err_typecheck_cast_to_incomplete)) {
2991 Self.Context.hasSameUnqualifiedType(DestType, SrcType)) {
2998 Self.isValidSveBitcast(SrcType, DestType)) {
3005 Self.RISCV().isValidRVVBitcast(SrcType, DestType)) {
3014 if (DestRecordTy &&
Self.Context.hasSameUnqualifiedType(DestType, SrcType)){
3016 Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_nonscalar)
3017 << DestType << SrcExpr.get()->getSourceRange();
3026 Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_to_union)
3027 << SrcExpr.get()->getSourceRange();
3031 Self.Diag(OpRange.getBegin(), diag::err_typecheck_cast_to_union_no_type)
3032 << SrcType << SrcExpr.get()->getSourceRange();
3039 if (
Self.getLangOpts().OpenCL && DestType->
isEventT()) {
3041 if (SrcExpr.get()->EvaluateAsInt(
Result,
Self.Context)) {
3042 llvm::APSInt CastInt =
Result.Val.getInt();
3044 Kind = CK_ZeroToOCLOpaqueType;
3047 Self.Diag(OpRange.getBegin(),
3048 diag::err_opencl_cast_non_zero_to_event_t)
3049 <<
toString(CastInt, 10) << SrcExpr.get()->getSourceRange();
3056 Self.Diag(OpRange.getBegin(), diag::err_typecheck_cond_expect_scalar)
3057 << DestType << SrcExpr.get()->getSourceRange();
3067 Self.Diag(SrcExpr.get()->getExprLoc(),
3068 diag::err_typecheck_expect_scalar_operand)
3069 << SrcType << SrcExpr.get()->getSourceRange();
3084 Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_nullptr_cast)
3095 Self.CurFPFeatureOverrides());
3099 Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_nullptr_cast)
3106 SrcExpr =
Self.CheckExtVectorCast(OpRange, DestType, SrcExpr.get(), Kind);
3111 if (
Self.CheckMatrixCast(OpRange, DestType, SrcType, Kind))
3117 if (
Self.CheckAltivecInitFromScalar(OpRange, DestType, SrcType)) {
3121 if (
Self.ShouldSplatAltivecScalarInCast(DestVecTy) &&
3123 Kind = CK_VectorSplat;
3124 SrcExpr =
Self.prepareVectorSplat(DestType, SrcExpr.get());
3125 }
else if (
Self.CheckVectorCast(OpRange, DestType, SrcType, Kind)) {
3132 if (
Self.CheckVectorCast(OpRange, SrcType, DestType, Kind))
3142 if (isa<ObjCSelectorExpr>(SrcExpr.get())) {
3143 Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_cast_selector_expr);
3152 Self.Diag(SrcExpr.get()->getExprLoc(),
3153 diag::err_cast_pointer_from_non_pointer_int)
3154 << SrcType << SrcExpr.get()->getSourceRange();
3163 Self.Diag(SrcExpr.get()->getBeginLoc(),
3164 diag::err_cast_pointer_to_non_pointer_int)
3165 << DestType << SrcExpr.get()->getSourceRange();
3170 if ((
Self.Context.getTypeSize(SrcType) >
3171 Self.Context.getTypeSize(DestType)) &&
3181 : diag::warn_void_pointer_to_int_cast;
3183 Diag = diag::warn_pointer_to_enum_cast;
3185 Diag = diag::warn_pointer_to_int_cast;
3186 Self.Diag(OpRange.getBegin(),
Diag) << SrcType << DestType << OpRange;
3190 if (
Self.getLangOpts().OpenCL && !
Self.getOpenCLOptions().isAvailableOption(
3191 "cl_khr_fp16",
Self.getLangOpts())) {
3193 Self.Diag(SrcExpr.get()->getBeginLoc(), diag::err_opencl_cast_to_half)
3194 << DestType << SrcExpr.get()->getSourceRange();
3201 if (
Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) {
3203 if (SrcExpr.isInvalid())
3207 if (
Self.getLangOpts().ObjCAutoRefCount && CastPtr) {
3210 Qualifiers ExprQuals = ExprPtr->getPointeeType().getQualifiers();
3212 ExprPtr->getPointeeType()->isObjCLifetimeType() &&
3214 Self.Diag(SrcExpr.get()->getBeginLoc(),
3215 diag::err_typecheck_incompatible_ownership)
3217 << SrcExpr.get()->getSourceRange();
3221 }
else if (!
Self.ObjC().CheckObjCARCUnavailableWeakConversion(DestType,
3223 Self.Diag(SrcExpr.get()->getBeginLoc(),
3224 diag::err_arc_convesion_of_weak_unavailable)
3225 << 1 << SrcType << DestType << SrcExpr.get()->getSourceRange();
3232 Self.Diag(OpRange.getBegin(), DiagID) << SrcType << DestType << OpRange;
3234 if (isa<PointerType>(SrcType) && isa<PointerType>(DestType)) {
3241 if (SrcRD && DestRD && SrcRD->
hasAttr<RandomizeLayoutAttr>() &&
3244 Self.Diag(OpRange.getBegin(), diag::err_cast_from_randomized_struct)
3245 << SrcType << DestType;
3254 Kind =
Self.PrepareScalarCast(SrcExpr, DestType);
3255 if (SrcExpr.isInvalid())
3258 if (Kind == CK_BitCast)
3262void CastOperation::CheckBuiltinBitCast() {
3263 QualType SrcType = SrcExpr.get()->getType();
3265 if (
Self.RequireCompleteType(OpRange.getBegin(), DestType,
3266 diag::err_typecheck_cast_to_incomplete) ||
3267 Self.RequireCompleteType(OpRange.getBegin(), SrcType,
3268 diag::err_incomplete_type)) {
3273 if (SrcExpr.get()->isPRValue())
3274 SrcExpr =
Self.CreateMaterializeTemporaryExpr(SrcType, SrcExpr.get(),
3277 CharUnits DestSize =
Self.Context.getTypeSizeInChars(DestType);
3278 CharUnits SourceSize =
Self.Context.getTypeSizeInChars(SrcType);
3279 if (DestSize != SourceSize) {
3280 Self.Diag(OpRange.getBegin(), diag::err_bit_cast_type_size_mismatch)
3287 Self.Diag(OpRange.getBegin(), diag::err_bit_cast_non_trivially_copyable)
3294 Self.Diag(OpRange.getBegin(), diag::err_bit_cast_non_trivially_copyable)
3300 Kind = CK_LValueToRValueBitCast;
3315 QualType TheOffendingSrcType, TheOffendingDestType;
3318 &TheOffendingSrcType, &TheOffendingDestType,
3319 &CastAwayQualifiers) !=
3320 CastAwayConstnessKind::CACK_Similar)
3324 int qualifiers = -1;
3327 }
else if (CastAwayQualifiers.
hasConst()) {
3333 if (qualifiers == -1)
3335 << SrcType << DestType;
3338 << TheOffendingSrcType << TheOffendingDestType << qualifiers;
3350 Op.CheckCXXCStyleCast(
false,
3353 Op.CheckCStyleCast();
3356 if (Op.SrcExpr.isInvalid())
3363 Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
3372 assert(LPLoc.
isValid() &&
"List-initialization shouldn't get here.");
3375 Op.OpRange =
SourceRange(Op.DestRange.getBegin(), RPLoc);
3377 Op.CheckCXXCStyleCast(
true,
false);
3378 if (Op.SrcExpr.isInvalid())
3381 auto *SubExpr = Op.SrcExpr.get();
3382 if (
auto *BindExpr = dyn_cast<CXXBindTemporaryExpr>(SubExpr))
3383 SubExpr = BindExpr->getSubExpr();
3384 if (
auto *ConstructExpr = dyn_cast<CXXConstructExpr>(SubExpr))
3385 ConstructExpr->setParenOrBraceRange(
SourceRange(LPLoc, RPLoc));
3391 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 ...
void UnwrapSimilarArrayTypes(QualType &T1, QualType &T2, bool AllowPiMismatch=true)
Attempt to unwrap two types that may both be array types with the same bound (or both be array types ...
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.
bool UnwrapSimilarTypes(QualType &T1, QualType &T2, bool AllowPiMismatch=true)
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)
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.
bool isAtLeastAsQualifiedAs(CanQual< T > Other) const
Determines whether this canonical type is at least as qualified as the Other canonical type.
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 isAtLeastAsQualifiedAs(QualType Other) const
Determine whether this type is at least as qualified as the other given type, requiring exact equalit...
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.
bool isAddressSpaceOverlapping(QualType T) const
Returns true if address space qualifiers overlap with T address space qualifiers.
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)
The collection of all-type qualifiers we support.
unsigned getCVRQualifiers() const
void removeObjCLifetime()
static Qualifiers fromCVRMask(unsigned CVR)
static bool isAddressSpaceSupersetOf(LangAS A, LangAS B)
Returns true if address space A is equal to or a superset of B.
bool compatiblyIncludes(Qualifiers other) const
Determines if these qualifiers compatibly include another set.
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.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
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.
@ 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...