diff options
author | John McCall <rjmccall@apple.com> | 2010-04-14 00:24:33 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-04-14 00:24:33 +0000 |
commit | 74256f5ea6950c9fd34595aa124eb4740372f15c (patch) | |
tree | 9452ff202125013bb51edb28d0cd83a644c40043 | |
parent | aa1d76163e4b0b1cc54e222be67379f8c02e8ffa (diff) |
Parse friend template ids as types instead of ending up in
ActOnClassTemplateSpecialization and being very confused.
Fixes PR6514 (for non-templated-scope friends).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101198 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 12 | ||||
-rw-r--r-- | test/CXX/temp/temp.decls/temp.friend/p1.cpp | 17 |
2 files changed, 25 insertions, 4 deletions
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index c6df57193b..60aee6abd1 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -780,9 +780,6 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, Action::DeclResult TagOrTempResult = true; // invalid Action::TypeResult TypeResult = true; // invalid - // FIXME: When TUK == TUK_Reference and we have a template-id, we need - // to turn that template-id into a type. - bool Owned = false; if (TemplateId) { // Explicit specialization, class template partial specialization, @@ -806,7 +803,14 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, TemplateArgsPtr, TemplateId->RAngleLoc, AttrList); - } else if (TUK == Action::TUK_Reference) { + + // Friend template-ids are treated as references unless + // they have template headers, in which case they're ill-formed + // (FIXME: "template <class T> friend class A<T>::B<int>;"). + // We diagnose this error in ActOnClassTemplateSpecialization. + } else if (TUK == Action::TUK_Reference || + (TUK == Action::TUK_Friend && + TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) { TypeResult = Actions.ActOnTemplateIdType(TemplateTy::make(TemplateId->Template), TemplateId->TemplateNameLoc, diff --git a/test/CXX/temp/temp.decls/temp.friend/p1.cpp b/test/CXX/temp/temp.decls/temp.friend/p1.cpp index 41cf3632b1..7604a23edb 100644 --- a/test/CXX/temp/temp.decls/temp.friend/p1.cpp +++ b/test/CXX/temp/temp.decls/temp.friend/p1.cpp @@ -276,3 +276,20 @@ namespace test12 { return Foo<long>(t, true); } } + +// PR6514 +namespace test13 { + template <int N, template <int> class Temp> + class Role : public Temp<N> { + friend class Temp<N>; + int x; + }; + + template <int N> class Foo { + void foo(Role<N, test13::Foo> &role) { + (void) role.x; + } + }; + + template class Foo<0>; +} |