[cfe-commits] r127702 - in /cfe/trunk: lib/CodeGen/CGExprConstant.cpp test/CodeGenCXX/member-function-pointers.cpp
John McCall
rjmccall at apple.com
Tue Mar 15 14:17:48 PDT 2011
Author: rjmccall
Date: Tue Mar 15 16:17:48 2011
New Revision: 127702
URL: http://llvm.org/viewvc/llvm-project?rev=127702&view=rev
Log:
Reorganize the emission of (unfoldable) constant casts a bit, and
make sure that upcasts of member pointer types are covered as constants.
Fixed rdar://problem/9130221
Modified:
cfe/trunk/lib/CodeGen/CGExprConstant.cpp
cfe/trunk/test/CodeGenCXX/member-function-pointers.cpp
Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=127702&r1=127701&r2=127702&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Tue Mar 15 16:17:48 2011
@@ -483,18 +483,17 @@
}
llvm::Constant *VisitCastExpr(CastExpr* E) {
+ Expr *subExpr = E->getSubExpr();
+ llvm::Constant *C = CGM.EmitConstantExpr(subExpr, subExpr->getType(), CGF);
+ if (!C) return 0;
+
+ const llvm::Type *destType = ConvertType(E->getType());
+
switch (E->getCastKind()) {
case CK_ToUnion: {
// GCC cast to union extension
assert(E->getType()->isUnionType() &&
"Destination type is not union type!");
- const llvm::Type *Ty = ConvertType(E->getType());
- Expr *SubExpr = E->getSubExpr();
-
- llvm::Constant *C =
- CGM.EmitConstantExpr(SubExpr, SubExpr->getType(), CGF);
- if (!C)
- return 0;
// Build a struct with the union sub-element as the first member,
// and padded to the appropriate size
@@ -503,7 +502,7 @@
Elts.push_back(C);
Types.push_back(C->getType());
unsigned CurSize = CGM.getTargetData().getTypeAllocSize(C->getType());
- unsigned TotalSize = CGM.getTargetData().getTypeAllocSize(Ty);
+ unsigned TotalSize = CGM.getTargetData().getTypeAllocSize(destType);
assert(CurSize <= TotalSize && "Union size mismatch!");
if (unsigned NumPadBytes = TotalSize - CurSize) {
@@ -523,39 +522,101 @@
const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>();
return CGM.getCXXABI().EmitNullMemberPointer(MPT);
}
-
- case CK_BaseToDerivedMemberPointer: {
- Expr *SubExpr = E->getSubExpr();
- llvm::Constant *C =
- CGM.EmitConstantExpr(SubExpr, SubExpr->getType(), CGF);
- if (!C) return 0;
+ case CK_DerivedToBaseMemberPointer:
+ case CK_BaseToDerivedMemberPointer:
return CGM.getCXXABI().EmitMemberPointerConversion(C, E);
- }
- case CK_BitCast:
- // This must be a member function pointer cast.
- return Visit(E->getSubExpr());
-
- default: {
- // FIXME: This should be handled by the CK_NoOp cast kind.
- // Explicit and implicit no-op casts
- QualType Ty = E->getType(), SubTy = E->getSubExpr()->getType();
- if (CGM.getContext().hasSameUnqualifiedType(Ty, SubTy))
- return Visit(E->getSubExpr());
-
- // Handle integer->integer casts for address-of-label differences.
- if (Ty->isIntegerType() && SubTy->isIntegerType() &&
- CGF) {
- llvm::Value *Src = Visit(E->getSubExpr());
- if (Src == 0) return 0;
-
- // Use EmitScalarConversion to perform the conversion.
- return cast<llvm::Constant>(CGF->EmitScalarConversion(Src, SubTy, Ty));
- }
-
+ case CK_LValueToRValue:
+ case CK_NoOp:
+ return C;
+
+ case CK_AnyPointerToObjCPointerCast:
+ case CK_AnyPointerToBlockPointerCast:
+ case CK_LValueBitCast:
+ case CK_BitCast:
+ if (C->getType() == destType) return C;
+ return llvm::ConstantExpr::getBitCast(C, destType);
+
+ case CK_Dependent: llvm_unreachable("saw dependent cast!");
+
+ // These will never be supported.
+ case CK_ObjCObjectLValueCast:
+ case CK_GetObjCProperty:
+ case CK_ToVoid:
+ case CK_Dynamic:
return 0;
+
+ // These might need to be supported for constexpr.
+ case CK_UserDefinedConversion:
+ case CK_ConstructorConversion:
+ return 0;
+
+ // These should eventually be supported.
+ case CK_ArrayToPointerDecay:
+ case CK_FunctionToPointerDecay:
+ case CK_BaseToDerived:
+ case CK_DerivedToBase:
+ case CK_UncheckedDerivedToBase:
+ case CK_MemberPointerToBoolean:
+ case CK_VectorSplat:
+ case CK_FloatingRealToComplex:
+ case CK_FloatingComplexToReal:
+ case CK_FloatingComplexToBoolean:
+ case CK_FloatingComplexCast:
+ case CK_FloatingComplexToIntegralComplex:
+ case CK_IntegralRealToComplex:
+ case CK_IntegralComplexToReal:
+ case CK_IntegralComplexToBoolean:
+ case CK_IntegralComplexCast:
+ case CK_IntegralComplexToFloatingComplex:
+ return 0;
+
+ case CK_PointerToIntegral:
+ if (!E->getType()->isBooleanType())
+ return llvm::ConstantExpr::getPtrToInt(C, destType);
+ // fallthrough
+
+ case CK_PointerToBoolean:
+ return llvm::ConstantExpr::getICmp(llvm::CmpInst::ICMP_EQ, C,
+ llvm::ConstantPointerNull::get(cast<llvm::PointerType>(C->getType())));
+
+ case CK_NullToPointer:
+ return llvm::ConstantPointerNull::get(cast<llvm::PointerType>(destType));
+
+ case CK_IntegralCast: {
+ bool isSigned = subExpr->getType()->isSignedIntegerType();
+ return llvm::ConstantExpr::getIntegerCast(C, destType, isSigned);
+ }
+
+ case CK_IntegralToPointer: {
+ bool isSigned = subExpr->getType()->isSignedIntegerType();
+ C = llvm::ConstantExpr::getIntegerCast(C, CGM.IntPtrTy, isSigned);
+ return llvm::ConstantExpr::getIntToPtr(C, destType);
}
+
+ case CK_IntegralToBoolean:
+ return llvm::ConstantExpr::getICmp(llvm::CmpInst::ICMP_EQ, C,
+ llvm::Constant::getNullValue(C->getType()));
+
+ case CK_IntegralToFloating:
+ if (subExpr->getType()->isSignedIntegerType())
+ return llvm::ConstantExpr::getSIToFP(C, destType);
+ else
+ return llvm::ConstantExpr::getUIToFP(C, destType);
+
+ case CK_FloatingToIntegral:
+ if (E->getType()->isSignedIntegerType())
+ return llvm::ConstantExpr::getFPToSI(C, destType);
+ else
+ return llvm::ConstantExpr::getFPToUI(C, destType);
+
+ case CK_FloatingToBoolean:
+ return llvm::ConstantExpr::getFCmp(llvm::CmpInst::FCMP_UNE, C,
+ llvm::Constant::getNullValue(C->getType()));
+
+ case CK_FloatingCast:
+ return llvm::ConstantExpr::getFPCast(C, destType);
}
}
Modified: cfe/trunk/test/CodeGenCXX/member-function-pointers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/member-function-pointers.cpp?rev=127702&r1=127701&r2=127702&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/member-function-pointers.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/member-function-pointers.cpp Tue Mar 15 16:17:48 2011
@@ -209,3 +209,26 @@
return pmf();
}
}
+
+namespace test9 {
+ struct A {
+ void foo();
+ };
+ struct B : A {
+ void foo();
+ };
+
+ typedef void (A::*fooptr)();
+
+ struct S {
+ fooptr p;
+ };
+
+ // CHECK: define void @_ZN5test94testEv(
+ // CHECK: alloca i32
+ // CHECK-NEXT: ret void
+ void test() {
+ int x;
+ static S array[] = { (fooptr) &B::foo };
+ }
+}
More information about the cfe-commits
mailing list