]> granicus.if.org Git - clang/commitdiff
Handle array to pointer decay in EmitCastExpr and get rid of VisitImplicitCastExpr.
authorAnders Carlsson <andersca@mac.com>
Mon, 24 Aug 2009 18:37:17 +0000 (18:37 +0000)
committerAnders Carlsson <andersca@mac.com>
Mon, 24 Aug 2009 18:37:17 +0000 (18:37 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79930 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExprScalar.cpp

index 0524b447180fdccb81610f049af2b9875434df3f..e8b7304552bb33486b5a7641018373e430dc787d 100644 (file)
@@ -226,7 +226,6 @@ public:
   Value *VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
     return llvm::Constant::getNullValue(ConvertType(E->getType()));
   }
-  Value *VisitImplicitCastExpr(const ImplicitCastExpr *E);
   Value *VisitCastExpr(const CastExpr *E) {
     // Make sure to evaluate VLA bounds now so that we have them for later.
     if (E->getType()->isVariablyModifiedType())
@@ -609,21 +608,26 @@ Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
   return Builder.CreateExtractElement(Base, Idx, "vecext");
 }
 
-/// VisitImplicitCastExpr - Implicit casts are the same as normal casts, but
-/// also handle things like function to pointer-to-function decay, and array to
-/// pointer decay.
-Value *ScalarExprEmitter::VisitImplicitCastExpr(const ImplicitCastExpr *E) {
-  const Expr *Op = E->getSubExpr();
+// VisitCastExpr - Emit code for an explicit or implicit cast.  Implicit casts
+// have to handle a more broad range of conversions than explicit casts, as they
+// handle things like function to ptr-to-function decay etc.
+Value *ScalarExprEmitter::EmitCastExpr(const Expr *E, QualType DestTy,
+                                       CastExpr::CastKind Kind) {
+  if (!DestTy->isVoidType())
+    TestAndClearIgnoreResultAssign();
   
-  // If this is due to array->pointer conversion, emit the array expression as
-  // an l-value.
-  if (Op->getType()->isArrayType()) {
-    assert(E->getCastKind() == CastExpr::CK_ArrayToPointerDecay);
-    Value *V = EmitLValue(Op).getAddress();  // Bitfields can't be arrays.
+  switch (Kind) {
+  default:
+    break;
+  case CastExpr::CK_ArrayToPointerDecay: {
+    assert(E->getType()->isArrayType() &&
+           "Array to pointer decay must have array source type!");
+    
+    Value *V = EmitLValue(E).getAddress();  // Bitfields can't be arrays.
 
     // Note that VLA pointers are always decayed, so we don't need to do
     // anything here.
-    if (!Op->getType()->isVariableArrayType()) {
+    if (!E->getType()->isVariableArrayType()) {
       assert(isa<llvm::PointerType>(V->getType()) && "Expected pointer");
       assert(isa<llvm::ArrayType>(cast<llvm::PointerType>(V->getType())
                                  ->getElementType()) &&
@@ -633,33 +637,17 @@ Value *ScalarExprEmitter::VisitImplicitCastExpr(const ImplicitCastExpr *E) {
     
     // The resultant pointer type can be implicitly casted to other pointer
     // types as well (e.g. void*) and can be implicitly converted to integer.
-    const llvm::Type *DestTy = ConvertType(E->getType());
-    if (V->getType() != DestTy) {
-      if (isa<llvm::PointerType>(DestTy))
-        V = Builder.CreateBitCast(V, DestTy, "ptrconv");
+    const llvm::Type *DestLTy = ConvertType(DestTy);
+    if (V->getType() != DestLTy) {
+      if (isa<llvm::PointerType>(DestLTy))
+        V = Builder.CreateBitCast(V, DestLTy, "ptrconv");
       else {
-        assert(isa<llvm::IntegerType>(DestTy) && "Unknown array decay");
-        V = Builder.CreatePtrToInt(V, DestTy, "ptrconv");
+        assert(isa<llvm::IntegerType>(DestLTy) && "Unknown array decay");
+        V = Builder.CreatePtrToInt(V, DestLTy, "ptrconv");
       }
     }
     return V;
-  }
-
-  return EmitCastExpr(Op, E->getType(), E->getCastKind());
-}
-
-
-// VisitCastExpr - Emit code for an explicit or implicit cast.  Implicit casts
-// have to handle a more broad range of conversions than explicit casts, as they
-// handle things like function to ptr-to-function decay etc.
-Value *ScalarExprEmitter::EmitCastExpr(const Expr *E, QualType DestTy,
-                                       CastExpr::CastKind Kind) {
-  if (!DestTy->isVoidType())
-    TestAndClearIgnoreResultAssign();
-  
-  switch (Kind) {
-  default:
-    break;
+  }      
   case CastExpr::CK_NullToMemberPointer:
     return CGF.CGM.EmitNullConstant(DestTy);
   }