From cfe682274cee000fe8b39131090a27e87e970346 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 1 Jul 2010 18:27:03 +0000 Subject: Teach DeclareImplicitCopyConstructor how to cope with virtual bases and multi-dimensional array fields. Fixes several bugs found by inspection. llvm-svn: 107411 --- clang/lib/Sema/SemaDeclCXX.cpp | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'clang/lib/Sema/SemaDeclCXX.cpp') diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 4b7015caec5..d7103219393 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -4915,8 +4915,6 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(Scope *S, // If the class definition does not explicitly declare a copy // constructor, one is declared implicitly. - // FIXME: virtual bases! - // C++ [class.copy]p5: // The implicitly-declared copy constructor for a class X will // have the form @@ -4933,6 +4931,20 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(Scope *S, BaseEnd = ClassDecl->bases_end(); HasConstCopyConstructor && Base != BaseEnd; ++Base) { + // Virtual bases are handled below. + if (Base->isVirtual()) + continue; + + const CXXRecordDecl *BaseClassDecl + = cast(Base->getType()->getAs()->getDecl()); + HasConstCopyConstructor + = BaseClassDecl->hasConstCopyConstructor(Context); + } + + for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(), + BaseEnd = ClassDecl->vbases_end(); + HasConstCopyConstructor && Base != BaseEnd; + ++Base) { const CXXRecordDecl *BaseClassDecl = cast(Base->getType()->getAs()->getDecl()); HasConstCopyConstructor @@ -4947,14 +4959,12 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(Scope *S, FieldEnd = ClassDecl->field_end(); HasConstCopyConstructor && Field != FieldEnd; ++Field) { - QualType FieldType = (*Field)->getType(); - if (const ArrayType *Array = Context.getAsArrayType(FieldType)) - FieldType = Array->getElementType(); + QualType FieldType = Context.getBaseElementType((*Field)->getType()); if (const RecordType *FieldClassType = FieldType->getAs()) { const CXXRecordDecl *FieldClassDecl - = cast(FieldClassType->getDecl()); + = cast(FieldClassType->getDecl()); HasConstCopyConstructor - = FieldClassDecl->hasConstCopyConstructor(Context); + = FieldClassDecl->hasConstCopyConstructor(Context); } } -- cgit v1.2.3