1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 17:56:01 +02:00

Bug 326492: Overloaded function-sets in instantiation of function templates.

This commit is contained in:
Markus Schorn 2010-09-29 12:54:36 +00:00
parent ef4a1226fe
commit bbf5a39ad8
8 changed files with 180 additions and 98 deletions

View file

@ -648,7 +648,7 @@ public class AST2BaseTest extends BaseTestCase {
Iterator i = col.nameList.iterator(); Iterator i = col.nameList.iterator();
while (i.hasNext()) { while (i.hasNext()) {
IASTName n = (IASTName) i.next(); IASTName n = (IASTName) i.next();
assertFalse(n.resolveBinding() instanceof IProblemBinding); assertFalse("ProblemBinding for " + n.getRawSignature(), n.resolveBinding() instanceof IProblemBinding);
} }
} }

View file

@ -5154,4 +5154,36 @@ public class AST2TemplateTests extends AST2BaseTest {
public void testAdressOfUniqueTemplateInst_Bug326076() throws Exception { public void testAdressOfUniqueTemplateInst_Bug326076() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template <typename T> void f(T (*)(int), char);
// template <typename T> void f(int (*)(T), int);
// template <typename T> void f(T, int);
//
// int g(char);
// void g(int);
//
// void b() {
// f(g, '1');
// f(g, 1);
// }
public void testInstantiationOfFunctionTemplateWithOverloadedFunctionSetArgument_Bug326492() throws Exception {
String code= getAboveComment();
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
ICPPFunctionTemplate f1= bh.assertNonProblem("f(T (*)(int), char)", 1);
ICPPFunctionTemplate f2= bh.assertNonProblem("f(int (*)(T), int)", 1);
IFunction g1= bh.assertNonProblem("g(char)", 1);
IFunction g2= bh.assertNonProblem("g(int)", 1);
ICPPTemplateInstance t;
t= bh.assertNonProblem("f(g, '1')", 1);
assertSame(f1, t.getTemplateDefinition());
t= bh.assertNonProblem("f(g, 1)", 1);
assertSame(f2, t.getTemplateDefinition());
ICPPFunction g;
g= bh.assertNonProblem("g, '1')", 1);
assertSame(g2, g);
g= bh.assertNonProblem("g, 1)", 1);
assertSame(g1, g);
}
} }

View file

@ -5915,12 +5915,13 @@ public class AST2Tests extends AST2BaseTest {
final Runtime runtime = Runtime.getRuntime(); final Runtime runtime = Runtime.getRuntime();
long mem= runtime.totalMemory()-runtime.freeMemory(); long mem= runtime.totalMemory()-runtime.freeMemory();
long newMem= mem; long newMem= mem;
int i=0;
do { do {
Thread.sleep(50); Thread.sleep(50);
System.gc(); System.gc();
mem= newMem; mem= newMem;
newMem= runtime.totalMemory()-runtime.freeMemory(); newMem= runtime.totalMemory()-runtime.freeMemory();
} while (newMem < mem); } while (newMem < mem && ++i<5);
return mem; return mem;
} }

View file

@ -22,6 +22,7 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionT
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -2295,8 +2296,9 @@ public class CPPSemantics {
// Reduce our set of candidate functions to only those who have the right number of parameters // Reduce our set of candidate functions to only those who have the right number of parameters
final IType[] argTypes = data.getFunctionArgumentTypes(); final IType[] argTypes = data.getFunctionArgumentTypes();
ICPPFunction[] tmp= selectByArgumentCount(data, fns); ICPPFunction[] tmp= selectByArgumentCount(data, fns);
tmp= CPPTemplates.instantiateFunctionTemplates(tmp, argTypes, data.getFunctionArgumentValueCategories(), tmp= CPPTemplates.instantiateForFunctionCall(data.astName, tmp,
data.astName, data.argsContainImpliedObject); Arrays.asList(argTypes),
Arrays.asList(data.getFunctionArgumentValueCategories()), data.argsContainImpliedObject);
if (tmp.length == 0 || tmp[0] == null) if (tmp.length == 0 || tmp[0] == null)
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, fns); return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, fns);
@ -2437,7 +2439,7 @@ public class CPPSemantics {
} }
if (result instanceof ICPPFunctionTemplate) if (result instanceof ICPPFunctionTemplate)
return CPPTemplates.instantiateFunctionTemplate((ICPPFunctionTemplate) result, null, name); return CPPTemplates.instantiateForAddressOfFunction((ICPPFunctionTemplate) result, null, name);
return result; return result;
} }
@ -2452,8 +2454,10 @@ public class CPPSemantics {
private static IBinding resolveFunctionDeclaration(LookupData data, ICPPFunction[] fns) throws DOMException { private static IBinding resolveFunctionDeclaration(LookupData data, ICPPFunction[] fns) throws DOMException {
if (data.forExplicitFunctionSpecialization()) { if (data.forExplicitFunctionSpecialization()) {
fns= CPPTemplates.instantiateFunctionTemplates(fns, data.getFunctionArgumentTypes(), fns = CPPTemplates.instantiateForFunctionCall(data.astName,
data.getFunctionArgumentValueCategories(), data.astName, data.argsContainImpliedObject); fns,
Arrays.asList(data.getFunctionArgumentTypes()), Arrays.asList(data.getFunctionArgumentValueCategories()),
data.argsContainImpliedObject);
} }
int argCount = data.getFunctionArgumentCount(); int argCount = data.getFunctionArgumentCount();
@ -2812,7 +2816,7 @@ public class CPPSemantics {
try { try {
if (fn instanceof ICPPFunctionTemplate) { if (fn instanceof ICPPFunctionTemplate) {
final ICPPFunctionTemplate template = (ICPPFunctionTemplate) fn; final ICPPFunctionTemplate template = (ICPPFunctionTemplate) fn;
ICPPFunction inst= CPPTemplates.instantiateFunctionTemplate(template, (ICPPFunctionType) targetType, name); ICPPFunction inst= CPPTemplates.instantiateForAddressOfFunction(template, (ICPPFunctionType) targetType, name);
if (inst != null) { if (inst != null) {
int cmp= -1; int cmp= -1;
if (result != null) { if (result != null) {

View file

@ -16,8 +16,12 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
@ -1538,97 +1542,126 @@ public class CPPTemplates {
return result; return result;
} }
static ICPPFunction[] instantiateFunctionTemplates(ICPPFunction[] fns, IType[] allFnArgs, static ICPPFunction[] instantiateForFunctionCall(IASTName name, ICPPFunction[] fns,
ValueCategory[] allValueCategories, IASTName name, boolean argsContainImpliedObject) { List<IType> fnArgs, List<ValueCategory> argCats, boolean withImpliedObjectArg) {
boolean requireTemplate= false; if (name != null && name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) {
if (name != null) { name= (IASTName) name.getParent();
if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) {
name= (IASTName) name.getParent();
requireTemplate= true;
} else if (name instanceof ICPPASTTemplateId) {
requireTemplate= true;
}
} }
IType[] reducedFnArgs= null; // Extract template arguments.
ValueCategory[] reducedValueCategories= null; ICPPTemplateArgument[] tmplArgs= ICPPTemplateArgument.EMPTY_ARGUMENTS;
ICPPTemplateArgument[] tmplArgs= null; boolean requireTemplate= name instanceof ICPPASTTemplateId;
ICPPFunction[] result= fns; boolean haveTemplate= false;
int idx= 0;
for (int i = 0; i < fns.length; i++) { for (final ICPPFunction func : fns) {
final ICPPFunction func = fns[i]; if (func instanceof ICPPConstructor || (func instanceof ICPPMethod && ((ICPPMethod) func).isDestructor()))
ICPPFunction rf= null; requireTemplate= false;
if (func instanceof ICPPFunctionTemplate) { if (func instanceof ICPPFunctionTemplate) {
ICPPFunctionTemplate template= (ICPPFunctionTemplate) func; ICPPFunctionTemplate template= (ICPPFunctionTemplate) func;
final IType[] fnArgs;
final ValueCategory[] valueCategories;
if (argsContainImpliedObject && template instanceof ICPPMethod) {
if (reducedValueCategories == null) {
if (allFnArgs != null && allFnArgs.length > 0) {
reducedFnArgs= ArrayUtil.removeFirst(allFnArgs);
}
if (allValueCategories == null || allValueCategories.length == 0) {
reducedValueCategories= new ValueCategory[0];
} else {
reducedValueCategories= ArrayUtil.removeFirst(allValueCategories);
}
}
fnArgs= reducedFnArgs;
valueCategories= reducedValueCategories;
} else {
fnArgs= allFnArgs;
valueCategories= allValueCategories;
}
// extract template arguments and parameter types.
if (tmplArgs == null || fnArgs == null) {
tmplArgs = ICPPTemplateArgument.EMPTY_ARGUMENTS;
try {
if (fnArgs == null || containsDependentType(fnArgs)) {
return new ICPPFunction[] {CPPUnknownFunction.createForSample(template)};
}
if (name instanceof ICPPASTTemplateId && !(template instanceof ICPPConstructor)) {
tmplArgs = createTemplateArgumentArray((ICPPASTTemplateId) name);
if (hasDependentArgument(tmplArgs)) {
return new ICPPFunction[] {CPPUnknownFunction.createForSample(template)};
}
}
} catch (DOMException e) {
return NO_FUNCTIONS;
}
}
CPPTemplateParameterMap map= new CPPTemplateParameterMap(fnArgs.length);
try { try {
ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForFunctionCall(template, tmplArgs, fnArgs, valueCategories, map); if (containsDependentType(fnArgs))
if (args != null) { return new ICPPFunction[] {CPPUnknownFunction.createForSample(template)};
IBinding instance= instantiateFunctionTemplate(template, args, map);
if (instance instanceof ICPPFunction) { if (requireTemplate) {
rf= (ICPPFunction) instance; tmplArgs = createTemplateArgumentArray((ICPPASTTemplateId) name);
} if (hasDependentArgument(tmplArgs))
return new ICPPFunction[] {CPPUnknownFunction.createForSample(template)};
} }
} catch (DOMException e) { } catch (DOMException e) {
// try next candidate return NO_FUNCTIONS;
} }
} else if (!requireTemplate haveTemplate= true;
|| (func instanceof ICPPConstructor) || (func instanceof ICPPUnknownBinding) break;
|| (func instanceof ICPPMethod && ((ICPPMethod) func).isDestructor())) {
rf= func;
} }
if (rf != func || result != fns) { }
if (result == fns) {
result= new ICPPFunction[fns.length-(i-idx)]; if (!haveTemplate && !requireTemplate)
System.arraycopy(fns, 0, result, 0, idx); return fns;
final List<ICPPFunction> result= new ArrayList<ICPPFunction>(fns.length);
final List<List<IType>> crossProduct= expandOverloadedSets(fnArgs);
for (ICPPFunction fn : fns) {
if (fn != null) {
if (fn instanceof ICPPFunctionTemplate) {
ICPPFunctionTemplate fnTmpl= (ICPPFunctionTemplate) fn;
for (List<IType> args : crossProduct) {
ICPPFunction inst = instantiateForFunctionCall(fnTmpl, tmplArgs, args, argCats, withImpliedObjectArg);
if (inst != null)
result.add(inst);
}
} else if (!requireTemplate || fn instanceof ICPPUnknownBinding) {
result.add(fn);
}
}
}
return result.toArray(new ICPPFunction[result.size()]);
}
private static List<List<IType>> expandOverloadedSets(List<IType> fnArgs) {
List<List<IType>> result= Collections.singletonList(fnArgs);
int i= 0;
for (IType arg : fnArgs) {
if (arg instanceof FunctionSetType) {
Collection<ICPPFunctionType> targetTypes= getFunctionTypes((FunctionSetType) arg);
if (targetTypes.isEmpty())
return Collections.emptyList();
List<List<IType>> expanded= new ArrayList<List<IType>>(targetTypes.size() * result.size());
for (IType targetType : targetTypes) {
for (List<IType> orig : result) {
ArrayList<IType> copy = new ArrayList<IType>(orig);
copy.set(i, new CPPPointerType(targetType));
expanded.add(copy);
}
}
result= expanded;
}
i++;
}
return result;
}
private static Collection<ICPPFunctionType> getFunctionTypes(FunctionSetType fst) {
final ICPPFunction[] functionSet = fst.getFunctionSet();
Set<String> handled= new HashSet<String>();
Collection<ICPPFunctionType> result= new ArrayList<ICPPFunctionType>(functionSet.length);
for (ICPPFunction f : functionSet) {
if (! (f instanceof ICPPFunctionTemplate)) {
try {
ICPPFunctionType t= f.getType();
if (handled.add(ASTTypeUtil.getType(t, true)))
result.add(t);
} catch (DOMException e) {
} }
if (rf != null)
result[idx]= rf;
} }
if (rf != null)
idx++;
} }
return result; return result;
} }
static protected void instantiateConversionTemplates(IFunction[] functions, IType conversionType) { private static ICPPFunction instantiateForFunctionCall(ICPPFunctionTemplate template,
ICPPTemplateArgument[] tmplArgs, List<IType> fnArgs, List<ValueCategory> argCats,
boolean withImpliedObjectArg) {
if (withImpliedObjectArg && template instanceof ICPPMethod) {
fnArgs= fnArgs.subList(1, fnArgs.size());
argCats= argCats.subList(1, argCats.size());
}
CPPTemplateParameterMap map= new CPPTemplateParameterMap(fnArgs.size());
try {
ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForFunctionCall(template, tmplArgs, fnArgs, argCats, map);
if (args != null) {
IBinding instance= instantiateFunctionTemplate(template, args, map);
if (instance instanceof ICPPFunction) {
return (ICPPFunction) instance;
}
}
} catch (DOMException e) {
}
return null;
}
static void instantiateConversionTemplates(IFunction[] functions, IType conversionType) {
boolean checkedForDependentType= false; boolean checkedForDependentType= false;
for (int i = 0; i < functions.length; i++) { for (int i = 0; i < functions.length; i++) {
IFunction func = functions[i]; IFunction func = functions[i];
@ -1667,7 +1700,7 @@ public class CPPTemplates {
/** /**
* 14.8.2.2 Deducing template arguments taking the address of a function template [temp.deduct.funcaddr] * 14.8.2.2 Deducing template arguments taking the address of a function template [temp.deduct.funcaddr]
*/ */
static protected ICPPFunction instantiateFunctionTemplate(ICPPFunctionTemplate template, IFunctionType target, IASTName name) { static ICPPFunction instantiateForAddressOfFunction(ICPPFunctionTemplate template, IFunctionType target, IASTName name) {
if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) { if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) {
name= (IASTName) name.getParent(); name= (IASTName) name.getParent();
} }
@ -1728,7 +1761,7 @@ public class CPPTemplates {
return args; return args;
} }
static protected int orderTemplateFunctions(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2) static int orderTemplateFunctions(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2)
throws DOMException { throws DOMException {
// 14.5.5.2 // 14.5.5.2
// A template is more specialized than another if and only if it is at least as specialized as the // A template is more specialized than another if and only if it is at least as specialized as the
@ -1765,7 +1798,7 @@ public class CPPTemplates {
map= new CPPTemplateParameterMap(2); map= new CPPTemplateParameterMap(2);
final IType[] transferredParameterTypes = ((ICPPFunction) transferredTemplate).getType().getParameterTypes(); final IType[] transferredParameterTypes = ((ICPPFunction) transferredTemplate).getType().getParameterTypes();
if (!TemplateArgumentDeduction.deduceFromFunctionArgs(f2, transferredParameterTypes, null, map, true)) if (!TemplateArgumentDeduction.deduceFromFunctionArgs(f2, Arrays.asList(transferredParameterTypes), null, map, true))
return false; return false;
final int last = tmplParams1.length -1; final int last = tmplParams1.length -1;
@ -1912,7 +1945,7 @@ public class CPPTemplates {
return arg != null && isValidType(arg.isTypeValue() ? arg.getTypeValue() : arg.getTypeOfNonTypeValue()); return arg != null && isValidType(arg.isTypeValue() ? arg.getTypeValue() : arg.getTypeOfNonTypeValue());
} }
static protected ICPPTemplateArgument matchTemplateParameterAndArgument(ICPPTemplateParameter param, static ICPPTemplateArgument matchTemplateParameterAndArgument(ICPPTemplateParameter param,
ICPPTemplateArgument arg, CPPTemplateParameterMap map) { ICPPTemplateArgument arg, CPPTemplateParameterMap map) {
if (arg == null || !isValidType(arg.getTypeValue())) { if (arg == null || !isValidType(arg.getTypeValue())) {
return null; return null;
@ -2078,7 +2111,15 @@ public class CPPTemplates {
return Value.isDependentValue(arg.getNonTypeValue()); return Value.isDependentValue(arg.getNonTypeValue());
} }
public static boolean containsDependentType(List<IType> ts) {
for (IType t : ts) {
if (isDependentType(t))
return true;
}
return false;
}
public static boolean containsDependentType(IType[] ts) { public static boolean containsDependentType(IType[] ts) {
for (IType t : ts) { for (IType t : ts) {
if (isDependentType(t)) if (isDependentType(t))

View file

@ -16,6 +16,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -1819,8 +1820,8 @@ public class CPPVisitor extends ASTQueries {
} }
ICPPFunctionTemplate template = new AutoTypeResolver(type); ICPPFunctionTemplate template = new AutoTypeResolver(type);
CPPTemplateParameterMap paramMap = new CPPTemplateParameterMap(1); CPPTemplateParameterMap paramMap = new CPPTemplateParameterMap(1);
TemplateArgumentDeduction.deduceFromFunctionArgs(template, new IType[] { initType }, TemplateArgumentDeduction.deduceFromFunctionArgs(template, Collections.singletonList(initType),
new ValueCategory[] { valueCat }, paramMap, false); Collections.singletonList(valueCat), paramMap, false);
ICPPTemplateArgument argument = paramMap.getArgument(0, 0); ICPPTemplateArgument argument = paramMap.getArgument(0, 0);
if (argument == null) { if (argument == null) {
return null; return null;

View file

@ -19,6 +19,8 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CVQualifier
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromReturnType; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromReturnType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
import java.util.Collections;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
@ -668,7 +670,8 @@ public class Conversions {
FunctionCost cost1= null; FunctionCost cost1= null;
Cost cost2= null; Cost cost2= null;
ICPPFunction[] ctors= t.getConstructors(); ICPPFunction[] ctors= t.getConstructors();
ctors= CPPTemplates.instantiateFunctionTemplates(ctors, new IType[]{source}, new ValueCategory[] {valueCat}, null, false); ctors = CPPTemplates.instantiateForFunctionCall(null, ctors,
Collections.singletonList(source), Collections.singletonList(valueCat), false);
for (ICPPFunction f : ctors) { for (ICPPFunction f : ctors) {
if (!(f instanceof ICPPConstructor) || f instanceof IProblemBinding) if (!(f instanceof ICPPConstructor) || f instanceof IProblemBinding)

View file

@ -61,7 +61,7 @@ public class TemplateArgumentDeduction {
* 14.8.2.1 * 14.8.2.1
*/ */
static ICPPTemplateArgument[] deduceForFunctionCall(ICPPFunctionTemplate template, static ICPPTemplateArgument[] deduceForFunctionCall(ICPPFunctionTemplate template,
ICPPTemplateArgument[] tmplArgs, IType[] fnArgs, ValueCategory[] argIsLValue, CPPTemplateParameterMap map) ICPPTemplateArgument[] tmplArgs, List<IType> fnArgs, List<ValueCategory> argIsLValue, CPPTemplateParameterMap map)
throws DOMException { throws DOMException {
final ICPPTemplateParameter[] tmplParams = template.getTemplateParameters(); final ICPPTemplateParameter[] tmplParams = template.getTemplateParameters();
final int numTmplParams = tmplParams.length; final int numTmplParams = tmplParams.length;
@ -235,7 +235,7 @@ public class TemplateArgumentDeduction {
* Deduces the mapping for the template parameters from the function parameters, * Deduces the mapping for the template parameters from the function parameters,
* returns <code>false</code> if there is no mapping. * returns <code>false</code> if there is no mapping.
*/ */
static boolean deduceFromFunctionArgs(ICPPFunctionTemplate template, IType[] fnArgs, ValueCategory[] argIsLValue, static boolean deduceFromFunctionArgs(ICPPFunctionTemplate template, List<IType> fnArgs, List<ValueCategory> argCats,
CPPTemplateParameterMap map, boolean checkExactMatch) { CPPTemplateParameterMap map, boolean checkExactMatch) {
try { try {
IType[] fnPars = template.getType().getParameterTypes(); IType[] fnPars = template.getType().getParameterTypes();
@ -246,7 +246,7 @@ public class TemplateArgumentDeduction {
final ICPPTemplateParameter[] tmplPars = template.getTemplateParameters(); final ICPPTemplateParameter[] tmplPars = template.getTemplateParameters();
TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(tmplPars, map, new CPPTemplateParameterMap(fnParCount), 0); TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(tmplPars, map, new CPPTemplateParameterMap(fnParCount), 0);
IType fnParPack= null; IType fnParPack= null;
for (int j= 0; j < fnArgs.length; j++) { for (int j= 0; j < fnArgs.size(); j++) {
IType par; IType par;
if (fnParPack != null) { if (fnParPack != null) {
par= fnParPack; par= fnParPack;
@ -258,7 +258,7 @@ public class TemplateArgumentDeduction {
continue; // non-deduced context continue; // non-deduced context
par= fnParPack= ((ICPPParameterPackType) par).getType(); par= fnParPack= ((ICPPParameterPackType) par).getType();
deduct= new TemplateArgumentDeduction(deduct, fnArgs.length - j); deduct= new TemplateArgumentDeduction(deduct, fnArgs.size() - j);
} }
} else { } else {
break; break;
@ -270,7 +270,7 @@ public class TemplateArgumentDeduction {
boolean isDependentPar= CPPTemplates.isDependentType(par); boolean isDependentPar= CPPTemplates.isDependentType(par);
if (checkExactMatch || isDependentPar) { if (checkExactMatch || isDependentPar) {
IType arg = fnArgs[j]; IType arg = fnArgs.get(j);
par= SemanticUtil.getNestedType(par, SemanticUtil.TDEF); // adjustParameterType preserves typedefs par= SemanticUtil.getNestedType(par, SemanticUtil.TDEF); // adjustParameterType preserves typedefs
// C++0x: 14.9.2.1-1 // C++0x: 14.9.2.1-1
@ -293,7 +293,7 @@ public class TemplateArgumentDeduction {
} }
// 14.8.2.1-2 // 14.8.2.1-2
ValueCategory cat= argIsLValue != null ? argIsLValue[j] : LVALUE; ValueCategory cat= argCats != null ? argCats.get(j) : LVALUE;
if (!deduceFromFunctionArg(par, arg, cat, checkExactMatch, isDependentPar, deduct)) { if (!deduceFromFunctionArg(par, arg, cat, checkExactMatch, isDependentPar, deduct)) {
return false; return false;
} }