[cfe-commits] r102270 - in /cfe/trunk/lib/CodeGen: CGClass.cpp CGExprScalar.cpp CodeGenFunction.h
Anders Carlsson
andersca at mac.com
Sat Apr 24 14:06:20 PDT 2010
Author: andersca
Date: Sat Apr 24 16:06:20 2010
New Revision: 102270
URL: http://llvm.org/viewvc/llvm-project?rev=102270&view=rev
Log:
Add a new GetAddressOfBaseClass overload that takes a base path and. Use it for derived-to-base casts.
Modified:
cfe/trunk/lib/CodeGen/CGClass.cpp
cfe/trunk/lib/CodeGen/CGExprScalar.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=102270&r1=102269&r2=102270&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Sat Apr 24 16:06:20 2010
@@ -20,6 +20,35 @@
using namespace CodeGen;
static uint64_t
+ComputeNonVirtualBaseClassOffset(ASTContext &Context,
+ const CXXRecordDecl *DerivedClass,
+ CXXBaseSpecifierArray::iterator Start,
+ CXXBaseSpecifierArray::iterator End) {
+ uint64_t Offset = 0;
+
+ const CXXRecordDecl *RD = DerivedClass;
+
+ for (CXXBaseSpecifierArray::iterator I = Start; I != End; ++I) {
+ const CXXBaseSpecifier *Base = *I;
+ assert(!Base->isVirtual() && "Should not see virtual bases here!");
+
+ // Get the layout.
+ const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+
+ const CXXRecordDecl *BaseDecl =
+ cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+
+ // Add the offset.
+ Offset += Layout.getBaseClassOffset(BaseDecl);
+
+ RD = BaseDecl;
+ }
+
+ // FIXME: We should not use / 8 here.
+ return Offset / 8;
+}
+
+static uint64_t
ComputeNonVirtualBaseClassOffset(ASTContext &Context,
const CXXBasePath &Path,
unsigned Start) {
@@ -133,6 +162,81 @@
}
llvm::Value *
+CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value,
+ const CXXRecordDecl *ClassDecl,
+ const CXXBaseSpecifierArray &BasePath,
+ bool NullCheckValue) {
+ assert(!BasePath.empty() && "Base path should not be empty!");
+
+ CXXBaseSpecifierArray::iterator Start = BasePath.begin();
+ const CXXRecordDecl *VBase = 0;
+
+ // Get the virtual base.
+ if ((*Start)->isVirtual()) {
+ VBase =
+ cast<CXXRecordDecl>((*Start)->getType()->getAs<RecordType>()->getDecl());
+ ++Start;
+ }
+
+ uint64_t NonVirtualOffset =
+ ComputeNonVirtualBaseClassOffset(getContext(), VBase ? VBase : ClassDecl,
+ Start, BasePath.end());
+
+ // Get the base pointer type.
+ const llvm::Type *BasePtrTy =
+ llvm::PointerType::getUnqual(ConvertType((BasePath.end()[-1])->getType()));
+
+ if (!NonVirtualOffset && !VBase) {
+ // Just cast back.
+ return Builder.CreateBitCast(Value, BasePtrTy);
+ }
+
+ 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 *VirtualOffset = 0;
+
+ if (VBase)
+ VirtualOffset = GetVirtualBaseClassOffset(Value, ClassDecl, VBase);
+
+ // Apply the offsets.
+ Value = ApplyNonVirtualAndVirtualOffset(*this, Value, NonVirtualOffset,
+ VirtualOffset);
+
+ // Cast back.
+ Value = Builder.CreateBitCast(Value, BasePtrTy);
+
+ if (NullCheckValue) {
+ Builder.CreateBr(CastEnd);
+ EmitBlock(CastNull);
+ Builder.CreateBr(CastEnd);
+ EmitBlock(CastEnd);
+
+ 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::GetAddressOfBaseClass(llvm::Value *Value,
const CXXRecordDecl *Class,
const CXXRecordDecl *BaseClass,
Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=102270&r1=102269&r2=102270&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Sat Apr 24 16:06:20 2010
@@ -840,15 +840,9 @@
CXXRecordDecl *DerivedClassDecl =
cast<CXXRecordDecl>(DerivedClassTy->getDecl());
- const RecordType *BaseClassTy =
- DestTy->getAs<PointerType>()->getPointeeType()->getAs<RecordType>();
- CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseClassTy->getDecl());
-
- Value *Src = Visit(const_cast<Expr*>(E));
-
- bool NullCheckValue = ShouldNullCheckClassCastValue(CE);
- return CGF.GetAddressOfBaseClass(Src, DerivedClassDecl, BaseClassDecl,
- NullCheckValue);
+ return CGF.GetAddressOfBaseClass(Visit(E), DerivedClassDecl,
+ CE->getBasePath(),
+ ShouldNullCheckClassCastValue(CE));
}
case CastExpr::CK_Dynamic: {
Value *V = Visit(const_cast<Expr*>(E));
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=102270&r1=102269&r2=102270&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Sat Apr 24 16:06:20 2010
@@ -787,7 +787,11 @@
const CXXRecordDecl *ClassDecl,
const CXXRecordDecl *BaseClassDecl,
bool NullCheckValue);
-
+ llvm::Value *GetAddressOfBaseClass(llvm::Value *Value,
+ const CXXRecordDecl *ClassDecl,
+ const CXXBaseSpecifierArray &BasePath,
+ bool NullCheckValue);
+
llvm::Value *GetAddressOfDerivedClass(llvm::Value *Value,
const CXXRecordDecl *ClassDecl,
const CXXRecordDecl *DerivedClassDecl,
More information about the cfe-commits
mailing list