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 08589ff17fd..f980f5a5e68 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 @@ -2880,4 +2880,64 @@ public class AST2TemplateTests extends AST2BaseTest { BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true); ba.assertProblem("A", 6); } + + // template + // class That { + // public: + // That(int x) {} + // }; + // + // template + // class This : public That { + // public: + // inline This(); + // }; + // + // template + // inline This::This() : That(I) { + // } + public void testParameterReferenceInChainInitializer_a() throws Exception { + BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true); + + // These intermediate assertions will not hold until deferred non-type arguments are + // correctly modelled + /* + ICPPClassType tid= ba.assertNonProblem("This::T", 7, ICPPClassType.class); + assertFalse(tid instanceof ICPPSpecialization); + ICPPConstructor th1sCtor= ba.assertNonProblem("This() :", 4, ICPPConstructor.class); + assertFalse(th1sCtor instanceof ICPPSpecialization);ICPPTemplateNonTypeParameter np= ba.assertNonProblem("I)", 1, ICPPTemplateNonTypeParameter.class); + */ + + ICPPTemplateNonTypeParameter np= ba.assertNonProblem("I>(I)", 1, ICPPTemplateNonTypeParameter.class); + ICPPClassType clazz= ba.assertNonProblem("That(I)", 4, ICPPClassType.class); + ICPPConstructor ctor= ba.assertNonProblem("That(I)", 7, ICPPConstructor.class); + } + + // template + // class That { + // public: + // That() {} + // }; + // + // template + // class This : public That { + // public: + // inline This(); + // }; + // + // template + // inline This::This() : That() { + // } + public void testParameterReferenceInChainInitializer_b() throws Exception { + BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true); + + ICPPClassType tid= ba.assertNonProblem("This::T", 7, ICPPClassType.class); + assertFalse(tid instanceof ICPPSpecialization); + ICPPConstructor th1sCtor= ba.assertNonProblem("This() :", 4, ICPPConstructor.class); + assertFalse(th1sCtor instanceof ICPPSpecialization); + + ICPPTemplateTypeParameter np= ba.assertNonProblem("I>()", 1, ICPPTemplateTypeParameter.class); + ICPPClassType clazz= ba.assertNonProblem("That()", 4, ICPPClassType.class); + ICPPConstructor ctor= ba.assertNonProblem("That()", 7, ICPPConstructor.class); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java index 9baa2101ca7..ddc813c9970 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java @@ -1374,4 +1374,60 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa assertTrue(!a1.isSameType(a5c)); assertTrue(!a1.isSameType(a5d)); } + + // template + // class That { + // public: + // That(int x) {} + // }; + // + // template + // class This : public That { + // public: + // inline This(); + // }; + + // template + // inline This::This() : That(I) { + // } + public void testParameterReferenceInChainInitializer_a() throws Exception { + // These intermediate assertions will not hold until deferred non-type arguments are + // correctly modelled + /* + ICPPClassType tid= ba.assertNonProblem("This::T", 7, ICPPClassType.class); + assertFalse(tid instanceof ICPPSpecialization); + ICPPConstructor th1sCtor= ba.assertNonProblem("This() :", 4, ICPPConstructor.class); + assertFalse(th1sCtor instanceof ICPPSpecialization);ICPPTemplateNonTypeParameter np= ba.assertNonProblem("I)", 1, ICPPTemplateNonTypeParameter.class); + */ + + ICPPTemplateNonTypeParameter np= getBindingFromASTName("I>(I)", 1, ICPPTemplateNonTypeParameter.class); + ICPPClassType clazz= getBindingFromASTName("That(I)", 4, ICPPClassType.class); + ICPPConstructor ctor= getBindingFromASTName("That(I)", 7, ICPPConstructor.class); + } + + // template + // class That { + // public: + // That() {} + // }; + // + // template + // class This : public That { + // public: + // inline This(); + // }; + + // template + // inline This::This() : That() { + // } + public void testParameterReferenceInChainInitializer_b() throws Exception { + ICPPClassType tid= getBindingFromASTName("This::T", 7, ICPPClassType.class); + assertFalse(tid instanceof ICPPSpecialization); + ICPPConstructor th1sCtor= getBindingFromASTName("This() :", 4, ICPPConstructor.class); + assertFalse(th1sCtor instanceof ICPPSpecialization); + + ICPPTemplateTypeParameter np= getBindingFromASTName("I>()", 1, ICPPTemplateTypeParameter.class); + ICPPClassType clazz= getBindingFromASTName("That()", 4, ICPPClassType.class); + ICPPConstructor ctor= getBindingFromASTName("That()", 7, ICPPConstructor.class); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java index 73f538b8793..18f8b0f6eec 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java @@ -167,7 +167,8 @@ public abstract class CPPTemplateDefinition extends PlatformObject implements IC public IBinding resolveTemplateParameter(ICPPASTTemplateParameter templateParameter) { IASTName name = CPPTemplates.getTemplateParameterName(templateParameter); - IBinding binding = name.getBinding(); + IASTName preferredName= name; + IBinding binding = name.getBinding(); if (binding != null) return binding; @@ -186,6 +187,7 @@ public abstract class CPPTemplateDefinition extends PlatformObject implements IC ICPPASTTemplateParameter[] params = temp.getTemplateParameters(); if (params.length > i) { IASTName paramName = CPPTemplates.getTemplateParameterName(params[i]); + preferredName= paramName; if (paramName.getBinding() != null) { binding = paramName.getBinding(); name.setBinding(binding); @@ -197,11 +199,11 @@ public abstract class CPPTemplateDefinition extends PlatformObject implements IC } //create a new binding and set it for the corresponding parameter in all known decls if (templateParameter instanceof ICPPASTSimpleTypeTemplateParameter) { - binding = new CPPTemplateTypeParameter(name); + binding = new CPPTemplateTypeParameter(preferredName); } else if (templateParameter instanceof ICPPASTParameterDeclaration) { - binding = new CPPTemplateNonTypeParameter(name); + binding = new CPPTemplateNonTypeParameter(preferredName); } else { - binding = new CPPTemplateTemplateParameter(name); + binding = new CPPTemplateTemplateParameter(preferredName); } int length = (declarations != null) ? declarations.length : 0; 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 248cc34dbf4..379c4e8fc9d 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 @@ -283,7 +283,7 @@ public class CPPSemantics { ICPPASTTemplateId id = (ICPPASTTemplateId) data.astName; IType[] args = CPPTemplates.createTemplateArgumentArray(id); IBinding inst = ((ICPPInternalTemplateInstantiator)cls).instantiate(args); - cls = inst instanceof ICPPClassType ? (ICPPClassType)inst : cls; + cls = inst instanceof ICPPClassType && !(inst instanceof ICPPDeferredTemplateInstance) ? (ICPPClassType)inst : cls; } if (cls != null) { try { @@ -736,13 +736,13 @@ public class CPPSemantics { ICPPScope parentScope = (ICPPScope) getParentScope(scope, data.tu); if (parentScope instanceof ICPPTemplateScope) { - IASTNode parent = node.getParent(); - while (parent != null && !(parent instanceof ICPPASTTemplateDeclaration)) { - node = parent; - parent = parent.getParent(); + IASTNode declNode = node; + while (declNode != null && !(declNode instanceof ICPPASTTemplateDeclaration)) { + node = declNode; + declNode = declNode.getParent(); } - if (parent != null) { - ICPPASTTemplateDeclaration templateDecl = (ICPPASTTemplateDeclaration) parent; + if (declNode != null) { + ICPPASTTemplateDeclaration templateDecl = (ICPPASTTemplateDeclaration) declNode; ICPPTemplateScope templateScope = templateDecl.getScope(); if (templateScope.getTemplateDefinition() == ((ICPPTemplateScope)parentScope).getTemplateDefinition()) { parentScope = templateScope;