From ca28361fb0a72c50e0a400fae2fad9520e61c0a5 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 7 Aug 2009 23:51:33 +0000 Subject: [PATCH] Synthesized copy constructor now generates code for copying non-virtual base classes which have non-trivial constructor. Work in progress. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78436 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGCXX.cpp | 64 ++++++++++++++++++++++++--------- lib/CodeGen/CodeGenFunction.cpp | 2 +- lib/CodeGen/CodeGenFunction.h | 7 +++- 3 files changed, 55 insertions(+), 18 deletions(-) diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index d79e1cef09..a9d0a1f60e 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -664,6 +664,42 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) { return vtable; } +/// EmitClassMemberwiseCopy - This routine generates code to copy a class +/// object from SrcValue to DestValue. Copying can be either a bitwise copy +/// of via a copy constructor call. +void CodeGenFunction::EmitClassMemberwiseCopy( + llvm::Value *DestValue, llvm::Value *SrcValue, + const CXXRecordDecl *ClassDecl, + const CXXRecordDecl *BaseClassDecl) { + // FIXME. Do bitwise copy of trivial copy constructors. + if (BaseClassDecl->hasTrivialCopyConstructor()) + return; + unsigned TypeQuals; + if (CXXConstructorDecl *BaseCopyCtor = + BaseClassDecl->getCopyConstructor(getContext(), TypeQuals)) { + llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor, + Ctor_Complete); + + llvm::Value *Dest = + AddressCXXOfBaseClass(DestValue, ClassDecl, BaseClassDecl); + + CallArgList CallArgs; + // Push the this (Dest) ptr. + CallArgs.push_back(std::make_pair(RValue::get(Dest), + BaseCopyCtor->getThisType(getContext()))); + + llvm::Value *Src = + AddressCXXOfBaseClass(SrcValue, ClassDecl, BaseClassDecl); + // Push the Src ptr. + CallArgs.push_back(std::make_pair(RValue::get(Src), + BaseCopyCtor->getThisType(getContext()))); + QualType ResultType = + BaseCopyCtor->getType()->getAsFunctionType()->getResultType(); + EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs), + Callee, CallArgs, BaseCopyCtor); + } +} + /// EmitCopyCtorBody - This routine implicitly defines body of a copy /// constructor, in accordance with section 12.8 (p7 and p8) of C++03 /// The implicitly-defined copy constructor for class X performs a memberwise @@ -679,7 +715,8 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) { /// Virtual base class subobjects shall be copied only once by the /// implicitly-defined copy constructor -void CodeGenFunction::EmitCopyCtorBody(const CXXConstructorDecl *CD) { +void CodeGenFunction::EmitCopyCtorBody(const CXXConstructorDecl *CD, + const FunctionArgList &Args) { const CXXRecordDecl *ClassDecl = cast(CD->getDeclContext()); assert(!ClassDecl->hasUserDeclaredCopyConstructor() && "EmitCopyCtorBody - copy constructor has definition already"); @@ -689,23 +726,18 @@ void CodeGenFunction::EmitCopyCtorBody(const CXXConstructorDecl *CD) { // FIXME. copy constrution of virtual base NYI if (Base->isVirtual()) continue; -#if 0 - unsigned TypeQuals; + + FunctionArgList::const_iterator i = Args.begin(); + const VarDecl *ThisArg = i->first; + llvm::Value *ThisObj = GetAddrOfLocalVar(ThisArg); + llvm::Value *LoadOfThis = Builder.CreateLoad(ThisObj, "this"); + const VarDecl *SrcArg = (i+1)->first; + llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg); + llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj); + CXXRecordDecl *BaseClassDecl = cast(Base->getType()->getAs()->getDecl()); - if (CXXConstructorDecl *BaseCopyCtor = - BaseClassDecl->getCopyConstructor(getContext(), TypeQuals)) { - - llvm::Value *LoadOfThis = LoadCXXThis(); - llvm::Value *V = AddressCXXOfBaseClass(LoadOfThis, ClassDecl, - BaseClassDecl); - EmitCXXConstructorCall(BaseCopyCtor, - Ctor_Complete, V, - Member->const_arg_begin(), - Member->const_arg_end()); - - } -#endif + EmitClassMemberwiseCopy(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl); } } diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 7c9b3af8d3..0a3d9d4be9 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -247,7 +247,7 @@ void CodeGenFunction::GenerateCode(const FunctionDecl *FD, assert(!ClassDecl->hasUserDeclaredCopyConstructor() && "bogus constructor is being synthesize"); StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation()); - EmitCopyCtorBody(CD); + EmitCopyCtorBody(CD, Args); FinishFunction(); } else { diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index b512d3670b..383f844e93 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -369,7 +369,8 @@ public: void EmitCtorPrologue(const CXXConstructorDecl *CD); - void EmitCopyCtorBody(const CXXConstructorDecl *CD); + void EmitCopyCtorBody(const CXXConstructorDecl *CD, + const FunctionArgList &Args); /// EmitDtorEpilogue - Emit all code that comes at the end of class's /// destructor. This is to call destructors on members and base classes @@ -552,6 +553,10 @@ public: const CXXRecordDecl *ClassDecl, const CXXRecordDecl *BaseClassDecl); + void EmitClassMemberwiseCopy(llvm::Value *DestValue, llvm::Value *SrcValue, + const CXXRecordDecl *ClassDecl, + const CXXRecordDecl *BaseClassDecl); + void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, llvm::Value *This, CallExpr::const_arg_iterator ArgBeg, -- 2.40.0