[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