From ae87b6d4403ea861df8dd698de6e07ac8b8fbbbb Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Thu, 7 Oct 2010 12:14:53 +0000 Subject: [PATCH] Bug 327069: ADL for class specializations. --- .../parser/tests/ast2/AST2TemplateTests.java | 13 ++++ .../parser/cpp/semantics/CPPSemantics.java | 74 +++++++++++-------- 2 files changed, 58 insertions(+), 29 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 db21d0cffab..9d97853113d 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 @@ -5100,4 +5100,17 @@ public class AST2TemplateTests extends AST2BaseTest { g= bh.assertNonProblem("g, 1)", 1); assertSame(g1, g); } + + // template class Ptr{}; + // namespace ns { + // class T {}; + // void f(Ptr); + // } + // void test() { + // Ptr parm; + // f(parm); + // } + public void testADLForTemplateSpecializations_Bug327069() throws Exception { + parseAndCheckBindings(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index 7f35c1daf29..3a4f51e4386 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -652,53 +652,69 @@ public class CPPSemantics { IType[] ps = data.getFunctionArgumentTypes(); Set namespaces = new HashSet(2); - ObjectSet classes = new ObjectSet(2); + ObjectSet handled = new ObjectSet(2); for (IType p : ps) { - p = getUltimateType(p, true); try { - getAssociatedScopes(p, namespaces, classes, data.tu); + getAssociatedScopes(p, namespaces, handled, data.tu); } catch (DOMException e) { } } return namespaces; } + // 3.4.2-2 private static void getAssociatedScopes(IType t, Set namespaces, - ObjectSet classes, CPPASTTranslationUnit tu) throws DOMException { - // 3.4.2-2 - if (t instanceof ICPPClassType) { + ObjectSet handled, CPPASTTranslationUnit tu) throws DOMException { + t = getNestedType(t, TDEF | CVTYPE | PTR | ARRAY | REF); + if (t instanceof IBinding) { + if (handled.containsKey(t)) + return; + handled.put(t); + + IBinding owner= ((IBinding) t).getOwner(); + if (owner instanceof ICPPClassType) { + getAssociatedScopes((IType) owner, namespaces, handled, tu); + } else { + getAssociatedNamespaceScopes(getContainingNamespaceScope((IBinding) t, tu), namespaces); + } + } + if (t instanceof ICPPClassType && !(t instanceof ICPPClassTemplate)) { ICPPClassType ct= (ICPPClassType) t; - if (!classes.containsKey(ct)) { - classes.put(ct); - getAssociatedNamespaceScopes(getContainingNamespaceScope((IBinding) t, tu), namespaces); - - ICPPClassType cls = (ICPPClassType) t; - ICPPBase[] bases = cls.getBases(); - for (ICPPBase base : bases) { - if (base instanceof IProblemBinding) - continue; - IBinding b = base.getBaseClass(); - if (b instanceof IType) - getAssociatedScopes((IType) b, namespaces, classes, tu); - } - } - } else if (t instanceof IEnumeration) { - getAssociatedNamespaceScopes(getContainingNamespaceScope((IBinding) t, tu), namespaces); + ICPPBase[] bases = ct.getBases(); + for (ICPPBase base : bases) { + if (!(base instanceof IProblemBinding)) { + IBinding b = base.getBaseClass(); + if (b instanceof IType) + getAssociatedScopes((IType) b, namespaces, handled, tu); + } + } + // Furthermore, if T is a class template ... + // * ... types of the template arguments for template type parameters + // (excluding template template parameters); + // * ... owners of which any template template arguments are members; + if (ct instanceof ICPPTemplateInstance) { + ICPPTemplateArgument[] args = ((ICPPTemplateInstance) ct).getTemplateArguments(); + for (ICPPTemplateArgument arg : args) { + if (arg.isTypeValue()) { + getAssociatedScopes(arg.getTypeValue(), namespaces, handled, tu); + } + } + } } else if (t instanceof IFunctionType) { IFunctionType ft = (IFunctionType) t; - - getAssociatedScopes(getUltimateType(ft.getReturnType(), true), namespaces, classes, tu); + getAssociatedScopes(ft.getReturnType(), namespaces, handled, tu); IType[] ps = ft.getParameterTypes(); - for (IType element : ps) { - getAssociatedScopes(getUltimateType(element, true), namespaces, classes, tu); + for (IType pt : ps) { + getAssociatedScopes(pt, namespaces, handled, tu); } } else if (t instanceof ICPPPointerToMemberType) { - IType binding = ((ICPPPointerToMemberType) t).getMemberOfClass(); - getAssociatedScopes(binding, namespaces, classes, tu); + final ICPPPointerToMemberType pmt = (ICPPPointerToMemberType) t; + getAssociatedScopes(pmt.getMemberOfClass(), namespaces, handled, tu); + getAssociatedScopes(pmt.getType(), namespaces, handled, tu); } else if (t instanceof FunctionSetType) { FunctionSetType fst= (FunctionSetType) t; for (ICPPFunction fn : fst.getFunctionSet()) { - getAssociatedScopes(fn.getType(), namespaces, classes, tu); + getAssociatedScopes(fn.getType(), namespaces, handled, tu); } } }