From c5dc285ca547924f02910e4fee5290bffbed3a14 Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Tue, 14 Mar 2017 20:25:23 -0700 Subject: [PATCH] Bug 513681 - Unresolved name with a friend declaration in a namespace Change-Id: I778886f802576a9b8d7804eb32abfe091bf0568d --- .../parser/tests/ast2/AST2TemplateTests.java | 20 +++++++++++ .../index/tests/IndexMultiFileTest.java | 33 +++++++++++++++++++ .../parser/cpp/semantics/CPPTemplates.java | 13 ++++++-- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index 6e32e8aa394..4c4ac69fa2a 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -10160,4 +10160,24 @@ public class AST2TemplateTests extends AST2TestBase { public void testNoexceptSpecifierInTypeTemplateArgument_511186() throws Exception { parseAndCheckBindings(); } + + // namespace ns { + // + // template + // class A { + // friend void waldo(A flag); + // }; + // + // void waldo(A flag); + // + // } + // + // ns::A a; + // + // void func() { + // waldo(a); + // } + public void testFriendFunctionDeclarationInNamespace_513681() throws Exception { + parseAndCheckBindings(); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexMultiFileTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexMultiFileTest.java index e05c33ed74e..0e9481bebb0 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexMultiFileTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexMultiFileTest.java @@ -268,4 +268,37 @@ public class IndexMultiFileTest extends IndexBindingResolutionTestBase { // This code is invalid, so we don't checkBindings(). // If the test gets this far (doesn't throw in setup() during indexing), it passes. } + + // test.h + // namespace ns { + // + // template + // class A { + // friend void waldo(A p); + // }; + // + // void waldo(A p); + // + // } + + // test.cpp * + // #include "test.h" + // + // ns::A b; + // + // void test() { + // ns::waldo(b); + // } + + // z.cpp + // #include "test.h" + // + // ns::A a; + // + // void func() { + // waldo(a); + // } + public void testFriendFunctionDeclarationInNamespace_513681() throws Exception { + checkBindings(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 7d35f33ce15..3bf437daac2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -1105,14 +1105,21 @@ public class CPPTemplates { } else if (decl instanceof ICPPMethod && classOwner != null) { functionSpec = new CPPMethodSpecialization((ICPPMethod) decl, classOwner, tpMap, type, exceptionSpecs); } else if (decl instanceof ICPPFunction) { - IBinding oldOwner = decl.getOwner(); - functionSpec = new CPPFunctionSpecialization((ICPPFunction) decl, oldOwner, tpMap, type, exceptionSpecs); + if (type.isSameType(func.getType())) { + // There is no need to create a CPPFunctionSpecialization object since the function is + // a friend function with the type that is not affected by the specialization. + // See http://bugs.eclipse.org/513681 + spec = func; + } else { + IBinding oldOwner = decl.getOwner(); + functionSpec = new CPPFunctionSpecialization(func, oldOwner, tpMap, type, exceptionSpecs); + } } if (functionSpec != null) { functionSpec.setParameters(specializeParameters(func.getParameters(), functionSpec, context, IntegralValue.MAX_RECURSION_DEPTH)); + spec = functionSpec; } - spec = functionSpec; } else if (decl instanceof ITypedef) { InstantiationContext context = createInstantiationContext(tpMap, owner, point); IType type= instantiateType(((ITypedef) decl).getType(), context);