mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 355304: Argument deduction for explicit function template specialization.
This commit is contained in:
parent
49342dc9bf
commit
64c383952a
12 changed files with 475 additions and 439 deletions
|
@ -9480,4 +9480,16 @@ public class AST2CPPTests extends AST2BaseTest {
|
||||||
public void testAmbiguityResolution_Bug354599() throws Exception {
|
public void testAmbiguityResolution_Bug354599() throws Exception {
|
||||||
parseAndCheckBindings();
|
parseAndCheckBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// void (g)(char);
|
||||||
|
// void (g )(int);
|
||||||
|
// void (g )(int);
|
||||||
|
public void testFunctionRedeclarations() throws Exception {
|
||||||
|
BindingAssertionHelper bh= getAssertionHelper();
|
||||||
|
IFunction g1= bh.assertNonProblem("g)", 1);
|
||||||
|
IFunction g2= bh.assertNonProblem("g )", 1);
|
||||||
|
IFunction g3= bh.assertNonProblem("g )", 1);
|
||||||
|
assertNotSame(g1, g2);
|
||||||
|
assertSame(g2, g3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5454,4 +5454,16 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
public void testTemplateTemplateParameterMatching_352859() throws Exception {
|
public void testTemplateTemplateParameterMatching_352859() throws Exception {
|
||||||
parseAndCheckBindings();
|
parseAndCheckBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template<typename T> T f();
|
||||||
|
// template<> int f() {
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
public void testArgumentDeductionFromReturnTypeOfExplicitSpecialization_355304() throws Exception {
|
||||||
|
parseAndCheckBindings();
|
||||||
|
BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
ICPPFunctionTemplate template= bh.assertNonProblem("f();", 1);
|
||||||
|
ICPPTemplateInstance inst= bh.assertNonProblem("f() {", 1);
|
||||||
|
assertSame(template, inst.getTemplateDefinition());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,18 +11,23 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.pdom.tests;
|
package org.eclipse.cdt.internal.pdom.tests;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import junit.framework.Test;
|
import junit.framework.Test;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.dom.IPDOMManager;
|
import org.eclipse.cdt.core.dom.IPDOMManager;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
|
||||||
import org.eclipse.cdt.core.index.IndexFilter;
|
import org.eclipse.cdt.core.index.IndexFilter;
|
||||||
import org.eclipse.cdt.core.model.ICProject;
|
import org.eclipse.cdt.core.model.ICProject;
|
||||||
import org.eclipse.cdt.core.testplugin.CProjectHelper;
|
import org.eclipse.cdt.core.testplugin.CProjectHelper;
|
||||||
import org.eclipse.cdt.core.testplugin.CTestPlugin;
|
import org.eclipse.cdt.core.testplugin.CTestPlugin;
|
||||||
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
|
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
|
||||||
import org.eclipse.cdt.internal.core.CCoreInternals;
|
import org.eclipse.cdt.internal.core.CCoreInternals;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
|
||||||
import org.eclipse.cdt.internal.core.index.IIndexFragment;
|
import org.eclipse.cdt.internal.core.index.IIndexFragment;
|
||||||
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
||||||
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
|
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
|
||||||
|
@ -96,7 +101,15 @@ public class CPPFunctionTemplateTests extends PDOMTestBase {
|
||||||
ICPPFunctionTemplate fooX= (ICPPFunctionTemplate) bs[b ? 0 : 1];
|
ICPPFunctionTemplate fooX= (ICPPFunctionTemplate) bs[b ? 0 : 1];
|
||||||
ICPPFunctionTemplate fooAB= (ICPPFunctionTemplate) bs[b ? 1 : 0];
|
ICPPFunctionTemplate fooAB= (ICPPFunctionTemplate) bs[b ? 1 : 0];
|
||||||
|
|
||||||
assertNameCount(pdom, fooX, IIndexFragment.FIND_REFERENCES, 3);
|
List<ICPPTemplateInstance> instances= Arrays.asList(((ICPPInstanceCache) fooX).getAllInstances());
|
||||||
assertNameCount(pdom, fooAB, IIndexFragment.FIND_REFERENCES, 6);
|
assertEquals(3, instances.size());
|
||||||
|
for (ICPPTemplateInstance inst : instances) {
|
||||||
|
assertEquals(1, pdom.findNames(inst, IIndexFragment.FIND_REFERENCES).length);
|
||||||
|
}
|
||||||
|
instances= Arrays.asList(((ICPPInstanceCache) fooAB).getAllInstances());
|
||||||
|
assertEquals(6, instances.size());
|
||||||
|
for (ICPPTemplateInstance inst : instances) {
|
||||||
|
assertEquals(1, pdom.findNames(inst, IIndexFragment.FIND_REFERENCES).length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ abstract class CElementHandle implements ICElementHandle, ISourceReference {
|
||||||
|
|
||||||
private IRegion fRegion;
|
private IRegion fRegion;
|
||||||
private long fTimestamp;
|
private long fTimestamp;
|
||||||
|
private int fIndex;
|
||||||
|
|
||||||
public CElementHandle(ICElement parent, int type, String name) {
|
public CElementHandle(ICElement parent, int type, String name) {
|
||||||
fParent= parent;
|
fParent= parent;
|
||||||
|
@ -57,8 +58,8 @@ abstract class CElementHandle implements ICElementHandle, ISourceReference {
|
||||||
// undo this here
|
// undo this here
|
||||||
if (name.length() > 0 && name.charAt(0)=='{') {
|
if (name.length() > 0 && name.charAt(0)=='{') {
|
||||||
fName= ""; //$NON-NLS-1$
|
fName= ""; //$NON-NLS-1$
|
||||||
}
|
fIndex= name.hashCode();
|
||||||
else {
|
} else {
|
||||||
fName= name;
|
fName= name;
|
||||||
}
|
}
|
||||||
fRegion= new Region(0,0);
|
fRegion= new Region(0,0);
|
||||||
|
@ -313,6 +314,6 @@ abstract class CElementHandle implements ICElementHandle, ISourceReference {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getIndex() {
|
public int getIndex() {
|
||||||
return 0;
|
return fIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,7 +163,7 @@ public class CPPTemplateParameterMap implements ICPPTemplateParameterMap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean mergeToExplicit(CPPTemplateParameterMap deducedMap) {
|
public boolean addDeducedArgs(CPPTemplateParameterMap deducedMap) {
|
||||||
Integer[] keys= deducedMap.getAllParameterPositions();
|
Integer[] keys= deducedMap.getAllParameterPositions();
|
||||||
for (Integer key : keys) {
|
for (Integer key : keys) {
|
||||||
Object explicit= fMap.get(key);
|
Object explicit= fMap.get(key);
|
||||||
|
|
|
@ -458,16 +458,12 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// explicit function specializations are found via name resolution, need to
|
// Some declarations are found via name resolution (e.g. when using a qualified name),
|
||||||
// add name as definition and check the declaration specifier.
|
// add name as definition and check the declaration specifier.
|
||||||
|
final IASTDeclaration declaration = data.forDeclaration();
|
||||||
|
if (declaration != null) {
|
||||||
|
// Functions
|
||||||
if (binding instanceof IFunction) {
|
if (binding instanceof IFunction) {
|
||||||
if (data.forFunctionDeclaration()) {
|
|
||||||
IASTNode declaration= data.astName;
|
|
||||||
while (declaration instanceof IASTName)
|
|
||||||
declaration= declaration.getParent();
|
|
||||||
while (declaration instanceof IASTDeclarator)
|
|
||||||
declaration= declaration.getParent();
|
|
||||||
|
|
||||||
binding= checkDeclSpecifier(binding, data.astName, declaration);
|
binding= checkDeclSpecifier(binding, data.astName, declaration);
|
||||||
if (!(binding instanceof IProblemBinding)) {
|
if (!(binding instanceof IProblemBinding)) {
|
||||||
if (declaration instanceof ICPPASTFunctionDefinition) {
|
if (declaration instanceof ICPPASTFunctionDefinition) {
|
||||||
|
@ -475,24 +471,17 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
// Definitions of static fields.
|
||||||
|
|
||||||
// Definitions of static fields are found via name resolution, need to add name to
|
|
||||||
// the binding to get the right type of arrays that may be declared incomplete.
|
|
||||||
if (binding instanceof ICPPField && data.astName.isDefinition()) {
|
if (binding instanceof ICPPField && data.astName.isDefinition()) {
|
||||||
IASTNode declaration= data.astName;
|
|
||||||
while (declaration instanceof IASTName)
|
|
||||||
declaration= declaration.getParent();
|
|
||||||
while (declaration instanceof IASTDeclarator)
|
|
||||||
declaration= declaration.getParent();
|
|
||||||
if (declaration.getPropertyInParent() != IASTCompositeTypeSpecifier.MEMBER_DECLARATION) {
|
if (declaration.getPropertyInParent() != IASTCompositeTypeSpecifier.MEMBER_DECLARATION) {
|
||||||
ASTInternal.addDefinition(binding, data.astName);
|
ASTInternal.addDefinition(binding, data.astName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If we're still null...
|
// If we're still null...
|
||||||
if (binding == null) {
|
if (binding == null) {
|
||||||
if (name instanceof ICPPASTQualifiedName && data.forFunctionDeclaration()) {
|
if (name instanceof ICPPASTQualifiedName && declaration != null) {
|
||||||
binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_MEMBER_DECLARATION_NOT_FOUND,
|
binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_MEMBER_DECLARATION_NOT_FOUND,
|
||||||
data.getFoundBindings());
|
data.getFoundBindings());
|
||||||
} else {
|
} else {
|
||||||
|
@ -601,9 +590,7 @@ public class CPPSemantics {
|
||||||
data.forceQualified = true;
|
data.forceQualified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent instanceof ICPPASTFunctionDeclarator) {
|
if (parent instanceof IASTIdExpression) {
|
||||||
data.setFunctionParameters(((ICPPASTFunctionDeclarator) parent).getParameters());
|
|
||||||
} else if (parent instanceof IASTIdExpression) {
|
|
||||||
IASTNode grand= parent.getParent();
|
IASTNode grand= parent.getParent();
|
||||||
while (grand instanceof IASTUnaryExpression
|
while (grand instanceof IASTUnaryExpression
|
||||||
&& ((IASTUnaryExpression) grand).getOperator() == IASTUnaryExpression.op_bracketedPrimary) {
|
&& ((IASTUnaryExpression) grand).getOperator() == IASTUnaryExpression.op_bracketedPrimary) {
|
||||||
|
@ -2276,7 +2263,7 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ICPPFunction[] selectByArgumentCount(LookupData data, ICPPFunction[] functions) throws DOMException {
|
private static ICPPFunction[] selectByArgumentCount(LookupData data, ICPPFunction[] functions) throws DOMException {
|
||||||
assert !data.forFunctionDeclaration();
|
assert data.forDeclaration() == null;
|
||||||
|
|
||||||
int argumentCount = data.getFunctionArgumentCount();
|
int argumentCount = data.getFunctionArgumentCount();
|
||||||
|
|
||||||
|
@ -2328,16 +2315,6 @@ public class CPPSemantics {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isMatchingFunctionDeclaration(ICPPFunction candidate, LookupData data) {
|
|
||||||
IASTNode node = data.astName.getParent();
|
|
||||||
while (node instanceof IASTName)
|
|
||||||
node = node.getParent();
|
|
||||||
if (node instanceof IASTDeclarator) {
|
|
||||||
return isSameFunction(candidate, (IASTDeclarator) node);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static IBinding resolveFunction(LookupData data, ICPPFunction[] fns, boolean allowUDC) throws DOMException {
|
static IBinding resolveFunction(LookupData data, ICPPFunction[] fns, boolean allowUDC) throws DOMException {
|
||||||
fns= (ICPPFunction[]) ArrayUtil.trim(ICPPFunction.class, fns);
|
fns= (ICPPFunction[]) ArrayUtil.trim(ICPPFunction.class, fns);
|
||||||
if (fns == null || fns.length == 0)
|
if (fns == null || fns.length == 0)
|
||||||
|
@ -2348,17 +2325,18 @@ public class CPPSemantics {
|
||||||
if (data.forUsingDeclaration())
|
if (data.forUsingDeclaration())
|
||||||
return new CPPUsingDeclaration(data.astName, fns);
|
return new CPPUsingDeclaration(data.astName, fns);
|
||||||
|
|
||||||
// No arguments to resolve function
|
|
||||||
if (!data.hasFunctionArguments()) {
|
|
||||||
return createFunctionSet(data.astName, fns);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.astName instanceof ICPPASTConversionName) {
|
if (data.astName instanceof ICPPASTConversionName) {
|
||||||
return resolveUserDefinedConversion(data, fns);
|
return resolveUserDefinedConversion(data, fns);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.forFunctionDeclaration())
|
if (data.forDeclaration() != null) {
|
||||||
return resolveFunctionDeclaration(data, fns);
|
return resolveFunctionDeclaration(data, fns);
|
||||||
|
}
|
||||||
|
|
||||||
|
// No arguments to resolve function
|
||||||
|
if (!data.hasFunctionArguments()) {
|
||||||
|
return createFunctionSet(data.astName, fns);
|
||||||
|
}
|
||||||
|
|
||||||
// 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();
|
||||||
|
@ -2519,39 +2497,78 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called for declarations with qualified name or template-id. Also for explicit function
|
||||||
|
* specializations or instantiations.
|
||||||
|
*/
|
||||||
private static IBinding resolveFunctionDeclaration(LookupData data, ICPPFunction[] fns) throws DOMException {
|
private static IBinding resolveFunctionDeclaration(LookupData data, ICPPFunction[] fns) throws DOMException {
|
||||||
if (data.forExplicitFunctionSpecialization()) {
|
final IASTDeclarator dtor= ASTQueries.findTypeRelevantDeclarator(data.getDeclarator());
|
||||||
fns = CPPTemplates.instantiateForFunctionCall(data.astName,
|
final IType t = CPPVisitor.createType(dtor);
|
||||||
fns,
|
if (!(t instanceof ICPPFunctionType))
|
||||||
Arrays.asList(data.getFunctionArgumentTypes()), Arrays.asList(data.getFunctionArgumentValueCategories()),
|
return null;
|
||||||
data.argsContainImpliedObject);
|
|
||||||
}
|
final ICPPFunctionType ft= (ICPPFunctionType) t;
|
||||||
|
|
||||||
int argCount = data.getFunctionArgumentCount();
|
IASTName templateID= data.astName;
|
||||||
if (argCount == 1) {
|
if (templateID.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) {
|
||||||
// check for parameter of type void
|
templateID= (ICPPASTTemplateId) templateID.getParent();
|
||||||
final IType[] argTypes = data.getFunctionArgumentTypes();
|
|
||||||
if (argTypes.length == 1 && SemanticUtil.isVoidType(argTypes[0])) {
|
|
||||||
argCount= 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 14.5.4 Friends with template ids require instantiation
|
||||||
|
boolean isFriend= CPPVisitor.isFriendDeclaration(data.forDeclaration());
|
||||||
|
if (!data.forExplicitFunctionSpecialization()
|
||||||
|
&& !(isFriend && templateID instanceof ICPPASTTemplateId)) {
|
||||||
|
// Search for a matching function
|
||||||
for (ICPPFunction fn : fns) {
|
for (ICPPFunction fn : fns) {
|
||||||
if (fn != null && !(fn instanceof IProblemBinding) && !(fn instanceof ICPPUnknownBinding)) {
|
if (fn != null && !(fn instanceof IProblemBinding) && !(fn instanceof ICPPUnknownBinding)) {
|
||||||
// The index is optimized to provide the function type, avoid using the parameters
|
if (isSameFunction(fn, dtor)) {
|
||||||
// as long as possible.
|
|
||||||
final IType[] parameterTypes = fn.getType().getParameterTypes();
|
|
||||||
int parCount = parameterTypes.length;
|
|
||||||
if (parCount == 1 && SemanticUtil.isVoidType(parameterTypes[0]))
|
|
||||||
parCount= 0;
|
|
||||||
|
|
||||||
if (parCount == argCount && isMatchingFunctionDeclaration(fn, data)) {
|
|
||||||
return fn;
|
return fn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 14.5.4 Friends with qualified ids allow for instantiation
|
||||||
|
if (!data.forExplicitFunctionInstantiation()
|
||||||
|
&& !(isFriend && templateID.getParent() instanceof ICPPASTQualifiedName)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to instantiate a template
|
||||||
|
IASTTranslationUnit tu= data.tu;
|
||||||
|
ICPPTemplateArgument[] tmplArgs= ICPPTemplateArgument.EMPTY_ARGUMENTS;
|
||||||
|
if (templateID instanceof ICPPASTTemplateId) {
|
||||||
|
tmplArgs = CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) templateID);
|
||||||
|
}
|
||||||
|
|
||||||
|
ICPPFunctionTemplate bestTemplate= null;
|
||||||
|
ICPPFunction bestInst= null;
|
||||||
|
boolean isAmbiguous= false;
|
||||||
|
for (ICPPFunction fn : fns) {
|
||||||
|
if (fn instanceof ICPPFunctionTemplate
|
||||||
|
&& !(fn instanceof IProblemBinding) && !(fn instanceof ICPPUnknownBinding)) {
|
||||||
|
ICPPFunctionTemplate template= (ICPPFunctionTemplate) fn;
|
||||||
|
ICPPFunction inst= CPPTemplates.instantiateForFunctionDeclaration(template, tmplArgs, ft);
|
||||||
|
if (inst != null) {
|
||||||
|
int cmp= CPPTemplates.orderFunctionTemplates(bestTemplate, template, TypeSelection.PARAMETERS_AND_RETURN_TYPE);
|
||||||
|
if (cmp == 0)
|
||||||
|
cmp= compareByRelevance(tu, bestTemplate, template);
|
||||||
|
|
||||||
|
if (cmp == 0)
|
||||||
|
isAmbiguous= true;
|
||||||
|
|
||||||
|
if (cmp < 0) {
|
||||||
|
isAmbiguous= false;
|
||||||
|
bestTemplate= template;
|
||||||
|
bestInst= inst;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isAmbiguous)
|
||||||
|
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, fns);
|
||||||
|
|
||||||
|
return bestInst;
|
||||||
|
}
|
||||||
|
|
||||||
public static void sortAstBeforeIndex(IFunction[] fns) {
|
public static void sortAstBeforeIndex(IFunction[] fns) {
|
||||||
int iast= 0;
|
int iast= 0;
|
||||||
|
@ -2691,14 +2708,15 @@ public class CPPSemantics {
|
||||||
return new CPPReferenceType(implicitType, false);
|
return new CPPReferenceType(implicitType, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IBinding resolveUserDefinedConversion(LookupData data, IFunction[] fns) {
|
private static IBinding resolveUserDefinedConversion(LookupData data, ICPPFunction[] fns) {
|
||||||
ICPPASTConversionName astName= (ICPPASTConversionName) data.astName;
|
ICPPASTConversionName astName= (ICPPASTConversionName) data.astName;
|
||||||
IType t= CPPVisitor.createType(astName.getTypeId());
|
IType t= CPPVisitor.createType(astName.getTypeId());
|
||||||
if (t instanceof ISemanticProblem) {
|
if (t instanceof ISemanticProblem) {
|
||||||
return new ProblemBinding(astName, IProblemBinding.SEMANTIC_INVALID_TYPE, data.getFoundBindings());
|
return new ProblemBinding(astName, IProblemBinding.SEMANTIC_INVALID_TYPE, data.getFoundBindings());
|
||||||
}
|
}
|
||||||
if (!data.forFunctionDeclaration() || data.forExplicitFunctionSpecialization()) {
|
if (data.forDeclaration() == null ||
|
||||||
CPPTemplates.instantiateConversionTemplates(fns, t);
|
data.forExplicitFunctionSpecialization() || data.forExplicitFunctionInstantiation()) {
|
||||||
|
fns= CPPTemplates.instantiateConversionTemplates(fns, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
IFunction unknown= null;
|
IFunction unknown= null;
|
||||||
|
@ -2896,12 +2914,10 @@ public class CPPSemantics {
|
||||||
final ICPPFunctionTemplate template = (ICPPFunctionTemplate) fn;
|
final ICPPFunctionTemplate template = (ICPPFunctionTemplate) fn;
|
||||||
ICPPFunction inst= CPPTemplates.instantiateForAddressOfFunction(template, (ICPPFunctionType) targetType, name);
|
ICPPFunction inst= CPPTemplates.instantiateForAddressOfFunction(template, (ICPPFunctionType) targetType, name);
|
||||||
if (inst != null) {
|
if (inst != null) {
|
||||||
int cmp= -1;
|
int cmp= CPPTemplates.orderFunctionTemplates(resultTemplate, template, TypeSelection.PARAMETERS_AND_RETURN_TYPE);
|
||||||
if (result != null) {
|
|
||||||
cmp= CPPTemplates.orderFunctionTemplates(resultTemplate, template, TypeSelection.PARAMETERS_AND_RETURN_TYPE);
|
|
||||||
if (cmp == 0)
|
if (cmp == 0)
|
||||||
cmp= compareByRelevance(tu, resultTemplate, template);
|
cmp= compareByRelevance(tu, resultTemplate, template);
|
||||||
}
|
|
||||||
if (cmp == 0)
|
if (cmp == 0)
|
||||||
isAmbiguous= true;
|
isAmbiguous= true;
|
||||||
|
|
||||||
|
@ -3627,7 +3643,9 @@ public class CPPSemantics {
|
||||||
if (templateDecl != null) {
|
if (templateDecl != null) {
|
||||||
|
|
||||||
if (templateDecl instanceof ICPPASTTemplateSpecialization) {
|
if (templateDecl instanceof ICPPASTTemplateSpecialization) {
|
||||||
if (!(function instanceof ICPPSpecialization))
|
if (!(function instanceof ICPPTemplateInstance))
|
||||||
|
return false;
|
||||||
|
if (!((ICPPTemplateInstance) function).isExplicitSpecialization())
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if (function instanceof ICPPTemplateDefinition) {
|
if (function instanceof ICPPTemplateDefinition) {
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier;
|
||||||
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;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
|
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
|
||||||
|
@ -51,6 +52,7 @@ import org.eclipse.cdt.core.dom.ast.ITypedef;
|
||||||
import org.eclipse.cdt.core.dom.ast.IValue;
|
import org.eclipse.cdt.core.dom.ast.IValue;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
|
||||||
|
@ -706,10 +708,17 @@ public class CPPTemplates {
|
||||||
parentOfName= parentOfName.getParent();
|
parentOfName= parentOfName.getParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
return parentOfName instanceof ICPPASTElaboratedTypeSpecifier ||
|
if (parentOfName instanceof ICPPASTElaboratedTypeSpecifier ||
|
||||||
parentOfName instanceof ICPPASTCompositeTypeSpecifier ||
|
parentOfName instanceof ICPPASTCompositeTypeSpecifier ||
|
||||||
parentOfName instanceof ICPPASTNamedTypeSpecifier ||
|
parentOfName instanceof ICPPASTNamedTypeSpecifier ||
|
||||||
parentOfName instanceof ICPPASTBaseSpecifier;
|
parentOfName instanceof ICPPASTBaseSpecifier)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (parentOfName instanceof IASTDeclarator) {
|
||||||
|
IASTDeclarator rel= ASTQueries.findTypeRelevantDeclarator((IASTDeclarator) parentOfName);
|
||||||
|
return !(rel instanceof IASTFunctionDeclarator);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1310,7 +1319,7 @@ public class CPPTemplates {
|
||||||
|
|
||||||
// determine nesting level of parent
|
// determine nesting level of parent
|
||||||
int level= missingTemplateDecls;
|
int level= missingTemplateDecls;
|
||||||
if (!CPPVisitor.isFriendFunctionDeclaration(innerMostTDecl.getDeclaration())) {
|
if (!isFriendFunctionDeclaration(innerMostTDecl.getDeclaration())) {
|
||||||
node= outerMostTDecl.getParent();
|
node= outerMostTDecl.getParent();
|
||||||
while (node != null) {
|
while (node != null) {
|
||||||
if (node instanceof ICPPASTInternalTemplateDeclaration) {
|
if (node instanceof ICPPASTInternalTemplateDeclaration) {
|
||||||
|
@ -1335,6 +1344,23 @@ public class CPPTemplates {
|
||||||
innerMostTDecl.setAssociatedWithLastName(lastIsTemplate);
|
innerMostTDecl.setAssociatedWithLastName(lastIsTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isFriendFunctionDeclaration(IASTDeclaration declaration) {
|
||||||
|
while (declaration instanceof ICPPASTTemplateDeclaration) {
|
||||||
|
declaration= ((ICPPASTTemplateDeclaration) declaration).getDeclaration();
|
||||||
|
}
|
||||||
|
if (declaration instanceof IASTSimpleDeclaration) {
|
||||||
|
IASTSimpleDeclaration sdecl = (IASTSimpleDeclaration) declaration;
|
||||||
|
ICPPASTDeclSpecifier declspec= (ICPPASTDeclSpecifier) sdecl.getDeclSpecifier();
|
||||||
|
if (declspec.isFriend()) {
|
||||||
|
IASTDeclarator[] dtors= sdecl.getDeclarators();
|
||||||
|
if (dtors.length == 1 && ASTQueries.findTypeRelevantDeclarator(dtors[0]) instanceof IASTFunctionDeclarator) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private static CharArraySet collectTemplateParameterNames(ICPPASTTemplateDeclaration tdecl) {
|
private static CharArraySet collectTemplateParameterNames(ICPPASTTemplateDeclaration tdecl) {
|
||||||
CharArraySet set= new CharArraySet(4);
|
CharArraySet set= new CharArraySet(4);
|
||||||
while(true) {
|
while(true) {
|
||||||
|
@ -1628,24 +1654,30 @@ public class CPPTemplates {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void instantiateConversionTemplates(IFunction[] functions, IType conversionType) {
|
/**
|
||||||
|
* 14.8.2.3 Deducing conversion function template arguments
|
||||||
|
*/
|
||||||
|
static ICPPFunction[] instantiateConversionTemplates(ICPPFunction[] functions, IType conversionType) {
|
||||||
boolean checkedForDependentType= false;
|
boolean checkedForDependentType= false;
|
||||||
for (int i = 0; i < functions.length; i++) {
|
ICPPFunction[] result= functions;
|
||||||
IFunction func = functions[i];
|
int i=0;
|
||||||
if (func instanceof ICPPFunctionTemplate) {
|
boolean done= false;
|
||||||
ICPPFunctionTemplate template= (ICPPFunctionTemplate) func;
|
for (ICPPFunction f : functions) {
|
||||||
functions[i]= null;
|
ICPPFunction inst = f;
|
||||||
|
if (f instanceof ICPPFunctionTemplate) {
|
||||||
|
ICPPFunctionTemplate template= (ICPPFunctionTemplate) f;
|
||||||
|
inst= null;
|
||||||
|
|
||||||
// extract template arguments and parameter types.
|
// Extract template arguments and parameter types.
|
||||||
if (!checkedForDependentType) {
|
if (!checkedForDependentType) {
|
||||||
try {
|
try {
|
||||||
if (isDependentType(conversionType)) {
|
if (isDependentType(conversionType)) {
|
||||||
functions[i]= CPPUnknownFunction.createForSample(template);
|
inst= CPPUnknownFunction.createForSample(template);
|
||||||
return;
|
done= true;
|
||||||
}
|
}
|
||||||
checkedForDependentType= true;
|
checkedForDependentType= true;
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
return;
|
return functions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CPPTemplateParameterMap map= new CPPTemplateParameterMap(1);
|
CPPTemplateParameterMap map= new CPPTemplateParameterMap(1);
|
||||||
|
@ -1653,16 +1685,48 @@ public class CPPTemplates {
|
||||||
ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForConversion(template, conversionType, map);
|
ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForConversion(template, conversionType, map);
|
||||||
if (args != null) {
|
if (args != null) {
|
||||||
IBinding instance= instantiateFunctionTemplate(template, args, map);
|
IBinding instance= instantiateFunctionTemplate(template, args, map);
|
||||||
if (instance instanceof IFunction) {
|
if (instance instanceof ICPPFunction) {
|
||||||
functions[i]= (IFunction) instance;
|
inst= (ICPPFunction) instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
// try next candidate
|
// try next candidate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (result != functions || f != inst) {
|
||||||
|
if (result == functions) {
|
||||||
|
result= new ICPPFunction[functions.length];
|
||||||
|
System.arraycopy(functions, 0, result, 0, i);
|
||||||
|
}
|
||||||
|
result[i++]= inst;
|
||||||
|
}
|
||||||
|
if (done)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 14.8.2.6 Deducing template arguments from a function declaration
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static ICPPFunction instantiateForFunctionDeclaration(ICPPFunctionTemplate template,
|
||||||
|
ICPPTemplateArgument[] args, ICPPFunctionType functionType) {
|
||||||
|
CPPTemplateParameterMap map= new CPPTemplateParameterMap(1);
|
||||||
|
try {
|
||||||
|
args= TemplateArgumentDeduction.deduceForDeclaration(template, args, functionType, map);
|
||||||
|
if (args != null) {
|
||||||
|
IBinding instance= instantiateFunctionTemplate(template, args, map);
|
||||||
|
if (instance instanceof ICPPFunction) {
|
||||||
|
return (ICPPFunction) instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (DOMException e) {
|
||||||
|
// try next candidate
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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]
|
||||||
|
@ -1702,6 +1766,13 @@ public class CPPTemplates {
|
||||||
// 14.5.6.2 Partial ordering of function templates
|
// 14.5.6.2 Partial ordering of function templates
|
||||||
static int orderFunctionTemplates(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2, TypeSelection mode)
|
static int orderFunctionTemplates(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2, TypeSelection mode)
|
||||||
throws DOMException {
|
throws DOMException {
|
||||||
|
if (f1 == f2)
|
||||||
|
return 0;
|
||||||
|
if (f1 == null)
|
||||||
|
return -1;
|
||||||
|
if (f2 == null)
|
||||||
|
return 1;
|
||||||
|
|
||||||
int s1 = compareSpecialization(f1, f2, mode);
|
int s1 = compareSpecialization(f1, f2, mode);
|
||||||
int s2 = compareSpecialization(f2, f1, mode);
|
int s2 = compareSpecialization(f2, f1, mode);
|
||||||
|
|
||||||
|
|
|
@ -633,13 +633,7 @@ public class CPPVisitor extends ASTQueries {
|
||||||
boolean isFriendDecl= false;
|
boolean isFriendDecl= false;
|
||||||
ICPPScope scope = (ICPPScope) getContainingNonTemplateScope(name);
|
ICPPScope scope = (ICPPScope) getContainingNonTemplateScope(name);
|
||||||
if (scope instanceof ICPPClassScope) {
|
if (scope instanceof ICPPClassScope) {
|
||||||
if (parent instanceof IASTSimpleDeclaration) {
|
isFriendDecl = isFriendDeclaration(parent);
|
||||||
ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTSimpleDeclaration) parent).getDeclSpecifier();
|
|
||||||
isFriendDecl= declSpec.isFriend();
|
|
||||||
} else if (parent instanceof IASTFunctionDefinition) {
|
|
||||||
ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTFunctionDefinition) parent).getDeclSpecifier();
|
|
||||||
isFriendDecl= declSpec.isFriend();
|
|
||||||
}
|
|
||||||
if (isFriendDecl) {
|
if (isFriendDecl) {
|
||||||
try {
|
try {
|
||||||
while (scope.getKind() == EScopeKind.eClassType) {
|
while (scope.getKind() == EScopeKind.eClassType) {
|
||||||
|
@ -753,6 +747,18 @@ public class CPPVisitor extends ASTQueries {
|
||||||
return binding;
|
return binding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isFriendDeclaration(IASTNode decl) {
|
||||||
|
IASTDeclSpecifier declSpec;
|
||||||
|
if (decl instanceof IASTSimpleDeclaration) {
|
||||||
|
declSpec = ((IASTSimpleDeclaration) decl).getDeclSpecifier();
|
||||||
|
} else if (decl instanceof IASTFunctionDefinition) {
|
||||||
|
declSpec = ((IASTFunctionDefinition) decl).getDeclSpecifier();
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return declSpec instanceof ICPPASTDeclSpecifier && ((ICPPASTDeclSpecifier) declSpec).isFriend();
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isConstructor(IScope containingScope, IASTDeclarator declarator) {
|
public static boolean isConstructor(IScope containingScope, IASTDeclarator declarator) {
|
||||||
if (containingScope == null || !(containingScope instanceof ICPPClassScope))
|
if (containingScope == null || !(containingScope instanceof ICPPClassScope))
|
||||||
return false;
|
return false;
|
||||||
|
@ -2340,7 +2346,6 @@ public class CPPVisitor extends ASTQueries {
|
||||||
*/
|
*/
|
||||||
public static IBinding findDeclarationOwner(IASTNode node, boolean allowFunction) {
|
public static IBinding findDeclarationOwner(IASTNode node, boolean allowFunction) {
|
||||||
// Search for declaration
|
// Search for declaration
|
||||||
boolean isFriend= false;
|
|
||||||
boolean isNonSimpleElabDecl= false;
|
boolean isNonSimpleElabDecl= false;
|
||||||
while (!(node instanceof IASTDeclaration)) {
|
while (!(node instanceof IASTDeclaration)) {
|
||||||
if (node == null)
|
if (node == null)
|
||||||
|
@ -2360,19 +2365,7 @@ public class CPPVisitor extends ASTQueries {
|
||||||
node= node.getParent();
|
node= node.getParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node instanceof IASTSimpleDeclaration) {
|
boolean isFriend= isFriendDeclaration(node);
|
||||||
final IASTSimpleDeclaration sdecl = (IASTSimpleDeclaration) node;
|
|
||||||
ICPPASTDeclSpecifier declSpec= (ICPPASTDeclSpecifier) sdecl.getDeclSpecifier();
|
|
||||||
if (declSpec.isFriend()) {
|
|
||||||
isFriend= true;
|
|
||||||
}
|
|
||||||
} else if (node instanceof IASTFunctionDefinition) {
|
|
||||||
IASTFunctionDefinition funcDefinition = (IASTFunctionDefinition) node;
|
|
||||||
ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) funcDefinition.getDeclSpecifier();
|
|
||||||
if (declSpec.isFriend()) {
|
|
||||||
isFriend= true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search for enclosing binding
|
// Search for enclosing binding
|
||||||
IASTName name= null;
|
IASTName name= null;
|
||||||
|
@ -2409,26 +2402,6 @@ public class CPPVisitor extends ASTQueries {
|
||||||
return name.resolveBinding();
|
return name.resolveBinding();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether a given declaration is a friend function declaration.
|
|
||||||
*/
|
|
||||||
public static boolean isFriendFunctionDeclaration(IASTDeclaration declaration) {
|
|
||||||
while (declaration instanceof ICPPASTTemplateDeclaration) {
|
|
||||||
declaration= ((ICPPASTTemplateDeclaration) declaration).getDeclaration();
|
|
||||||
}
|
|
||||||
if (declaration instanceof IASTSimpleDeclaration) {
|
|
||||||
IASTSimpleDeclaration sdecl = (IASTSimpleDeclaration) declaration;
|
|
||||||
ICPPASTDeclSpecifier declspec= (ICPPASTDeclSpecifier) sdecl.getDeclSpecifier();
|
|
||||||
if (declspec.isFriend()) {
|
|
||||||
IASTDeclarator[] dtors= sdecl.getDeclarators();
|
|
||||||
if (dtors.length == 1 && findTypeRelevantDeclarator(dtors[0]) instanceof IASTFunctionDeclarator) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean doesNotSpecifyType(IASTDeclSpecifier declspec) {
|
public static boolean doesNotSpecifyType(IASTDeclSpecifier declspec) {
|
||||||
if (declspec instanceof ICPPASTSimpleDeclSpecifier) {
|
if (declspec instanceof ICPPASTSimpleDeclSpecifier) {
|
||||||
ICPPASTSimpleDeclSpecifier ds= (ICPPASTSimpleDeclSpecifier) declspec;
|
ICPPASTSimpleDeclSpecifier ds= (ICPPASTSimpleDeclSpecifier) declspec;
|
||||||
|
|
|
@ -684,10 +684,11 @@ public class Conversions {
|
||||||
|
|
||||||
final IType uqSource= getNestedType(source, TDEF | REF | CVTYPE);
|
final IType uqSource= getNestedType(source, TDEF | REF | CVTYPE);
|
||||||
if (uqSource instanceof ICPPClassType) {
|
if (uqSource instanceof ICPPClassType) {
|
||||||
ICPPMethod[] ops = SemanticUtil.getConversionOperators((ICPPClassType) uqSource);
|
ICPPFunction[] ops = SemanticUtil.getConversionOperators((ICPPClassType) uqSource);
|
||||||
CPPTemplates.instantiateConversionTemplates(ops, t);
|
ops= CPPTemplates.instantiateConversionTemplates(ops, t);
|
||||||
for (final ICPPMethod op : ops) {
|
for (final ICPPFunction f : ops) {
|
||||||
if (op != null && !(op instanceof IProblemBinding)) {
|
if (f instanceof ICPPMethod && !(f instanceof IProblemBinding)) {
|
||||||
|
ICPPMethod op= (ICPPMethod) f;
|
||||||
if (op.isExplicit())
|
if (op.isExplicit())
|
||||||
continue;
|
continue;
|
||||||
final IType returnType = op.getType().getReturnType();
|
final IType returnType = op.getType().getReturnType();
|
||||||
|
@ -733,12 +734,13 @@ public class Conversions {
|
||||||
c.setDeferredUDC(DeferredUDC.INIT_BY_CONVERSION);
|
c.setDeferredUDC(DeferredUDC.INIT_BY_CONVERSION);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
ICPPMethod[] ops = SemanticUtil.getConversionOperators(uqSource);
|
ICPPFunction[] ops = SemanticUtil.getConversionOperators(uqSource);
|
||||||
CPPTemplates.instantiateConversionTemplates(ops, target);
|
ops= CPPTemplates.instantiateConversionTemplates(ops, target);
|
||||||
FunctionCost cost1= null;
|
FunctionCost cost1= null;
|
||||||
Cost cost2= null;
|
Cost cost2= null;
|
||||||
for (final ICPPMethod op : ops) {
|
for (final ICPPFunction f : ops) {
|
||||||
if (op != null && !(op instanceof IProblemBinding)) {
|
if (f instanceof ICPPMethod && !(f instanceof IProblemBinding)) {
|
||||||
|
ICPPMethod op= (ICPPMethod) f;
|
||||||
final boolean isExplicitConversion= op.isExplicit();
|
final boolean isExplicitConversion= op.isExplicit();
|
||||||
if (isExplicitConversion /** && !direct **/)
|
if (isExplicitConversion /** && !direct **/)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
||||||
|
|
||||||
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.getSimplifiedType;
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getSimplifiedType;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -53,7 +52,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||||
|
@ -69,7 +67,6 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
|
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||||
import org.eclipse.cdt.core.parser.util.ObjectSet;
|
import org.eclipse.cdt.core.parser.util.ObjectSet;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
|
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
|
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPCompositeBinding;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPCompositeBinding;
|
||||||
|
@ -103,7 +100,6 @@ public class LookupData {
|
||||||
/** In list-initialization **/
|
/** In list-initialization **/
|
||||||
public boolean fNoNarrowing= false;
|
public boolean fNoNarrowing= false;
|
||||||
|
|
||||||
private ICPPASTParameterDeclaration[] functionParameters;
|
|
||||||
private IASTInitializerClause[] functionArgs;
|
private IASTInitializerClause[] functionArgs;
|
||||||
private IType[] functionArgTypes;
|
private IType[] functionArgTypes;
|
||||||
private ValueCategory[] functionArgValueCategories;
|
private ValueCategory[] functionArgValueCategories;
|
||||||
|
@ -171,81 +167,58 @@ public class LookupData {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean forFunctionDeclaration() {
|
/**
|
||||||
if (astName == null) return false;
|
* Returns whether the name belongs to a simple declaration or function definition.
|
||||||
if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false;
|
*/
|
||||||
|
public IASTDeclaration forDeclaration() {
|
||||||
|
IASTNode node = getDeclarator();
|
||||||
|
|
||||||
IASTName n = astName;
|
while (node instanceof IASTDeclarator)
|
||||||
if (n.getParent() instanceof ICPPASTTemplateId)
|
node= node.getParent();
|
||||||
n = (IASTName) n.getParent();
|
|
||||||
IASTNode p1 = n.getParent();
|
if (node instanceof IASTSimpleDeclaration || node instanceof IASTFunctionDefinition)
|
||||||
if (p1 instanceof ICPPASTQualifiedName) {
|
return (IASTDeclaration) node;
|
||||||
if (((ICPPASTQualifiedName) p1).getLastName() != n)
|
|
||||||
return false;
|
return null;
|
||||||
p1 = p1.getParent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p1 instanceof IASTDeclarator) {
|
public IASTDeclarator getDeclarator() {
|
||||||
IASTNode p2= ASTQueries.findOutermostDeclarator((IASTDeclarator) p1).getParent();
|
IASTName name= astName;
|
||||||
if (p2 instanceof IASTSimpleDeclaration) {
|
if (name == null || name.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY)
|
||||||
if (p2.getParent() instanceof ICPPASTExplicitTemplateInstantiation)
|
return null;
|
||||||
return false;
|
|
||||||
if (astName instanceof ICPPASTTemplateId &&
|
|
||||||
((ICPPASTDeclSpecifier)((IASTSimpleDeclaration) p2).getDeclSpecifier()).isFriend())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
if (name.getParent() instanceof ICPPASTTemplateId)
|
||||||
|
name= (IASTName) name.getParent();
|
||||||
|
|
||||||
|
IASTNode node= name.getParent();
|
||||||
|
if (node instanceof ICPPASTQualifiedName) {
|
||||||
|
if (((ICPPASTQualifiedName) node).getLastName() != name)
|
||||||
|
return null;
|
||||||
|
node = node.getParent();
|
||||||
}
|
}
|
||||||
return p2 instanceof IASTFunctionDefinition;
|
|
||||||
}
|
if (node instanceof IASTDeclarator)
|
||||||
return false;
|
return (IASTDeclarator) node;
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean forExplicitFunctionSpecialization() {
|
public boolean forExplicitFunctionSpecialization() {
|
||||||
if (astName == null) return false;
|
IASTDeclaration decl= forDeclaration();
|
||||||
if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false;
|
if (decl != null) {
|
||||||
|
|
||||||
IASTName n = astName;
|
IASTName n = astName;
|
||||||
if (n.getParent() instanceof ICPPASTTemplateId)
|
if (n.getParent() instanceof ICPPASTTemplateId)
|
||||||
n = (IASTName) n.getParent();
|
n = (IASTName) n.getParent();
|
||||||
IASTNode p1 = n.getParent();
|
|
||||||
if (p1 instanceof ICPPASTQualifiedName) {
|
|
||||||
if (((ICPPASTQualifiedName) p1).getLastName() != n)
|
|
||||||
return false;
|
|
||||||
p1 = p1.getParent();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p1 instanceof IASTDeclarator) {
|
|
||||||
IASTNode p2= ASTQueries.findOutermostDeclarator((IASTDeclarator) p1).getParent();
|
|
||||||
if (p2 instanceof IASTSimpleDeclaration || p2 instanceof IASTFunctionDefinition) {
|
|
||||||
ICPPASTTemplateDeclaration tmplDecl = CPPTemplates.getTemplateDeclaration(n);
|
ICPPASTTemplateDeclaration tmplDecl = CPPTemplates.getTemplateDeclaration(n);
|
||||||
return tmplDecl instanceof ICPPASTTemplateSpecialization;
|
return tmplDecl instanceof ICPPASTTemplateSpecialization;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean forExplicitFunctionInstantiation() {
|
public boolean forExplicitFunctionInstantiation() {
|
||||||
if (astName == null) return false;
|
IASTDeclaration decl= forDeclaration();
|
||||||
if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false;
|
return decl != null && decl.getParent() instanceof ICPPASTExplicitTemplateInstantiation;
|
||||||
|
|
||||||
IASTName n = astName;
|
|
||||||
if (n.getParent() instanceof ICPPASTTemplateId)
|
|
||||||
n = (IASTName) n.getParent();
|
|
||||||
IASTNode p1 = n.getParent();
|
|
||||||
if (p1 instanceof ICPPASTQualifiedName) {
|
|
||||||
if (((ICPPASTQualifiedName) p1).getLastName() != n)
|
|
||||||
return false;
|
|
||||||
p1 = p1.getParent();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p1 instanceof IASTDeclarator) {
|
|
||||||
IASTNode p2= ASTQueries.findOutermostDeclarator((IASTDeclarator) p1).getParent();
|
|
||||||
if (p2 instanceof IASTDeclaration) {
|
|
||||||
return p2.getParent() instanceof ICPPASTExplicitTemplateInstantiation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean qualified() {
|
public boolean qualified() {
|
||||||
|
@ -414,14 +387,6 @@ public class LookupData {
|
||||||
}
|
}
|
||||||
return CPPVisitor.getImpliedObjectType(scope);
|
return CPPVisitor.getImpliedObjectType(scope);
|
||||||
}
|
}
|
||||||
if (prop == IASTDeclarator.DECLARATOR_NAME) {
|
|
||||||
if (forExplicitFunctionInstantiation()) {
|
|
||||||
IScope scope = CPPVisitor.getContainingScope(astName);
|
|
||||||
if (scope instanceof ICPPClassScope) {
|
|
||||||
return ((ICPPClassScope) scope).getClassType();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,13 +456,7 @@ public class LookupData {
|
||||||
return false;
|
return false;
|
||||||
if (p instanceof IASTDeclaration) {
|
if (p instanceof IASTDeclaration) {
|
||||||
if (prop == IASTCompositeTypeSpecifier.MEMBER_DECLARATION) {
|
if (prop == IASTCompositeTypeSpecifier.MEMBER_DECLARATION) {
|
||||||
if (p instanceof IASTSimpleDeclaration) {
|
return CPPVisitor.isFriendDeclaration(p);
|
||||||
ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTSimpleDeclaration) p).getDeclSpecifier();
|
|
||||||
return declSpec.isFriend();
|
|
||||||
} else if (p instanceof IASTFunctionDefinition) {
|
|
||||||
ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTFunctionDefinition) p).getDeclSpecifier();
|
|
||||||
return declSpec.isFriend();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -547,13 +506,6 @@ public class LookupData {
|
||||||
functionArgTypes[i]= new InitializerListType((ICPPASTInitializerList) e);
|
functionArgTypes[i]= new InitializerListType((ICPPASTInitializerList) e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (functionParameters != null) {
|
|
||||||
ICPPASTParameterDeclaration[] pdecls= functionParameters;
|
|
||||||
functionArgTypes= new IType[pdecls.length];
|
|
||||||
for (int i = 0; i < pdecls.length; i++) {
|
|
||||||
functionArgTypes[i] = SemanticUtil.getSimplifiedType(CPPVisitor.createType(
|
|
||||||
pdecls[i], true));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return functionArgTypes;
|
return functionArgTypes;
|
||||||
|
@ -570,36 +522,19 @@ public class LookupData {
|
||||||
functionArgValueCategories[i] = ExpressionTypes.valueCat((IASTExpression) arg);
|
functionArgValueCategories[i] = ExpressionTypes.valueCat((IASTExpression) arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
IType[] argTypes= getFunctionArgumentTypes();
|
|
||||||
if (argTypes != null) {
|
|
||||||
functionArgValueCategories= new ValueCategory[argTypes.length];
|
|
||||||
for (int i = 0; i < argTypes.length; i++) {
|
|
||||||
IType t= argTypes[i];
|
|
||||||
functionArgValueCategories[i]= valueCategoryFromReturnType(t);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
functionArgValueCategories= new ValueCategory[0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return functionArgValueCategories;
|
return functionArgValueCategories;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFunctionParameters(ICPPASTParameterDeclaration[] parameters) {
|
|
||||||
functionParameters= parameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getFunctionArgumentCount() {
|
public int getFunctionArgumentCount() {
|
||||||
if (functionArgs != null)
|
if (functionArgs != null)
|
||||||
return functionArgs.length;
|
return functionArgs.length;
|
||||||
if (functionParameters != null)
|
|
||||||
return functionParameters.length;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasFunctionArguments() {
|
public boolean hasFunctionArguments() {
|
||||||
return functionArgs != null || functionParameters != null;
|
return functionArgs != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IBinding[] getFoundBindings() {
|
public IBinding[] getFoundBindings() {
|
||||||
|
|
|
@ -38,6 +38,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
|
||||||
|
@ -67,181 +68,16 @@ public class TemplateArgumentDeduction {
|
||||||
static ICPPTemplateArgument[] deduceForFunctionCall(ICPPFunctionTemplate template,
|
static ICPPTemplateArgument[] deduceForFunctionCall(ICPPFunctionTemplate template,
|
||||||
ICPPTemplateArgument[] tmplArgs, List<IType> fnArgs, List<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 numTmplArgs = tmplArgs.length;
|
|
||||||
|
|
||||||
tmplArgs= SemanticUtil.getSimplifiedArguments(tmplArgs);
|
if (!addExplicitArguments(tmplParams, tmplArgs, map))
|
||||||
ICPPTemplateParameter tmplParam= null;
|
|
||||||
int packOffset= -1;
|
|
||||||
for (int i = 0; i < numTmplArgs; i++) {
|
|
||||||
if (packOffset < 0 || tmplParam == null) {
|
|
||||||
if (i >= numTmplParams)
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
tmplParam= tmplParams[i];
|
|
||||||
if (tmplParam.isParameterPack()) {
|
|
||||||
packOffset= i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ICPPTemplateArgument tmplArg= tmplArgs[i];
|
|
||||||
tmplArg= CPPTemplates.matchTemplateParameterAndArgument(tmplParam, tmplArg, map);
|
|
||||||
if (tmplArg == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (packOffset < 0) {
|
|
||||||
map.put(tmplParam, tmplArg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (packOffset >= 0) {
|
|
||||||
final int packSize= tmplArgs.length- packOffset;
|
|
||||||
ICPPTemplateArgument[] pack= new ICPPTemplateArgument[packSize];
|
|
||||||
System.arraycopy(tmplArgs, packOffset, pack, 0, packSize);
|
|
||||||
map.put(tmplParam, pack);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!deduceFromFunctionArgs(template, fnArgs, argIsLValue, map))
|
if (!deduceFromFunctionArgs(template, fnArgs, argIsLValue, map))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
List<ICPPTemplateArgument> result= new ArrayList<ICPPTemplateArgument>(numTmplParams);
|
return createArguments(map, tmplParams);
|
||||||
for (ICPPTemplateParameter tpar : tmplParams) {
|
|
||||||
if (tpar.isParameterPack()) {
|
|
||||||
ICPPTemplateArgument[] deducedArgs= map.getPackExpansion(tpar);
|
|
||||||
if (deducedArgs == null)
|
|
||||||
return null;
|
|
||||||
result.addAll(Arrays.asList(deducedArgs));
|
|
||||||
} else {
|
|
||||||
ICPPTemplateArgument deducedArg= map.getArgument(tpar);
|
|
||||||
if (deducedArg == null) {
|
|
||||||
deducedArg= tpar.getDefaultValue();
|
|
||||||
if (deducedArg == null)
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
result.add(deducedArg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result.toArray(new ICPPTemplateArgument[result.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 14.8.2.2 [temp.deduct.funcaddr]
|
|
||||||
* Deducing template arguments taking the address of a function template
|
|
||||||
* @throws DOMException
|
|
||||||
*/
|
|
||||||
static ICPPTemplateArgument[] deduceForAddressOf(ICPPFunctionTemplate template,
|
|
||||||
ICPPTemplateArgument[] tmplArgs, IFunctionType arg, CPPTemplateParameterMap map) throws DOMException {
|
|
||||||
final ICPPTemplateParameter[] tmplParams = template.getTemplateParameters();
|
|
||||||
final int numTmplParams = tmplParams.length;
|
|
||||||
final int numTmplArgs = tmplArgs.length;
|
|
||||||
|
|
||||||
tmplArgs= SemanticUtil.getSimplifiedArguments(tmplArgs);
|
|
||||||
ICPPTemplateParameter tmplParam= null;
|
|
||||||
int packOffset= -1;
|
|
||||||
for (int i = 0; i < numTmplArgs; i++) {
|
|
||||||
if (packOffset < 0 || tmplParam == null) {
|
|
||||||
if (i >= numTmplParams)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
tmplParam= tmplParams[i];
|
|
||||||
if (tmplParam.isParameterPack()) {
|
|
||||||
packOffset= i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ICPPTemplateArgument tmplArg= tmplArgs[i];
|
|
||||||
tmplArg= CPPTemplates.matchTemplateParameterAndArgument(tmplParam, tmplArg, map);
|
|
||||||
if (tmplArg == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (packOffset < 0) {
|
|
||||||
map.put(tmplParam, tmplArg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (packOffset >= 0) {
|
|
||||||
final int packSize= tmplArgs.length- packOffset;
|
|
||||||
ICPPTemplateArgument[] pack= new ICPPTemplateArgument[packSize];
|
|
||||||
System.arraycopy(tmplArgs, packOffset, pack, 0, packSize);
|
|
||||||
map.put(tmplParam, pack);
|
|
||||||
}
|
|
||||||
|
|
||||||
IType par= template.getType();
|
|
||||||
par= CPPTemplates.instantiateType(par, map, -1, null);
|
|
||||||
if (!CPPTemplates.isValidType(par))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
boolean isDependentPar= CPPTemplates.isDependentType(par);
|
|
||||||
if (isDependentPar) {
|
|
||||||
TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(tmplParams, map, new CPPTemplateParameterMap(tmplParams.length), 0);
|
|
||||||
par= SemanticUtil.getNestedType(par, SemanticUtil.TDEF);
|
|
||||||
if (arg != null && !deduct.fromType(par, arg, false))
|
|
||||||
return null;
|
|
||||||
if (!map.mergeToExplicit(deduct.fDeducedArgs))
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!verifyDeduction(tmplParams, map, true))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (isDependentPar)
|
|
||||||
par= CPPTemplates.instantiateType(par, map, -1, null);
|
|
||||||
|
|
||||||
if (arg == null || arg.isSameType(par)) {
|
|
||||||
List<ICPPTemplateArgument> result= new ArrayList<ICPPTemplateArgument>(numTmplParams);
|
|
||||||
for (ICPPTemplateParameter tpar : tmplParams) {
|
|
||||||
if (tpar.isParameterPack()) {
|
|
||||||
ICPPTemplateArgument[] deducedArgs= map.getPackExpansion(tpar);
|
|
||||||
if (deducedArgs == null)
|
|
||||||
return null;
|
|
||||||
result.addAll(Arrays.asList(deducedArgs));
|
|
||||||
} else {
|
|
||||||
ICPPTemplateArgument deducedArg= map.getArgument(tpar);
|
|
||||||
if (deducedArg == null) {
|
|
||||||
deducedArg= tpar.getDefaultValue();
|
|
||||||
if (deducedArg == null)
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
result.add(deducedArg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result.toArray(new ICPPTemplateArgument[result.size()]);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deduce arguments for a user defined conversion template
|
|
||||||
* 14.8.2.3
|
|
||||||
*/
|
|
||||||
static ICPPTemplateArgument[] deduceForConversion(ICPPFunctionTemplate template,
|
|
||||||
IType conversionType, CPPTemplateParameterMap map) throws DOMException {
|
|
||||||
final ICPPTemplateParameter[] tmplParams = template.getTemplateParameters();
|
|
||||||
final int length = tmplParams.length;
|
|
||||||
|
|
||||||
ICPPTemplateArgument[] result = new ICPPTemplateArgument[length];
|
|
||||||
IType a= SemanticUtil.getSimplifiedType(conversionType);
|
|
||||||
IType p= template.getType().getReturnType();
|
|
||||||
p= getArgumentTypeForDeduction(p, a instanceof ICPPReferenceType);
|
|
||||||
a= SemanticUtil.getNestedType(a, SemanticUtil.REF | SemanticUtil.TDEF);
|
|
||||||
TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(tmplParams, null, map, 0);
|
|
||||||
if (!deduct.fromType(p, a, false)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
if (result[i] == null) {
|
|
||||||
final ICPPTemplateParameter tpar = tmplParams[i];
|
|
||||||
ICPPTemplateArgument deducedArg= map.getArgument(tpar);
|
|
||||||
if (deducedArg == null) {
|
|
||||||
deducedArg= tpar.getDefaultValue();
|
|
||||||
if (deducedArg == null)
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
result[i]= deducedArg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -253,9 +89,6 @@ public class TemplateArgumentDeduction {
|
||||||
try {
|
try {
|
||||||
IType[] fnPars = template.getType().getParameterTypes();
|
IType[] fnPars = template.getType().getParameterTypes();
|
||||||
final int fnParCount = fnPars.length;
|
final int fnParCount = fnPars.length;
|
||||||
if (fnParCount == 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
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;
|
||||||
|
@ -338,7 +171,7 @@ public class TemplateArgumentDeduction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!deduct.fExplicitArgs.mergeToExplicit(deduct.fDeducedArgs))
|
if (!map.addDeducedArgs(deduct.fDeducedArgs))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return verifyDeduction(tmplPars, map, true);
|
return verifyDeduction(tmplPars, map, true);
|
||||||
|
@ -407,6 +240,112 @@ public class TemplateArgumentDeduction {
|
||||||
return deduct.fromType(par, arg, true);
|
return deduct.fromType(par, arg, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 14.8.2.2 [temp.deduct.funcaddr]
|
||||||
|
* Deducing template arguments taking the address of a function template
|
||||||
|
* @throws DOMException
|
||||||
|
*/
|
||||||
|
static ICPPTemplateArgument[] deduceForAddressOf(ICPPFunctionTemplate template,
|
||||||
|
ICPPTemplateArgument[] tmplArgs, IFunctionType arg, CPPTemplateParameterMap map) throws DOMException {
|
||||||
|
final ICPPTemplateParameter[] tmplParams = template.getTemplateParameters();
|
||||||
|
if (!addExplicitArguments(tmplParams, tmplArgs, map))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
IType par= template.getType();
|
||||||
|
par= CPPTemplates.instantiateType(par, map, -1, null);
|
||||||
|
if (!CPPTemplates.isValidType(par))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
boolean isDependentPar= CPPTemplates.isDependentType(par);
|
||||||
|
if (isDependentPar) {
|
||||||
|
TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(tmplParams, map, new CPPTemplateParameterMap(tmplParams.length), 0);
|
||||||
|
par= SemanticUtil.getNestedType(par, SemanticUtil.TDEF);
|
||||||
|
if (arg != null && !deduct.fromType(par, arg, false))
|
||||||
|
return null;
|
||||||
|
if (!map.addDeducedArgs(deduct.fDeducedArgs))
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!verifyDeduction(tmplParams, map, true))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (isDependentPar)
|
||||||
|
par= CPPTemplates.instantiateType(par, map, -1, null);
|
||||||
|
|
||||||
|
if (arg == null || arg.isSameType(par)) {
|
||||||
|
return createArguments(map, tmplParams);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deduce arguments for a user defined conversion template
|
||||||
|
* 14.8.2.3
|
||||||
|
*/
|
||||||
|
static ICPPTemplateArgument[] deduceForConversion(ICPPFunctionTemplate template,
|
||||||
|
IType conversionType, CPPTemplateParameterMap map) throws DOMException {
|
||||||
|
final ICPPTemplateParameter[] tmplParams = template.getTemplateParameters();
|
||||||
|
final int length = tmplParams.length;
|
||||||
|
|
||||||
|
ICPPTemplateArgument[] result = new ICPPTemplateArgument[length];
|
||||||
|
IType a= SemanticUtil.getSimplifiedType(conversionType);
|
||||||
|
IType p= template.getType().getReturnType();
|
||||||
|
p= getArgumentTypeForDeduction(p, a instanceof ICPPReferenceType);
|
||||||
|
a= SemanticUtil.getNestedType(a, SemanticUtil.REF | SemanticUtil.TDEF);
|
||||||
|
TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(tmplParams, null, map, 0);
|
||||||
|
if (!deduct.fromType(p, a, false)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
if (result[i] == null) {
|
||||||
|
final ICPPTemplateParameter tpar = tmplParams[i];
|
||||||
|
ICPPTemplateArgument deducedArg= map.getArgument(tpar);
|
||||||
|
if (deducedArg == null) {
|
||||||
|
deducedArg= tpar.getDefaultValue();
|
||||||
|
if (deducedArg == null)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
result[i]= deducedArg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deduce arguments for a function declaration
|
||||||
|
* 14.8.2.6
|
||||||
|
*/
|
||||||
|
static ICPPTemplateArgument[] deduceForDeclaration(ICPPFunctionTemplate template,
|
||||||
|
ICPPTemplateArgument[] args, ICPPFunctionType ftype, CPPTemplateParameterMap map) throws DOMException {
|
||||||
|
final ICPPTemplateParameter[] tmplParams = template.getTemplateParameters();
|
||||||
|
|
||||||
|
if (!addExplicitArguments(tmplParams, args, map))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
IType a= SemanticUtil.getSimplifiedType(ftype);
|
||||||
|
IType p= CPPTemplates.instantiateType(template.getType(), map, -1, null);
|
||||||
|
if (!CPPTemplates.isValidType(p))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(tmplParams, map, new CPPTemplateParameterMap(tmplParams.length), 0);
|
||||||
|
if (!deduct.fromType(p, a, false)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!map.addDeducedArgs(deduct.fDeducedArgs))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (!verifyDeduction(tmplParams, map, true))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
IType type= CPPTemplates.instantiateType(p, map, -1, null);
|
||||||
|
if (!ftype.isSameType(type))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return createArguments(map, tmplParams);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
|
@ -470,6 +409,64 @@ public class TemplateArgumentDeduction {
|
||||||
return isMoreCVQualified ? 1 : 0;
|
return isMoreCVQualified ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the explicit arguments to the map.
|
||||||
|
*/
|
||||||
|
private static boolean addExplicitArguments(final ICPPTemplateParameter[] tmplParams,
|
||||||
|
ICPPTemplateArgument[] tmplArgs, CPPTemplateParameterMap map) {
|
||||||
|
tmplArgs= SemanticUtil.getSimplifiedArguments(tmplArgs);
|
||||||
|
ICPPTemplateParameter tmplParam= null;
|
||||||
|
int packOffset= -1;
|
||||||
|
for (int i = 0; i < tmplArgs.length; i++) {
|
||||||
|
if (packOffset < 0 || tmplParam == null) {
|
||||||
|
if (i >= tmplParams.length)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
tmplParam= tmplParams[i];
|
||||||
|
if (tmplParam.isParameterPack()) {
|
||||||
|
packOffset= i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ICPPTemplateArgument tmplArg= tmplArgs[i];
|
||||||
|
tmplArg= CPPTemplates.matchTemplateParameterAndArgument(tmplParam, tmplArg, map);
|
||||||
|
if (tmplArg == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (packOffset < 0) {
|
||||||
|
map.put(tmplParam, tmplArg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packOffset >= 0) {
|
||||||
|
final int packSize= tmplArgs.length- packOffset;
|
||||||
|
ICPPTemplateArgument[] pack= new ICPPTemplateArgument[packSize];
|
||||||
|
System.arraycopy(tmplArgs, packOffset, pack, 0, packSize);
|
||||||
|
map.put(tmplParam, pack);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ICPPTemplateArgument[] createArguments(CPPTemplateParameterMap map,
|
||||||
|
final ICPPTemplateParameter[] tmplParams) {
|
||||||
|
List<ICPPTemplateArgument> result= new ArrayList<ICPPTemplateArgument>(tmplParams.length);
|
||||||
|
for (ICPPTemplateParameter tpar : tmplParams) {
|
||||||
|
if (tpar.isParameterPack()) {
|
||||||
|
ICPPTemplateArgument[] deducedArgs= map.getPackExpansion(tpar);
|
||||||
|
if (deducedArgs == null)
|
||||||
|
return null;
|
||||||
|
result.addAll(Arrays.asList(deducedArgs));
|
||||||
|
} else {
|
||||||
|
ICPPTemplateArgument deducedArg= map.getArgument(tpar);
|
||||||
|
if (deducedArg == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.add(deducedArg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toArray(new ICPPTemplateArgument[result.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 14.8.2.1.3 If P is a class and has the form template-id, then A can be a derived class of the deduced A.
|
* 14.8.2.1.3 If P is a class and has the form template-id, then A can be a derived class of the deduced A.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -43,6 +43,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
|
||||||
|
@ -254,7 +255,8 @@ abstract public class PDOMWriter {
|
||||||
try {
|
try {
|
||||||
final IBinding binding = name.resolveBinding();
|
final IBinding binding = name.resolveBinding();
|
||||||
if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME &&
|
if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME &&
|
||||||
((IASTName) name.getParent()).getBinding() == binding) {
|
(((IASTName) name.getParent()).getBinding() == binding ||
|
||||||
|
binding instanceof ICPPFunctionTemplate)) {
|
||||||
na[0]= null;
|
na[0]= null;
|
||||||
} else if (binding instanceof IProblemBinding) {
|
} else if (binding instanceof IProblemBinding) {
|
||||||
fStatistics.fProblemBindingCount++;
|
fStatistics.fProblemBindingCount++;
|
||||||
|
|
Loading…
Add table
Reference in a new issue