[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