Correctly propagate defaultedness across template instantiation. This

fixes PR9965, but we're not out of the water yet, as we do not
successfully handle out-of-line definitions, due to my utter
misunderstanding of how we manage templates.

llvm-svn: 131920
This commit is contained in:
Alexis Hunt 2011-05-23 21:07:59 +00:00
parent 6c4a319088
commit 1fb4e76218
3 changed files with 29 additions and 2 deletions

View File

@ -2997,6 +2997,7 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {
// have inherited constructors.
DeclareInheritedConstructors(Record);
if (!Record->isDependentType())
CheckExplicitlyDefaultedMethods(Record);
}
@ -8657,6 +8658,12 @@ void Sema::SetDeclDefaulted(Decl *Dcl, SourceLocation DefaultLoc) {
CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Dcl);
if (MD) {
if (MD->getParent()->isDependentType()) {
MD->setDefaulted();
MD->setExplicitlyDefaulted();
return;
}
CXXSpecialMember Member = getSpecialMember(MD);
if (Member == CXXInvalid) {
Diag(DefaultLoc, diag::err_default_special_members);

View File

@ -1264,6 +1264,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
PrincipalDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))
PrincipalDecl->setNonMemberOperator();
assert(!D->isDefaulted() && "only methods should be defaulted");
return Function;
}
@ -1497,6 +1498,13 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
Owner->addDecl(DeclToAdd);
}
if (D->isExplicitlyDefaulted()) {
SemaRef.SetDeclDefaulted(Method, Method->getLocation());
} else {
assert(!D->isDefaulted() &&
"should not implicitly default uninstantiated function");
}
return Method;
}

View File

@ -0,0 +1,12 @@
// RUN: %clang_cc1 -std=c++0x -emit-llvm -o - %s | FileCheck %s
template<typename T>
struct X
{
X() = default;
};
X<int> x;
// CHECK: define internal void @__cxx_global_var_init()
// CHECK: call void @_ZN1XIiEC1Ev
// CHECK: define linkonce_odr void @_ZN1XIiEC1Ev
// CHECK: define linkonce_odr void @_ZN1XIiEC2Ev