]> granicus.if.org Git - clang/commitdiff
DefineImplicitCopyConstructor now uses SetBaseOrMemberInitializers to create implicit...
authorAnders Carlsson <andersca@mac.com>
Sat, 24 Apr 2010 22:25:18 +0000 (22:25 +0000)
committerAnders Carlsson <andersca@mac.com>
Sat, 24 Apr 2010 22:25:18 +0000 (22:25 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102279 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGClass.cpp
lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/constructor-initializer.cpp

index 7a452ec929d060d396a8da179860640f419b202a..78a29ad35f6b9bf69bdba5b3fc8ae22c50a5c76a 100644 (file)
@@ -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;
index d7cbc17a7a5bd59436e1b3986ce97dab9c9e4971..af4245d21c5bdefb66a9af935a5b2d06487c65a1 100644 (file)
@@ -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) {
index ff963a9bce2ade792a55af4b94cff8ee559aedf3..8e9e133d94cbdad8ad3ff49c2d19a11e4b12c8e2 100644 (file)
@@ -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;
+}
+
+}