26 #include "llvm/ADT/SmallVector.h" 28 using namespace clang;
55 struct CastOperation {
57 : Self(S), SrcExpr(src), DestType(destType),
60 Kind(CK_Dependent), IsARCUnbridgedCast(
false) {
63 src.
get()->getType()->getAsPlaceholderType()) {
64 PlaceholderKind = placeholder->getKind();
78 bool IsARCUnbridgedCast;
84 void CheckConstCast();
85 void CheckReinterpretCast();
86 void CheckStaticCast();
87 void CheckDynamicCast();
88 void CheckCXXCStyleCast(
bool FunctionalCast,
bool ListInitialization);
89 void CheckCStyleCast();
90 void CheckBuiltinBitCast();
92 void updatePartOfExplicitCastFlags(
CastExpr *CE) {
97 ICE->setIsPartOfExplicitCast(
true);
105 if (IsARCUnbridgedCast) {
108 CK_Dependent, castExpr,
nullptr,
111 updatePartOfExplicitCastFlags(castExpr);
121 if (PlaceholderKind != K)
return false;
127 bool isPlaceholder()
const {
128 return PlaceholderKind != 0;
131 return PlaceholderKind == K;
137 void checkCastAlign() {
147 IsARCUnbridgedCast =
true;
152 void checkNonOverloadPlaceholders() {
153 if (!isPlaceholder() || isPlaceholder(BuiltinType::Overload))
199 QualType OrigDestType,
unsigned &msg,
215 bool ListInitialization);
222 bool ListInitialization);
247 if (getLangOpts().CPlusPlus) {
249 CheckExtraCXXDefaultArguments(D);
252 return BuildCXXNamedCast(OpLoc, Kind, TInfo, E,
268 CastOperation Op(*
this, DestType, E);
270 Op.DestRange = AngleBrackets;
273 default: llvm_unreachable(
"Unknown C++ cast!");
275 case tok::kw_const_cast:
276 if (!TypeDependent) {
278 if (Op.SrcExpr.isInvalid())
280 DiscardMisalignedMemberAddress(DestType.
getTypePtr(), E);
283 Op.ValueKind, Op.SrcExpr.get(), DestTInfo,
287 case tok::kw_dynamic_cast: {
289 if (getLangOpts().OpenCLCPlusPlus) {
290 return ExprError(
Diag(OpLoc, diag::err_openclcxx_not_supported)
294 if (!TypeDependent) {
295 Op.CheckDynamicCast();
296 if (Op.SrcExpr.isInvalid())
300 Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
301 &Op.BasePath, DestTInfo,
305 case tok::kw_reinterpret_cast: {
306 if (!TypeDependent) {
307 Op.CheckReinterpretCast();
308 if (Op.SrcExpr.isInvalid())
310 DiscardMisalignedMemberAddress(DestType.
getTypePtr(), E);
313 Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
314 nullptr, DestTInfo, OpLoc,
318 case tok::kw_static_cast: {
319 if (!TypeDependent) {
320 Op.CheckStaticCast();
321 if (Op.SrcExpr.isInvalid())
323 DiscardMisalignedMemberAddress(DestType.
getTypePtr(), E);
327 Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
328 &Op.BasePath, DestTInfo,
344 return BuildBuiltinBitCastExpr(KWLoc, TInfo, Operand.
get(), RParenLoc);
350 CastOperation Op(*
this, TSI->
getType(), Operand);
356 Op.CheckBuiltinBitCast();
357 if (Op.SrcExpr.isInvalid())
363 Op.SrcExpr.get(), TSI, KWLoc, RParenLoc);
364 return Op.complete(BCE);
372 bool listInitialization) {
394 range, listInitialization)
400 assert(sequence.
Failed() &&
"initialization succeeded on second try?");
402 default:
return false;
415 case OR_Success: llvm_unreachable(
"successful failed overload");
417 if (candidates.
empty())
418 msg = diag::err_ovl_no_conversion_in_cast;
420 msg = diag::err_ovl_no_viable_conversion_in_cast;
425 msg = diag::err_ovl_ambiguous_conversion_in_cast;
430 msg = diag::err_ovl_deleted_conversion_in_cast;
437 S.
PDiag(msg) << CT << srcType << destType << range
439 S, howManyCandidates, src);
447 bool listInitialization) {
448 if (msg == diag::err_bad_cxx_cast_generic &&
457 int DifferentPtrness = 0;
468 if (!DifferentPtrness) {
471 if (RecFrom && RecTo) {
473 if (!DeclFrom->isCompleteDefinition())
474 S.
Diag(DeclFrom->getLocation(), diag::note_type_incomplete)
475 << DeclFrom->getDeclName();
477 if (!DeclTo->isCompleteDefinition())
478 S.
Diag(DeclTo->getLocation(), diag::note_type_incomplete)
479 << DeclTo->getDeclName();
494 CACK_SimilarKind = 2,
515 enum {
None, Ptr, MemPtr, BlockPtr, Array };
517 if (T->isAnyPointerType())
return Ptr;
518 if (T->isMemberPointerType())
return MemPtr;
519 if (T->isBlockPointerType())
return BlockPtr;
522 if (T->isConstantArrayType() || T->isIncompleteArrayType())
return Array;
528 return AT->getElementType();
529 return T->getPointeeType();
540 Kind = CastAwayConstnessKind::CACK_Similar;
542 Kind = CastAwayConstnessKind::CACK_Similar;
545 int T1Class = Classify(T1);
547 return CastAwayConstnessKind::CACK_None;
549 int T2Class = Classify(T2);
551 return CastAwayConstnessKind::CACK_None;
555 Kind = T1Class == T2Class ? CastAwayConstnessKind::CACK_SimilarKind
556 : CastAwayConstnessKind::CACK_Incoherent;
566 if (Classify(T1) != Array)
569 auto T2Class = Classify(T2);
573 if (T2Class != Array)
574 Kind = CastAwayConstnessKind::CACK_Incoherent;
575 else if (Kind != CastAwayConstnessKind::CACK_Incoherent)
576 Kind = CastAwayConstnessKind::CACK_SimilarKind;
593 bool CheckCVR,
bool CheckObjCLifetime,
594 QualType *TheOffendingSrcType =
nullptr,
595 QualType *TheOffendingDestType =
nullptr,
600 return CastAwayConstnessKind::CACK_None;
605 "Source type is not pointer or pointer to member.");
608 "Destination type is not pointer or pointer to member.");
617 QualType PrevUnwrappedSrcType = UnwrappedSrcType;
618 QualType PrevUnwrappedDestType = UnwrappedDestType;
619 auto WorstKind = CastAwayConstnessKind::CACK_Similar;
620 bool AllConstSoFar =
true;
622 Self.
Context, UnwrappedSrcType, UnwrappedDestType)) {
625 if (
Kind > WorstKind)
637 UnwrappedDestType->isObjCObjectType())
646 if (SrcCvrQuals != DestCvrQuals) {
647 if (CastAwayQualifiers)
648 *CastAwayQualifiers = SrcCvrQuals - DestCvrQuals;
651 if (!DestCvrQuals.compatiblyIncludes(SrcCvrQuals)) {
652 if (TheOffendingSrcType)
653 *TheOffendingSrcType = PrevUnwrappedSrcType;
654 if (TheOffendingDestType)
655 *TheOffendingDestType = PrevUnwrappedDestType;
666 if (CheckObjCLifetime &&
672 if (AllConstSoFar && !DestQuals.
hasConst()) {
673 AllConstSoFar =
false;
674 if (TheOffendingSrcType)
675 *TheOffendingSrcType = PrevUnwrappedSrcType;
676 if (TheOffendingDestType)
677 *TheOffendingDestType = PrevUnwrappedDestType;
680 PrevUnwrappedSrcType = UnwrappedSrcType;
681 PrevUnwrappedDestType = UnwrappedDestType;
684 return CastAwayConstnessKind::CACK_None;
690 case CastAwayConstnessKind::CACK_None:
691 llvm_unreachable(
"did not cast away constness");
693 case CastAwayConstnessKind::CACK_Similar:
695 case CastAwayConstnessKind::CACK_SimilarKind:
696 DiagID = diag::err_bad_cxx_cast_qualifiers_away;
699 case CastAwayConstnessKind::CACK_Incoherent:
700 DiagID = diag::ext_bad_cxx_cast_qualifiers_away_incoherent;
704 llvm_unreachable(
"unexpected cast away constness kind");
710 void CastOperation::CheckDynamicCast() {
713 else if (isPlaceholder())
732 Self.
Diag(OpRange.
getBegin(), diag::err_bad_dynamic_cast_not_ref_or_ptr)
733 << this->DestType << DestRange;
740 assert(DestPointer &&
"Reference to void is not possible");
741 }
else if (DestRecord) {
743 diag::err_bad_cast_incomplete,
749 Self.
Diag(OpRange.
getBegin(), diag::err_bad_dynamic_cast_not_class)
765 Self.
Diag(OpRange.
getBegin(), diag::err_bad_dynamic_cast_not_ptr)
766 << OrigSrcType << this->DestType << SrcExpr.
get()->getSourceRange();
770 }
else if (DestReference->isLValueReferenceType()) {
771 if (!SrcExpr.
get()->isLValue()) {
772 Self.
Diag(OpRange.
getBegin(), diag::err_bad_cxx_cast_rvalue)
773 <<
CT_Dynamic << OrigSrcType << this->DestType << OpRange;
775 SrcPointee = SrcType;
779 if (SrcExpr.
get()->isRValue())
781 SrcType, SrcExpr.
get(),
false);
782 SrcPointee = SrcType;
788 diag::err_bad_cast_incomplete,
794 Self.
Diag(OpRange.
getBegin(), diag::err_bad_dynamic_cast_not_class)
800 assert((DestPointer || DestReference) &&
801 "Bad destination non-ptr/ref slipped through.");
802 assert((DestRecord || DestPointee->
isVoidType()) &&
803 "Bad destination pointee slipped through.");
804 assert(SrcRecord &&
"Bad source pointee slipped through.");
808 Self.
Diag(OpRange.
getBegin(), diag::err_bad_cxx_cast_qualifiers_away)
809 <<
CT_Dynamic << OrigSrcType << this->DestType << OpRange;
816 if (DestRecord == SrcRecord) {
832 Kind = CK_DerivedToBase;
838 assert(SrcDecl &&
"Definition missing");
839 if (!cast<CXXRecordDecl>(SrcDecl)->isPolymorphic()) {
840 Self.
Diag(OpRange.
getBegin(), diag::err_bad_dynamic_cast_not_polymorphic)
849 Self.
Diag(OpRange.
getBegin(), diag::err_no_dynamic_cast_with_fno_rtti);
863 void CastOperation::CheckConstCast() {
866 else if (isPlaceholder())
871 unsigned msg = diag::err_bad_cxx_cast_generic;
872 auto TCR =
TryConstCast(Self, SrcExpr, DestType,
false, msg);
875 << SrcExpr.
get()->getType() << DestType << OpRange;
912 ReinterpretKind = ReinterpretUpcast;
914 ReinterpretKind = ReinterpretDowncast;
918 bool VirtualBase =
true;
919 bool NonZeroOffset =
false;
925 bool IsVirtual =
false;
926 for (CXXBasePath::const_iterator IElem = Path.begin(), EElem = Path.end();
927 IElem != EElem; ++IElem) {
928 IsVirtual = IElem->Base->isVirtual();
931 const CXXRecordDecl *BaseRD = IElem->Base->getType()->getAsCXXRecordDecl();
932 assert(BaseRD &&
"Base type should be a valid unqualified class type");
938 !ClassDefinition->isCompleteDefinition())
951 NonZeroOffset =
true;
953 VirtualBase = VirtualBase && IsVirtual;
956 (void) NonZeroOffset;
957 assert((VirtualBase || NonZeroOffset) &&
958 "Should have returned if has non-virtual base with zero offset");
961 ReinterpretKind == ReinterpretUpcast? DestType : SrcType;
963 ReinterpretKind == ReinterpretUpcast? SrcType : DestType;
966 Self.
Diag(BeginLoc, diag::warn_reinterpret_different_from_static)
967 << DerivedType << BaseType << !VirtualBase << int(ReinterpretKind)
969 Self.
Diag(BeginLoc, diag::note_reinterpret_updowncast_use_static)
970 << int(ReinterpretKind)
979 void CastOperation::CheckReinterpretCast() {
980 if (ValueKind ==
VK_RValue && !isPlaceholder(BuiltinType::Overload))
983 checkNonOverloadPlaceholders();
987 unsigned msg = diag::err_bad_cxx_cast_generic;
990 false, OpRange, msg,
Kind);
996 Self.
Diag(OpRange.
getBegin(), diag::err_bad_reinterpret_cast_overload)
998 << DestType << OpRange;
1020 void CastOperation::CheckStaticCast() {
1021 if (isPlaceholder()) {
1022 checkNonOverloadPlaceholders();
1033 if (claimPlaceholder(BuiltinType::Overload)) {
1037 OpRange, DestType, diag::err_bad_static_cast_overload);
1047 !isPlaceholder(BuiltinType::Overload)) {
1053 unsigned msg = diag::err_bad_cxx_cast_generic;
1056 Kind, BasePath,
false);
1062 Self.
Diag(OpRange.
getBegin(), diag::err_bad_static_cast_overload)
1063 << oe->
getName() << DestType << OpRange
1073 if (
Kind == CK_BitCast)
1090 DestPtrType->getPointeeType().getAddressSpace();
1101 bool ListInitialization) {
1127 OpRange, msg,
Kind, BasePath);
1142 Kind, ListInitialization);
1162 if (Enum->getDecl()->isScoped()) {
1164 Kind = CK_IntegralToBoolean;
1167 Kind = CK_IntegralCast;
1170 Kind = CK_IntegralToFloating;
1186 diag::err_bad_cast_incomplete)) {
1191 Kind = CK_IntegralCast;
1194 Kind = CK_FloatingToIntegral;
1210 OpRange, msg, Kind, BasePath);
1233 if (DestPointeeQuals != SrcPointeeQuals &&
1235 msg = diag::err_bad_cxx_cast_qualifiers_away;
1240 ? CK_AddressSpaceConversion
1249 Self.
Diag(OpRange.getBegin(), diag::ext_ms_cast_fn_obj) << OpRange;
1257 Kind = CK_CPointerToObjCPointerCast;
1262 Kind = CK_AnyPointerToBlockPointerCast;
1283 if (SrcPointer->getPointeeType()->getAs<
RecordType>() &&
1285 msg = diag::err_bad_cxx_cast_unrelated_class;
1318 SrcExpr->
getBeginLoc(), ToType, FromType, &RefConv);
1325 msg = SrcExpr->
isLValue() ? diag::err_bad_lvalue_to_rvalue_cast
1326 : diag::err_bad_rvalue_to_rvalue_cast;
1330 if (RefConv & Sema::ReferenceConversions::DerivedToBase) {
1331 Kind = CK_DerivedToBase;
1361 if (!DestReference) {
1365 if (!RValueRef && !SrcExpr->
isLValue()) {
1367 msg = diag::err_bad_cxx_cast_rvalue;
1404 msg = diag::err_bad_static_cast_pointer_nonpointer;
1411 CStyle, OpRange, SrcType, DestType, msg, Kind,
1421 QualType OrigDestType,
unsigned &msg,
1459 msg = diag::err_bad_cxx_cast_qualifiers_away;
1463 if (Paths.
isAmbiguous(SrcType.getUnqualifiedType())) {
1473 std::string PathDisplayStr;
1474 std::set<unsigned> DisplayedPaths;
1476 if (DisplayedPaths.insert(Path.back().SubobjectNumber).second) {
1479 PathDisplayStr +=
"\n ";
1481 PathDisplayStr += PE.Base->getType().getAsString() +
" -> ";
1486 Self.
Diag(OpRange.
getBegin(), diag::err_ambiguous_base_to_derived_cast)
1489 << PathDisplayStr << OpRange;
1496 Self.
Diag(OpRange.
getBegin(), diag::err_static_downcast_via_virtual)
1497 << OrigSrcType << OrigDestType << VirtualBase << OpRange;
1506 diag::err_downcast_from_inaccessible_base)) {
1519 Kind = CK_BaseToDerived;
1540 bool WasOverloadedFunction =
false;
1549 WasOverloadedFunction =
true;
1555 msg = diag::err_bad_static_cast_member_pointer_nonmp;
1582 Paths.setRecordingPaths(
true);
1588 Self.
Diag(OpRange.
getBegin(), diag::err_ambiguous_memptr_conv)
1589 << 1 << SrcClass << DestClass << PathDisplayStr << OpRange;
1594 if (
const RecordType *VBase = Paths.getDetectedVirtual()) {
1595 Self.
Diag(OpRange.
getBegin(), diag::err_memptr_conv_via_virtual)
1596 << SrcClass << DestClass <<
QualType(VBase, 0) << OpRange;
1603 DestClass, SrcClass,
1605 diag::err_upcast_to_inaccessible_base)) {
1619 if (WasOverloadedFunction) {
1639 Kind = CK_DerivedToBaseMemberPointer;
1655 diag::err_bad_cast_incomplete) ||
1657 diag::err_allocation_of_abstract_type)) {
1671 Expr *SrcExprRaw = SrcExpr.
get();
1694 Kind = CK_ConstructorConversion;
1709 bool NeedToMaterializeTemporary =
false;
1723 if (isa<LValueReferenceType>(DestTypeTmp) && !SrcExpr.
get()->isLValue()) {
1727 msg = diag::err_bad_cxx_cast_rvalue;
1731 if (isa<RValueReferenceType>(DestTypeTmp) && SrcExpr.
get()->isRValue()) {
1735 msg = diag::err_bad_cxx_cast_rvalue;
1741 NeedToMaterializeTemporary =
true;
1749 if (SrcExpr.
get()->refersToBitField()) {
1750 msg = diag::err_bad_cxx_cast_bitfield;
1770 msg = diag::err_bad_const_cast_dest;
1779 msg = diag::err_bad_const_cast_dest;
1792 if (NeedToMaterializeTemporary)
1810 unsigned DiagID = IsDereference ?
1811 diag::warn_pointer_indirection_from_incompatible_type :
1812 diag::warn_undefined_reinterpret_cast;
1814 if (Diags.isIgnored(DiagID, Range.
getBegin()))
1818 if (IsDereference) {
1854 Diag(Range.
getBegin(), DiagID) << SrcType << DestType << Range;
1863 if (SrcPtrTy->isObjCSelType()) {
1865 if (isa<PointerType>(DestType))
1868 Self.
Diag(SrcExpr.
get()->getExprLoc(),
1869 diag::warn_cast_pointer_from_sel)
1870 << SrcType << DestType << SrcExpr.
get()->getSourceRange();
1884 const auto *SrcFTy =
1886 const auto *DstFTy =
1895 Expr *Src = SrcExpr.
get()->IgnoreParenImpCasts();
1896 if (
auto *UO = dyn_cast<UnaryOperator>(Src))
1897 if (UO->getOpcode() == UO_AddrOf)
1911 FD->isVariadic(), FD->isCXXInstanceMember());
1912 if (DstCC == DefaultCC || SrcCC != DefaultCC)
1918 Self.
Diag(OpRange.
getBegin(), diag::warn_cast_calling_conv)
1919 << SrcCCName << DstCCName << OpRange;
1931 SourceLocation NameLoc = FD->getFirstDecl()->getNameInfo().getLoc();
1935 llvm::raw_svector_ostream OS(CCAttrText);
1938 OS <<
"__" << DstCCName;
1945 OS <<
"__attribute__((" << DstCCName <<
"))";
1946 AttrTokens.push_back(tok::kw___attribute);
1947 AttrTokens.push_back(tok::l_paren);
1948 AttrTokens.push_back(tok::l_paren);
1953 AttrTokens.push_back(tok::r_paren);
1954 AttrTokens.push_back(tok::r_paren);
1957 if (!AttrSpelling.empty())
1958 CCAttrText = AttrSpelling;
1960 Self.
Diag(NameLoc, diag::note_change_calling_conv_fixit)
1984 diag::warn_int_to_void_pointer_cast
1985 : diag::warn_int_to_pointer_cast;
1986 Self.
Diag(Loc, Diag) << SrcType << DestType;
2022 bool IsLValueCast =
false;
2034 assert(FixedExpr.
isUsable() &&
"Invalid result fixing overloaded expr");
2035 SrcExpr = FixedExpr;
2036 SrcType = SrcExpr.get()->getType();
2040 if (!SrcExpr.
get()->isGLValue()) {
2043 msg = diag::err_bad_cxx_cast_rvalue;
2056 const char *inappropriate =
nullptr;
2057 switch (SrcExpr.
get()->getObjectKind()) {
2061 msg = diag::err_bad_cxx_cast_bitfield;
2066 case OK_ObjCSubscript: inappropriate =
"container subscripting expression";
2069 if (inappropriate) {
2070 Self.
Diag(OpRange.
getBegin(), diag::err_bad_reinterpret_cast_reference)
2071 << inappropriate << DestType
2072 << OpRange << SrcExpr.
get()->getSourceRange();
2081 IsLValueCast =
true;
2089 if (DestMemPtr && SrcMemPtr) {
2095 SrcMemPtr->isMemberFunctionPointer())
2108 msg = diag::err_bad_cxx_cast_member_pointer_size;
2122 assert(!IsLValueCast);
2123 Kind = CK_ReinterpretMemberPointer;
2135 msg = diag::err_bad_reinterpret_cast_small_int;
2138 Kind = CK_PointerToIntegral;
2146 if (srcIsVector || destIsVector) {
2163 msg = diag::err_bad_cxx_cast_vector_to_scalar_different_size;
2164 else if (!srcIsVector)
2165 msg = diag::err_bad_cxx_cast_scalar_to_vector_different_size;
2167 msg = diag::err_bad_cxx_cast_vector_to_vector_different_size;
2172 if (SrcType == DestType) {
2196 if (!destIsPtr && !srcIsPtr) {
2203 assert(srcIsPtr &&
"One type must be a pointer");
2207 bool MicrosoftException = Self.
getLangOpts().MicrosoftExt &&
2211 !MicrosoftException) {
2212 msg = diag::err_bad_reinterpret_cast_small_int;
2215 Kind = CK_PointerToIntegral;
2220 assert(destIsPtr &&
"One type must be a pointer");
2227 Kind = CK_IntegralToPointer;
2231 if (!destIsPtr || !srcIsPtr) {
2251 Kind = CK_AddressSpaceConversion;
2258 }
else if (IsLValueCast) {
2259 Kind = CK_LValueBitCast;
2264 Kind = CK_AnyPointerToBlockPointerCast;
2275 return SuccessResult;
2289 return SuccessResult;
2300 diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)
2302 return SuccessResult;
2309 diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)
2311 return SuccessResult;
2324 diag::warn_bad_cxx_cast_nested_pointer_addr_space)
2325 << CStyle << SrcType << DestType << SrcExpr.
get()->getSourceRange();
2337 return SuccessResult;
2350 auto SrcType = SrcExpr.
get()->getType();
2357 auto SrcPointeeType = SrcPtrType->getPointeeType();
2358 auto DestPointeeType = DestPtrType->getPointeeType();
2359 if (SrcPointeeType.getAddressSpace() == DestPointeeType.getAddressSpace())
2361 if (!DestPtrType->isAddressSpaceOverlapping(*SrcPtrType)) {
2362 msg = diag::err_bad_cxx_cast_addr_space_mismatch;
2365 auto SrcPointeeTypeWithoutAS =
2367 auto DestPointeeTypeWithoutAS =
2370 DestPointeeTypeWithoutAS)
2375 void CastOperation::checkAddressSpaceCast(
QualType SrcType,
QualType DestType) {
2388 const Type *DestPtr, *SrcPtr;
2389 bool Nested =
false;
2390 unsigned DiagID = diag::err_typecheck_incompatible_address_space;
2394 while (isa<PointerType>(DestPtr) && isa<PointerType>(SrcPtr)) {
2395 const PointerType *DestPPtr = cast<PointerType>(DestPtr);
2396 const PointerType *SrcPPtr = cast<PointerType>(SrcPtr);
2399 if (Nested ? DestPPointee.getAddressSpace() !=
2404 << SrcExpr.
get()->getSourceRange();
2413 DiagID = diag::ext_nested_pointer_qualifier_mismatch;
2418 void CastOperation::CheckCXXCStyleCast(
bool FunctionalStyle,
2419 bool ListInitialization) {
2423 if (isPlaceholder()) {
2425 if (claimPlaceholder(BuiltinType::UnknownAny)) {
2428 ValueKind, BasePath);
2432 checkNonOverloadPlaceholders();
2443 if (claimPlaceholder(BuiltinType::Overload)) {
2446 true, DestRange, DestType,
2447 diag::err_bad_cstyle_cast_overload);
2458 SrcExpr.
get()->isValueDependent()) {
2459 assert(
Kind == CK_Dependent);
2464 !isPlaceholder(BuiltinType::Overload)) {
2473 && (SrcExpr.
get()->getType()->isIntegerType()
2474 || SrcExpr.
get()->getType()->isFloatingType())) {
2475 Kind = CK_VectorSplat;
2492 unsigned msg = diag::err_bad_cxx_cast_generic;
2508 Kind = CK_AddressSpaceConversion;
2513 BasePath, ListInitialization);
2520 OpRange, msg,
Kind);
2529 checkObjCConversion(CCK);
2543 Self.
Diag(OpRange.
getBegin(), diag::err_bad_cstyle_cast_overload)
2544 << OE->
getName() << DestType << OpRange
2550 OpRange, SrcExpr.
get(), DestType, ListInitialization);
2555 if (
Kind == CK_BitCast)
2568 SrcExpr.
get()->getExprLoc()))
2571 if (!isa<CallExpr>(SrcExpr.
get()))
2593 Self.
Diag(SrcExpr.
get()->getExprLoc(),
2594 diag::warn_bad_function_cast)
2595 << SrcType << DestType << SrcExpr.
get()->getSourceRange();
2599 void CastOperation::CheckCStyleCast() {
2603 if (claimPlaceholder(BuiltinType::UnknownAny)) {
2606 ValueKind, BasePath);
2627 SrcExpr.
get(), DestType,
true, DAP))
2634 if (SrcExpr.isInvalid())
2636 QualType SrcType = SrcExpr.get()->getType();
2640 checkAddressSpaceCast(SrcType, DestType);
2641 if (SrcExpr.isInvalid())
2645 diag::err_typecheck_cast_to_incomplete)) {
2655 Self.
Diag(OpRange.
getBegin(), diag::ext_typecheck_cast_nonscalar)
2656 << DestType << SrcExpr.get()->getSourceRange();
2665 Self.
Diag(OpRange.
getBegin(), diag::ext_typecheck_cast_to_union)
2666 << SrcExpr.get()->getSourceRange();
2670 Self.
Diag(OpRange.
getBegin(), diag::err_typecheck_cast_to_union_no_type)
2671 << SrcType << SrcExpr.get()->getSourceRange();
2680 if (SrcExpr.get()->EvaluateAsInt(Result, Self.
Context)) {
2683 Kind = CK_ZeroToOCLOpaqueType;
2687 diag::err_opencl_cast_non_zero_to_event_t)
2688 << CastInt.toString(10) << SrcExpr.get()->getSourceRange();
2695 Self.
Diag(OpRange.
getBegin(), diag::err_typecheck_cond_expect_scalar)
2696 << DestType << SrcExpr.get()->getSourceRange();
2705 Self.
Diag(SrcExpr.get()->getExprLoc(),
2706 diag::err_typecheck_expect_scalar_operand)
2707 << SrcType << SrcExpr.get()->getSourceRange();
2720 Kind = CK_VectorSplat;
2739 if (isa<ObjCSelectorExpr>(SrcExpr.get())) {
2740 Self.
Diag(SrcExpr.get()->getExprLoc(), diag::err_cast_selector_expr);
2749 Self.
Diag(SrcExpr.get()->getExprLoc(),
2750 diag::err_cast_pointer_from_non_pointer_int)
2751 << SrcType << SrcExpr.get()->getSourceRange();
2760 Self.
Diag(SrcExpr.get()->getBeginLoc(),
2761 diag::err_cast_pointer_to_non_pointer_int)
2762 << DestType << SrcExpr.get()->getSourceRange();
2771 Self.
Diag(SrcExpr.get()->getBeginLoc(), diag::err_opencl_cast_to_half)
2772 << DestType << SrcExpr.get()->getSourceRange();
2781 if (SrcExpr.isInvalid())
2785 if (Self.
getLangOpts().ObjCAutoRefCount && CastPtr) {
2788 Qualifiers ExprQuals = ExprPtr->getPointeeType().getQualifiers();
2790 ExprPtr->getPointeeType()->isObjCLifetimeType() &&
2792 Self.
Diag(SrcExpr.get()->getBeginLoc(),
2793 diag::err_typecheck_incompatible_ownership)
2795 << SrcExpr.get()->getSourceRange();
2801 Self.
Diag(SrcExpr.get()->getBeginLoc(),
2802 diag::err_arc_convesion_of_weak_unavailable)
2803 << 1 << SrcType << DestType << SrcExpr.get()->getSourceRange();
2813 if (SrcExpr.isInvalid())
2816 if (
Kind == CK_BitCast)
2820 void CastOperation::CheckBuiltinBitCast() {
2824 diag::err_typecheck_cast_to_incomplete) ||
2826 diag::err_incomplete_type)) {
2831 if (SrcExpr.
get()->isRValue())
2837 if (DestSize != SourceSize) {
2838 Self.
Diag(OpRange.
getBegin(), diag::err_bit_cast_type_size_mismatch)
2845 Self.
Diag(OpRange.
getBegin(), diag::err_bit_cast_non_trivially_copyable)
2852 Self.
Diag(OpRange.
getBegin(), diag::err_bit_cast_non_trivially_copyable)
2858 Kind = CK_LValueToRValueBitCast;
2873 QualType TheOffendingSrcType, TheOffendingDestType;
2876 &TheOffendingSrcType, &TheOffendingDestType,
2877 &CastAwayQualifiers) !=
2878 CastAwayConstnessKind::CACK_Similar)
2882 int qualifiers = -1;
2885 }
else if (CastAwayQualifiers.
hasConst()) {
2891 if (qualifiers == -1)
2892 Self.
Diag(SrcExpr.
get()->getBeginLoc(), diag::warn_cast_qual2)
2893 << SrcType << DestType;
2895 Self.
Diag(SrcExpr.
get()->getBeginLoc(), diag::warn_cast_qual)
2896 << TheOffendingSrcType << TheOffendingDestType << qualifiers;
2903 CastOperation Op(*
this, CastTypeInfo->
getType(), CastExpr);
2907 if (getLangOpts().CPlusPlus) {
2908 Op.CheckCXXCStyleCast(
false,
2909 isa<InitListExpr>(CastExpr));
2911 Op.CheckCStyleCast();
2914 if (Op.SrcExpr.isInvalid())
2921 Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
2922 &Op.BasePath, CastTypeInfo, LPLoc, RPLoc));
2930 assert(LPLoc.
isValid() &&
"List-initialization shouldn't get here.");
2931 CastOperation Op(*
this, Type, CastExpr);
2935 Op.CheckCXXCStyleCast(
true,
false);
2936 if (Op.SrcExpr.isInvalid())
2939 auto *SubExpr = Op.SrcExpr.
get();
2940 if (
auto *BindExpr = dyn_cast<CXXBindTemporaryExpr>(SubExpr))
2941 SubExpr = BindExpr->getSubExpr();
2942 if (
auto *ConstructExpr = dyn_cast<CXXConstructExpr>(SubExpr))
2943 ConstructExpr->setParenOrBraceRange(
SourceRange(LPLoc, RPLoc));
2946 Op.ValueKind, CastTypeInfo, Op.Kind,
2947 Op.SrcExpr.get(), &Op.BasePath, LPLoc, RPLoc));
Defines the clang::ASTContext interface.
bool RequireNonAbstractType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
Represents a function declaration or definition.
static bool IsAddressSpaceConversion(QualType SrcType, QualType DestType)
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.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
bool isBlockPointerType() const
bool isMemberPointerType() const
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
A cast other than a C-style cast.
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range covering the entirety of this nested-name-specifier.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
bool isArithmeticType() const
FunctionType - C99 6.7.5.3 - Function Declarators.
ARCConversionResult CheckObjCConversion(SourceRange castRange, QualType castType, Expr *&op, CheckedConversionKind CCK, bool Diagnose=true, bool DiagnoseCFAudited=false, BinaryOperatorKind Opc=BO_PtrMemD)
Checks for invalid conversions and casts between retainable pointers and other pointer kinds for ARC ...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
static CXXDynamicCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets)
bool isRealFloatingType() const
Floating point categories.
bool isRecordType() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, Sema::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.
bool isExtVectorType() const
The cast method is appropriate and successful.
FailureKind getFailureKind() const
Determine why initialization failed.
CanQualType ARCUnbridgedCastTy
The base class of the type hierarchy.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
StringRef getLastMacroWithSpelling(SourceLocation Loc, ArrayRef< TokenValue > Tokens) const
Return the name of the macro defined before Loc that has spelling Tokens.
static ExprValueKind getValueKindForType(QualType T)
getValueKindForType - Given a formal return or parameter type, give its value kind.
Overloading for a user-defined conversion failed.
bool isZero() const
isZero - Test whether the quantity equals zero.
Ambiguous candidates found.
const TargetInfo & getTargetInfo() const
A container of type source information.
static CXXFunctionalCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, TypeSourceInfo *Written, CastKind Kind, Expr *Op, const CXXCastPath *Path, SourceLocation LPLoc, SourceLocation RPLoc)
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
SourceLocation getEndLoc() const
Get the end source location.
static InitializedEntity InitializeTemporary(QualType Type)
Create the initialization entity for a temporary.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
bool CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty, CastKind &Kind)
An Objective-C array/dictionary subscripting which reads an object or writes at the subscripted array...
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
Information about one declarator, including the parsed type information and the identifier.
void removeObjCLifetime()
DiagnosticsEngine & Diags
bool isEnumeralType() const
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...
const T * getAs() const
Member-template getAs<specific type>'.
void clear()
Clear the base-paths results.
CastAwayConstnessKind
The kind of unwrapping we did when determining whether a conversion casts away constness.
QualType getMemberPointerType(QualType T, const Type *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
DeclarationName getName() const
Gets the name looked up.
bool isInvalidDecl() const
ReferenceCompareResult CompareReferenceRelationship(SourceLocation Loc, QualType T1, QualType T2, ReferenceConversions *Conv=nullptr)
CompareReferenceRelationship - Compare the two types T1 and T2 to determine whether they are referenc...
OpenCLOptions & getOpenCLOptions()
Defines the clang::Expr interface and subclasses for C++ expressions.
The collection of all-type qualifiers we support.
bool isRecordingPaths() const
Whether we are recording paths.
bool UnwrapSimilarTypes(QualType &T1, QualType &T2)
Attempt to unwrap two types that may be similar (C++ [conv.qual]).
Base wrapper for a particular "section" of type source info.
Expr * FixOverloadedFunctionReference(Expr *E, DeclAccessPair FoundDecl, FunctionDecl *Fn)
FixOverloadedFunctionReference - E is an expression that refers to a C++ overloaded function (possibl...
Represents a struct/union/class.
One of these records is kept for each identifier that is lexed.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
void setRecordingPaths(bool RP)
Specify whether we should be recording paths or not.
A vector component is an element or range of elements on a vector.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool allowsNonTrivialObjCLifetimeQualifiers() const
True if any ObjC types may have non-trivial lifetime qualifiers.
bool isObjCLifetimeType() const
Returns true if objects of this type have lifetime semantics under ARC.
The cast method is not applicable.
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base)
Determine whether the type Derived is a C++ class that is derived from the type Base.
SourceLocation getBeginLoc() const LLVM_READONLY
static TryCastResult getCastAwayConstnessCastKind(CastAwayConstnessKind CACK, unsigned &DiagID)
bool isReferenceType() const
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Ref_Incompatible - The two types are incompatible, so direct reference binding is not possible...
bool isAtLeastAsQualifiedAs(QualType Other) const
Determine whether this type is at least as qualified as the other given type, requiring exact equalit...
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
OverloadCandidateDisplayKind
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
bool isInvalidType() const
ExprResult ActOnBuiltinBitCastExpr(SourceLocation KWLoc, Declarator &Dcl, ExprResult Operand, SourceLocation RParenLoc)
static bool isValidCast(TryCastResult TCR)
bool isCompleteType(SourceLocation Loc, QualType T)
An rvalue reference type, per C++11 [dcl.ref].
ReferenceConversions
The conversions that would be performed on an lvalue of type T2 when binding a reference of type T1 t...
tok::TokenKind getTokenID() const
If this is a source-language token (e.g.
CharUnits - This is an opaque type for sizes expressed in character units.
Succeeded, but refers to a deleted function.
APValue Val
Val - This is the value the expression can be folded to.
Ref_Compatible - The two types are reference-compatible.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
OverloadCandidateSet & getFailedCandidateSet()
Retrieve a reference to the candidate set when overload resolution fails.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
const Type * getClass() const
bool isRValueReferenceType() const
CheckedConversionKind
The kind of conversion being performed.
static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, bool CStyle, SourceRange OpRange, unsigned &msg, CastKind &Kind)
FunctionDecl * ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr, QualType TargetType, bool Complain, DeclAccessPair &Found, bool *pHadMultipleCandidates=nullptr)
ResolveAddressOfOverloadedFunction - Try to resolve the address of an overloaded function (C++ [over...
ExprResult Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType *ResultType=nullptr)
Perform the actual initialization of the given entity based on the computed initialization sequence...
const RecordType * getDetectedVirtual() const
The virtual base discovered on the path (if we are merely detecting virtuals).
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
static void DiagnoseCastQual(Sema &Self, const ExprResult &SrcExpr, QualType DestType)
DiagnoseCastQual - Warn whenever casts discards a qualifiers, be it either const, volatile or both...
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang's AST.
const LangOptions & getLangOpts() const
bool isTypeDependent() const
isTypeDependent - Determines whether this expression is type-dependent (C++ [temp.dep.expr]), which means that its type could change from one template instantiation to the next.
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
bool isScalarType() const
bool compatiblyIncludesObjCLifetime(Qualifiers other) const
Determines if these qualifiers compatibly include another set of qualifiers from the narrow perspecti...
An ordinary object is located at an address in memory.
CastKind PrepareScalarCast(ExprResult &src, QualType destType)
Prepares for a scalar cast, performing all the necessary stages except the final cast and returning t...
static CastAwayConstnessKind unwrapCastAwayConstnessLevel(ASTContext &Context, QualType &T1, QualType &T2)
Unwrap one level of types for CastsAwayConstness.
CallingConv getDefaultCallingConvention(bool IsVariadic, bool IsCXXMethod, bool IsBuiltin=false) const
Retrieves the default calling convention for the current target.
Sema - This implements semantic analysis and AST building for C.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool compatiblyIncludes(Qualifiers other) const
Determines if these qualifiers compatibly include another set.
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
CastKind
CastKind - The kind of operation required for a conversion.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat)
bool UnwrapSimilarArrayTypes(QualType &T1, QualType &T2)
Attempt to unwrap two types that may both be array types with the same bound (or both be array types ...
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...
bool isEnabled(llvm::StringRef Ext) const
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
An Objective-C property is a logical field of an Objective-C object which is read and written via Obj...
SourceLocation getBeginLoc() const
Get the begin source location.
This represents one expression.
static void diagnoseBadCast(Sema &S, unsigned msg, CastType castType, SourceRange opRange, Expr *src, QualType destType, bool listInitialization)
Diagnose a failed cast.
QualType getPointeeType() const
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
static InitializationKind CreateFunctionalCast(SourceRange TypeRange, bool InitList)
Create a direct initialization for a functional cast.
void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath)
static FindResult find(Expr *E)
Finds the overloaded expression in the given expression E of OverloadTy.
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to...
const T * castAs() const
Member-template castAs<specific type>.
OverloadingResult getFailedOverloadResult() const
Get the overloading result, for when the initialization sequence failed due to a bad overload...
The cast method is appropriate and accepted as a language extension.
Defines the clang::Preprocessor interface.
bool isNullPtrType() const
static CXXStaticCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets)
CXXRecordDecl * getDefinition() const
Overload resolution succeeded.
ExprResult BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, TypeSourceInfo *Ty, Expr *E, SourceRange AngleBrackets, SourceRange Parens)
Stores token information for comparing actual tokens with predefined values.
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
static TryCastResult TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, Sema::CheckedConversionKind CCK, SourceRange OpRange, unsigned &msg, CastKind &Kind, bool ListInitialization)
TryStaticImplicitCast - Tests whether a conversion according to C++ 5.2.9p2 is valid: ...
bool isConstructorInitialization() const
Determine whether this initialization is direct call to a constructor.
ReferenceCompareResult
ReferenceCompareResult - Expresses the result of comparing two types (cv1 T1 and cv2 T2) to determine...
bool RequireCompleteType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char, signed char, short, int, long..], or an enum decl which has a signed representation.
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: ...
bool ResolveAndFixSingleFunctionTemplateSpecialization(ExprResult &SrcExpr, bool DoFunctionPointerConverion=false, bool Complain=false, SourceRange OpRangeForComplaining=SourceRange(), QualType DestTypeForComplaining=QualType(), unsigned DiagIDForComplaining=0)
bool isAtLeastAsQualifiedAs(CanQual< T > Other) const
Determines whether this canonical type is at least as qualified as the Other canonical type...
SourceLocation getEnd() const
Preprocessor & getPreprocessor() const
Represents a GCC generic vector type.
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.
bool CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, CastKind &Kind)
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
The result type of a method or function.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
bool isKeyword(const LangOptions &LangOpts) const
Return true if this token is a keyword in the specified language.
SourceLocation getEndLoc() const LLVM_READONLY
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
bool isVoidPointerType() const
bool areLaxCompatibleVectorTypes(QualType srcType, QualType destType)
Are the two types lax-compatible vector types? That is, given that one of them is a vector...
RecordDecl * getDecl() const
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 CXXConstCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets)
A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr...
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
ASTContext & getASTContext() const
Encodes a location in the source.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
CastKind PrepareCastToObjCObjectPointer(ExprResult &E)
Prepare a conversion of the given expression to an ObjC object pointer type.
LangAS getAddressSpace() const
Return the address space of this type.
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 const FieldDecl * getTargetFieldForToUnionCast(QualType unionType, QualType opType)
Represents a C++2a __builtin_bit_cast(T, v) expression.
Requests that only tied-for-best candidates be shown.
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs. ...
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
Represents a static or instance method of a struct/union/class.
ExprResult ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, SourceLocation LAngleBracketLoc, Declarator &D, SourceLocation RAngleBracketLoc, SourceLocation LParenLoc, Expr *E, SourceLocation RParenLoc)
ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
bool CheckObjCARCUnavailableWeakConversion(QualType castType, QualType ExprType)
std::string getAmbiguousPathsDisplayString(CXXBasePaths &Paths)
Builds a string representing ambiguous paths from a specific derived class to different subobjects of...
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
Represents a canonical, potentially-qualified type.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Describes the kind of initialization being performed, along with location information for tokens rela...
bool isMemberFunctionPointerType() const
bool isObjCObjectPointerType() const
bool isAnyPointerType() const
bool resolveAndFixAddressOfSingleOverloadCandidate(ExprResult &SrcExpr, bool DoFunctionPointerConversion=false)
Given an overloaded function, tries to turn it into a non-overloaded function reference using resolve...
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language...
Overloading for initialization by constructor failed.
Requests that all candidates be shown.
bool isAddressSpaceOverlapping(const PointerType &other) const
Returns true if address spaces of pointers overlap.
bool isAnyCharacterType() const
Determine whether this type is any of the built-in character types.
bool isVectorType() const
OverloadCandidateSet - A set of overload candidates, used in C++ overload resolution (C++ 13...
static TryCastResult TryAddressSpaceCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, bool CStyle, unsigned &msg)
static InitializationKind CreateCast(SourceRange TypeRange)
Create a direct initialization due to a cast that isn't a C-style or functional cast.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
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)
CanProxy< U > getAs() const
Retrieve a canonical type pointer with a different static type, upcasting or downcasting as needed...
ExprResult checkUnknownAnyCast(SourceRange TypeRange, QualType CastType, Expr *CastExpr, CastKind &CastKind, ExprValueKind &VK, CXXCastPath &Path)
Check a cast of an unknown-any type.
A POD class for pairing a NamedDecl* with an access specifier.
bool isPlaceholderType() const
Test for a type which does not represent an actual type-system type but is instead used as a placehol...
Represents an element in a path from a derived class to a base class.
std::list< CXXBasePath >::const_iterator const_paths_iterator
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
EvalResult is a struct with detailed info about an evaluated expression.
void CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType, bool IsDereference, SourceRange Range)
bool hasCvrSimilarType(QualType T1, QualType T2)
Determine if two types are similar, ignoring only CVR qualifiers.
The cast method is appropriate, but failed.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined...
bool isBooleanType() const
ExprResult prepareVectorSplat(QualType VectorTy, Expr *SplattedExpr)
Prepare SplattedExpr for a vector splat operation, adding implicit casts if necessary.
static void checkIntToPointerCast(bool CStyle, SourceLocation Loc, const Expr *SrcExpr, QualType DestType, Sema &Self)
Requests that only viable candidates be shown.
bool isAmbiguous(CanQualType BaseType)
Determine whether the path from the most-derived type to the given base type is ambiguous (i...
A pointer to member type per C++ 8.3.3 - Pointers to members.
bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx, SourceLocation *Loc=nullptr, bool isEvaluated=true) const
isIntegerConstantExpr - Return true if this expression is a valid integer constant expression...
static InitializationKind CreateCStyleCast(SourceLocation StartLoc, SourceRange TypeRange, bool InitList)
Create a direct initialization for a C-style cast.
void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange)
CheckCastAlign - Implements -Wcast-align, which warns when a pointer cast increases the alignment req...
static void DiagnoseCastOfObjCSEL(Sema &Self, const ExprResult &SrcExpr, QualType DestType)
static bool fixOverloadedReinterpretCastExpr(Sema &Self, QualType DestType, ExprResult &Result)
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
ExprResult IgnoredValueConversions(Expr *E)
IgnoredValueConversions - Given that an expression's result is syntactically ignored, perform any conversions that are required.
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT, SourceRange range, Expr *src, QualType destType, bool listInitialization)
Try to diagnose a failed overloaded cast.
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
ExprResult CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *CastExpr, CastKind &Kind)
static CStyleCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation R)
bool CheckDerivedToBaseConversion(QualType Derived, QualType Base, SourceLocation Loc, SourceRange Range, CXXCastPath *BasePath=nullptr, bool IgnoreAccess=false)
bool isFunctionType() const
MaterializeTemporaryExpr * CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary, bool BoundToLvalueReference)
Base for LValueReferenceType and RValueReferenceType.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
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 FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream...
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type...
A bitfield object is a bitfield on a C or C++ record.
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...
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
bool isObjCObjectType() const
QualType withCVRQualifiers(unsigned CVR) const
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool isLValueReferenceType() const
ExprResult BuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo, QualType Type, SourceLocation LParenLoc, Expr *CastExpr, SourceLocation RParenLoc)
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
bool Failed() const
Determine whether the initialization sequence is invalid.
CallingConv getCallConv() const
Describes the sequence of initializations required to initialize a given object or reference with a s...
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Represents a C++ struct/union/class.
bool isMemberFunctionPointer() const
Returns true if the member type (i.e.
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...
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType removeAddrSpaceQualType(QualType T) const
Remove any existing address space on the type and returns the type with qualifiers intact (or that's ...
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, const CXXBasePath &Path, unsigned DiagID, bool ForceCheck=false, bool ForceUnprivileged=false)
Checks access for a hierarchy conversion.
static bool isAddressSpaceSupersetOf(LangAS A, LangAS B)
Returns true if address space A is equal to or a superset of B.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
This class is used for builtin types like 'int'.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Defines the clang::TargetInfo interface.
bool isComplexIntegerType() const
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
unsigned getCVRQualifiers() const
static Qualifiers fromCVRMask(unsigned CVR)
static void DiagnoseBadFunctionCast(Sema &Self, const ExprResult &SrcExpr, QualType DestType)
DiagnoseBadFunctionCast - Warn whenever a function call is cast to a non-matching type...
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
A reference to a declared variable, function, enum, etc.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
NestedNameSpecifierLoc getQualifierLoc() const
Fetches the nested-name qualifier with source-location information, if one was given.
bool isPointerType() const
void NoteAllOverloadCandidates(Expr *E, QualType DestType=QualType(), bool TakingAddress=false)
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
No viable function found.
static StringRef getNameForCallConv(CallingConv CC)
bool isFloatingType() const
A trivial tuple used to represent a source range.
Describes an entity that is being initialized.
bool isFunctionPointerType() const
SourceLocation getBegin() const
const LangOptions & getLangOpts() const
ExprResult BuildBuiltinBitCastExpr(SourceLocation KWLoc, TypeSourceInfo *TSI, Expr *Operand, SourceLocation RParenLoc)
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals)
Return this type as a completely-unqualified array type, capturing the qualifiers in Quals...
bool isIncompleteOrObjectType() const
Return true if this is an incomplete or object type, in other words, not a function type...
QualType getPointeeType() const
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...
QualType getType() const
Return the type wrapped by this type source info.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.