aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaCXXCast.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-09-09 21:33:21 +0000
committerAnders Carlsson <andersca@mac.com>2009-09-09 21:33:21 +0000
commit0aebc81e02397a5987aaa8e8c7acbdb01a31d7c3 (patch)
tree244e1626acebcedf768fd386036799602daa598c /lib/Sema/SemaCXXCast.cpp
parentcfcd7fd0de701c5ce05e96de1ed2d0bf8c7035d9 (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.cpp40
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;
}