diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-10-13 16:30:37 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-10-13 16:30:37 +0000 |
commit | fd056bc86a8b22a9421b5d921bbca276d0f9d0f7 (patch) | |
tree | e70aa9a7122aa2803f39ddd507f7c02bc1f87594 /lib/Sema/SemaTemplate.cpp | |
parent | a735b206fdb5c15767a45289e1ffb3b568f70f2b (diff) |
When explicitly specializing a member that is a template, mark the
template as a specialization. For example, this occurs with:
template<typename T>
struct X {
template<typename U> struct Inner { /* ... */ };
};
template<> template<typename T>
struct X<int>::Inner {
T member;
};
We need to treat templates that are member specializations as special
in two contexts:
- When looking for a definition of a member template, we look
through the instantiation chain until we hit the primary template
*or a member specialization*. This allows us to distinguish
between the primary "Inner" definition and the X<int>::Inner
definition, above.
- When computing all of the levels of template arguments needed to
instantiate a member template, don't add template arguments
from contexts outside of the instantiation of a member
specialization, since the user has already manually substituted
those arguments.
Fix up the existing test for p18, which was actually wrong (but we
didn't diagnose it because of our poor handling of member
specializations of templates), and add a new test for member
specializations of templates.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83974 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 7412049857..3ee15a5b4d 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -716,6 +716,12 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, assert(T->isDependentType() && "Class template type is not dependent?"); (void)T; + // If we are providing an explicit specialization of a member that is a + // class template, make a note of that. + if (PrevClassTemplate && + PrevClassTemplate->getInstantiatedFromMemberTemplate()) + PrevClassTemplate->setMemberSpecialization(); + // Set the access specifier. if (!Invalid && TUK != TUK_Friend) SetMemberAccessSpecifier(NewTemplate, PrevClassTemplate, AS); |