@@ -3153,6 +3153,20 @@ void Sema::AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD) {
3153
3153
}
3154
3154
}
3155
3155
3156
+ static void DiagnoseInvalidRedeclaration (Sema &S, FunctionDecl *NewFD) {
3157
+ LookupResult Prev (S, NewFD->getDeclName (), NewFD->getLocation (),
3158
+ Sema::LookupOrdinaryName, Sema::ForRedeclaration);
3159
+ S.LookupQualifiedName (Prev, NewFD->getDeclContext ());
3160
+ assert (!Prev.isAmbiguous () &&
3161
+ " Cannot have an ambiguity in previous-declaration lookup" );
3162
+ for (LookupResult::iterator Func = Prev.begin (), FuncEnd = Prev.end ();
3163
+ Func != FuncEnd; ++Func) {
3164
+ if (isa<FunctionDecl>(*Func) &&
3165
+ isNearlyMatchingFunction (S.Context , cast<FunctionDecl>(*Func), NewFD))
3166
+ S.Diag ((*Func)->getLocation (), diag::note_member_def_close_match);
3167
+ }
3168
+ }
3169
+
3156
3170
NamedDecl*
3157
3171
Sema::ActOnFunctionDeclarator (Scope* S, Declarator& D, DeclContext* DC,
3158
3172
QualType R, TypeSourceInfo *TInfo,
@@ -3470,13 +3484,6 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
3470
3484
FilterLookupForScope (*this , Previous, DC, S, NewFD->hasLinkage ());
3471
3485
3472
3486
if (isFriend) {
3473
- // DC is the namespace in which the function is being declared.
3474
- assert ((DC->isFileContext () || !Previous.empty () ||
3475
- (D.getCXXScopeSpec ().isSet () &&
3476
- D.getCXXScopeSpec ().getScopeRep ()->isDependent ())) &&
3477
- " previously-undeclared friend function being created "
3478
- " in a non-namespace context" );
3479
-
3480
3487
// For now, claim that the objects have no previous declaration.
3481
3488
if (FunctionTemplate) {
3482
3489
FunctionTemplate->setObjectOfFriendDecl (false );
@@ -3675,24 +3682,36 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
3675
3682
: TPC_FunctionTemplate);
3676
3683
}
3677
3684
3678
- if (D.getCXXScopeSpec ().isSet () && !NewFD->isInvalidDecl ()) {
3679
- if (isFriend || !CurContext->isRecord ()) {
3680
- // Fake up an access specifier if it's supposed to be a class member.
3681
- if (!Redeclaration && isa<CXXRecordDecl>(NewFD->getDeclContext ()))
3682
- NewFD->setAccess (AS_public);
3683
-
3684
- // An out-of-line member function declaration must also be a
3685
- // definition (C++ [dcl.meaning]p1).
3686
- // Note that this is not the case for explicit specializations of
3687
- // function templates or member functions of class templates, per
3688
- // C++ [temp.expl.spec]p2. We also allow these declarations as an extension
3689
- // for compatibility with old SWIG code which likes to generate them.
3690
- if (!IsFunctionDefinition && !isFriend &&
3691
- !isFunctionTemplateSpecialization && !isExplicitSpecialization) {
3692
- Diag (NewFD->getLocation (), diag::ext_out_of_line_declaration)
3693
- << D.getCXXScopeSpec ().getRange ();
3694
- }
3695
- if (!Redeclaration && !(isFriend && CurContext->isDependentContext ())) {
3685
+ if (NewFD->isInvalidDecl ()) {
3686
+ // Ignore all the rest of this.
3687
+
3688
+ } else if (CurContext->isRecord () && D.getCXXScopeSpec ().isSet () &&
3689
+ !isFriend) {
3690
+ // The user provided a superfluous scope specifier inside a class
3691
+ // definition:
3692
+ //
3693
+ // class X {
3694
+ // void X::f();
3695
+ // };
3696
+ Diag (NewFD->getLocation (), diag::warn_member_extra_qualification)
3697
+ << Name << FixItHint::CreateRemoval (D.getCXXScopeSpec ().getRange ());
3698
+
3699
+ } else if (!Redeclaration) {
3700
+ // Fake up an access specifier if it's supposed to be a class member.
3701
+ if (isa<CXXRecordDecl>(NewFD->getDeclContext ()))
3702
+ NewFD->setAccess (AS_public);
3703
+
3704
+ // Qualified decls generally require a previous declaration.
3705
+ if (D.getCXXScopeSpec ().isSet ()) {
3706
+ // ...with the major exception of dependent friend declarations.
3707
+ // In theory, this condition could be whether the qualifier
3708
+ // is dependent; in practice, the way we nest template parameters
3709
+ // prevents this sort of matching from working, so we have to base it
3710
+ // on the general dependence of the context.
3711
+ if (isFriend && CurContext->isDependentContext ()) {
3712
+ // ignore these
3713
+
3714
+ } else {
3696
3715
// The user tried to provide an out-of-line definition for a
3697
3716
// function that is a member of a class or namespace, but there
3698
3717
// was no such member function declared (C++ [class.mfct]p2,
@@ -3711,27 +3730,28 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
3711
3730
<< Name << DC << D.getCXXScopeSpec ().getRange ();
3712
3731
NewFD->setInvalidDecl ();
3713
3732
3714
- LookupResult Prev (*this , Name, D.getIdentifierLoc (), LookupOrdinaryName,
3715
- ForRedeclaration);
3716
- LookupQualifiedName (Prev, DC);
3717
- assert (!Prev.isAmbiguous () &&
3718
- " Cannot have an ambiguity in previous-declaration lookup" );
3719
- for (LookupResult::iterator Func = Prev.begin (), FuncEnd = Prev.end ();
3720
- Func != FuncEnd; ++Func) {
3721
- if (isa<FunctionDecl>(*Func) &&
3722
- isNearlyMatchingFunction (Context, cast<FunctionDecl>(*Func), NewFD))
3723
- Diag ((*Func)->getLocation (), diag::note_member_def_close_match);
3724
- }
3733
+ DiagnoseInvalidRedeclaration (*this , NewFD);
3725
3734
}
3726
- } else {
3727
- // The user provided a superfluous scope specifier inside a class definition:
3728
- //
3729
- // class X {
3730
- // void X::f();
3731
- // };
3732
- Diag (NewFD->getLocation (), diag::warn_member_extra_qualification)
3733
- << Name << FixItHint::CreateRemoval (D.getCXXScopeSpec ().getRange ());
3734
- }
3735
+
3736
+ // Unqualified local friend declarations are required to resolve
3737
+ // to something.
3738
+ } else if (isFriend && cast<CXXRecordDecl>(CurContext)->isLocalClass ()) {
3739
+ Diag (D.getIdentifierLoc (), diag::err_no_matching_local_friend);
3740
+ NewFD->setInvalidDecl ();
3741
+ DiagnoseInvalidRedeclaration (*this , NewFD);
3742
+ }
3743
+
3744
+ } else if (!IsFunctionDefinition && D.getCXXScopeSpec ().isSet () &&
3745
+ !isFriend && !isFunctionTemplateSpecialization &&
3746
+ !isExplicitSpecialization) {
3747
+ // An out-of-line member function declaration must also be a
3748
+ // definition (C++ [dcl.meaning]p1).
3749
+ // Note that this is not the case for explicit specializations of
3750
+ // function templates or member functions of class templates, per
3751
+ // C++ [temp.expl.spec]p2. We also allow these declarations as an extension
3752
+ // for compatibility with old SWIG code which likes to generate them.
3753
+ Diag (NewFD->getLocation (), diag::ext_out_of_line_declaration)
3754
+ << D.getCXXScopeSpec ().getRange ();
3735
3755
}
3736
3756
3737
3757
// Handle attributes. We need to have merged decls when handling attributes
0 commit comments