1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 302282: Extending variadic template template parameters.

This commit is contained in:
Markus Schorn 2010-02-10 09:04:05 +00:00
parent 3e23c44676
commit c6fde503dc
7 changed files with 99 additions and 25 deletions

View file

@ -4787,4 +4787,41 @@ public class AST2TemplateTests extends AST2BaseTest {
ICPPASTExplicitTemplateInstantiation ti= getDeclaration(tu, 1); ICPPASTExplicitTemplateInstantiation ti= getDeclaration(tu, 1);
assertEquals(ICPPASTExplicitTemplateInstantiation.EXTERN, ti.getModifier()); assertEquals(ICPPASTExplicitTemplateInstantiation.EXTERN, ti.getModifier());
} }
// template <class T> struct eval;
// template <template <class, class...> class TT, class T1, class... Rest>
// struct eval<TT<T1, Rest...>> { };
// template <class T1> struct A;
// template <class T1, class T2> struct B;
// template <int N> struct C;
// template <class T1, int N> struct D;
// template <class T1, class T2, int N = 17> struct E;
//
// eval<A<int>> eA; // OK: matches partial specialization of eval
// eval<B<int, float>> eB; // OK: matches partial specialization of eval
// eval<C<17>> eC; // error: C does not match TT in partial specialization
// eval<D<int, 17>> eD; // error: D does not match TT in partial specialization
// eval<E<int, float>> eE; // error: E does not match TT in partial specialization
public void testExtendingVariadicTemplateTemplateParameters_302282() throws Exception {
final String code= getAboveComment();
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
ICPPClassTemplate ct= bh.assertNonProblem("eval;", -1);
ICPPClassTemplatePartialSpecialization pspec= bh.assertNonProblem("eval<TT<T1, Rest...>>", 0);
ICPPTemplateInstance inst= bh.assertNonProblem("eval<A<int>>", 0);
assertSame(pspec, inst.getSpecializedBinding());
inst= bh.assertNonProblem("eval<B<int, float>>", 0);
assertSame(pspec, inst.getSpecializedBinding());
inst= bh.assertNonProblem("eval<C<17>>", 0);
assertSame(ct, inst.getSpecializedBinding());
inst= bh.assertNonProblem("eval<D<int, 17>>", 0);
assertSame(ct, inst.getSpecializedBinding());
inst= bh.assertNonProblem("eval<E<int, float>>", 0);
assertSame(ct, inst.getSpecializedBinding());
}
} }

View file

@ -42,6 +42,7 @@ import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
import org.eclipse.cdt.internal.core.dom.parser.c.ICInternalBinding; import org.eclipse.cdt.internal.core.dom.parser.c.ICInternalBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTypeId; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTypeId;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
@ -682,12 +683,24 @@ public class ASTTypeUtil {
LinkedList<String> result= new LinkedList<String>(); LinkedList<String> result= new LinkedList<String>();
result.addFirst(getNameForAnonymous(binding)); result.addFirst(getNameForAnonymous(binding));
IBinding owner= binding.getOwner(); IBinding owner= binding;
while (owner instanceof ICPPNamespace || owner instanceof IType) { for (;;) {
if (owner instanceof ICPPTemplateParameter)
break;
if (owner instanceof ICPPDeferredClassInstance) {
ICPPDeferredClassInstance deferredInst = (ICPPDeferredClassInstance) owner;
if (deferredInst.getTemplateDefinition() instanceof ICPPTemplateParameter)
break;
}
owner = owner.getOwner();
if (!(owner instanceof ICPPNamespace || owner instanceof IType))
break;
char[] name = owner.getNameCharArray(); char[] name = owner.getNameCharArray();
if (name == null || name.length == 0) { if (name == null || name.length == 0) {
if (!(binding instanceof ICPPNamespace)) { if (!(owner instanceof ICPPNamespace)) {
char[] altname= createNameForAnonymous(binding); char[] altname = createNameForAnonymous(owner);
if (altname != null) { if (altname != null) {
result.addFirst(new String(altname)); result.addFirst(new String(altname));
} }
@ -699,10 +712,6 @@ public class ASTTypeUtil {
result.addFirst(new String(name)); result.addFirst(new String(name));
} }
} }
if (owner instanceof ICPPTemplateParameter)
break;
owner= owner.getOwner();
} }
return result.toArray(new String[result.size()]); return result.toArray(new String[result.size()]);
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2009 IBM Corporation and others. * Copyright (c) 2005, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -36,7 +36,9 @@ public class CPPDeferredClassInstance extends CPPUnknownClass implements ICPPDef
private final ICPPScope fLookupScope; private final ICPPScope fLookupScope;
public CPPDeferredClassInstance(ICPPClassTemplate template, ICPPTemplateArgument[] arguments, ICPPScope lookupScope) throws DOMException { public CPPDeferredClassInstance(ICPPClassTemplate template, ICPPTemplateArgument[] arguments, ICPPScope lookupScope) throws DOMException {
super(template.getOwner(), template.getNameCharArray()); // With template template parameters the owner must not be calculated, it'd lead to an infinite loop.
// Rather than that we override getOwner().
super(null, template.getNameCharArray());
fArguments= arguments; fArguments= arguments;
fClassTemplate= template; fClassTemplate= template;
fLookupScope= lookupScope; fLookupScope= lookupScope;
@ -46,6 +48,16 @@ public class CPPDeferredClassInstance extends CPPUnknownClass implements ICPPDef
this(template, arguments, null); this(template, arguments, null);
} }
@Override
public IBinding getOwner() {
try {
return fClassTemplate.getOwner();
} catch (DOMException e) {
return e.getProblem();
}
}
public ICPPClassTemplate getClassTemplate() { public ICPPClassTemplate getClassTemplate() {
return (ICPPClassTemplate) getSpecializedBinding(); return (ICPPClassTemplate) getSpecializedBinding();
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2009 IBM Corporation and others. * Copyright (c) 2005, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -78,7 +78,7 @@ public class CPPTemplateTemplateParameter extends CPPTemplateParameter implement
ICPPASTTemplateParameter[] params = template.getTemplateParameters(); ICPPASTTemplateParameter[] params = template.getTemplateParameters();
ICPPTemplateParameter[] result = null; ICPPTemplateParameter[] result = null;
for (ICPPASTTemplateParameter param : params) { for (ICPPASTTemplateParameter param : params) {
IBinding binding = CPPTemplates.getTemplateParameterName(param).resolveBinding(); IBinding binding = CPPTemplates.getTemplateParameterName(param).resolvePreBinding();
if (binding instanceof ICPPTemplateParameter) { if (binding instanceof ICPPTemplateParameter) {
result = (ICPPTemplateParameter[]) ArrayUtil.append(ICPPTemplateParameter.class, result, binding); result = (ICPPTemplateParameter[]) ArrayUtil.append(ICPPTemplateParameter.class, result, binding);
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others. * Copyright (c) 2004, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -78,14 +78,16 @@ public class CPPUnknownBinding extends PlatformObject
} }
public IScope getScope() throws DOMException { public IScope getScope() throws DOMException {
if (fOwner instanceof ICPPUnknownBinding) { // Use getOwner(), it is overridden by derived classes.
return ((ICPPUnknownBinding) fOwner).asScope(); final IBinding owner = getOwner();
} else if (fOwner instanceof ICPPClassType) { if (owner instanceof ICPPUnknownBinding) {
return ((ICPPClassType) fOwner).getCompositeScope(); return ((ICPPUnknownBinding) owner).asScope();
} else if (fOwner instanceof ICPPNamespace) { } else if (owner instanceof ICPPClassType) {
return ((ICPPNamespace) fOwner).getNamespaceScope(); return ((ICPPClassType) owner).getCompositeScope();
} else if (fOwner instanceof ICPPFunction) { } else if (owner instanceof ICPPNamespace) {
return ((ICPPFunction) fOwner).getFunctionScope(); return ((ICPPNamespace) owner).getNamespaceScope();
} else if (owner instanceof ICPPFunction) {
return ((ICPPFunction) owner).getFunctionScope();
} }
return null; return null;
} }

View file

@ -632,7 +632,7 @@ public class CPPTemplates {
// class template instance // class template instance
IBinding result= null; IBinding result= null;
IASTName templateName = id.getTemplateName(); IASTName templateName = id.getTemplateName();
IBinding template = templateName.resolveBinding(); IBinding template = templateName.resolvePreBinding();
if (template instanceof ICPPConstructor) { if (template instanceof ICPPConstructor) {
template= template.getOwner(); template= template.getOwner();

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009 Wind River Systems, Inc. and others. * Copyright (c) 2009, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -42,6 +42,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter;
import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
@ -536,9 +537,22 @@ public class TemplateArgumentDeduction {
throws DOMException { throws DOMException {
ICPPClassTemplate pTemplate= getPrimaryTemplate(pInst); ICPPClassTemplate pTemplate= getPrimaryTemplate(pInst);
ICPPClassTemplate aTemplate= getPrimaryTemplate(aInst); ICPPClassTemplate aTemplate= getPrimaryTemplate(aInst);
if (pTemplate == null || aTemplate == null || !aTemplate.isSameType(pTemplate)) if (pTemplate == null || aTemplate == null)
return false; return false;
if (pTemplate instanceof ICPPTemplateTemplateParameter) {
final int tparId = ((ICPPTemplateTemplateParameter) pTemplate).getParameterID();
ICPPTemplateArgument current= fDeducedArgs.getArgument(tparId, fPackOffset);
if (current != null) {
if (current.isNonTypeValue() || !current.getTypeValue().isSameType(aTemplate))
return false;
} else if (!deduce(tparId, new CPPTemplateArgument(aTemplate))) {
return false;
}
} else if (!aTemplate.isSameType(pTemplate)) {
return false;
}
// Check for being a non-deduced context. // Check for being a non-deduced context.
final ICPPTemplateArgument[] pArgs = pInst.getTemplateArguments(); final ICPPTemplateArgument[] pArgs = pInst.getTemplateArguments();
for (int i = 0; i < pArgs.length-1; i++) { for (int i = 0; i < pArgs.length-1; i++) {