Patch for code gen. for c-style cast which ends in

using class's conversion functions [12.3.2-p2]

llvm-svn: 80433
This commit is contained in:
Fariborz Jahanian 2009-08-29 19:15:16 +00:00
parent 9ab0319b2b
commit 3df8767869
6 changed files with 41 additions and 10 deletions

View File

@ -1173,8 +1173,13 @@ LValue CodeGenFunction::EmitConditionalOperator(const ConditionalOperator* E) {
/// noop aggregate casts, and cast from scalar to union.
LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
if (E->getCastKind() == CastExpr::CK_UserDefinedConversion) {
const CXXFunctionalCastExpr *CXXFExpr = cast<CXXFunctionalCastExpr>(E);
return LValue::MakeAddr(EmitCXXFunctionalCastExpr(CXXFExpr).getScalarVal(), 0);
if (const CXXFunctionalCastExpr *CXXFExpr =
dyn_cast<CXXFunctionalCastExpr>(E))
return LValue::MakeAddr(
EmitCXXFunctionalCastExpr(CXXFExpr).getScalarVal(), 0);
assert(isa<CStyleCastExpr>(E) &&
"EmitCastLValue - Expected CStyleCastExpr");
return EmitLValue(E->getSubExpr());
}
// If this is an aggregate-to-aggregate cast, just use the input's address as
@ -1188,10 +1193,6 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
if (ICE->isLvalueCast())
return EmitLValue(E->getSubExpr());
// FIXME: Implement this properly!
if (E->getCastKind() == CastExpr::CK_UserDefinedConversion)
return EmitUnsupportedLValue(E, "user-defined conversion");
// Otherwise, we must have a cast from scalar to union.
assert(E->getCastKind() == CastExpr::CK_ToUnion &&
"Expected scalar-to-union cast");

View File

@ -178,8 +178,12 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {
return;
}
if (E->getCastKind() == CastExpr::CK_UserDefinedConversion) {
CXXFunctionalCastExpr *CXXFExpr = cast<CXXFunctionalCastExpr>(E);
CGF.EmitCXXFunctionalCastExpr(CXXFExpr);
if (const CXXFunctionalCastExpr *CXXFExpr =
dyn_cast<CXXFunctionalCastExpr>(E))
CGF.EmitCXXFunctionalCastExpr(CXXFExpr);
else
if (isa<CStyleCastExpr>(E))
Visit(E->getSubExpr());
return;
}

View File

@ -228,8 +228,11 @@ public:
}
Value *VisitCastExpr(const CastExpr *E) {
if (E->getCastKind() == CastExpr::CK_UserDefinedConversion) {
const CXXFunctionalCastExpr *CXXFExpr = cast<CXXFunctionalCastExpr>(E);
return CGF.EmitCXXFunctionalCastExpr(CXXFExpr).getScalarVal();
if (const CXXFunctionalCastExpr *CXXFExpr =
dyn_cast<CXXFunctionalCastExpr>(E))
return CGF.EmitCXXFunctionalCastExpr(CXXFExpr).getScalarVal();
assert(isa<CStyleCastExpr>(E) &&
"VisitCastExpr - missing CStyleCastExpr");
}
// Make sure to evaluate VLA bounds now so that we have them for later.

View File

@ -3060,6 +3060,19 @@ Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, TypeTy *Ty,
if (CheckCastTypes(SourceRange(LParenLoc, RParenLoc), castType, castExpr,
Kind, ConversionDecl))
return ExprError();
if (ConversionDecl) {
// encounterred a c-style cast requiring a conversion function.
if (CXXConversionDecl *CD = dyn_cast<CXXConversionDecl>(ConversionDecl)) {
castExpr =
new (Context) CXXFunctionalCastExpr(castType.getNonReferenceType(),
castType, LParenLoc,
CastExpr::CK_UserDefinedConversion,
castExpr, CD,
RParenLoc);
Kind = CastExpr::CK_UserDefinedConversion;
}
// FIXME. AST for when dealing with conversion functions (FunctionDecl).
}
Op.release();
return Owned(new (Context) CStyleCastExpr(castType.getNonReferenceType(),

View File

@ -939,6 +939,7 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
OwningExprResult InitResult =
BuildCXXConstructExpr(ToType.getNonReferenceType(),
CD, &From, 1);
// Take ownership of this expression.
From = InitResult.takeAs<Expr>();
CastKind = CastExpr::CK_ConstructorConversion ;
}

View File

@ -49,6 +49,15 @@ int main() {
i = int(X(Z(y)));
f = float(X(Z(y)));
printf("i = %d float = %f\n", i,f);
f = (float)x;
i = (int)x;
printf("i = %d float = %f\n", i,f);
int d = (X)((Z)y);
printf("d = %d\n", d);
int e = (int)((X)((Z)y));
printf("e = %d\n", e);
}
// CHECK-LP64: .globl __ZN1ScviEv
// CHECK-LP64-NEXT: __ZN1ScviEv: