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 | 369acf9304103fd7ca93fc964ed625f241af724c (patch) | |
tree | 1dc539332f803346a6664bafae7cc15aec855283 /clang/lib/CodeGen/CodeGenFunction.cpp | |
parent | b3c44f9ee9e664dfbcf8a14412f504a9f523db85 (diff) | |
download | bcm5719-llvm-369acf9304103fd7ca93fc964ed625f241af724c.tar.gz bcm5719-llvm-369acf9304103fd7ca93fc964ed625f241af724c.zip |
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.
llvm-svn: 83212
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 72009daef68..f9e54b75708 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/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. |