forked from OSchip/llvm-project
DefineImplicitCopyConstructor now uses SetBaseOrMemberInitializers to create implicit base initializers. (Member initializers are still handled by CodeGenFunction::SynthesizeCXXCopyConstructor for now).
llvm-svn: 102279
This commit is contained in:
parent
283a350f4d
commit
90235beb55
|
@ -692,18 +692,6 @@ CodeGenFunction::SynthesizeCXXCopyConstructor(const FunctionArgList &Args) {
|
|||
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;
|
||||
|
||||
CXXRecordDecl *BaseClassDecl
|
||||
= cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
|
||||
EmitClassMemberwiseCopy(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl,
|
||||
Base->getType());
|
||||
}
|
||||
|
||||
for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(),
|
||||
E = ClassDecl->field_end(); I != E; ++I) {
|
||||
const FieldDecl *Field = *I;
|
||||
|
|
|
@ -1546,6 +1546,11 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
|
|||
FieldDecl *Field,
|
||||
CXXBaseOrMemberInitializer *&CXXMemberInit) {
|
||||
if (ImplicitInitKind == IIK_Copy) {
|
||||
// FIXME: We shouldn't return early here. The reason we do it is that
|
||||
// we don't handle copying arrays.
|
||||
CXXMemberInit = 0;
|
||||
return false;
|
||||
|
||||
ParmVarDecl *Param = Constructor->getParamDecl(0);
|
||||
QualType ParamType = Param->getType().getNonReferenceType();
|
||||
|
||||
|
@ -4199,25 +4204,16 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
|
|||
DeclContext *PreviousContext = CurContext;
|
||||
CurContext = CopyConstructor;
|
||||
|
||||
// C++ [class.copy] p209
|
||||
// Before the implicitly-declared copy constructor for a class is
|
||||
// implicitly defined, all the implicitly-declared copy constructors
|
||||
// for its base class and its non-static data members shall have been
|
||||
// implicitly defined.
|
||||
for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin();
|
||||
Base != ClassDecl->bases_end(); ++Base) {
|
||||
CXXRecordDecl *BaseClassDecl
|
||||
= cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
|
||||
if (CXXConstructorDecl *BaseCopyCtor =
|
||||
BaseClassDecl->getCopyConstructor(Context, TypeQuals)) {
|
||||
CheckDirectMemberAccess(Base->getSourceRange().getBegin(),
|
||||
BaseCopyCtor,
|
||||
PDiag(diag::err_access_copy_base)
|
||||
<< Base->getType());
|
||||
|
||||
MarkDeclarationReferenced(CurrentLocation, BaseCopyCtor);
|
||||
}
|
||||
if (SetBaseOrMemberInitializers(CopyConstructor, 0, 0, /*AnyErrors=*/false)) {
|
||||
Diag(CurrentLocation, diag::note_member_synthesized_at)
|
||||
<< CXXCopyConstructor << Context.getTagDeclType(ClassDecl);
|
||||
CopyConstructor->setInvalidDecl();
|
||||
} else {
|
||||
CopyConstructor->setUsed();
|
||||
}
|
||||
|
||||
// FIXME: Once we teach SetBaseOrMemberInitializers to copy fields, we can
|
||||
// get rid of this code.
|
||||
for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
|
||||
FieldEnd = ClassDecl->field_end();
|
||||
Field != FieldEnd; ++Field) {
|
||||
|
|
|
@ -183,9 +183,24 @@ struct B {
|
|||
|
||||
}
|
||||
|
||||
namespace test1 {
|
||||
namespace Test1 {
|
||||
struct A {
|
||||
enum Kind { Foo } Kind;
|
||||
A() : Kind(Foo) {}
|
||||
};
|
||||
}
|
||||
|
||||
namespace Test2 {
|
||||
|
||||
struct A {
|
||||
A(const A&);
|
||||
};
|
||||
|
||||
struct B : virtual A { };
|
||||
struct C : A, B { };
|
||||
|
||||
C f(C c) {
|
||||
return c;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue