Cleanup cast IRGen a bit; no intended functionality change.

llvm-svn: 133864
This commit is contained in:
Eli Friedman 2011-06-25 02:58:47 +00:00
parent f3e11190f3
commit 5836852e9c
2 changed files with 63 additions and 32 deletions

View File

@ -352,6 +352,8 @@ ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val,
ComplexPairTy ComplexExprEmitter::EmitCast(CastExpr::CastKind CK, Expr *Op, ComplexPairTy ComplexExprEmitter::EmitCast(CastExpr::CastKind CK, Expr *Op,
QualType DestTy) { QualType DestTy) {
switch (CK) { switch (CK) {
case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!");
case CK_GetObjCProperty: { case CK_GetObjCProperty: {
LValue LV = CGF.EmitLValue(Op); LValue LV = CGF.EmitLValue(Op);
assert(LV.isPropertyRef() && "Unknown LValue type!"); assert(LV.isPropertyRef() && "Unknown LValue type!");
@ -360,39 +362,73 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastExpr::CastKind CK, Expr *Op,
case CK_NoOp: case CK_NoOp:
case CK_LValueToRValue: case CK_LValueToRValue:
case CK_UserDefinedConversion:
return Visit(Op); return Visit(Op);
// TODO: do all of these case CK_LValueBitCast: {
default:
break;
}
// Two cases here: cast from (complex to complex) and (scalar to complex).
if (Op->getType()->isAnyComplexType())
return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy);
// FIXME: We should be looking at all of the cast kinds here, not
// cherry-picking the ones we have test cases for.
if (CK == CK_LValueBitCast) {
llvm::Value *V = CGF.EmitLValue(Op).getAddress(); llvm::Value *V = CGF.EmitLValue(Op).getAddress();
V = Builder.CreateBitCast(V, V = Builder.CreateBitCast(V,
CGF.ConvertType(CGF.getContext().getPointerType(DestTy))); CGF.ConvertType(CGF.getContext().getPointerType(DestTy)));
// FIXME: Are the qualifiers correct here? // FIXME: Are the qualifiers correct here?
return EmitLoadOfComplex(V, DestTy.isVolatileQualified()); return EmitLoadOfComplex(V, DestTy.isVolatileQualified());
} }
// C99 6.3.1.7: When a value of real type is converted to a complex type, the
// real part of the complex result value is determined by the rules of
// conversion to the corresponding real type and the imaginary part of the
// complex result value is a positive zero or an unsigned zero.
llvm::Value *Elt = CGF.EmitScalarExpr(Op);
// Convert the input element to the element type of the complex. case CK_BitCast:
DestTy = DestTy->getAs<ComplexType>()->getElementType(); case CK_BaseToDerived:
Elt = CGF.EmitScalarConversion(Elt, Op->getType(), DestTy); case CK_DerivedToBase:
case CK_UncheckedDerivedToBase:
case CK_Dynamic:
case CK_ToUnion:
case CK_ArrayToPointerDecay:
case CK_FunctionToPointerDecay:
case CK_NullToPointer:
case CK_NullToMemberPointer:
case CK_BaseToDerivedMemberPointer:
case CK_DerivedToBaseMemberPointer:
case CK_MemberPointerToBoolean:
case CK_ConstructorConversion:
case CK_IntegralToPointer:
case CK_PointerToIntegral:
case CK_PointerToBoolean:
case CK_ToVoid:
case CK_VectorSplat:
case CK_IntegralCast:
case CK_IntegralToBoolean:
case CK_IntegralToFloating:
case CK_FloatingToIntegral:
case CK_FloatingToBoolean:
case CK_FloatingCast:
case CK_AnyPointerToObjCPointerCast:
case CK_AnyPointerToBlockPointerCast:
case CK_ObjCObjectLValueCast:
case CK_FloatingComplexToReal:
case CK_FloatingComplexToBoolean:
case CK_IntegralComplexToReal:
case CK_IntegralComplexToBoolean:
case CK_ObjCProduceObject:
case CK_ObjCConsumeObject:
llvm_unreachable("invalid cast kind for complex value");
// Return (realval, 0). case CK_FloatingRealToComplex:
return ComplexPairTy(Elt, llvm::Constant::getNullValue(Elt->getType())); case CK_IntegralRealToComplex: {
llvm::Value *Elt = CGF.EmitScalarExpr(Op);
// Convert the input element to the element type of the complex.
DestTy = DestTy->getAs<ComplexType>()->getElementType();
Elt = CGF.EmitScalarConversion(Elt, Op->getType(), DestTy);
// Return (realval, 0).
return ComplexPairTy(Elt, llvm::Constant::getNullValue(Elt->getType()));
}
case CK_FloatingComplexCast:
case CK_FloatingComplexToIntegralComplex:
case CK_IntegralComplexCast:
case CK_IntegralComplexToFloatingComplex:
return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy);
}
llvm_unreachable("unknown cast resulting in complex value");
} }
ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E) { ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E) {

View File

@ -1146,15 +1146,10 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
return Builder.CreateIntToPtr(IntResult, ConvertType(DestTy)); return Builder.CreateIntToPtr(IntResult, ConvertType(DestTy));
} }
case CK_PointerToIntegral: { case CK_PointerToIntegral:
Value *Src = Visit(const_cast<Expr*>(E)); assert(!DestTy->isBooleanType() && "bool should use PointerToBool");
return Builder.CreatePtrToInt(Visit(E), ConvertType(DestTy));
// Handle conversion to bool correctly.
if (DestTy->isBooleanType())
return EmitScalarConversion(Src, E->getType(), DestTy);
return Builder.CreatePtrToInt(Src, ConvertType(DestTy));
}
case CK_ToVoid: { case CK_ToVoid: {
CGF.EmitIgnoredExpr(E); CGF.EmitIgnoredExpr(E);
return 0; return 0;