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);
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.cpp.CPPASTTypeId;
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.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
@ -682,12 +683,24 @@ public class ASTTypeUtil {
LinkedList<String> result= new LinkedList<String>();
result.addFirst(getNameForAnonymous(binding));
IBinding owner= binding.getOwner();
while (owner instanceof ICPPNamespace || owner instanceof IType) {
IBinding owner= binding;
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();
if (name == null || name.length == 0) {
if (!(binding instanceof ICPPNamespace)) {
char[] altname= createNameForAnonymous(binding);
if (!(owner instanceof ICPPNamespace)) {
char[] altname = createNameForAnonymous(owner);
if (altname != null) {
result.addFirst(new String(altname));
}
@ -699,10 +712,6 @@ public class ASTTypeUtil {
result.addFirst(new String(name));
}
}
if (owner instanceof ICPPTemplateParameter)
break;
owner= owner.getOwner();
}
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
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -36,7 +36,9 @@ public class CPPDeferredClassInstance extends CPPUnknownClass implements ICPPDef
private final ICPPScope fLookupScope;
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;
fClassTemplate= template;
fLookupScope= lookupScope;
@ -46,6 +48,16 @@ public class CPPDeferredClassInstance extends CPPUnknownClass implements ICPPDef
this(template, arguments, null);
}
@Override
public IBinding getOwner() {
try {
return fClassTemplate.getOwner();
} catch (DOMException e) {
return e.getProblem();
}
}
public ICPPClassTemplate getClassTemplate() {
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
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -78,7 +78,7 @@ public class CPPTemplateTemplateParameter extends CPPTemplateParameter implement
ICPPASTTemplateParameter[] params = template.getTemplateParameters();
ICPPTemplateParameter[] result = null;
for (ICPPASTTemplateParameter param : params) {
IBinding binding = CPPTemplates.getTemplateParameterName(param).resolveBinding();
IBinding binding = CPPTemplates.getTemplateParameterName(param).resolvePreBinding();
if (binding instanceof ICPPTemplateParameter) {
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
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -78,14 +78,16 @@ public class CPPUnknownBinding extends PlatformObject
}
public IScope getScope() throws DOMException {
if (fOwner instanceof ICPPUnknownBinding) {
return ((ICPPUnknownBinding) fOwner).asScope();
} else if (fOwner instanceof ICPPClassType) {
return ((ICPPClassType) fOwner).getCompositeScope();
} else if (fOwner instanceof ICPPNamespace) {
return ((ICPPNamespace) fOwner).getNamespaceScope();
} else if (fOwner instanceof ICPPFunction) {
return ((ICPPFunction) fOwner).getFunctionScope();
// Use getOwner(), it is overridden by derived classes.
final IBinding owner = getOwner();
if (owner instanceof ICPPUnknownBinding) {
return ((ICPPUnknownBinding) owner).asScope();
} else if (owner instanceof ICPPClassType) {
return ((ICPPClassType) owner).getCompositeScope();
} else if (owner instanceof ICPPNamespace) {
return ((ICPPNamespace) owner).getNamespaceScope();
} else if (owner instanceof ICPPFunction) {
return ((ICPPFunction) owner).getFunctionScope();
}
return null;
}

View file

@ -632,7 +632,7 @@ public class CPPTemplates {
// class template instance
IBinding result= null;
IASTName templateName = id.getTemplateName();
IBinding template = templateName.resolveBinding();
IBinding template = templateName.resolvePreBinding();
if (template instanceof ICPPConstructor) {
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
* are made available under the terms of the Eclipse Public License v1.0
* 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.ICPPTemplateInstance;
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.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
@ -536,9 +537,22 @@ public class TemplateArgumentDeduction {
throws DOMException {
ICPPClassTemplate pTemplate= getPrimaryTemplate(pInst);
ICPPClassTemplate aTemplate= getPrimaryTemplate(aInst);
if (pTemplate == null || aTemplate == null || !aTemplate.isSameType(pTemplate))
if (pTemplate == null || aTemplate == null)
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.
final ICPPTemplateArgument[] pArgs = pInst.getTemplateArguments();
for (int i = 0; i < pArgs.length-1; i++) {