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);