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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131920 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Sean Hunt 2011-05-23 21:07:59 +00:00
Родитель c8b3e6302f
Коммит eb88ae5f9a
3 изменённых файлов: 29 добавлений и 2 удалений

Просмотреть файл

@ -2997,7 +2997,8 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {
// have inherited constructors.
DeclareInheritedConstructors(Record);
CheckExplicitlyDefaultedMethods(Record);
if (!Record->isDependentType())
CheckExplicitlyDefaultedMethods(Record);
}
void Sema::CheckExplicitlyDefaultedMethods(CXXRecordDecl *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);

Просмотреть файл

@ -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;
}
@ -1496,7 +1497,14 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
else
Owner->addDecl(DeclToAdd);
}
if (D->isExplicitlyDefaulted()) {
SemaRef.SetDeclDefaulted(Method, Method->getLocation());
} else {
assert(!D->isDefaulted() &&
"should not implicitly default uninstantiated function");
}
return Method;
}

Просмотреть файл

@ -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