diff options
Diffstat (limited to 'lib/Sema/SemaCXXCast.cpp')
-rw-r--r-- | lib/Sema/SemaCXXCast.cpp | 60 |
1 files changed, 31 insertions, 29 deletions
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp index ab085fb8ee..e5c4390752 100644 --- a/lib/Sema/SemaCXXCast.cpp +++ b/lib/Sema/SemaCXXCast.cpp @@ -88,20 +88,21 @@ static TryCastResult TryStaticImplicitCast(Sema &Self, Expr *SrcExpr, QualType DestType, bool CStyle, const SourceRange &OpRange, unsigned &msg, + CastExpr::CastKind &Kind, CXXMethodDecl *&ConversionDecl); static TryCastResult TryStaticCast(Sema &Self, Expr *SrcExpr, QualType DestType, bool CStyle, - CastExpr::CastKind &Kind, const SourceRange &OpRange, unsigned &msg, + CastExpr::CastKind &Kind, CXXMethodDecl *&ConversionDecl); static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType, bool CStyle, unsigned &msg); static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, QualType DestType, bool CStyle, - CastExpr::CastKind &Kind, const SourceRange &OpRange, - unsigned &msg); + unsigned &msg, + CastExpr::CastKind &Kind); /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's. Action::OwningExprResult @@ -364,8 +365,8 @@ CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType, Self.DefaultFunctionArrayConversion(SrcExpr); unsigned msg = diag::err_bad_cxx_cast_generic; - if (TryReinterpretCast(Self, SrcExpr, DestType, /*CStyle*/false, Kind, - OpRange, msg) + if (TryReinterpretCast(Self, SrcExpr, DestType, /*CStyle*/false, OpRange, + msg, Kind) != TC_Success && msg != 0) Self.Diag(OpRange.getBegin(), msg) << CT_Reinterpret << SrcExpr->getType() << DestType << OpRange; @@ -390,8 +391,8 @@ CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType, Self.DefaultFunctionArrayConversion(SrcExpr); unsigned msg = diag::err_bad_cxx_cast_generic; - if (TryStaticCast(Self, SrcExpr, DestType, /*CStyle*/false, Kind, - OpRange, msg, ConversionDecl) + if (TryStaticCast(Self, SrcExpr, DestType, /*CStyle*/false,OpRange, msg, + Kind, ConversionDecl) != TC_Success && msg != 0) Self.Diag(OpRange.getBegin(), msg) << CT_Static << SrcExpr->getType() << DestType << OpRange; @@ -402,8 +403,8 @@ CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType, /// and casting away constness. static TryCastResult TryStaticCast(Sema &Self, Expr *SrcExpr, QualType DestType, bool CStyle, - CastExpr::CastKind &Kind, const SourceRange &OpRange, unsigned &msg, + CastExpr::CastKind &Kind, CXXMethodDecl *&ConversionDecl) { // The order the tests is not entirely arbitrary. There is one conversion // that can be handled in two different ways. Given: @@ -438,16 +439,9 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *SrcExpr, // C++ 5.2.9p2: An expression e can be explicitly converted to a type T // [...] if the declaration "T t(e);" is well-formed, [...]. tcr = TryStaticImplicitCast(Self, SrcExpr, DestType, CStyle, OpRange, msg, - ConversionDecl); - if (tcr != TC_NotApplicable) { - if (ConversionDecl) { - if (isa<CXXConstructorDecl>(ConversionDecl)) - Kind = CastExpr::CK_ConstructorConversion; - else if (isa<CXXConversionDecl>(ConversionDecl)) - Kind = CastExpr::CK_UserDefinedConversion; - } + Kind, ConversionDecl); + if (tcr != TC_NotApplicable) return tcr; - } // C++ 5.2.9p6: May apply the reverse of any standard conversion, except // lvalue-to-rvalue, array-to-pointer, function-to-pointer, and boolean @@ -771,6 +765,7 @@ TryStaticMemberPointerUpcast(Sema &Self, QualType SrcType, QualType DestType, TryCastResult TryStaticImplicitCast(Sema &Self, Expr *SrcExpr, QualType DestType, bool CStyle, const SourceRange &OpRange, unsigned &msg, + CastExpr::CastKind &Kind, CXXMethodDecl *&ConversionDecl) { if (DestType->isRecordType()) { if (Self.RequireCompleteType(OpRange.getBegin(), DestType, @@ -813,14 +808,21 @@ TryStaticImplicitCast(Sema &Self, Expr *SrcExpr, QualType DestType, /*ForceRValue=*/false, /*InOverloadResolution=*/false); + if (ICS.ConversionKind == ImplicitConversionSequence::BadConversion) + return TC_NotApplicable; + if (ICS.ConversionKind == ImplicitConversionSequence::UserDefinedConversion) { - if (CXXMethodDecl *MD = - dyn_cast<CXXMethodDecl>(ICS.UserDefined.ConversionFunction)) - ConversionDecl = MD; + ConversionDecl = cast<CXXMethodDecl>(ICS.UserDefined.ConversionFunction); + if (isa<CXXConstructorDecl>(ConversionDecl)) + Kind = CastExpr::CK_ConstructorConversion; + else if (isa<CXXConversionDecl>(ConversionDecl)) + Kind = CastExpr::CK_UserDefinedConversion; + } else if (ICS.ConversionKind == + ImplicitConversionSequence::StandardConversion) { + // FIXME: Set the cast kind depending on which types of conversions we have. } - - return ICS.ConversionKind == ImplicitConversionSequence::BadConversion ? - TC_NotApplicable : TC_Success; + + return TC_Success; } /// TryConstCast - See if a const_cast from source to destination is allowed, @@ -891,9 +893,9 @@ static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType, static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, QualType DestType, bool CStyle, - CastExpr::CastKind &Kind, const SourceRange &OpRange, - unsigned &msg) { + unsigned &msg, + CastExpr::CastKind &Kind) { QualType OrigDestType = DestType, OrigSrcType = SrcExpr->getType(); DestType = Self.Context.getCanonicalType(DestType); @@ -1107,12 +1109,12 @@ bool Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr, msg); if (tcr == TC_NotApplicable) { // ... or if that is not possible, a static_cast, ignoring const, ... - tcr = TryStaticCast(*this, CastExpr, CastTy, /*CStyle*/true, Kind, R, msg, - ConversionDecl); + tcr = TryStaticCast(*this, CastExpr, CastTy, /*CStyle*/true, R, msg, + Kind, ConversionDecl); if (tcr == TC_NotApplicable) { // ... and finally a reinterpret_cast, ignoring const. - tcr = TryReinterpretCast(*this, CastExpr, CastTy, /*CStyle*/true, Kind, - R, msg); + tcr = TryReinterpretCast(*this, CastExpr, CastTy, /*CStyle*/true, R, msg, + Kind); } } |