that has been explicitly specialized!
We assume in various places that we can tell the template specialization kind
of a class type by looking at the declaration produced by TagType::getDecl.
That was previously not quite true: for an explicit specialization, we could
have first seen a template-id denoting the specialization (with a use that does
not trigger an implicit instantiation of the defintiion) and then seen the
first explicit specialization declaration. TagType::getDecl would previously
return an arbitrary declaration when called on a not-yet-defined class; it
now consistently returns the most recent declaration in that case.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@295118
91177308-0d34-0410-b5e6-
96231b3b80d8
if (I->isCompleteDefinition() || I->isBeingDefined())
return I;
}
- // If there's no definition (not even in progress), return what we have.
- return decl;
+ // If there's no definition (not even in progress), return the most recent
+ // declaration. This is important for template specializations, in order to
+ // pick the declaration with the most complete TemplateSpecializationKind.
+ return decl->getMostRecentDecl();
}
TagDecl *TagType::getDecl() const {
template<typename T> void Helper<T>::func<2>() {} // expected-error {{cannot specialize a member}} \
// expected-error {{no function template matches}}
}
+
+namespace b35070233 {
+ template <typename T> struct Cls {
+ static void f() {}
+ };
+
+ void g(Cls<int>);
+
+ template<> struct Cls<int>; // expected-note {{forward declaration}}
+ template<> void Cls<int>::f(); // expected-error {{incomplete type}}
+}