[cfe-commits] r89678 - in /cfe/trunk/lib/CodeGen: CGCXX.cpp CGCXXClass.cpp CGExpr.cpp CGExprScalar.cpp CodeGenFunction.h
Anders Carlsson
andersca at mac.com
Mon Nov 23 09:57:55 PST 2009
Author: andersca
Date: Mon Nov 23 11:57:54 2009
New Revision: 89678
URL: http://llvm.org/viewvc/llvm-project?rev=89678&view=rev
Log:
Handle base-to-derived casts. Will land test case shortly.
Modified:
cfe/trunk/lib/CodeGen/CGCXX.cpp
cfe/trunk/lib/CodeGen/CGCXXClass.cpp
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/lib/CodeGen/CGExprScalar.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=89678&r1=89677&r2=89678&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Mon Nov 23 11:57:54 2009
@@ -1211,10 +1211,10 @@
const CXXRecordDecl *ClassDecl,
const CXXRecordDecl *BaseClassDecl, QualType Ty) {
if (ClassDecl) {
- Dest = GetAddressCXXOfBaseClass(Dest, ClassDecl, BaseClassDecl,
- /*NullCheckValue=*/false);
- Src = GetAddressCXXOfBaseClass(Src, ClassDecl, BaseClassDecl,
- /*NullCheckValue=*/false);
+ Dest = GetAddressOfBaseClass(Dest, ClassDecl, BaseClassDecl,
+ /*NullCheckValue=*/false);
+ Src = GetAddressOfBaseClass(Src, ClassDecl, BaseClassDecl,
+ /*NullCheckValue=*/false);
}
if (BaseClassDecl->hasTrivialCopyConstructor()) {
EmitAggregateCopy(Dest, Src, Ty);
@@ -1250,10 +1250,10 @@
const CXXRecordDecl *BaseClassDecl,
QualType Ty) {
if (ClassDecl) {
- Dest = GetAddressCXXOfBaseClass(Dest, ClassDecl, BaseClassDecl,
- /*NullCheckValue=*/false);
- Src = GetAddressCXXOfBaseClass(Src, ClassDecl, BaseClassDecl,
- /*NullCheckValue=*/false);
+ Dest = GetAddressOfBaseClass(Dest, ClassDecl, BaseClassDecl,
+ /*NullCheckValue=*/false);
+ Src = GetAddressOfBaseClass(Src, ClassDecl, BaseClassDecl,
+ /*NullCheckValue=*/false);
}
if (BaseClassDecl->hasTrivialCopyAssignment()) {
EmitAggregateCopy(Dest, Src, Ty);
@@ -1493,9 +1493,9 @@
const Type *BaseType = BaseInit->getBaseClass();
CXXRecordDecl *BaseClassDecl =
cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl());
- llvm::Value *V = CGF.GetAddressCXXOfBaseClass(ThisPtr, ClassDecl,
- BaseClassDecl,
- /*NullCheckValue=*/false);
+ llvm::Value *V = CGF.GetAddressOfBaseClass(ThisPtr, ClassDecl,
+ BaseClassDecl,
+ /*NullCheckValue=*/false);
CGF.EmitCXXConstructorCall(BaseInit->getConstructor(),
CtorType, V,
BaseInit->const_arg_begin(),
@@ -1710,9 +1710,9 @@
if (BaseClassDecl->hasTrivialDestructor())
continue;
- llvm::Value *V = GetAddressCXXOfBaseClass(LoadCXXThis(),
- ClassDecl, BaseClassDecl,
- /*NullCheckValue=*/false);
+ llvm::Value *V = GetAddressOfBaseClass(LoadCXXThis(),
+ ClassDecl, BaseClassDecl,
+ /*NullCheckValue=*/false);
EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()),
Dtor_Base, V);
}
Modified: cfe/trunk/lib/CodeGen/CGCXXClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXClass.cpp?rev=89678&r1=89677&r2=89678&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXXClass.cpp Mon Nov 23 11:57:54 2009
@@ -117,10 +117,10 @@
}
llvm::Value *
-CodeGenFunction::GetAddressCXXOfBaseClass(llvm::Value *BaseValue,
- const CXXRecordDecl *ClassDecl,
- const CXXRecordDecl *BaseClassDecl,
- bool NullCheckValue) {
+CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value,
+ const CXXRecordDecl *ClassDecl,
+ const CXXRecordDecl *BaseClassDecl,
+ bool NullCheckValue) {
QualType BTy =
getContext().getCanonicalType(
getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(BaseClassDecl)));
@@ -128,7 +128,7 @@
if (ClassDecl == BaseClassDecl) {
// Just cast back.
- return Builder.CreateBitCast(BaseValue, BasePtrTy);
+ return Builder.CreateBitCast(Value, BasePtrTy);
}
llvm::BasicBlock *CastNull = 0;
@@ -141,8 +141,8 @@
CastEnd = createBasicBlock("cast.end");
llvm::Value *IsNull =
- Builder.CreateICmpEQ(BaseValue,
- llvm::Constant::getNullValue(BaseValue->getType()));
+ Builder.CreateICmpEQ(Value,
+ llvm::Constant::getNullValue(Value->getType()));
Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
EmitBlock(CastNotNull);
}
@@ -150,16 +150,16 @@
const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
llvm::Value *Offset =
- GetCXXBaseClassOffset(*this, BaseValue, ClassDecl, BaseClassDecl);
+ GetCXXBaseClassOffset(*this, Value, ClassDecl, BaseClassDecl);
if (Offset) {
// Apply the offset.
- BaseValue = Builder.CreateBitCast(BaseValue, Int8PtrTy);
- BaseValue = Builder.CreateGEP(BaseValue, Offset, "add.ptr");
+ Value = Builder.CreateBitCast(Value, Int8PtrTy);
+ Value = Builder.CreateGEP(Value, Offset, "add.ptr");
}
// Cast back.
- BaseValue = Builder.CreateBitCast(BaseValue, BasePtrTy);
+ Value = Builder.CreateBitCast(Value, BasePtrTy);
if (NullCheckValue) {
Builder.CreateBr(CastEnd);
@@ -167,13 +167,73 @@
Builder.CreateBr(CastEnd);
EmitBlock(CastEnd);
- llvm::PHINode *PHI = Builder.CreatePHI(BaseValue->getType());
+ llvm::PHINode *PHI = Builder.CreatePHI(Value->getType());
+ PHI->reserveOperandSpace(2);
+ PHI->addIncoming(Value, CastNotNull);
+ PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()),
+ CastNull);
+ Value = PHI;
+ }
+
+ return Value;
+}
+
+llvm::Value *
+CodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value,
+ const CXXRecordDecl *ClassDecl,
+ const CXXRecordDecl *DerivedClassDecl,
+ bool NullCheckValue) {
+ QualType DerivedTy =
+ getContext().getCanonicalType(
+ getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(DerivedClassDecl)));
+ const llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo();
+
+ if (ClassDecl == DerivedClassDecl) {
+ // Just cast back.
+ return Builder.CreateBitCast(Value, DerivedPtrTy);
+ }
+
+ llvm::BasicBlock *CastNull = 0;
+ llvm::BasicBlock *CastNotNull = 0;
+ llvm::BasicBlock *CastEnd = 0;
+
+ if (NullCheckValue) {
+ CastNull = createBasicBlock("cast.null");
+ CastNotNull = createBasicBlock("cast.notnull");
+ CastEnd = createBasicBlock("cast.end");
+
+ llvm::Value *IsNull =
+ Builder.CreateICmpEQ(Value,
+ llvm::Constant::getNullValue(Value->getType()));
+ Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
+ EmitBlock(CastNotNull);
+ }
+
+ llvm::Value *Offset = GetCXXBaseClassOffset(*this, Value, DerivedClassDecl,
+ ClassDecl);
+ if (Offset) {
+ // Apply the offset.
+ Value = Builder.CreatePtrToInt(Value, Offset->getType());
+ Value = Builder.CreateSub(Value, Offset);
+ Value = Builder.CreateIntToPtr(Value, DerivedPtrTy);
+ } else {
+ // Just cast.
+ Value = Builder.CreateBitCast(Value, DerivedPtrTy);
+ }
+
+ if (NullCheckValue) {
+ Builder.CreateBr(CastEnd);
+ EmitBlock(CastNull);
+ Builder.CreateBr(CastEnd);
+ EmitBlock(CastEnd);
+
+ llvm::PHINode *PHI = Builder.CreatePHI(Value->getType());
PHI->reserveOperandSpace(2);
- PHI->addIncoming(BaseValue, CastNotNull);
- PHI->addIncoming(llvm::Constant::getNullValue(BaseValue->getType()),
+ PHI->addIncoming(Value, CastNotNull);
+ PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()),
CastNull);
- BaseValue = PHI;
+ Value = PHI;
}
- return BaseValue;
+ return Value;
}
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=89678&r1=89677&r2=89678&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Mon Nov 23 11:57:54 2009
@@ -148,8 +148,8 @@
if (BaseClassDecl) {
llvm::Value *Derived = Val.getAggregateAddr();
llvm::Value *Base =
- GetAddressCXXOfBaseClass(Derived, DerivedClassDecl, BaseClassDecl,
- /*NullCheckValue=*/false);
+ GetAddressOfBaseClass(Derived, DerivedClassDecl, BaseClassDecl,
+ /*NullCheckValue=*/false);
return RValue::get(Base);
}
}
@@ -1328,8 +1328,8 @@
// Perform the derived-to-base conversion
llvm::Value *Base =
- GetAddressCXXOfBaseClass(LV.getAddress(), DerivedClassDecl,
- BaseClassDecl, /*NullCheckValue=*/false);
+ GetAddressOfBaseClass(LV.getAddress(), DerivedClassDecl,
+ BaseClassDecl, /*NullCheckValue=*/false);
return LValue::MakeAddr(Base, MakeQualifiers(E->getType()));
}
@@ -1340,7 +1340,23 @@
return LValue::MakeAddr(Temp, MakeQualifiers(E->getType()));
}
case CastExpr::CK_BaseToDerived: {
- return EmitUnsupportedLValue(E, "base-to-derived cast lvalue");
+ const RecordType *BaseClassTy =
+ E->getSubExpr()->getType()->getAs<RecordType>();
+ CXXRecordDecl *BaseClassDecl =
+ cast<CXXRecordDecl>(BaseClassTy->getDecl());
+
+ const RecordType *DerivedClassTy = E->getType()->getAs<RecordType>();
+ CXXRecordDecl *DerivedClassDecl =
+ cast<CXXRecordDecl>(DerivedClassTy->getDecl());
+
+ LValue LV = EmitLValue(E->getSubExpr());
+
+ // Perform the base-to-derived conversion
+ llvm::Value *Derived =
+ GetAddressOfDerivedClass(LV.getAddress(), BaseClassDecl,
+ DerivedClassDecl, /*NullCheckValue=*/false);
+
+ return LValue::MakeAddr(Derived, MakeQualifiers(E->getType()));
}
case CastExpr::CK_BitCast: {
// This must be a reinterpret_cast (or c-style equivalent).
Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=89678&r1=89677&r2=89678&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Mon Nov 23 11:57:54 2009
@@ -748,6 +748,23 @@
return V;
}
+static bool ShouldNullCheckClassCastValue(const CastExpr *CE) {
+ const Expr *E = CE->getSubExpr();
+
+ if (isa<CXXThisExpr>(E)) {
+ // We always assume that 'this' is never null.
+ return false;
+ }
+
+ if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
+ // And that lvalue casts are never null.
+ if (ICE->isLvalueCast())
+ return false;
+ }
+
+ return true;
+}
+
// 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.
@@ -775,6 +792,19 @@
case CastExpr::CK_NoOp:
return Visit(const_cast<Expr*>(E));
+ case CastExpr::CK_BaseToDerived: {
+ const CXXRecordDecl *BaseClassDecl =
+ E->getType()->getCXXRecordDeclForPointerType();
+ const CXXRecordDecl *DerivedClassDecl =
+ DestTy->getCXXRecordDeclForPointerType();
+
+ Value *Src = Visit(const_cast<Expr*>(E));
+
+ bool NullCheckValue = ShouldNullCheckClassCastValue(CE);
+ return CGF.GetAddressOfDerivedClass(Src, BaseClassDecl, DerivedClassDecl,
+ NullCheckValue);
+ }
+
case CastExpr::CK_DerivedToBase: {
const RecordType *DerivedClassTy =
E->getType()->getAs<PointerType>()->getPointeeType()->getAs<RecordType>();
@@ -787,18 +817,9 @@
Value *Src = Visit(const_cast<Expr*>(E));
- bool NullCheckValue = true;
-
- if (isa<CXXThisExpr>(E)) {
- // We always assume that 'this' is never null.
- NullCheckValue = false;
- } else if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
- // And that lvalue casts are never null.
- if (ICE->isLvalueCast())
- NullCheckValue = false;
- }
- return CGF.GetAddressCXXOfBaseClass(Src, DerivedClassDecl, BaseClassDecl,
- NullCheckValue);
+ bool NullCheckValue = ShouldNullCheckClassCastValue(CE);
+ return CGF.GetAddressOfBaseClass(Src, DerivedClassDecl, BaseClassDecl,
+ NullCheckValue);
}
case CastExpr::CK_ToUnion: {
assert(0 && "Should be unreachable!");
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=89678&r1=89677&r2=89678&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Mon Nov 23 11:57:54 2009
@@ -598,15 +598,20 @@
/// generating code for an C++ member function.
llvm::Value *LoadCXXThis();
- /// GetAddressCXXOfBaseClass - This function will add the necessary delta
+ /// GetAddressOfBaseClass - This function will add the necessary delta
/// to the load of 'this' and returns address of the base class.
// FIXME. This currently only does a derived to non-virtual base conversion.
// Other kinds of conversions will come later.
- llvm::Value *GetAddressCXXOfBaseClass(llvm::Value *BaseValue,
+ llvm::Value *GetAddressOfBaseClass(llvm::Value *Value,
+ const CXXRecordDecl *ClassDecl,
+ const CXXRecordDecl *BaseClassDecl,
+ bool NullCheckValue);
+
+ llvm::Value *GetAddressOfDerivedClass(llvm::Value *Value,
const CXXRecordDecl *ClassDecl,
- const CXXRecordDecl *BaseClassDecl,
+ const CXXRecordDecl *DerivedClassDecl,
bool NullCheckValue);
-
+
llvm::Value *
GetVirtualCXXBaseClassOffset(llvm::Value *This,
const CXXRecordDecl *ClassDecl,
More information about the cfe-commits
mailing list