diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-08-07 20:22:40 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-08-07 20:22:40 +0000 |
commit | 40134e71bee0d7a233925b8ed67954ccc5ede6cf (patch) | |
tree | ef497180f518cffc8355b632c444120d30e87430 /clang/lib/CodeGen/CodeGenModule.cpp | |
parent | a4d94b1a95454899f696388f6a11db99d707cbdd (diff) | |
download | bcm5719-llvm-40134e71bee0d7a233925b8ed67954ccc5ede6cf.tar.gz bcm5719-llvm-40134e71bee0d7a233925b8ed67954ccc5ede6cf.zip |
More synthesis of copy constructors. Work in progress.
llvm-svn: 78402
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 8e53651c8e6..e1cf13c72da 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -645,10 +645,8 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName, else if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) { const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext()); - if (CD->isCopyConstructor(getContext())) { - if (!ClassDecl->hasUserDeclaredCopyConstructor()) - DeferredDeclsToEmit.push_back(D); - } + if (CD->isCopyConstructor(getContext())) + DeferredCopyConstructorToEmit(D); else if (!ClassDecl->hasUserDeclaredConstructor()) DeferredDeclsToEmit.push_back(D); } @@ -674,6 +672,47 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName, return F; } +/// Defer definition of copy constructor(s) which need be implicitly defined. +void CodeGenModule::DeferredCopyConstructorToEmit(GlobalDecl CopyCtorDecl) { + const CXXConstructorDecl *CD = + cast<CXXConstructorDecl>(CopyCtorDecl.getDecl()); + const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext()); + if (ClassDecl->hasTrivialCopyConstructor() || + ClassDecl->hasUserDeclaredCopyConstructor()) + return; + + // First make sure all direct base classes and virtual bases and non-static + // data mebers which need to have their copy constructors implicitly defined + // are defined. 12.8.p7 + for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin(); + Base != ClassDecl->bases_end(); ++Base) { + unsigned TypeQuals; + CXXRecordDecl *BaseClassDecl + = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); + if (CXXConstructorDecl *BaseCopyCtor = + BaseClassDecl->getCopyConstructor(Context, TypeQuals)) + GetAddrOfCXXConstructor(BaseCopyCtor, Ctor_Complete); + } + + for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), + FieldEnd = ClassDecl->field_end(); + Field != FieldEnd; ++Field) { + unsigned TypeQuals; + QualType FieldType = Context.getCanonicalType((*Field)->getType()); + if (const ArrayType *Array = Context.getAsArrayType(FieldType)) + FieldType = Array->getElementType(); + if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) { + CXXRecordDecl *FieldClassDecl + = cast<CXXRecordDecl>(FieldClassType->getDecl()); + if (CXXConstructorDecl *FieldCopyCtor = + FieldClassDecl->getCopyConstructor(Context, TypeQuals)) + GetAddrOfCXXConstructor(FieldCopyCtor, Ctor_Complete); + } + } + DeferredDeclsToEmit.push_back(CopyCtorDecl); + +} + /// GetAddrOfFunction - Return the address of the given function. If Ty is /// non-null, then this function will use the specified type if it has to /// create it (this occurs when we see a definition of the function). |