diff options
author | Anders Carlsson <andersca@mac.com> | 2009-09-09 21:33:21 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-09-09 21:33:21 +0000 |
commit | 0aebc81e02397a5987aaa8e8c7acbdb01a31d7c3 (patch) | |
tree | 244e1626acebcedf768fd386036799602daa598c /lib/Sema/SemaCXXCast.cpp | |
parent | cfcd7fd0de701c5ce05e96de1ed2d0bf8c7035d9 (diff) |
If a cast expression needs either a conversion function or a constructor to be called, generate implicit child expressions that call them.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81383 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaCXXCast.cpp')
-rw-r--r-- | lib/Sema/SemaCXXCast.cpp | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp index ac85b79b39..0ae5d343ca 100644 --- a/lib/Sema/SemaCXXCast.cpp +++ b/lib/Sema/SemaCXXCast.cpp @@ -44,7 +44,8 @@ static void CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType, const SourceRange &DestRange); static void CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType, const SourceRange &OpRange, - CastExpr::CastKind &Kind); + CastExpr::CastKind &Kind, + CXXMethodDecl *&ConversionDecl); static void CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType, const SourceRange &OpRange, const SourceRange &DestRange, @@ -143,8 +144,22 @@ Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, case tok::kw_static_cast: { CastExpr::CastKind Kind = CastExpr::CK_Unknown; - if (!TypeDependent) - CheckStaticCast(*this, Ex, DestType, OpRange, Kind); + if (!TypeDependent) { + CXXMethodDecl *Method = 0; + + CheckStaticCast(*this, Ex, DestType, OpRange, Kind, Method); + + if (Method) { + OwningExprResult CastArg + = BuildCXXCastArgument(OpLoc, DestType.getNonReferenceType(), + Kind, Method, Owned(Ex)); + if (CastArg.isInvalid()) + return ExprError(); + + Ex = CastArg.takeAs<Expr>(); + } + } + return Owned(new (Context) CXXStaticCastExpr(DestType.getNonReferenceType(), Kind, Ex, DestType, OpLoc)); } @@ -359,7 +374,8 @@ CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType, /// implicit conversions explicit and getting rid of data loss warnings. void CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType, - const SourceRange &OpRange, CastExpr::CastKind &Kind) { + const SourceRange &OpRange, CastExpr::CastKind &Kind, + CXXMethodDecl *&ConversionDecl) { // This test is outside everything else because it's the only case where // a non-lvalue-reference target type does not lead to decay. // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void". @@ -371,7 +387,6 @@ CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType, Self.DefaultFunctionArrayConversion(SrcExpr); unsigned msg = diag::err_bad_cxx_cast_generic; - CXXMethodDecl *ConversionDecl = 0; if (TryStaticCast(Self, SrcExpr, DestType, /*CStyle*/false, Kind, OpRange, msg, ConversionDecl) != TC_Success && msg != 0) @@ -421,9 +436,16 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *SrcExpr, // [...] if the declaration "T t(e);" is well-formed, [...]. tcr = TryStaticImplicitCast(Self, SrcExpr, DestType, CStyle, OpRange, msg, ConversionDecl); - if (tcr != TC_NotApplicable) + if (tcr != TC_NotApplicable) { + if (ConversionDecl) { + if (isa<CXXConstructorDecl>(ConversionDecl)) + Kind = CastExpr::CK_ConstructorConversion; + else if (isa<CXXConversionDecl>(ConversionDecl)) + Kind = CastExpr::CK_UserDefinedConversion; + } 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 // conversions, subject to further restrictions. @@ -787,10 +809,12 @@ TryStaticImplicitCast(Sema &Self, Expr *SrcExpr, QualType DestType, /*ForceRValue=*/false, /*InOverloadResolution=*/false); - if (ICS.ConversionKind == ImplicitConversionSequence::UserDefinedConversion) + if (ICS.ConversionKind == ImplicitConversionSequence::UserDefinedConversion) { if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(ICS.UserDefined.ConversionFunction)) ConversionDecl = MD; + } + return ICS.ConversionKind == ImplicitConversionSequence::BadConversion ? TC_NotApplicable : TC_Success; } |