forked from OSchip/llvm-project
Parse constructor names in friend declarations. Part of the fix for
PR6207. llvm-svn: 101119
This commit is contained in:
parent
069711865f
commit
84821e7143
clang/lib
|
@ -904,7 +904,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
||||||
// reinforced by the NAD status of core issue 635.
|
// reinforced by the NAD status of core issue 635.
|
||||||
TemplateIdAnnotation *TemplateId
|
TemplateIdAnnotation *TemplateId
|
||||||
= static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue());
|
= 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)) {
|
Actions.isCurrentClassName(*TemplateId->Name, CurScope, &SS)) {
|
||||||
if (isConstructorDeclarator()) {
|
if (isConstructorDeclarator()) {
|
||||||
// The user meant this to be an out-of-line constructor
|
// 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,
|
// If we're in a context where the identifier could be a class name,
|
||||||
// check whether this is a constructor declaration.
|
// 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,
|
Actions.isCurrentClassName(*Next.getIdentifierInfo(), CurScope,
|
||||||
&SS)) {
|
&SS)) {
|
||||||
if (isConstructorDeclarator())
|
if (isConstructorDeclarator())
|
||||||
|
@ -2599,12 +2602,17 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
|
||||||
Tok.is(tok::annot_template_id) || Tok.is(tok::tilde)) {
|
Tok.is(tok::annot_template_id) || Tok.is(tok::tilde)) {
|
||||||
// We found something that indicates the start of an unqualified-id.
|
// We found something that indicates the start of an unqualified-id.
|
||||||
// Parse that unqualified-id.
|
// Parse that unqualified-id.
|
||||||
bool AllowConstructorName
|
bool AllowConstructorName;
|
||||||
= ((D.getCXXScopeSpec().isSet() &&
|
if (D.getDeclSpec().hasTypeSpecifier())
|
||||||
D.getContext() == Declarator::FileContext) ||
|
AllowConstructorName = false;
|
||||||
(!D.getCXXScopeSpec().isSet() &&
|
else if (D.getCXXScopeSpec().isSet())
|
||||||
D.getContext() == Declarator::MemberContext)) &&
|
AllowConstructorName =
|
||||||
!D.getDeclSpec().hasTypeSpecifier();
|
(D.getContext() == Declarator::FileContext ||
|
||||||
|
(D.getContext() == Declarator::MemberContext &&
|
||||||
|
D.getDeclSpec().isFriendSpecified()));
|
||||||
|
else
|
||||||
|
AllowConstructorName = (D.getContext() == Declarator::MemberContext);
|
||||||
|
|
||||||
if (ParseUnqualifiedId(D.getCXXScopeSpec(),
|
if (ParseUnqualifiedId(D.getCXXScopeSpec(),
|
||||||
/*EnteringContext=*/true,
|
/*EnteringContext=*/true,
|
||||||
/*AllowDestructorName=*/true,
|
/*AllowDestructorName=*/true,
|
||||||
|
|
|
@ -3188,6 +3188,10 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||||
if (CheckMemberSpecialization(NewFD, Previous))
|
if (CheckMemberSpecialization(NewFD, Previous))
|
||||||
NewFD->setInvalidDecl();
|
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.
|
// Perform semantic checking on the function declaration.
|
||||||
bool OverloadableAttrRequired = false; // FIXME: HACK!
|
bool OverloadableAttrRequired = false; // FIXME: HACK!
|
||||||
|
@ -3199,7 +3203,10 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||||
"previous declaration set still overloaded");
|
"previous declaration set still overloaded");
|
||||||
|
|
||||||
if (isFriend && Redeclaration) {
|
if (isFriend && Redeclaration) {
|
||||||
AccessSpecifier Access = NewFD->getPreviousDeclaration()->getAccess();
|
AccessSpecifier Access = AS_public;
|
||||||
|
if (!NewFD->isInvalidDecl())
|
||||||
|
Access = NewFD->getPreviousDeclaration()->getAccess();
|
||||||
|
|
||||||
if (FunctionTemplate) {
|
if (FunctionTemplate) {
|
||||||
FunctionTemplate->setObjectOfFriendDecl(true);
|
FunctionTemplate->setObjectOfFriendDecl(true);
|
||||||
FunctionTemplate->setAccess(Access);
|
FunctionTemplate->setAccess(Access);
|
||||||
|
|
Loading…
Reference in New Issue