Parse friend template ids as types instead of ending up in

ActOnClassTemplateSpecialization and being very confused.
Fixes PR6514 (for non-templated-scope friends).

llvm-svn: 101198
This commit is contained in:
John McCall 2010-04-14 00:24:33 +00:00
parent 9ffd706bd4
commit b7c5c278bf
2 changed files with 25 additions and 4 deletions

View File

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

View File

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