[cfe-commits] r81614 - in /cfe/trunk: lib/CodeGen/CGExpr.cpp test/CodeGenCXX/derived-to-base.cpp

Anders Carlsson andersca at mac.com
Sat Sep 12 09:16:49 PDT 2009


Author: andersca
Date: Sat Sep 12 11:16:49 2009
New Revision: 81614

URL: http://llvm.org/viewvc/llvm-project?rev=81614&view=rev
Log:
Handle CK_DerivedToBase when emitting lvalue casts.

Added:
    cfe/trunk/test/CodeGenCXX/derived-to-base.cpp
Modified:
    cfe/trunk/lib/CodeGen/CGExpr.cpp

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=81614&r1=81613&r2=81614&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Sat Sep 12 11:16:49 2009
@@ -1153,30 +1153,51 @@
 /// all the reasons that casts are permitted with aggregate result, including
 /// noop aggregate casts, and cast from scalar to union.
 LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
-  // If this is an aggregate-to-aggregate cast, just use the input's address as
-  // the lvalue.
-  if (E->getCastKind() == CastExpr::CK_NoOp ||
-      E->getCastKind() == CastExpr::CK_ConstructorConversion ||
-      E->getCastKind() == CastExpr::CK_UserDefinedConversion)
+  switch (E->getCastKind()) {
+  default:
+    // If this is an lvalue cast, treat it as a no-op.
+    // FIXME: We shouldn't need to check for this explicitly!
+    if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E))
+      if (ICE->isLvalueCast())
+        return EmitLValue(E->getSubExpr());
+    
+    assert(0 && "Unhandled cast!");
+      
+  case CastExpr::CK_NoOp:
+  case CastExpr::CK_ConstructorConversion:
+  case CastExpr::CK_UserDefinedConversion:
     return EmitLValue(E->getSubExpr());
+  
+  case CastExpr::CK_DerivedToBase: {
+    const RecordType *DerivedClassTy = 
+      E->getSubExpr()->getType()->getAs<RecordType>();
+    CXXRecordDecl *DerivedClassDecl = 
+      cast<CXXRecordDecl>(DerivedClassTy->getDecl());
+
+    const RecordType *BaseClassTy = E->getType()->getAs<RecordType>();
+    CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseClassTy->getDecl());
+    
+    LValue LV = EmitLValue(E->getSubExpr());
+    
+    // Perform the derived-to-base conversion
+    llvm::Value *Base = 
+      GetAddressCXXOfBaseClass(LV.getAddress(), DerivedClassDecl, 
+                               BaseClassDecl, /*NullCheckValue=*/false);
+    
+    return LValue::MakeAddr(Base, E->getType().getCVRQualifiers(),
+                            getContext().getObjCGCAttrKind(E->getType()),
+                            E->getType().getAddressSpace());
+  }
 
-  // If this is an lvalue cast, treat it as a no-op.
-  // FIXME: We shouldn't need to check for this explicitly!
-  if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E))
-    if (ICE->isLvalueCast())
-      return EmitLValue(E->getSubExpr());
-
-  // Otherwise, we must have a cast from scalar to union.
-  assert(E->getCastKind() == CastExpr::CK_ToUnion &&
-         "Expected scalar-to-union cast");
-
-  // Casts are only lvalues when the source and destination types are the same.
-  llvm::Value *Temp = CreateTempAlloca(ConvertType(E->getType()));
-  EmitAnyExpr(E->getSubExpr(), Temp, false);
+  case CastExpr::CK_ToUnion: {
+    llvm::Value *Temp = CreateTempAlloca(ConvertType(E->getType()));
+    EmitAnyExpr(E->getSubExpr(), Temp, false);
 
-  return LValue::MakeAddr(Temp, E->getType().getCVRQualifiers(),
-                          getContext().getObjCGCAttrKind(E->getType()),
-                          E->getType().getAddressSpace());
+    return LValue::MakeAddr(Temp, E->getType().getCVRQualifiers(),
+                            getContext().getObjCGCAttrKind(E->getType()),
+                            E->getType().getAddressSpace());
+    }
+  }
 }
 
 //===--------------------------------------------------------------------===//

Added: cfe/trunk/test/CodeGenCXX/derived-to-base.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/derived-to-base.cpp?rev=81614&view=auto

==============================================================================
--- cfe/trunk/test/CodeGenCXX/derived-to-base.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/derived-to-base.cpp Sat Sep 12 11:16:49 2009
@@ -0,0 +1,16 @@
+// RUN: clang-cc -emit-llvm %s -o -
+struct A { 
+  void f(); 
+  
+  int a;
+};
+
+struct B : A { 
+  double b;
+};
+
+void f() {
+  B b;
+  
+  b.f();
+}





More information about the cfe-commits mailing list