diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index d18b9d3c4352..b5fb85856c81 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -11131,29 +11131,39 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D, // Find the appropriate context according to the above. DC = CurContext; - while (true) { - // Skip class contexts. If someone can cite chapter and verse - // for this behavior, that would be nice --- it's what GCC and - // EDG do, and it seems like a reasonable intent, but the spec - // really only says that checks for unqualified existing - // declarations should stop at the nearest enclosing namespace, - // not that they should only consider the nearest enclosing - // namespace. - while (DC->isRecord() || DC->isTransparentContext()) - DC = DC->getParent(); - LookupQualifiedName(Previous, DC); + // Skip class contexts. If someone can cite chapter and verse + // for this behavior, that would be nice --- it's what GCC and + // EDG do, and it seems like a reasonable intent, but the spec + // really only says that checks for unqualified existing + // declarations should stop at the nearest enclosing namespace, + // not that they should only consider the nearest enclosing + // namespace. + while (DC->isRecord()) + DC = DC->getParent(); + + DeclContext *LookupDC = DC; + while (LookupDC->isTransparentContext()) + LookupDC = LookupDC->getParent(); + + while (true) { + LookupQualifiedName(Previous, LookupDC); // TODO: decide what we think about using declarations. - if (isLocal || !Previous.empty()) + if (isLocal) break; - if (isTemplateId) { - if (isa(DC)) break; - } else { - if (DC->isFileContext()) break; + if (!Previous.empty()) { + DC = LookupDC; + break; } - DC = DC->getParent(); + + if (isTemplateId) { + if (isa(LookupDC)) break; + } else { + if (LookupDC->isFileContext()) break; + } + LookupDC = LookupDC->getParent(); } DCScope = getScopeForDeclContext(S, DC); diff --git a/clang/test/SemaCXX/linkage2.cpp b/clang/test/SemaCXX/linkage2.cpp index ddf4064215d7..3cfa98138bab 100644 --- a/clang/test/SemaCXX/linkage2.cpp +++ b/clang/test/SemaCXX/linkage2.cpp @@ -152,3 +152,15 @@ namespace test15 { const int a = 5; // expected-note {{previous definition is here}} static const int a; // expected-error {{redefinition of 'a'}} } + +namespace test16 { + extern "C" { + class Foo { + int x; + friend int bar(Foo *y); + }; + int bar(Foo *y) { + return y->x; + } + } +}