From 942f4f33d02dba823594bd2d7b3d317cb01c74f8 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Sat, 8 Aug 2009 23:32:22 +0000 Subject: [PATCH] ir-gen for initialization, in synthesize copy constructor, of base/field which have trivial copy constructor. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78516 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGCXX.cpp | 26 +++++---- lib/CodeGen/CodeGenFunction.h | 3 +- .../CodeGenCXX/copy-constructor-synthesis.cpp | 55 +++++++++++++++++++ 3 files changed, 71 insertions(+), 13 deletions(-) create mode 100644 test/CodeGenCXX/copy-constructor-synthesis.cpp diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index bcae8298e6..82813f51c3 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -761,27 +761,27 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) { /// 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, + llvm::Value *Dest, llvm::Value *Src, const CXXRecordDecl *ClassDecl, - const CXXRecordDecl *BaseClassDecl) { - // FIXME. Do bitwise copy of trivial copy constructors. - if (BaseClassDecl->hasTrivialCopyConstructor()) + const CXXRecordDecl *BaseClassDecl, QualType Ty) { + if (ClassDecl) { + Dest = AddressCXXOfBaseClass(Dest, ClassDecl, BaseClassDecl); + Src = AddressCXXOfBaseClass(Src, ClassDecl, BaseClassDecl) ; + } + if (BaseClassDecl->hasTrivialCopyConstructor()) { + EmitAggregateCopy(Dest, Src, Ty); return; + } + if (CXXConstructorDecl *BaseCopyCtor = BaseClassDecl->getCopyConstructor(getContext(), 0)) { llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor, Ctor_Complete); - - llvm::Value *Dest = ClassDecl ? - AddressCXXOfBaseClass(DestValue, ClassDecl, BaseClassDecl) : DestValue; - CallArgList CallArgs; // Push the this (Dest) ptr. CallArgs.push_back(std::make_pair(RValue::get(Dest), BaseCopyCtor->getThisType(getContext()))); - llvm::Value *Src = ClassDecl ? - AddressCXXOfBaseClass(SrcValue, ClassDecl, BaseClassDecl) : SrcValue; // Push the Src ptr. CallArgs.push_back(std::make_pair(RValue::get(Src), BaseCopyCtor->getThisType(getContext()))); @@ -832,7 +832,8 @@ void CodeGenFunction::SynthesizeCXXCopyConstructor(const CXXConstructorDecl *CD, CXXRecordDecl *BaseClassDecl = cast(Base->getType()->getAs()->getDecl()); - EmitClassMemberwiseCopy(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl); + EmitClassMemberwiseCopy(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl, + Base->getType()); } for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), @@ -849,8 +850,9 @@ void CodeGenFunction::SynthesizeCXXCopyConstructor(const CXXConstructorDecl *CD, = cast(FieldClassType->getDecl()); LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0); LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0); + EmitClassMemberwiseCopy(LHS.getAddress(), RHS.getAddress(), - 0 /*ClassDecl*/, FieldClassDecl); + 0 /*ClassDecl*/, FieldClassDecl, FieldType); continue; } // FIXME. Do a built-in assignment of scalar data members. diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index d18217fcc9..5b6826f57f 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -557,7 +557,8 @@ public: void EmitClassMemberwiseCopy(llvm::Value *DestValue, llvm::Value *SrcValue, const CXXRecordDecl *ClassDecl, - const CXXRecordDecl *BaseClassDecl); + const CXXRecordDecl *BaseClassDecl, + QualType Ty); void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, llvm::Value *This, diff --git a/test/CodeGenCXX/copy-constructor-synthesis.cpp b/test/CodeGenCXX/copy-constructor-synthesis.cpp new file mode 100644 index 0000000000..edc0c0ecb8 --- /dev/null +++ b/test/CodeGenCXX/copy-constructor-synthesis.cpp @@ -0,0 +1,55 @@ +// RUNX: clang-cc -triple x86_64-apple-darwin -S %s -o %t-64.s && +// RUNX: FileCheck -check-prefix LP64 --input-file=%t-64.s %s && +// RUN: clang-cc -triple i386-apple-darwin -S %s -o %t-32.s && +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s && +// RUN: true + +extern "C" int printf(...); + +int init = 100; + +struct M { + int iM; + M() : iM(init++) {} +}; + +struct N { + int iN; + N() : iN(200) {} + N(N const & arg){this->iN = arg.iN; } +}; + +struct P { + int iP; + P() : iP(init++) {} +}; + + +struct X : M, N, P { // ... + X(){} + P p0; + void pr() { printf("iM = %d iN = %d, m1.iM = %d\n", iM, iN, m1.iM); + printf("im = %d p0.iP = %d, p1.iP = %d\n", iP, p0.iP, p1.iP); } + M m1; + P p1; +}; + +int main() +{ + X a; + X b(a); + b.pr(); + X x; + X c(x); + c.pr(); +} +#if 0 +// -m64 does not work due to unrelated llvm bug! +// CHECK-LP64: .globl __ZN1XC1ERK1X +// CHECK-LP64: .weak_definition __ZN1XC1ERK1X +// CHECK-LP64: __ZN1XC1ERK1X: +#endif + +// CHECK-LP32: .globl __ZN1XC1ERK1X +// CHECK-LP32: .weak_definition __ZN1XC1ERK1X +// CHECK-LP32: __ZN1XC1ERK1X: -- 2.40.0