From 8a64c1c94c1e2280fbf49d0689afe563e3f4b7b1 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sat, 24 Apr 2010 21:23:59 +0000 Subject: [PATCH] Change CodeGenFunction::GetAddressOfDerivedClass to take a BasePath. llvm-svn: 102273 --- clang/lib/CodeGen/CGClass.cpp | 28 +++++++++++++++++++++------- clang/lib/CodeGen/CGExpr.cpp | 9 ++------- clang/lib/CodeGen/CGExprScalar.cpp | 10 +++------- clang/lib/CodeGen/CodeGenFunction.h | 2 +- clang/lib/CodeGen/CodeGenModule.h | 5 ++++- 5 files changed, 31 insertions(+), 23 deletions(-) diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index b8f7df927ce6..6dea9f77ae98 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -73,6 +73,23 @@ ComputeNonVirtualBaseClassOffset(ASTContext &Context, return Offset; } +llvm::Constant * +CodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, + const CXXBaseSpecifierArray &BasePath) { + assert(!BasePath.empty() && "Base path should not be empty!"); + + uint64_t Offset = + ComputeNonVirtualBaseClassOffset(getContext(), ClassDecl, + BasePath.begin(), BasePath.end()); + if (!Offset) + return 0; + + const llvm::Type *PtrDiffTy = + Types.ConvertType(getContext().getPointerDiffType()); + + return llvm::ConstantInt::get(PtrDiffTy, Offset); +} + llvm::Constant * CodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *Class, const CXXRecordDecl *BaseClass) { @@ -336,21 +353,18 @@ CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, llvm::Value * CodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value, - const CXXRecordDecl *Class, const CXXRecordDecl *DerivedClass, + const CXXBaseSpecifierArray &BasePath, bool NullCheckValue) { + assert(!BasePath.empty() && "Base path should not be empty!"); + QualType DerivedTy = getContext().getCanonicalType( getContext().getTypeDeclType(const_cast(DerivedClass))); const llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo(); - if (Class == DerivedClass) { - // Just cast back. - return Builder.CreateBitCast(Value, DerivedPtrTy); - } - llvm::Value *NonVirtualOffset = - CGM.GetNonVirtualBaseClassOffset(DerivedClass, Class); + CGM.GetNonVirtualBaseClassOffset(DerivedClass, BasePath); if (!NonVirtualOffset) { // No offset, we can just cast back. diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 62b5a3dbee67..5c9374dd2958 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1693,11 +1693,6 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { case CastExpr::CK_ToUnion: return EmitAggExprToLValue(E); case CastExpr::CK_BaseToDerived: { - const RecordType *BaseClassTy = - E->getSubExpr()->getType()->getAs(); - CXXRecordDecl *BaseClassDecl = - cast(BaseClassTy->getDecl()); - const RecordType *DerivedClassTy = E->getType()->getAs(); CXXRecordDecl *DerivedClassDecl = cast(DerivedClassTy->getDecl()); @@ -1706,8 +1701,8 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { // Perform the base-to-derived conversion llvm::Value *Derived = - GetAddressOfDerivedClass(LV.getAddress(), BaseClassDecl, - DerivedClassDecl, /*NullCheckValue=*/false); + GetAddressOfDerivedClass(LV.getAddress(), DerivedClassDecl, + E->getBasePath(),/*NullCheckValue=*/false); return LValue::MakeAddr(Derived, MakeQualifiers(E->getType())); } diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index f38126b8e7a8..ad072c6d01b5 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -822,16 +822,12 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) { return Visit(const_cast(E)); case CastExpr::CK_BaseToDerived: { - const CXXRecordDecl *BaseClassDecl = - E->getType()->getCXXRecordDeclForPointerType(); const CXXRecordDecl *DerivedClassDecl = DestTy->getCXXRecordDeclForPointerType(); - Value *Src = Visit(const_cast(E)); - - bool NullCheckValue = ShouldNullCheckClassCastValue(CE); - return CGF.GetAddressOfDerivedClass(Src, BaseClassDecl, DerivedClassDecl, - NullCheckValue); + return CGF.GetAddressOfDerivedClass(Visit(E), DerivedClassDecl, + CE->getBasePath(), + ShouldNullCheckClassCastValue(CE)); } case CastExpr::CK_UncheckedDerivedToBase: case CastExpr::CK_DerivedToBase: { diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 0707ada38c53..c0786b8c3ebd 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -793,8 +793,8 @@ public: bool NullCheckValue); llvm::Value *GetAddressOfDerivedClass(llvm::Value *Value, - const CXXRecordDecl *ClassDecl, const CXXRecordDecl *DerivedClassDecl, + const CXXBaseSpecifierArray &BasePath, bool NullCheckValue); llvm::Value *GetVirtualBaseClassOffset(llvm::Value *This, diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 238b36d3d2c3..c324d61a5d78 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -245,7 +245,10 @@ public: llvm::Constant * GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, const CXXRecordDecl *BaseClassDecl); - + llvm::Constant * + GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, + const CXXBaseSpecifierArray &BasePath); + /// GetStringForStringLiteral - Return the appropriate bytes for a string /// literal, properly padded to match the literal type. If only the address of /// a constant is needed consider using GetAddrOfConstantStringLiteral. -- GitLab