Parse constructor names in friend declarations. Part of the fix for

PR6207.

llvm-svn: 101119
This commit is contained in:
John McCall 2010-04-13 06:39:49 +00:00
parent 069711865f
commit 84821e7143
2 changed files with 24 additions and 9 deletions

View File

@ -904,7 +904,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// reinforced by the NAD status of core issue 635.
TemplateIdAnnotation *TemplateId
= static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue());
if (DSContext == DSC_top_level && TemplateId->Name &&
if ((DSContext == DSC_top_level ||
(DSContext == DSC_class && DS.isFriendSpecified())) &&
TemplateId->Name &&
Actions.isCurrentClassName(*TemplateId->Name, CurScope, &SS)) {
if (isConstructorDeclarator()) {
// The user meant this to be an out-of-line constructor
@ -949,7 +951,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// If we're in a context where the identifier could be a class name,
// check whether this is a constructor declaration.
if (DSContext == DSC_top_level &&
if ((DSContext == DSC_top_level ||
(DSContext == DSC_class && DS.isFriendSpecified())) &&
Actions.isCurrentClassName(*Next.getIdentifierInfo(), CurScope,
&SS)) {
if (isConstructorDeclarator())
@ -2599,12 +2602,17 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
Tok.is(tok::annot_template_id) || Tok.is(tok::tilde)) {
// We found something that indicates the start of an unqualified-id.
// Parse that unqualified-id.
bool AllowConstructorName
= ((D.getCXXScopeSpec().isSet() &&
D.getContext() == Declarator::FileContext) ||
(!D.getCXXScopeSpec().isSet() &&
D.getContext() == Declarator::MemberContext)) &&
!D.getDeclSpec().hasTypeSpecifier();
bool AllowConstructorName;
if (D.getDeclSpec().hasTypeSpecifier())
AllowConstructorName = false;
else if (D.getCXXScopeSpec().isSet())
AllowConstructorName =
(D.getContext() == Declarator::FileContext ||
(D.getContext() == Declarator::MemberContext &&
D.getDeclSpec().isFriendSpecified()));
else
AllowConstructorName = (D.getContext() == Declarator::MemberContext);
if (ParseUnqualifiedId(D.getCXXScopeSpec(),
/*EnteringContext=*/true,
/*AllowDestructorName=*/true,

View File

@ -3188,6 +3188,10 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
if (CheckMemberSpecialization(NewFD, Previous))
NewFD->setInvalidDecl();
}
// Make sure this is set before checking the function declaration.
// We'll override the visibility type later.
if (isFriend) NewFD->setObjectOfFriendDecl(false);
// Perform semantic checking on the function declaration.
bool OverloadableAttrRequired = false; // FIXME: HACK!
@ -3199,7 +3203,10 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
"previous declaration set still overloaded");
if (isFriend && Redeclaration) {
AccessSpecifier Access = NewFD->getPreviousDeclaration()->getAccess();
AccessSpecifier Access = AS_public;
if (!NewFD->isInvalidDecl())
Access = NewFD->getPreviousDeclaration()->getAccess();
if (FunctionTemplate) {
FunctionTemplate->setObjectOfFriendDecl(true);
FunctionTemplate->setAccess(Access);