From a754d862003304e8b61817d1b06328944d88284a Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Thu, 11 Nov 2010 16:31:12 +0000 Subject: [PATCH] Bug 329795: Resolution of nested typedef specializations. --- .../parser/tests/ast2/AST2TemplateTests.java | 21 ++++++++++++++++++- .../dom/parser/cpp/CPPSpecialization.java | 18 +++++++++++++++- 2 files changed, 37 insertions(+), 2 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 f7d6825e796..6c109d99d17 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 @@ -5135,5 +5135,24 @@ public class AST2TemplateTests extends AST2BaseTest { public void testPartialOrderingForConversions_Bug326900() throws Exception { parseAndCheckBindings(); } - + + // struct S { int foo; }; + // template struct L { + // typedef T& CR; + // template struct _CI { + // CR m(); + // }; + // typedef _CI CI; + // }; + // void test() { + // L::CI l; + // l.m().foo = 1; + // } + public void testNestedTypedefSpecialization_Bug329795() throws Exception { + String code= getAboveComment(); + BindingAssertionHelper bh= new BindingAssertionHelper(code, true); + ICPPField f1= bh.assertNonProblem("foo;", 3); + IBinding f2= bh.assertNonProblem("foo =", 3); + assertSame(f1, f2); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSpecialization.java index f9c5621da5a..953ef4203ce 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSpecialization.java @@ -54,12 +54,28 @@ public abstract class CPPSpecialization extends PlatformObject implements ICPPSp public IType specializeType(IType type) { if (owner instanceof ICPPClassSpecialization) { - return CPPTemplates.instantiateType(type, getTemplateParameterMap(), -1, (ICPPClassSpecialization) owner); + ICPPClassSpecialization within = getWithin((ICPPClassSpecialization) owner); + return CPPTemplates.instantiateType(type, getTemplateParameterMap(), -1, within); } else { return CPPTemplates.instantiateType(type, getTemplateParameterMap(), -1, null); } } + private ICPPClassSpecialization getWithin(ICPPClassSpecialization within) { + ICPPClassType orig = within.getSpecializedBinding(); + for(;;) { + IBinding o1 = within.getOwner(); + IBinding o2 = orig.getOwner(); + if (!(o1 instanceof ICPPClassSpecialization && o2 instanceof ICPPClassType)) + return within; + ICPPClassSpecialization nextWithin = (ICPPClassSpecialization) o1; + orig= (ICPPClassType) o2; + if (orig.isSameType(nextWithin)) + return within; + within= nextWithin; + } + } + public IType[] specializeTypePack(ICPPParameterPackType type) { if (owner instanceof ICPPClassSpecialization) { return CPPTemplates.instantiateTypes(new IType[]{type}, getTemplateParameterMap(), -1, (ICPPClassSpecialization) owner);