[cfe-commits] r78402 - in /cfe/trunk/lib/CodeGen: CGCXX.cpp CodeGenFunction.cpp CodeGenFunction.h CodeGenModule.cpp CodeGenModule.h

Fariborz Jahanian fjahanian at apple.com
Fri Aug 7 13:22:40 PDT 2009


Author: fjahanian
Date: Fri Aug  7 15:22:40 2009
New Revision: 78402

URL: http://llvm.org/viewvc/llvm-project?rev=78402&view=rev
Log:
More synthesis of copy constructors. Work in progress.


Modified:
    cfe/trunk/lib/CodeGen/CGCXX.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h

Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=78402&r1=78401&r2=78402&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Fri Aug  7 15:22:40 2009
@@ -652,6 +652,53 @@
   return vtable;
 }
 
+/// EmitCopyCtorBody - This routine implicitly defines body of a copy
+/// constructor, in accordance with section 12.8 (p7 and p8) of C++03
+/// The implicitly-defined copy constructor for class X performs a memberwise 
+/// copy of its subobjects. The order of copying is the same as the order 
+/// of initialization of bases and members in a user-defined constructor
+/// Each subobject is copied in the manner appropriate to its type:
+///  if the subobject is of class type, the copy constructor for the class is 
+///  used;
+///  if the subobject is an array, each element is copied, in the manner 
+///  appropriate to the element type;
+///  if the subobject is of scalar type, the built-in assignment operator is 
+///  used.
+/// Virtual base class subobjects shall be copied only once by the 
+/// implicitly-defined copy constructor 
+
+void CodeGenFunction::EmitCopyCtorBody(const CXXConstructorDecl *CD) {
+  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
+  assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
+         "EmitCopyCtorBody - copy constructor has definition already");
+ 
+  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;
+#if 0
+    unsigned TypeQuals;
+    CXXRecordDecl *BaseClassDecl
+      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+    if (CXXConstructorDecl *BaseCopyCtor = 
+          BaseClassDecl->getCopyConstructor(getContext(), TypeQuals)) {
+
+      llvm::Value *LoadOfThis = LoadCXXThis();
+      llvm::Value *V = AddressCXXOfBaseClass(LoadOfThis, ClassDecl, 
+                                             BaseClassDecl);
+      EmitCXXConstructorCall(BaseCopyCtor,
+                             Ctor_Complete, V,
+                             Member->const_arg_begin(), 
+                             Member->const_arg_end());
+
+    }
+#endif
+  }
+  
+}  
+
+
 /// EmitCtorPrologue - This routine generates necessary code to initialize
 /// base classes and non-static data members belonging to this constructor.
 void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) {

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=78402&r1=78401&r2=78402&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Fri Aug  7 15:22:40 2009
@@ -247,6 +247,7 @@
         assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
                "bogus constructor is being synthesize");
         StartFunction(FD, FD->getResultType(), Fn, Args, SourceLocation());
+        EmitCopyCtorBody(CD);
         FinishFunction();
       }
       else {

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=78402&r1=78401&r2=78402&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Fri Aug  7 15:22:40 2009
@@ -369,6 +369,8 @@
 
   void EmitCtorPrologue(const CXXConstructorDecl *CD);
   
+  void EmitCopyCtorBody(const CXXConstructorDecl *CD);
+  
   /// EmitDtorEpilogue - Emit all code that comes at the end of class's
   /// destructor. This is to call destructors on members and base classes 
   /// in reverse order of their construction.

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=78402&r1=78401&r2=78402&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri Aug  7 15:22:40 2009
@@ -645,10 +645,8 @@
     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 @@
   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).

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=78402&r1=78401&r2=78402&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Fri Aug  7 15:22:40 2009
@@ -393,6 +393,7 @@
   llvm::Constant *GetOrCreateLLVMGlobal(const char *MangledName,
                                         const llvm::PointerType *PTy,
                                         const VarDecl *D);
+  void DeferredCopyConstructorToEmit(GlobalDecl D);
   
   /// SetCommonAttributes - Set attributes which are common to any
   /// form of a global definition (alias, Objective-C method,





More information about the cfe-commits mailing list