@@ -17879,6 +17879,8 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D,
17879
17879
LookupResult Previous(*this, NameInfo, LookupOrdinaryName,
17880
17880
ForExternalRedeclaration);
17881
17881
17882
+ bool isTemplateId = D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId;
17883
+
17882
17884
// There are five cases here.
17883
17885
// - There's no scope specifier and we're in a local class. Only look
17884
17886
// for functions declared in the immediately-enclosing block scope.
@@ -17916,14 +17918,6 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D,
17916
17918
}
17917
17919
adjustContextForLocalExternDecl(DC);
17918
17920
17919
- // C++ [class.friend]p6:
17920
- // A function can be defined in a friend declaration of a class if and
17921
- // only if the class is a non-local class (9.8), the function name is
17922
- // unqualified, and the function has namespace scope.
17923
- if (D.isFunctionDefinition()) {
17924
- Diag(NameInfo.getBeginLoc(), diag::err_friend_def_in_local_class);
17925
- }
17926
-
17927
17921
// - There's no scope specifier, in which case we just go to the
17928
17922
// appropriate scope and look for a function or function template
17929
17923
// there as appropriate.
@@ -17934,8 +17928,6 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D,
17934
17928
// elaborated-type-specifier, the lookup to determine whether
17935
17929
// the entity has been previously declared shall not consider
17936
17930
// any scopes outside the innermost enclosing namespace.
17937
- bool isTemplateId =
17938
- D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId;
17939
17931
17940
17932
// Find the appropriate context according to the above.
17941
17933
DC = CurContext;
@@ -17988,39 +17980,12 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D,
17988
17980
diag::warn_cxx98_compat_friend_is_member :
17989
17981
diag::err_friend_is_member);
17990
17982
17991
- if (D.isFunctionDefinition()) {
17992
- // C++ [class.friend]p6:
17993
- // A function can be defined in a friend declaration of a class if and
17994
- // only if the class is a non-local class (9.8), the function name is
17995
- // unqualified, and the function has namespace scope.
17996
- //
17997
- // FIXME: We should only do this if the scope specifier names the
17998
- // innermost enclosing namespace; otherwise the fixit changes the
17999
- // meaning of the code.
18000
- SemaDiagnosticBuilder DB
18001
- = Diag(SS.getRange().getBegin(), diag::err_qualified_friend_def);
18002
-
18003
- DB << SS.getScopeRep();
18004
- if (DC->isFileContext())
18005
- DB << FixItHint::CreateRemoval(SS.getRange());
18006
- SS.clear();
18007
- }
18008
-
18009
17983
// - There's a scope specifier that does not match any template
18010
17984
// parameter lists, in which case we use some arbitrary context,
18011
17985
// create a method or method template, and wait for instantiation.
18012
17986
// - There's a scope specifier that does match some template
18013
17987
// parameter lists, which we don't handle right now.
18014
17988
} else {
18015
- if (D.isFunctionDefinition()) {
18016
- // C++ [class.friend]p6:
18017
- // A function can be defined in a friend declaration of a class if and
18018
- // only if the class is a non-local class (9.8), the function name is
18019
- // unqualified, and the function has namespace scope.
18020
- Diag(SS.getRange().getBegin(), diag::err_qualified_friend_def)
18021
- << SS.getScopeRep();
18022
- }
18023
-
18024
17989
DC = CurContext;
18025
17990
assert(isa<CXXRecordDecl>(DC) && "friend declaration not in class?");
18026
17991
}
@@ -18105,6 +18070,38 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D,
18105
18070
else
18106
18071
FD = cast<FunctionDecl>(ND);
18107
18072
18073
+ // C++ [class.friend]p6:
18074
+ // A function may be defined in a friend declaration of a class if and
18075
+ // only if the class is a non-local class, and the function name is
18076
+ // unqualified.
18077
+ if (D.isFunctionDefinition()) {
18078
+ // Qualified friend function definition.
18079
+ if (SS.isNotEmpty()) {
18080
+ // FIXME: We should only do this if the scope specifier names the
18081
+ // innermost enclosing namespace; otherwise the fixit changes the
18082
+ // meaning of the code.
18083
+ SemaDiagnosticBuilder DB =
18084
+ Diag(SS.getRange().getBegin(), diag::err_qualified_friend_def);
18085
+
18086
+ DB << SS.getScopeRep();
18087
+ if (DC->isFileContext())
18088
+ DB << FixItHint::CreateRemoval(SS.getRange());
18089
+
18090
+ // Friend function defined in a local class.
18091
+ } else if (FunctionContainingLocalClass) {
18092
+ Diag(NameInfo.getBeginLoc(), diag::err_friend_def_in_local_class);
18093
+
18094
+ // Per [basic.pre]p4, a template-id is not a name. Therefore, if we have
18095
+ // a template-id, the function name is not unqualified because these is
18096
+ // no name. While the wording requires some reading in-between the
18097
+ // lines, GCC, MSVC, and EDG all consider a friend function
18098
+ // specialization definitions // to be de facto explicit specialization
18099
+ // and diagnose them as such.
18100
+ } else if (isTemplateId) {
18101
+ Diag(NameInfo.getBeginLoc(), diag::err_friend_specialization_def);
18102
+ }
18103
+ }
18104
+
18108
18105
// C++11 [dcl.fct.default]p4: If a friend declaration specifies a
18109
18106
// default argument expression, that declaration shall be a definition
18110
18107
// and shall be the only declaration of the function or function
0 commit comments