aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGCXX.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-08-08 00:15:41 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-08-08 00:15:41 +0000
commit1e4edd5474f8cb966356afa6175d658002ff819c (patch)
tree6a9a289951b9b91fb19035c0963cdad92e6f342d /lib/CodeGen/CGCXX.cpp
parentca28361fb0a72c50e0a400fae2fad9520e61c0a5 (diff)
Synthesize copying of non-static data members with
non-trivial copy constructors. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78445 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCXX.cpp')
-rw-r--r--lib/CodeGen/CGCXX.cpp44
1 files changed, 32 insertions, 12 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index a9d0a1f60e..3ccde5b190 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -680,16 +680,16 @@ void CodeGenFunction::EmitClassMemberwiseCopy(
llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor,
Ctor_Complete);
- llvm::Value *Dest =
- AddressCXXOfBaseClass(DestValue, ClassDecl, BaseClassDecl);
+ 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 =
- AddressCXXOfBaseClass(SrcValue, ClassDecl, BaseClassDecl);
+ 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())));
@@ -721,25 +721,45 @@ void CodeGenFunction::EmitCopyCtorBody(const CXXConstructorDecl *CD,
assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
"EmitCopyCtorBody - copy constructor has definition already");
+ 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);
+
for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
Base != ClassDecl->bases_end(); ++Base) {
// FIXME. copy constrution of virtual base NYI
if (Base->isVirtual())
continue;
- 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<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
EmitClassMemberwiseCopy(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl);
}
+ for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+ FieldEnd = ClassDecl->field_end();
+ Field != FieldEnd; ++Field) {
+ QualType FieldType = getContext().getCanonicalType((*Field)->getType());
+
+ // FIXME. How about copying arrays!
+ assert(!getContext().getAsArrayType(FieldType) &&
+ "FIXME. Copying arrays NYI");
+
+ if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
+ CXXRecordDecl *FieldClassDecl
+ = cast<CXXRecordDecl>(FieldClassType->getDecl());
+ LValue LHS = EmitLValueForField(LoadOfThis, *Field, false, 0);
+ LValue RHS = EmitLValueForField(LoadOfSrc, *Field, false, 0);
+ EmitClassMemberwiseCopy(LHS.getAddress(), RHS.getAddress(),
+ 0 /*ClassDecl*/, FieldClassDecl);
+ continue;
+ }
+ // FIXME. Do a built-in assignment of scalar data members.
+ }
}