forked from OSchip/llvm-project
If a partial specialization of a member template is declared within a class
template and defined outside it, don't instantiate it twice when instantiating the surrounding class template specialization. That would cause us to reject the code because we think two partial specializations instantiated to produce the same signature. llvm-svn: 191418
This commit is contained in:
parent
fde9485297
commit
10b55fc85e
|
@ -2142,13 +2142,25 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
|
|||
|
||||
// Instantiate any out-of-line class template partial
|
||||
// specializations now.
|
||||
for (TemplateDeclInstantiator::delayed_partial_spec_iterator
|
||||
for (TemplateDeclInstantiator::delayed_partial_spec_iterator
|
||||
P = Instantiator.delayed_partial_spec_begin(),
|
||||
PEnd = Instantiator.delayed_partial_spec_end();
|
||||
P != PEnd; ++P) {
|
||||
if (!Instantiator.InstantiateClassTemplatePartialSpecialization(
|
||||
P->first,
|
||||
P->second)) {
|
||||
P->first, P->second)) {
|
||||
Instantiation->setInvalidDecl();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Instantiate any out-of-line variable template partial
|
||||
// specializations now.
|
||||
for (TemplateDeclInstantiator::delayed_var_partial_spec_iterator
|
||||
P = Instantiator.delayed_var_partial_spec_begin(),
|
||||
PEnd = Instantiator.delayed_var_partial_spec_end();
|
||||
P != PEnd; ++P) {
|
||||
if (!Instantiator.InstantiateVarTemplatePartialSpecialization(
|
||||
P->first, P->second)) {
|
||||
Instantiation->setInvalidDecl();
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -923,7 +923,7 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
|
|||
SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
|
||||
D->getPartialSpecializations(PartialSpecs);
|
||||
for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I)
|
||||
if (PartialSpecs[I]->isOutOfLine())
|
||||
if (PartialSpecs[I]->getFirstDeclaration()->isOutOfLine())
|
||||
OutOfLinePartialSpecs.push_back(std::make_pair(Inst, PartialSpecs[I]));
|
||||
}
|
||||
|
||||
|
@ -1004,7 +1004,7 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateDecl(VarTemplateDecl *D) {
|
|||
SmallVector<VarTemplatePartialSpecializationDecl *, 4> PartialSpecs;
|
||||
D->getPartialSpecializations(PartialSpecs);
|
||||
for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I)
|
||||
if (PartialSpecs[I]->isOutOfLine())
|
||||
if (PartialSpecs[I]->getFirstDeclaration()->isOutOfLine())
|
||||
OutOfLineVarPartialSpecs.push_back(
|
||||
std::make_pair(Inst, PartialSpecs[I]));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
// RUN: %clang_cc1 -std=c++1y -verify %s
|
||||
// expected-no-diagnostics
|
||||
|
||||
template<typename T> struct A {
|
||||
template<typename U> struct B;
|
||||
template<typename U> struct B<U*>;
|
||||
};
|
||||
template<typename T> template<typename U> struct A<T>::B<U*> {};
|
||||
template struct A<int>;
|
||||
A<int>::B<int*> b;
|
||||
|
||||
|
||||
template<typename T> struct B {
|
||||
template<typename U> static const int var1;
|
||||
template<typename U> static const int var1<U*>;
|
||||
|
||||
template<typename U> static const int var2;
|
||||
};
|
||||
template<typename T> template<typename U> const int B<T>::var1<U*> = 1;
|
||||
template<typename T> template<typename U> const int B<T>::var2<U*> = 1;
|
||||
template struct B<int>;
|
||||
int b_test1[B<int>::var1<int*>];
|
||||
int b_test2[B<int>::var2<int*>];
|
Loading…
Reference in New Issue