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:
parent
ef4a1226fe
commit
bbf5a39ad8
8 changed files with 180 additions and 98 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
|
||||||
if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) {
|
|
||||||
name= (IASTName) name.getParent();
|
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 {
|
try {
|
||||||
if (fnArgs == null || containsDependentType(fnArgs)) {
|
if (containsDependentType(fnArgs))
|
||||||
return new ICPPFunction[] {CPPUnknownFunction.createForSample(template)};
|
return new ICPPFunction[] {CPPUnknownFunction.createForSample(template)};
|
||||||
}
|
|
||||||
if (name instanceof ICPPASTTemplateId && !(template instanceof ICPPConstructor)) {
|
if (requireTemplate) {
|
||||||
tmplArgs = createTemplateArgumentArray((ICPPASTTemplateId) name);
|
tmplArgs = createTemplateArgumentArray((ICPPASTTemplateId) name);
|
||||||
if (hasDependentArgument(tmplArgs)) {
|
if (hasDependentArgument(tmplArgs))
|
||||||
return new ICPPFunction[] {CPPUnknownFunction.createForSample(template)};
|
return new ICPPFunction[] {CPPUnknownFunction.createForSample(template)};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
return NO_FUNCTIONS;
|
return NO_FUNCTIONS;
|
||||||
}
|
}
|
||||||
}
|
haveTemplate= true;
|
||||||
CPPTemplateParameterMap map= new CPPTemplateParameterMap(fnArgs.length);
|
break;
|
||||||
try {
|
|
||||||
ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForFunctionCall(template, tmplArgs, fnArgs, valueCategories, map);
|
|
||||||
if (args != null) {
|
|
||||||
IBinding instance= instantiateFunctionTemplate(template, args, map);
|
|
||||||
if (instance instanceof ICPPFunction) {
|
|
||||||
rf= (ICPPFunction) instance;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (DOMException e) {
|
|
||||||
// try next candidate
|
if (!haveTemplate && !requireTemplate)
|
||||||
|
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
|
} else if (!requireTemplate || fn instanceof ICPPUnknownBinding) {
|
||||||
|| (func instanceof ICPPConstructor) || (func instanceof ICPPUnknownBinding)
|
result.add(fn);
|
||||||
|| (func instanceof ICPPMethod && ((ICPPMethod) func).isDestructor())) {
|
|
||||||
rf= func;
|
|
||||||
}
|
}
|
||||||
if (rf != func || result != fns) {
|
|
||||||
if (result == fns) {
|
|
||||||
result= new ICPPFunction[fns.length-(i-idx)];
|
|
||||||
System.arraycopy(fns, 0, result, 0, idx);
|
|
||||||
}
|
}
|
||||||
if (rf != null)
|
|
||||||
result[idx]= rf;
|
|
||||||
}
|
}
|
||||||
if (rf != null)
|
return result.toArray(new ICPPFunction[result.size()]);
|
||||||
idx++;
|
}
|
||||||
|
|
||||||
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static protected void instantiateConversionTemplates(IFunction[] functions, IType conversionType) {
|
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) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
@ -2079,6 +2112,14 @@ 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))
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue