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 cbac60e7ef9..1a635922c7d 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 @@ -4390,6 +4390,66 @@ public class AST2TemplateTests extends AST2TestBase { parseAndCheckBindings(); } + // template + // struct E {}; + // + // template + // struct D; + // + // template + // struct D> : D> {}; + // + // template + // struct D<0, E> { + // typedef T type; + // }; + // + // template + // class A; + // + // template + // struct F { + // using type = T; + // }; + // + // template + // struct C; + // + // template + // struct C> { + // using type = typename D...>>::type::type; + // }; + // + // template + // struct B : public B { + // using U = typename C::type; + // using Base = B; + // using Base::Base; + // + // B(const U& value); + // }; + // + // template + // struct B<-1, A> {}; + // + // template + // struct A : public B> { + // using B = B; + // using B::B; + // }; + // + // struct X {}; + // struct Y {}; + // + // void waldo(const A& p); + // + // void test() { + // waldo(X()); + // waldo(Y()); + // } + public void testInheritedConstructor_489710() throws Exception { + parseAndCheckBindings(); + } // template // struct A { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java index ecd64534509..51d0a42d0e3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java @@ -42,6 +42,7 @@ import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression; @@ -155,8 +156,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { } } - private ICPPBase[] findInheritedConstructorsSourceBases( - ICPPASTCompositeTypeSpecifier compositeTypeSpec) { + private ICPPBase[] findInheritedConstructorsSourceBases(ICPPASTCompositeTypeSpecifier compositeTypeSpec) { ICPPBase[] bases = ClassTypeHelper.getBases(getClassType(), compositeTypeSpec); if (bases.length == 0) return bases; @@ -173,9 +173,8 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { IBinding parent = qualifier[qualifier.length - 1].resolveBinding(); if (!(parent instanceof IType) || parent instanceof IProblemBinding) continue; - IType type = SemanticUtil.getNestedType((IType) parent, TDEF); - if (type instanceof IBinding && - Arrays.equals(((IBinding) type).getNameCharArray(), qName.getLastName().getSimpleID())) { + if (isConstructorNameForType(qName.getLastName().getSimpleID(), (IType) parent)) { + IType type = SemanticUtil.getNestedType((IType) parent, TDEF); for (ICPPBase base : bases) { IType baseClass = base.getBaseClassType(); if (type.isSameType(baseClass)) { @@ -189,6 +188,17 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { return trim(results, n); } + private static boolean isConstructorNameForType(char[] lastName, IType type) { + while (type instanceof IBinding) { + if (Arrays.equals(((IBinding) type).getNameCharArray(), lastName)) + return true; + if (!(type instanceof ITypedef)) + break; + type = ((ITypedef) type).getType(); + } + return false; + } + static ICPPMethod[] createInheritedConsructors(ICPPClassScope scope, char[] className, ICPPBase[] bases, IType[][] existingConstructorParamTypes, IASTNode point) { ICPPMethod[] inheritedConstructors = ICPPMethod.EMPTY_CPPMETHOD_ARRAY;