aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-04-13 06:39:49 +0000
committerJohn McCall <rjmccall@apple.com>2010-04-13 06:39:49 +0000
commitba9d853bec0d9cc10ac5fdeab807cc4b13d65791 (patch)
tree2cfa02cf60c8e323afaf8022c24c5ad3dda6dca3 /lib
parentb21b1c94285b174772a754f96a4fd70cb641846a (diff)
Parse constructor names in friend declarations. Part of the fix for
PR6207. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101119 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Parse/ParseDecl.cpp24
-rw-r--r--lib/Sema/SemaDecl.cpp9
2 files changed, 24 insertions, 9 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index da4a002844..09ae231c5e 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -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,
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 171bee66ca..005311f075 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -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);