From 6b8b4b459d0851ca7630a9584242df56687afc3c Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Tue, 1 Sep 2009 18:33:46 +0000 Subject: [PATCH] We can generate constructors/destructors with base classes and non-trivial fields just fine now. llvm-svn: 80701 --- clang/lib/CodeGen/CGCXX.cpp | 28 ++------------------------- clang/test/CodeGenCXX/destructors.cpp | 22 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 26 deletions(-) create mode 100644 clang/test/CodeGenCXX/destructors.cpp diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index cb12ac948c59..d71597fd93bf 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/lib/CodeGen/CGCXX.cpp @@ -719,28 +719,7 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) { EmitBlock(DeleteEnd); } -static bool canGenerateCXXstructor(const CXXRecordDecl *RD, - ASTContext &Context) { - // The class has base classes - we don't support that right now. - if (RD->getNumBases() > 0) - return false; - - for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); - I != E; ++I) { - // We don't support ctors for fields that aren't POD. - if (!I->getType()->isPODType()) - return false; - } - - return true; -} - void CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) { - if (!canGenerateCXXstructor(D->getParent(), getContext())) { - ErrorUnsupported(D, "C++ constructor", true); - return; - } - EmitGlobal(GlobalDecl(D, Ctor_Complete)); EmitGlobal(GlobalDecl(D, Ctor_Base)); } @@ -778,11 +757,6 @@ const char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D, } void CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) { - if (!canGenerateCXXstructor(D->getParent(), getContext())) { - ErrorUnsupported(D, "C++ destructor", true); - return; - } - EmitCXXDestructor(D, Dtor_Complete); EmitCXXDestructor(D, Dtor_Base); } @@ -1613,6 +1587,7 @@ void CodeGenFunction::SynthesizeCXXCopyAssignment(const CXXMethodDecl *CD, /// EmitCtorPrologue - This routine generates necessary code to initialize /// base classes and non-static data members belonging to this constructor. +/// FIXME: This needs to take a CXXCtorType. void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) { const CXXRecordDecl *ClassDecl = cast(CD->getDeclContext()); // FIXME: Add vbase initialization @@ -1766,6 +1741,7 @@ void CodeGenFunction::EmitCtorPrologue(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. +/// FIXME: This needs to take a CXXDtorType. void CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD) { const CXXRecordDecl *ClassDecl = cast(DD->getDeclContext()); assert(!ClassDecl->isPolymorphic() && diff --git a/clang/test/CodeGenCXX/destructors.cpp b/clang/test/CodeGenCXX/destructors.cpp new file mode 100644 index 000000000000..e8080577ff69 --- /dev/null +++ b/clang/test/CodeGenCXX/destructors.cpp @@ -0,0 +1,22 @@ +// RUN: clang-cc %s -emit-llvm -o - +struct A { + int a; + + ~A(); +}; + +// Base with non-trivial destructor +struct B : A { + ~B(); +}; + +B::~B() { } + +// Field with non-trivial destructor +struct C { + A a; + + ~C(); +}; + +C::~C() { } \ No newline at end of file