[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