diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-10-01 20:44:19 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-10-01 20:44:19 +0000 |
commit | 4513272f444c59705123ccb6207414ce62c9a568 (patch) | |
tree | 148a26d62eae4944dcd8e632862e369c4feeed9c /lib/CodeGen/CodeGenFunction.cpp | |
parent | 249ceade4942a2a5d7888541c547abeda5bb85b4 (diff) |
CodeGen may see out-of-line declarations of the various special member
functions when they are explicitly declared, e.g., via a function
template specialization or explicit template instantiation
declaration. Don't try to synthesize bodies for the special member
functions in this case; rather, check whether we have an implicit
declaration and, if so, synthesize the appropriate function
body. Fixes PR5084.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83212 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 72009daef6..f9e54b7570 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -239,28 +239,37 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD)) EmitDtorEpilogue(DD, GD.getDtorType()); FinishFunction(S->getRBracLoc()); - } - else + } else if (FD->isImplicit()) { + const CXXRecordDecl *ClassDecl = + cast<CXXRecordDecl>(FD->getDeclContext()); + (void) ClassDecl; if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) { - const CXXRecordDecl *ClassDecl = - cast<CXXRecordDecl>(CD->getDeclContext()); - (void) ClassDecl; + // FIXME: For C++0x, we want to look for implicit *definitions* of + // these special member functions, rather than implicit *declarations*. if (CD->isCopyConstructor(getContext())) { assert(!ClassDecl->hasUserDeclaredCopyConstructor() && - "bogus constructor is being synthesize"); + "Cannot synthesize a non-implicit copy constructor"); SynthesizeCXXCopyConstructor(CD, GD.getCtorType(), Fn, Args); - } - else { + } else if (CD->isDefaultConstructor()) { assert(!ClassDecl->hasUserDeclaredConstructor() && - "bogus constructor is being synthesize"); + "Cannot synthesize a non-implicit default constructor."); SynthesizeDefaultConstructor(CD, GD.getCtorType(), Fn, Args); + } else { + assert(false && "Implicit constructor cannot be synthesized"); } - } - else if (const CXXDestructorDecl *CD = dyn_cast<CXXDestructorDecl>(FD)) - SynthesizeDefaultDestructor(CD, GD.getDtorType(), Fn, Args); - else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) { - if (MD->isCopyAssignment()) + } else if (const CXXDestructorDecl *CD = dyn_cast<CXXDestructorDecl>(FD)) { + assert(!ClassDecl->hasUserDeclaredDestructor() && + "Cannot synthesize a non-implicit destructor"); + SynthesizeDefaultDestructor(CD, GD.getDtorType(), Fn, Args); + } else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) { + assert(MD->isCopyAssignment() && + !ClassDecl->hasUserDeclaredCopyAssignment() && + "Cannot synthesize a method that is not an implicit-defined " + "copy constructor"); SynthesizeCXXCopyAssignment(MD, Fn, Args); + } else { + assert(false && "Cannot synthesize unknown implicit function"); + } } // Destroy the 'this' declaration. |