mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-09-09 19:43:27 +02:00
Bug 85843: ADL for overloaded function sets.
This commit is contained in:
parent
497b9282a8
commit
4720831a18
16 changed files with 809 additions and 442 deletions
|
@ -66,7 +66,7 @@ public class ASTCPPSpecDefectTests extends AST2BaseTest {
|
||||||
// void test() {
|
// void test() {
|
||||||
// fp(f0);
|
// fp(f0);
|
||||||
// }
|
// }
|
||||||
public void _testADLForOverloadSet_324842() throws Exception {
|
public void testADLForOverloadSet_324842() throws Exception {
|
||||||
parseAndCheckBindings();
|
parseAndCheckBindings();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -445,7 +445,7 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
|
||||||
// A<B> a;
|
// A<B> a;
|
||||||
// a.f= foo<B>;
|
// a.f= foo<B>;
|
||||||
// }
|
// }
|
||||||
public void _testOverloadedFunctionTemplate() {
|
public void testOverloadedFunctionTemplate() {
|
||||||
IBinding b0= getBindingFromASTName("foo<B>;", 6);
|
IBinding b0= getBindingFromASTName("foo<B>;", 6);
|
||||||
assertInstance(b0, ICPPFunction.class);
|
assertInstance(b0, ICPPFunction.class);
|
||||||
assertInstance(b0, ICPPSpecialization.class);
|
assertInstance(b0, ICPPSpecialization.class);
|
||||||
|
|
|
@ -14,6 +14,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
|
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
|
||||||
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
|
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
|
||||||
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.XVALUE;
|
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.XVALUE;
|
||||||
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
|
||||||
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 org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
|
@ -213,17 +214,22 @@ public class CPPASTConditionalExpression extends ASTNode implements IASTConditio
|
||||||
|
|
||||||
final ValueCategory vcat2= expr2.getValueCategory();
|
final ValueCategory vcat2= expr2.getValueCategory();
|
||||||
final ValueCategory vcat3= expr3.getValueCategory();
|
final ValueCategory vcat3= expr3.getValueCategory();
|
||||||
final boolean isClassType2 = uqt2 instanceof ICPPClassType;
|
|
||||||
final boolean isClassType3 = uqt3 instanceof ICPPClassType;
|
|
||||||
|
|
||||||
// Same type and same value category
|
// Same type
|
||||||
if (t2.isSameType(t3)) {
|
if (t2.isSameType(t3)) {
|
||||||
if (vcat2 == vcat3) {
|
if (vcat2 == vcat3) {
|
||||||
fType= t2;
|
fType= t2;
|
||||||
fValueCategory= vcat2;
|
fValueCategory= vcat2;
|
||||||
|
} else {
|
||||||
|
fType= prvalueType(t2);
|
||||||
|
fValueCategory= PRVALUE;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
final boolean isClassType2 = uqt2 instanceof ICPPClassType;
|
||||||
|
final boolean isClassType3 = uqt3 instanceof ICPPClassType;
|
||||||
|
|
||||||
// Different types with at least one class type
|
// Different types with at least one class type
|
||||||
if (isClassType2 || isClassType3) {
|
if (isClassType2 || isClassType3) {
|
||||||
final Cost cost2= convertToMatch(t2, vcat2, uqt2, t3, vcat3, uqt3); // sets fType and fValueCategory
|
final Cost cost2= convertToMatch(t2, vcat2, uqt2, t3, vcat3, uqt3); // sets fType and fValueCategory
|
||||||
|
@ -253,7 +259,6 @@ public class CPPASTConditionalExpression extends ASTNode implements IASTConditio
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 5.16-5: At least one class type but no conversion
|
// 5.16-5: At least one class type but no conversion
|
||||||
if (isClassType2 || isClassType3) {
|
if (isClassType2 || isClassType3) {
|
||||||
|
|
|
@ -14,8 +14,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
|
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
|
||||||
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
|
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromFunctionCall;
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.*;
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromFunctionCall;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
|
@ -155,20 +154,24 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
|
||||||
return overloads = NO_FUNCTIONS;
|
return overloads = NO_FUNCTIONS;
|
||||||
|
|
||||||
overloads = new ICPPFunction[exprs.length-1];
|
overloads = new ICPPFunction[exprs.length-1];
|
||||||
IType lookupType = exprs[0].getExpressionType();
|
IType lookupType = typeOrFunctionSet(exprs[0]);
|
||||||
|
ValueCategory vcat= valueCat(exprs[0]);
|
||||||
|
|
||||||
for(int i = 1; i < exprs.length; i++) {
|
for (int i = 1; i < exprs.length; i++) {
|
||||||
IASTExpression e1 = exprs[i-1], e2 = exprs[i];
|
IASTExpression e1 = exprs[i - 1], e2 = exprs[i];
|
||||||
ICPPFunction overload = CPPSemantics.findOverloadedOperatorComma(e1, e2, lookupType);
|
ICPPFunction overload = CPPSemantics.findOverloadedOperatorComma(e1, lookupType, vcat, e2);
|
||||||
if(overload == null) {
|
if (overload == null) {
|
||||||
lookupType = e2.getExpressionType();
|
lookupType = typeOrFunctionSet(e2);
|
||||||
}
|
vcat= valueCat(e2);
|
||||||
else {
|
} else {
|
||||||
overloads[i-1] = overload;
|
overloads[i - 1] = overload;
|
||||||
try {
|
try {
|
||||||
lookupType = overload.getType().getReturnType();
|
lookupType = overload.getType().getReturnType();
|
||||||
|
vcat= valueCategoryFromReturnType(lookupType);
|
||||||
|
lookupType= typeFromReturnType(lookupType);
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
lookupType = e2.getExpressionType();
|
lookupType = typeOrFunctionSet(e2);
|
||||||
|
vcat= valueCat(e2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPFunctionSet;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||||
|
@ -108,6 +109,9 @@ public class CPPASTIdExpression extends ASTNode implements IASTIdExpression, ICP
|
||||||
|
|
||||||
public IType getExpressionType() {
|
public IType getExpressionType() {
|
||||||
IBinding binding = name.resolvePreBinding();
|
IBinding binding = name.resolvePreBinding();
|
||||||
|
if (binding instanceof CPPFunctionSet)
|
||||||
|
binding= name.resolveBinding();
|
||||||
|
|
||||||
if (checkForTransformation(binding)) {
|
if (checkForTransformation(binding)) {
|
||||||
return fTransformedExpression.getExpressionType();
|
return fTransformedExpression.getExpressionType();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
|
||||||
*/
|
*/
|
||||||
public class CPPUnknownFunction extends CPPUnknownBinding implements ICPPFunction {
|
public class CPPUnknownFunction extends CPPUnknownBinding implements ICPPFunction {
|
||||||
|
|
||||||
public static IFunction createForSample(IFunction sample) throws DOMException {
|
public static ICPPFunction createForSample(IFunction sample) throws DOMException {
|
||||||
if (sample instanceof ICPPConstructor)
|
if (sample instanceof ICPPConstructor)
|
||||||
return new CPPUnknownConstructor(((ICPPConstructor) sample).getClassOwner());
|
return new CPPUnknownConstructor(((ICPPConstructor) sample).getClassOwner());
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
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.typeOrFunctionSet;
|
||||||
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;
|
||||||
|
@ -83,13 +84,13 @@ class BuiltinOperators {
|
||||||
fUnary= args.length<2;
|
fUnary= args.length<2;
|
||||||
fGlobalCandidates= globCandidates;
|
fGlobalCandidates= globCandidates;
|
||||||
if (args.length > 0 && args[0] instanceof IASTExpression) {
|
if (args.length > 0 && args[0] instanceof IASTExpression) {
|
||||||
IType type= ((IASTExpression) args[0]).getExpressionType();
|
IType type= typeOrFunctionSet((IASTExpression) args[0]);
|
||||||
if (!(type instanceof IProblemBinding))
|
if (!(type instanceof IProblemBinding))
|
||||||
fType1= type;
|
fType1= type;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (args.length > 1 && args[1] instanceof IASTExpression) {
|
if (args.length > 1 && args[1] instanceof IASTExpression) {
|
||||||
IType type= ((IASTExpression) args[1]).getExpressionType();
|
IType type= typeOrFunctionSet((IASTExpression) args[1]);
|
||||||
if (!(type instanceof IProblemBinding))
|
if (!(type instanceof IProblemBinding))
|
||||||
fType2= type;
|
fType2= type;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* CPPFunctionSet.java
|
||||||
|
* Created on Sep 13, 2010
|
||||||
|
*
|
||||||
|
* Copyright 2010 Wind River Systems, Inc. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ILinkage;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
|
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.Linkage;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPTwoPhaseBinding;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used as intermediate binding for names nominating a function without calling it.
|
||||||
|
* The actual function can be resolved in certain contexts.
|
||||||
|
*/
|
||||||
|
public class CPPFunctionSet implements ICPPTwoPhaseBinding {
|
||||||
|
|
||||||
|
final ICPPFunction[] fBindings;
|
||||||
|
|
||||||
|
public CPPFunctionSet(ICPPFunction[] bindingList) {
|
||||||
|
fBindings = ArrayUtil.removeNulls(bindingList);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return fBindings[0].getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public char[] getNameCharArray() {
|
||||||
|
return fBindings[0].getNameCharArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IScope getScope() throws DOMException {
|
||||||
|
return fBindings[0].getScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBinding getOwner() {
|
||||||
|
return fBindings[0].getOwner();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICPPFunction[] getBindings() {
|
||||||
|
return fBindings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ILinkage getLinkage() {
|
||||||
|
return Linkage.CPP_LINKAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBinding resolveFinalBinding(CPPASTNameBase astName) {
|
||||||
|
return CPPSemantics.resolveTargetedFunction(astName, fBindings);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
|
||||||
|
if (adapter.isAssignableFrom(getClass()))
|
||||||
|
return this;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,8 @@ 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 static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
|
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
|
||||||
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeOrFunctionSet;
|
||||||
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCat;
|
||||||
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;
|
||||||
|
@ -51,6 +53,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
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.IASTImplicitNameOwner;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
|
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
|
||||||
|
@ -150,7 +153,6 @@ import org.eclipse.cdt.core.index.IIndexBinding;
|
||||||
import org.eclipse.cdt.core.index.IIndexFile;
|
import org.eclipse.cdt.core.index.IIndexFile;
|
||||||
import org.eclipse.cdt.core.index.IIndexFileSet;
|
import org.eclipse.cdt.core.index.IIndexFileSet;
|
||||||
import org.eclipse.cdt.core.index.IIndexName;
|
import org.eclipse.cdt.core.index.IIndexName;
|
||||||
import org.eclipse.cdt.core.parser.IProblem;
|
|
||||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
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;
|
||||||
|
@ -642,7 +644,7 @@ public class CPPSemantics {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static private Set<ICPPNamespaceScope> getAssociatedScopes(LookupData data) {
|
private static Set<ICPPNamespaceScope> getAssociatedScopes(LookupData data) {
|
||||||
if (!data.hasFunctionArguments())
|
if (!data.hasFunctionArguments())
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
|
|
||||||
|
@ -659,7 +661,7 @@ public class CPPSemantics {
|
||||||
return namespaces;
|
return namespaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
static private void getAssociatedScopes(IType t, Set<ICPPNamespaceScope> namespaces,
|
private static void getAssociatedScopes(IType t, Set<ICPPNamespaceScope> namespaces,
|
||||||
ObjectSet<ICPPClassType> classes, CPPASTTranslationUnit tu) throws DOMException {
|
ObjectSet<ICPPClassType> classes, CPPASTTranslationUnit tu) throws DOMException {
|
||||||
// 3.4.2-2
|
// 3.4.2-2
|
||||||
if (t instanceof ICPPClassType) {
|
if (t instanceof ICPPClassType) {
|
||||||
|
@ -691,11 +693,15 @@ public class CPPSemantics {
|
||||||
} else if (t instanceof ICPPPointerToMemberType) {
|
} else if (t instanceof ICPPPointerToMemberType) {
|
||||||
IType binding = ((ICPPPointerToMemberType) t).getMemberOfClass();
|
IType binding = ((ICPPPointerToMemberType) t).getMemberOfClass();
|
||||||
getAssociatedScopes(binding, namespaces, classes, tu);
|
getAssociatedScopes(binding, namespaces, classes, tu);
|
||||||
|
} else if (t instanceof FunctionSetType) {
|
||||||
|
FunctionSetType fst= (FunctionSetType) t;
|
||||||
|
for (ICPPFunction fn : fst.getFunctionSet()) {
|
||||||
|
getAssociatedScopes(fn.getType(), namespaces, classes, tu);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static private ICPPNamespaceScope getContainingNamespaceScope(IBinding binding,
|
private static ICPPNamespaceScope getContainingNamespaceScope(IBinding binding,
|
||||||
CPPASTTranslationUnit tu) throws DOMException {
|
CPPASTTranslationUnit tu) throws DOMException {
|
||||||
if (binding == null)
|
if (binding == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -1099,7 +1105,7 @@ public class CPPSemantics {
|
||||||
public int visit(IASTExpression expression) {
|
public int visit(IASTExpression expression) {
|
||||||
if (expression instanceof IASTLiteralExpression) {
|
if (expression instanceof IASTLiteralExpression) {
|
||||||
if (((IASTLiteralExpression) expression).getKind() == IASTLiteralExpression.lk_this) {
|
if (((IASTLiteralExpression) expression).getKind() == IASTLiteralExpression.lk_this) {
|
||||||
final IType thisType = SemanticUtil.getNestedType(expression.getExpressionType(), TDEF | ALLCVQ | PTR | ARRAY | MPTR | REF);
|
final IType thisType = SemanticUtil.getNestedType(typeOrFunctionSet(expression), TDEF | ALLCVQ | PTR | ARRAY | MPTR | REF);
|
||||||
if (thisType instanceof ICPPUnknownBinding || thisType instanceof ICPPTemplateDefinition) {
|
if (thisType instanceof ICPPUnknownBinding || thisType instanceof ICPPTemplateDefinition) {
|
||||||
result[0]= true;
|
result[0]= true;
|
||||||
return PROCESS_ABORT;
|
return PROCESS_ABORT;
|
||||||
|
@ -1250,7 +1256,7 @@ public class CPPSemantics {
|
||||||
* In case of an unqualified lookup the transitive directives are stored, also. This is important because
|
* In case of an unqualified lookup the transitive directives are stored, also. This is important because
|
||||||
* the members nominated by a transitive directive can appear before those of the original directive.
|
* the members nominated by a transitive directive can appear before those of the original directive.
|
||||||
*/
|
*/
|
||||||
static private void storeUsingDirective(LookupData data, ICPPNamespaceScope container,
|
private static void storeUsingDirective(LookupData data, ICPPNamespaceScope container,
|
||||||
ICPPUsingDirective directive, Set<ICPPNamespaceScope> handled) throws DOMException {
|
ICPPUsingDirective directive, Set<ICPPNamespaceScope> handled) throws DOMException {
|
||||||
ICPPNamespaceScope nominated= directive.getNominatedScope();
|
ICPPNamespaceScope nominated= directive.getNominatedScope();
|
||||||
if (nominated instanceof IIndexScope && data.tu != null) {
|
if (nominated instanceof IIndexScope && data.tu != null) {
|
||||||
|
@ -1291,7 +1297,7 @@ public class CPPSemantics {
|
||||||
/**
|
/**
|
||||||
* Computes the common enclosing scope of s1 and s2.
|
* Computes the common enclosing scope of s1 and s2.
|
||||||
*/
|
*/
|
||||||
static private ICPPScope getCommonEnclosingScope(IScope s1, IScope s2, CPPASTTranslationUnit tu) throws DOMException {
|
private static ICPPScope getCommonEnclosingScope(IScope s1, IScope s2, CPPASTTranslationUnit tu) throws DOMException {
|
||||||
ObjectSet<IScope> set = new ObjectSet<IScope>(2);
|
ObjectSet<IScope> set = new ObjectSet<IScope>(2);
|
||||||
IScope parent= s1;
|
IScope parent= s1;
|
||||||
while (parent != null) {
|
while (parent != null) {
|
||||||
|
@ -1629,7 +1635,7 @@ public class CPPSemantics {
|
||||||
* are considered if the lookup of the original directive returns empty.
|
* are considered if the lookup of the original directive returns empty.
|
||||||
* @param fileSet
|
* @param fileSet
|
||||||
*/
|
*/
|
||||||
static private void lookupInNominated(LookupData data, IIndexFileSet fileSet, ICPPNamespaceScope scope) throws DOMException {
|
private static void lookupInNominated(LookupData data, IIndexFileSet fileSet, ICPPNamespaceScope scope) throws DOMException {
|
||||||
List<ICPPNamespaceScope> allNominated= data.usingDirectives.remove(scope);
|
List<ICPPNamespaceScope> allNominated= data.usingDirectives.remove(scope);
|
||||||
while (allNominated != null) {
|
while (allNominated != null) {
|
||||||
for (ICPPNamespaceScope nominated : allNominated) {
|
for (ICPPNamespaceScope nominated : allNominated) {
|
||||||
|
@ -1821,13 +1827,13 @@ public class CPPSemantics {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static private IBinding resolveAmbiguities(LookupData data, IASTName name) throws DOMException {
|
private static IBinding resolveAmbiguities(LookupData data, IASTName name) throws DOMException {
|
||||||
if (!data.hasResults() || data.contentAssist)
|
if (!data.hasResults() || data.contentAssist)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
final boolean indexBased= data.tu != null && data.tu.getIndex() != null;
|
final boolean indexBased= data.tu != null && data.tu.getIndex() != null;
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
ObjectSet<IFunction> fns= ObjectSet.EMPTY_SET;
|
ObjectSet<ICPPFunction> fns= ObjectSet.EMPTY_SET;
|
||||||
IBinding type = null;
|
IBinding type = null;
|
||||||
IBinding obj = null;
|
IBinding obj = null;
|
||||||
IBinding temp = null;
|
IBinding temp = null;
|
||||||
|
@ -1878,15 +1884,15 @@ public class CPPSemantics {
|
||||||
mergeResults(data, bindings, false);
|
mergeResults(data, bindings, false);
|
||||||
items = (Object[]) data.foundItems;
|
items = (Object[]) data.foundItems;
|
||||||
continue;
|
continue;
|
||||||
} else if (temp instanceof IFunction) {
|
} else if (temp instanceof ICPPFunction) {
|
||||||
if (temp instanceof ICPPTemplateInstance) {
|
if (temp instanceof ICPPTemplateInstance) {
|
||||||
temp= ((ICPPTemplateInstance) temp).getSpecializedBinding();
|
temp= ((ICPPTemplateInstance) temp).getSpecializedBinding();
|
||||||
if (!(temp instanceof IFunction))
|
if (!(temp instanceof IFunction))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (fns == ObjectSet.EMPTY_SET)
|
if (fns == ObjectSet.EMPTY_SET)
|
||||||
fns = new ObjectSet<IFunction>(2);
|
fns = new ObjectSet<ICPPFunction>(2);
|
||||||
fns.put((IFunction) temp);
|
fns.put((ICPPFunction) temp);
|
||||||
} else if (temp instanceof IType) {
|
} else if (temp instanceof IType) {
|
||||||
// specializations are selected during instantiation
|
// specializations are selected during instantiation
|
||||||
if (temp instanceof ICPPClassTemplatePartialSpecialization)
|
if (temp instanceof ICPPClassTemplatePartialSpecialization)
|
||||||
|
@ -1977,7 +1983,7 @@ public class CPPSemantics {
|
||||||
|
|
||||||
|
|
||||||
if (fns.size() > 0) {
|
if (fns.size() > 0) {
|
||||||
final IFunction[] fnArray = fns.keyArray(IFunction.class);
|
final ICPPFunction[] fnArray = fns.keyArray(ICPPFunction.class);
|
||||||
if (type != null && overrulesByRelevance(data, type, fnArray)) {
|
if (type != null && overrulesByRelevance(data, type, fnArray)) {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
@ -2200,69 +2206,60 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static private void reduceToViable(LookupData data, IBinding[] functions) throws DOMException {
|
private static ICPPFunction[] selectByArgumentCount(LookupData data, ICPPFunction[] functions) throws DOMException {
|
||||||
if (functions == null || functions.length == 0)
|
assert !data.forFunctionDeclaration();
|
||||||
return;
|
|
||||||
|
|
||||||
final boolean def = data.forFunctionDeclaration();
|
|
||||||
int argumentCount = data.getFunctionArgumentCount();
|
int argumentCount = data.getFunctionArgumentCount();
|
||||||
|
|
||||||
if (def && argumentCount == 1) {
|
|
||||||
// check for parameter of type void
|
|
||||||
final IType[] argTypes = data.getFunctionArgumentTypes();
|
|
||||||
if (argTypes.length == 1 && SemanticUtil.isVoidType(argTypes[0])) {
|
|
||||||
argumentCount= 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trim the list down to the set of viable functions
|
// Trim the list down to the set of viable functions
|
||||||
ICPPFunction function = null;
|
ICPPFunction[] result= new ICPPFunction[functions.length];
|
||||||
int size = functions.length;
|
int idx= 0;
|
||||||
for (int i = 0; i < size; i++) {
|
for (ICPPFunction fn : functions) {
|
||||||
if (functions[i] instanceof IProblemBinding) {
|
if (fn != null && !(fn instanceof IProblemBinding)) {
|
||||||
functions[i]= null;
|
if (fn instanceof ICPPUnknownBinding) {
|
||||||
continue;
|
return new ICPPFunction[] {fn};
|
||||||
}
|
}
|
||||||
|
|
||||||
function = (ICPPFunction) functions[i];
|
// The index is optimized to provide the function type, try not to use the parameters
|
||||||
if (function == null)
|
|
||||||
continue;
|
|
||||||
if (function instanceof ICPPUnknownBinding) {
|
|
||||||
if (def) {
|
|
||||||
functions[i]= null;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// the index is optimized to provide the function type, try not to use the parameters
|
|
||||||
// as long as possible.
|
// as long as possible.
|
||||||
final IType[] parameterTypes = function.getType().getParameterTypes();
|
final ICPPFunctionType ft = fn.getType();
|
||||||
|
final IType[] parameterTypes = ft.getParameterTypes();
|
||||||
int numPars = parameterTypes.length;
|
int numPars = parameterTypes.length;
|
||||||
if (numPars == 1 && SemanticUtil.isVoidType(parameterTypes[0]))
|
if (numPars == 1 && SemanticUtil.isVoidType(parameterTypes[0]))
|
||||||
numPars= 0;
|
numPars= 0;
|
||||||
|
|
||||||
int numArgs = argumentCount;
|
int numArgs = argumentCount;
|
||||||
if (function instanceof ICPPMethod && data.argsContainImpliedObject)
|
if (fn instanceof ICPPMethod && data.argsContainImpliedObject)
|
||||||
numArgs--;
|
numArgs--;
|
||||||
|
|
||||||
if (def) {
|
boolean ok;
|
||||||
if (numPars != numArgs || !isMatchingFunctionDeclaration(function, data)) {
|
|
||||||
functions[i] = null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// more arguments than parameters --> need ellipsis
|
|
||||||
if (numArgs > numPars) {
|
if (numArgs > numPars) {
|
||||||
if (!function.takesVarArgs() && !function.hasParameterPack()) {
|
// more arguments than parameters --> need ellipsis or parameter pack
|
||||||
functions[i] = null;
|
ok= fn.takesVarArgs() || fn.hasParameterPack();
|
||||||
|
} else {
|
||||||
|
ok = numArgs >= fn.getRequiredArgumentCount();
|
||||||
}
|
}
|
||||||
} else if (numArgs < function.getRequiredArgumentCount()) {
|
if (ok) {
|
||||||
// fewer arguments than required
|
if (fn instanceof IIndexBinding) {
|
||||||
functions[i]= null;
|
for (ICPPFunction other : result) {
|
||||||
|
if (other == null || other instanceof IIndexBinding)
|
||||||
|
break;
|
||||||
|
if (other.getType().isSameType(ft)) {
|
||||||
|
ok= false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
result[idx++]= fn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static private boolean isMatchingFunctionDeclaration(ICPPFunction candidate, LookupData data) {
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isMatchingFunctionDeclaration(ICPPFunction candidate, LookupData data) {
|
||||||
IASTNode node = data.astName.getParent();
|
IASTNode node = data.astName.getParent();
|
||||||
while (node instanceof IASTName)
|
while (node instanceof IASTName)
|
||||||
node = node.getParent();
|
node = node.getParent();
|
||||||
|
@ -2272,54 +2269,65 @@ public class CPPSemantics {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static IBinding resolveFunction(LookupData data, IFunction[] fns, boolean allowUDC) throws DOMException {
|
static IBinding resolveFunction(LookupData data, ICPPFunction[] fns, boolean allowUDC) throws DOMException {
|
||||||
fns= (IFunction[]) ArrayUtil.trim(IFunction.class, fns);
|
fns= (ICPPFunction[]) ArrayUtil.trim(ICPPFunction.class, fns);
|
||||||
if (fns == null || fns.length == 0)
|
if (fns == null || fns.length == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (data.forUsingDeclaration()) {
|
sortAstBeforeIndex(fns);
|
||||||
return new CPPUsingDeclaration(data.astName, fns);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We don't have any arguments with which to resolve the function
|
if (data.forUsingDeclaration())
|
||||||
final boolean isFuncDecl = data.forFunctionDeclaration();
|
return new CPPUsingDeclaration(data.astName, fns);
|
||||||
|
|
||||||
|
// No arguments to resolve function
|
||||||
if (!data.hasFunctionArguments()) {
|
if (!data.hasFunctionArguments()) {
|
||||||
return resolveTargetedFunction(data, fns);
|
ICPPFunction cand= fns[0];
|
||||||
|
if (!(cand instanceof ICPPFunctionTemplate)) {
|
||||||
|
if (fns.length == 1)
|
||||||
|
return cand;
|
||||||
|
// Just one binding from ast, use it.
|
||||||
|
if (!(cand instanceof IIndexBinding) && fns[1] instanceof IIndexBinding)
|
||||||
|
return cand;
|
||||||
|
}
|
||||||
|
return new CPPFunctionSet(fns);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.astName instanceof ICPPASTConversionName) {
|
if (data.astName instanceof ICPPASTConversionName) {
|
||||||
return resolveUserDefinedConversion(data, fns);
|
return resolveUserDefinedConversion(data, fns);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isFuncDecl || data.forExplicitFunctionSpecialization()) {
|
if (data.forFunctionDeclaration())
|
||||||
CPPTemplates.instantiateFunctionTemplates(fns, data.getFunctionArgumentTypes(), data.getFunctionArgumentValueCategories(),
|
return resolveFunctionDeclaration(data, fns);
|
||||||
data.astName, data.argsContainImpliedObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
||||||
reduceToViable(data, fns);
|
final IType[] argTypes = data.getFunctionArgumentTypes();
|
||||||
|
ICPPFunction[] tmp= selectByArgumentCount(data, fns);
|
||||||
|
tmp= CPPTemplates.instantiateFunctionTemplates(tmp, argTypes, data.getFunctionArgumentValueCategories(),
|
||||||
|
data.astName, data.argsContainImpliedObject);
|
||||||
|
if (tmp.length == 0 || tmp[0] == null)
|
||||||
|
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, fns);
|
||||||
|
|
||||||
|
|
||||||
int viableCount= 0;
|
int viableCount= 0;
|
||||||
IFunction firstViable= null;
|
for (IFunction f : tmp) {
|
||||||
for (IFunction f : fns) {
|
|
||||||
if (f != null) {
|
|
||||||
if (++viableCount == 1) {
|
|
||||||
firstViable= f;
|
|
||||||
}
|
|
||||||
if (f instanceof ICPPUnknownBinding) {
|
if (f instanceof ICPPUnknownBinding) {
|
||||||
|
setTargetedFunctionsToUnknown(argTypes);
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
if (f == null)
|
||||||
|
break;
|
||||||
|
++viableCount;
|
||||||
}
|
}
|
||||||
}
|
if (viableCount == 0)
|
||||||
if (firstViable == null || isFuncDecl)
|
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, fns);
|
||||||
return firstViable;
|
|
||||||
|
|
||||||
// The arguments the function is being called with
|
// Check for dependent arguments
|
||||||
IType[] argTypes = data.getFunctionArgumentTypes();
|
fns= tmp;
|
||||||
if (CPPTemplates.containsDependentType(argTypes)) {
|
if (CPPTemplates.containsDependentType(argTypes)) {
|
||||||
if (viableCount == 1)
|
if (viableCount == 1)
|
||||||
return firstViable;
|
return fns[0];
|
||||||
return CPPUnknownFunction.createForSample(firstViable);
|
setTargetedFunctionsToUnknown(argTypes);
|
||||||
|
return CPPUnknownFunction.createForSample(fns[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
IFunction[] ambiguousFunctions= null; // ambiguity, 2 functions are equally good
|
IFunction[] ambiguousFunctions= null; // ambiguity, 2 functions are equally good
|
||||||
|
@ -2337,8 +2345,9 @@ public class CPPSemantics {
|
||||||
|
|
||||||
if (fnCost == CONTAINS_DEPENDENT_TYPES) {
|
if (fnCost == CONTAINS_DEPENDENT_TYPES) {
|
||||||
if (viableCount == 1)
|
if (viableCount == 1)
|
||||||
return firstViable;
|
return fns[0];
|
||||||
return CPPUnknownFunction.createForSample(firstViable);
|
setTargetedFunctionsToUnknown(argTypes);
|
||||||
|
return CPPUnknownFunction.createForSample(fns[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fnCost.hasDeferredUDC()) {
|
if (fnCost.hasDeferredUDC()) {
|
||||||
|
@ -2384,9 +2393,69 @@ public class CPPSemantics {
|
||||||
data.getFoundBindings());
|
data.getFoundBindings());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < argTypes.length; i++) {
|
||||||
|
IType iType = argTypes[i];
|
||||||
|
if (iType instanceof FunctionSetType) {
|
||||||
|
((FunctionSetType) iType).applySelectedFunction(bestFnCost.getCost(i).getSelectedFunction());
|
||||||
|
}
|
||||||
|
}
|
||||||
return bestFnCost.getFunction();
|
return bestFnCost.getFunction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void setTargetedFunctionsToUnknown(IType[] argTypes) {
|
||||||
|
for (IType argType : argTypes) {
|
||||||
|
if (argType instanceof FunctionSetType) {
|
||||||
|
((FunctionSetType) argType).setToUnknown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IBinding resolveFunctionDeclaration(LookupData data, ICPPFunction[] fns) throws DOMException {
|
||||||
|
if (data.forExplicitFunctionSpecialization()) {
|
||||||
|
fns= CPPTemplates.instantiateFunctionTemplates(fns, data.getFunctionArgumentTypes(),
|
||||||
|
data.getFunctionArgumentValueCategories(), data.astName, data.argsContainImpliedObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
int argCount = data.getFunctionArgumentCount();
|
||||||
|
if (argCount == 1) {
|
||||||
|
// check for parameter of type void
|
||||||
|
final IType[] argTypes = data.getFunctionArgumentTypes();
|
||||||
|
if (argTypes.length == 1 && SemanticUtil.isVoidType(argTypes[0])) {
|
||||||
|
argCount= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ICPPFunction fn : fns) {
|
||||||
|
if (fn != null && !(fn instanceof IProblemBinding) && !(fn instanceof ICPPUnknownBinding)) {
|
||||||
|
// The index is optimized to provide the function type, avoid using the parameters
|
||||||
|
// 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 null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sortAstBeforeIndex(IFunction[] fns) {
|
||||||
|
int iast= 0;
|
||||||
|
for (int i = 0; i < fns.length; i++) {
|
||||||
|
IFunction fn= fns[i];
|
||||||
|
if (!(fn instanceof IIndexBinding)) {
|
||||||
|
if (iast != i) {
|
||||||
|
fns[i]= fns[iast];
|
||||||
|
fns[iast]= fn;
|
||||||
|
iast++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static FunctionCost costForFunctionCall(IFunction fn, boolean allowUDC, LookupData data)
|
private static FunctionCost costForFunctionCall(IFunction fn, boolean allowUDC, LookupData data)
|
||||||
throws DOMException {
|
throws DOMException {
|
||||||
IType[] argTypes = data.getFunctionArgumentTypes();
|
IType[] argTypes = data.getFunctionArgumentTypes();
|
||||||
|
@ -2466,7 +2535,9 @@ public class CPPSemantics {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argType.isSameType(paramType)) {
|
if (argType instanceof FunctionSetType) {
|
||||||
|
cost= ((FunctionSetType) argType).costForTarget(paramType);
|
||||||
|
} else if (argType.isSameType(paramType)) {
|
||||||
cost = new Cost(argType, paramType, Rank.IDENTITY);
|
cost = new Cost(argType, paramType, Rank.IDENTITY);
|
||||||
} else {
|
} else {
|
||||||
if (CPPTemplates.isDependentType(paramType))
|
if (CPPTemplates.isDependentType(paramType))
|
||||||
|
@ -2537,148 +2608,92 @@ public class CPPSemantics {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 13.4-1 A use of an overloaded function without arguments is resolved in certain contexts to a function
|
* 13.4-1 A use of an overloaded function without arguments is resolved in certain contexts to a function
|
||||||
* @param data
|
|
||||||
* @param fns
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
private static IBinding resolveTargetedFunction(LookupData data, IBinding[] fns) {
|
static IBinding resolveTargetedFunction(IASTName name, ICPPFunction[] fns) {
|
||||||
if (fns.length == 1)
|
boolean addressOf= false;
|
||||||
return fns[0];
|
IASTNode node= name.getParent();
|
||||||
|
while (node instanceof IASTName)
|
||||||
|
node= node.getParent();
|
||||||
|
|
||||||
IBinding oneFromAST= null;
|
if (!(node instanceof IASTIdExpression))
|
||||||
for (IBinding fn : fns) {
|
return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_OVERLOAD);
|
||||||
if (!isFromIndex(fn)) {
|
|
||||||
if (oneFromAST != null) {
|
ASTNodeProperty prop= node.getPropertyInParent();
|
||||||
oneFromAST= null;
|
IASTNode parent = node.getParent();
|
||||||
|
while (parent instanceof IASTUnaryExpression) {
|
||||||
|
final int op= ((IASTUnaryExpression) parent).getOperator();
|
||||||
|
if (op == IASTUnaryExpression.op_bracketedPrimary) {
|
||||||
|
} else if (!addressOf && op == IASTUnaryExpression.op_amper) {
|
||||||
|
addressOf= true;
|
||||||
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
oneFromAST= fn;
|
node= parent;
|
||||||
}
|
prop= node.getPropertyInParent();
|
||||||
}
|
parent= node.getParent();
|
||||||
if (oneFromAST != null)
|
|
||||||
return oneFromAST;
|
|
||||||
|
|
||||||
if (data.forAssociatedScopes) {
|
|
||||||
return new CPPCompositeBinding(fns);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IBinding result = null;
|
IType targetType= null;
|
||||||
|
|
||||||
Object o = getTargetType(data);
|
|
||||||
IType type, types[] = null;
|
|
||||||
int idx = -1;
|
|
||||||
if (o instanceof IType[]) {
|
|
||||||
types = (IType[]) o;
|
|
||||||
type = types[++idx];
|
|
||||||
} else {
|
|
||||||
type = (IType) o;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (type != null) {
|
|
||||||
type = getUltimateType(type, false);
|
|
||||||
if (type == null || !(type instanceof IFunctionType)) {
|
|
||||||
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
|
|
||||||
data.getFoundBindings());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (IBinding fn2 : fns) {
|
|
||||||
IFunction fn = (IFunction) fn2;
|
|
||||||
IType ft = null;
|
|
||||||
try {
|
|
||||||
ft = fn.getType();
|
|
||||||
} catch (DOMException e) {
|
|
||||||
ft = e.getProblem();
|
|
||||||
}
|
|
||||||
if (type.isSameType(ft)) {
|
|
||||||
if (result == null) {
|
|
||||||
result = fn;
|
|
||||||
} else {
|
|
||||||
int c = compareByRelevance(data, result, fn);
|
|
||||||
if (c < 0) {
|
|
||||||
result= fn;
|
|
||||||
} else if (c == 0) {
|
|
||||||
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
|
|
||||||
data.getFoundBindings());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (types != null && ++idx < types.length) {
|
|
||||||
type = types[idx];
|
|
||||||
} else {
|
|
||||||
type = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result != null ? result :
|
|
||||||
new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.getFoundBindings());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Object getTargetType(LookupData data) {
|
|
||||||
IASTName name = data.astName;
|
|
||||||
|
|
||||||
if (name.getPropertyInParent() == ICPPASTQualifiedName.SEGMENT_NAME)
|
|
||||||
name = (IASTName) name.getParent();
|
|
||||||
|
|
||||||
if (name.getPropertyInParent() != IASTIdExpression.ID_NAME)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
IASTIdExpression idExp = (IASTIdExpression) name.getParent();
|
|
||||||
IASTNode node = idExp;
|
|
||||||
ASTNodeProperty prop = null;
|
|
||||||
while (node != null) {
|
|
||||||
prop = node.getPropertyInParent();
|
|
||||||
if (prop == IASTDeclarator.INITIALIZER) {
|
if (prop == IASTDeclarator.INITIALIZER) {
|
||||||
// target is an object or reference being initialized
|
// Target is an object or reference being initialized
|
||||||
IASTDeclarator dtor = (IASTDeclarator) node.getParent();
|
IASTDeclarator dtor = (IASTDeclarator) parent;
|
||||||
return CPPVisitor.createType(dtor);
|
targetType= CPPVisitor.createType(dtor);
|
||||||
} else if (prop == IASTEqualsInitializer.INITIALIZER) {
|
} else if (prop == IASTEqualsInitializer.INITIALIZER) {
|
||||||
IASTEqualsInitializer initExp = (IASTEqualsInitializer) node.getParent();
|
IASTEqualsInitializer initExp = (IASTEqualsInitializer) parent;
|
||||||
if (initExp.getParent() instanceof IASTDeclarator) {
|
if (initExp.getParent() instanceof IASTDeclarator) {
|
||||||
IASTDeclarator dtor = (IASTDeclarator) initExp.getParent();
|
IASTDeclarator dtor = (IASTDeclarator) initExp.getParent();
|
||||||
return CPPVisitor.createType(dtor);
|
targetType= CPPVisitor.createType(dtor);
|
||||||
|
}
|
||||||
|
} else if (prop == ICPPASTConstructorInitializer.ARGUMENT) {
|
||||||
|
ICPPASTConstructorInitializer init = (ICPPASTConstructorInitializer) parent;
|
||||||
|
if (init.getArguments().length == 1) {
|
||||||
|
final IASTNode parentOfInit = init.getParent();
|
||||||
|
if (parentOfInit instanceof IASTDeclarator) {
|
||||||
|
IASTDeclarator dtor = (IASTDeclarator) parentOfInit;
|
||||||
|
targetType= CPPVisitor.createType(dtor);
|
||||||
|
} else if (parentOfInit instanceof ICPPASTConstructorChainInitializer) {
|
||||||
|
ICPPASTConstructorChainInitializer memInit= (ICPPASTConstructorChainInitializer) parentOfInit;
|
||||||
|
IBinding var= memInit.getMemberInitializerId().resolveBinding();
|
||||||
|
if (var instanceof IVariable) {
|
||||||
|
try {
|
||||||
|
targetType= ((IVariable) var).getType();
|
||||||
|
} catch (DOMException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (prop == IASTBinaryExpression.OPERAND_TWO) {
|
||||||
|
IASTBinaryExpression binaryExp = (IASTBinaryExpression) parent;
|
||||||
|
if (binaryExp.getOperator() == IASTBinaryExpression.op_assign) {
|
||||||
|
targetType= binaryExp.getOperand1().getExpressionType();
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
} else if (prop == IASTBinaryExpression.OPERAND_TWO &&
|
|
||||||
((IASTBinaryExpression) node.getParent()).getOperator() == IASTBinaryExpression.op_assign) {
|
|
||||||
// target is the left side of an assignment
|
|
||||||
IASTBinaryExpression binaryExp = (IASTBinaryExpression) node.getParent();
|
|
||||||
IASTExpression exp = binaryExp.getOperand1();
|
|
||||||
return exp.getExpressionType();
|
|
||||||
} else if (prop == IASTFunctionCallExpression.ARGUMENT) {
|
} else if (prop == IASTFunctionCallExpression.ARGUMENT) {
|
||||||
// target is a parameter of a function
|
// Target is a parameter of a function, need to resolve the function call
|
||||||
// if this function call refers to an overloaded function, there is more than one possibility
|
IASTFunctionCallExpression fnCall = (IASTFunctionCallExpression) parent;
|
||||||
// for the target type
|
IType t= SemanticUtil.getNestedType(fnCall.getFunctionNameExpression().getExpressionType(), TDEF|REF|CVTYPE);
|
||||||
IASTFunctionCallExpression fnCall = (IASTFunctionCallExpression) node.getParent();
|
if (t instanceof IPointerType) {
|
||||||
int idx = 0;
|
t= SemanticUtil.getNestedType(((IPointerType) t).getType(), TDEF | REF | CVTYPE);
|
||||||
final IASTInitializerClause[] arguments = fnCall.getArguments();
|
}
|
||||||
for (IASTInitializerClause arg : arguments) {
|
if (t instanceof IFunctionType) {
|
||||||
if (arg == node)
|
int i= 0;
|
||||||
|
for (IASTNode arg : fnCall.getArguments()) {
|
||||||
|
if (arg == node) {
|
||||||
|
IType[] params= ((IFunctionType) t).getParameterTypes();
|
||||||
|
if (params.length > i) {
|
||||||
|
targetType= params[i];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
idx++;
|
|
||||||
}
|
}
|
||||||
if (idx >= arguments.length)
|
i++;
|
||||||
return null;
|
}
|
||||||
|
|
||||||
IFunctionType[] types = getPossibleFunctions(fnCall);
|
|
||||||
if (types == null)
|
|
||||||
return null;
|
|
||||||
IType[] result = null;
|
|
||||||
for (int i = 0; i < types.length && types[i] != null; i++) {
|
|
||||||
IType[] pts = null;
|
|
||||||
pts = types[i].getParameterTypes();
|
|
||||||
if (pts.length > idx)
|
|
||||||
result = (IType[]) ArrayUtil.append(IType.class, result, pts[idx]);
|
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
} else if (prop == IASTCastExpression.OPERAND) {
|
} else if (prop == IASTCastExpression.OPERAND) {
|
||||||
// target is an explicit type conversion
|
// target is an explicit type conversion
|
||||||
IASTCastExpression cast = (IASTCastExpression) node.getParent();
|
IASTCastExpression cast = (IASTCastExpression) parent;
|
||||||
return CPPVisitor.createType(cast.getTypeId().getAbstractDeclarator());
|
targetType= CPPVisitor.createType(cast.getTypeId().getAbstractDeclarator());
|
||||||
} else if (prop == ICPPASTTemplateId.TEMPLATE_ID_ARGUMENT) {
|
} else if (prop == ICPPASTTemplateId.TEMPLATE_ID_ARGUMENT) {
|
||||||
//target is a template non-type parameter (14.3.2-5)
|
// target is a template non-type parameter (14.3.2-5)
|
||||||
ICPPASTTemplateId id = (ICPPASTTemplateId) node.getParent();
|
ICPPASTTemplateId id = (ICPPASTTemplateId) parent;
|
||||||
IASTNode[] args = id.getTemplateArguments();
|
IASTNode[] args = id.getTemplateArguments();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (; i < args.length; i++) {
|
for (; i < args.length; i++) {
|
||||||
|
@ -2686,97 +2701,94 @@ public class CPPSemantics {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IBinding template =id.getTemplateName().resolveBinding();
|
IBinding template = id.getTemplateName().resolveBinding();
|
||||||
if (template instanceof ICPPTemplateDefinition) {
|
if (template instanceof ICPPTemplateDefinition) {
|
||||||
try {
|
try {
|
||||||
ICPPTemplateParameter[] ps = ((ICPPTemplateDefinition) template).getTemplateParameters();
|
ICPPTemplateParameter[] ps = ((ICPPTemplateDefinition) template).getTemplateParameters();
|
||||||
if (i < args.length && i < ps.length && ps[i] instanceof ICPPTemplateNonTypeParameter) {
|
if (i < args.length && i < ps.length && ps[i] instanceof ICPPTemplateNonTypeParameter) {
|
||||||
return ((ICPPTemplateNonTypeParameter) ps[i]).getType();
|
targetType= ((ICPPTemplateNonTypeParameter) ps[i]).getType();
|
||||||
}
|
}
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (prop == IASTReturnStatement.RETURNVALUE) {
|
} else if (prop == IASTReturnStatement.RETURNVALUE) {
|
||||||
// target is the return value of a function, operator or conversion
|
// target is the return value of a function, operator or conversion
|
||||||
while (!(node instanceof IASTFunctionDefinition)) {
|
while (parent != null && !(parent instanceof IASTFunctionDefinition)) {
|
||||||
node = node.getParent();
|
parent = parent.getParent();
|
||||||
}
|
}
|
||||||
IASTDeclarator dtor = ((IASTFunctionDefinition) node).getDeclarator();
|
if (parent instanceof IASTFunctionDefinition) {
|
||||||
|
IASTDeclarator dtor = ((IASTFunctionDefinition) parent).getDeclarator();
|
||||||
dtor= ASTQueries.findInnermostDeclarator(dtor);
|
dtor= ASTQueries.findInnermostDeclarator(dtor);
|
||||||
IBinding binding = dtor.getName().resolveBinding();
|
IBinding binding = dtor.getName().resolveBinding();
|
||||||
if (binding instanceof IFunction) {
|
if (binding instanceof IFunction) {
|
||||||
try {
|
try {
|
||||||
IFunctionType ft = ((IFunction) binding).getType();
|
IFunctionType ft = ((IFunction) binding).getType();
|
||||||
return ft.getReturnType();
|
targetType= ft.getReturnType();
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (prop == IASTUnaryExpression.OPERAND) {
|
|
||||||
IASTUnaryExpression parent = (IASTUnaryExpression) node.getParent();
|
|
||||||
if (parent.getOperator() == IASTUnaryExpression.op_bracketedPrimary ||
|
|
||||||
parent.getOperator() == IASTUnaryExpression.op_amper) {
|
|
||||||
node = parent;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
if (targetType == null && parent instanceof IASTExpression
|
||||||
|
&& parent instanceof IASTImplicitNameOwner) {
|
||||||
|
// Trigger resolution of overloaded operator, which may resolve the
|
||||||
|
// function set.
|
||||||
|
((IASTImplicitNameOwner) parent).getImplicitNames();
|
||||||
|
final IBinding newBinding = name.getPreBinding();
|
||||||
|
if (!(newBinding instanceof CPPFunctionSet))
|
||||||
|
return newBinding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ICPPFunction function = resolveTargetedFunction(targetType, name, fns);
|
||||||
|
if (function == null)
|
||||||
|
return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_OVERLOAD);
|
||||||
|
|
||||||
|
return function;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ICPPFunction resolveTargetedFunction(IType targetType, IASTName name, ICPPFunction[] fns) {
|
||||||
|
targetType= getNestedType(targetType, TDEF | REF | CVTYPE | PTR | MPTR);
|
||||||
|
if (!(targetType instanceof ICPPFunctionType))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// First pass, consider functions
|
||||||
|
for (ICPPFunction fn : fns) {
|
||||||
|
try {
|
||||||
|
if (!(fn instanceof ICPPFunctionTemplate)) {
|
||||||
|
if (targetType.isSameType(fn.getType()))
|
||||||
|
return fn;
|
||||||
|
}
|
||||||
|
} catch (DOMException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second pass, consider templates
|
||||||
|
ICPPFunction result= null;
|
||||||
|
ICPPFunctionTemplate resultTemplate= null;
|
||||||
|
for (IFunction fn : fns) {
|
||||||
|
try {
|
||||||
|
if (fn instanceof ICPPFunctionTemplate) {
|
||||||
|
final ICPPFunctionTemplate template = (ICPPFunctionTemplate) fn;
|
||||||
|
ICPPFunction inst= CPPTemplates.instantiateFunctionTemplate(template, (ICPPFunctionType) targetType, name);
|
||||||
|
if (inst != null) {
|
||||||
|
int cmp= -1;
|
||||||
|
if (result != null) {
|
||||||
|
cmp= CPPTemplates.orderTemplateFunctions(resultTemplate, template);
|
||||||
|
if (cmp == 0)
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (cmp < 0) {
|
||||||
static private IFunctionType[] getPossibleFunctions(IASTFunctionCallExpression call) {
|
resultTemplate= template;
|
||||||
IFunctionType[] result = null;
|
result= inst;
|
||||||
|
|
||||||
IASTExpression exp = call.getFunctionNameExpression();
|
|
||||||
if (exp instanceof IASTIdExpression) {
|
|
||||||
IASTIdExpression idExp = (IASTIdExpression) exp;
|
|
||||||
IASTName name = idExp.getName();
|
|
||||||
LookupData data = createLookupData(name);
|
|
||||||
try {
|
|
||||||
lookup(data, null);
|
|
||||||
} catch (DOMException e) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
final boolean isIndexBased= data.tu != null && data.tu.getIndex() != null;
|
|
||||||
if (data.hasResults()) {
|
|
||||||
Object[] items = (Object[]) data.foundItems;
|
|
||||||
IBinding temp = null;
|
|
||||||
for (Object o : items) {
|
|
||||||
if (o == null) break;
|
|
||||||
if (o instanceof IASTName) {
|
|
||||||
temp = ((IASTName) o).resolveBinding();
|
|
||||||
} else if (o instanceof IBinding) {
|
|
||||||
temp = (IBinding) o;
|
|
||||||
if (!declaredBefore(temp, name, isIndexBased))
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
if (temp instanceof IFunction) {
|
|
||||||
result = (IFunctionType[]) ArrayUtil.append(IFunctionType.class, result, ((IFunction) temp).getType());
|
|
||||||
} else if (temp instanceof IVariable) {
|
|
||||||
IType type = getUltimateType(((IVariable) temp).getType(), false);
|
|
||||||
if (type instanceof IFunctionType)
|
|
||||||
result = (IFunctionType[]) ArrayUtil.append(IFunctionType.class, result, type);
|
|
||||||
}
|
}
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
|
||||||
IType type = exp.getExpressionType();
|
|
||||||
type = getUltimateType(type, false);
|
|
||||||
if (type instanceof IFunctionType) {
|
|
||||||
result = new IFunctionType[] { (IFunctionType) type };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For a pointer dereference expression e1->e2, return the type that e1 ultimately evaluates to
|
* For a pointer dereference expression e1->e2, return the type that e1 ultimately evaluates to
|
||||||
* when chaining overloaded class member access operators <code>operator->()</code> calls.
|
* when chaining overloaded class member access operators <code>operator->()</code> calls.
|
||||||
|
@ -2790,7 +2802,7 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Also collections the function bindings if requested.
|
* Also collects the function bindings if requested.
|
||||||
*/
|
*/
|
||||||
public static IType getFieldOwnerType(ICPPASTFieldReference fieldReference, Collection<ICPPFunction> functionBindings) throws DOMException {
|
public static IType getFieldOwnerType(ICPPASTFieldReference fieldReference, Collection<ICPPFunction> functionBindings) throws DOMException {
|
||||||
final IASTExpression owner = fieldReference.getFieldOwner();
|
final IASTExpression owner = fieldReference.getFieldOwner();
|
||||||
|
@ -2849,9 +2861,10 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ICPPFunction findOverloadedOperator(IASTArraySubscriptExpression exp) {
|
public static ICPPFunction findOverloadedOperator(IASTArraySubscriptExpression exp) {
|
||||||
IASTInitializerClause[] args = {exp.getArrayExpression(), exp.getArgument()};
|
final IASTExpression arrayExpression = exp.getArrayExpression();
|
||||||
IType type = exp.getArrayExpression().getExpressionType();
|
IASTInitializerClause[] args = {arrayExpression, exp.getArgument()};
|
||||||
type = SemanticUtil.getUltimateTypeUptoPointers(type);
|
IType type = typeOrFunctionSet(arrayExpression);
|
||||||
|
type = SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE);
|
||||||
return findOverloadedOperator(exp, args, type, OverloadableOperator.BRACKET, LookupMode.NO_GLOBALS);
|
return findOverloadedOperator(exp, args, type, OverloadableOperator.BRACKET, LookupMode.NO_GLOBALS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2871,7 +2884,7 @@ public class CPPSemantics {
|
||||||
OverloadableOperator op = OverloadableOperator.fromNewExpression(exp);
|
OverloadableOperator op = OverloadableOperator.fromNewExpression(exp);
|
||||||
|
|
||||||
IType type = exp.getExpressionType();
|
IType type = exp.getExpressionType();
|
||||||
if (type instanceof IProblem)
|
if (!(type instanceof IPointerType))
|
||||||
return null;
|
return null;
|
||||||
type = ((IPointerType) type).getType();
|
type = ((IPointerType) type).getType();
|
||||||
|
|
||||||
|
@ -2964,8 +2977,8 @@ public class CPPSemantics {
|
||||||
ValueCategory isLValue= PRVALUE;
|
ValueCategory isLValue= PRVALUE;
|
||||||
if (initClause instanceof IASTExpression) {
|
if (initClause instanceof IASTExpression) {
|
||||||
final IASTExpression expr = (IASTExpression) initClause;
|
final IASTExpression expr = (IASTExpression) initClause;
|
||||||
isLValue= expr.getValueCategory();
|
isLValue= valueCat(expr);
|
||||||
sourceType= SemanticUtil.getSimplifiedType(expr.getExpressionType());
|
sourceType= SemanticUtil.getSimplifiedType(typeOrFunctionSet(expr));
|
||||||
} else if (initClause instanceof ICPPASTInitializerList) {
|
} else if (initClause instanceof ICPPASTInitializerList) {
|
||||||
sourceType= new InitializerListType((ICPPASTInitializerList) initClause);
|
sourceType= new InitializerListType((ICPPASTInitializerList) initClause);
|
||||||
}
|
}
|
||||||
|
@ -3044,25 +3057,26 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ICPPFunction findOverloadedOperator(IASTUnaryExpression exp) {
|
public static ICPPFunction findOverloadedOperator(IASTUnaryExpression exp) {
|
||||||
if (exp.getOperand() == null)
|
final IASTExpression operand = exp.getOperand();
|
||||||
|
if (operand == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
OverloadableOperator op = OverloadableOperator.fromUnaryExpression(exp);
|
OverloadableOperator op = OverloadableOperator.fromUnaryExpression(exp);
|
||||||
if (op == null)
|
if (op == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
IASTExpression[] args;
|
IType type = typeOrFunctionSet(operand);
|
||||||
int operator = exp.getOperator();
|
|
||||||
if (operator == IASTUnaryExpression.op_postFixDecr || operator == IASTUnaryExpression.op_postFixIncr)
|
|
||||||
args = new IASTExpression[] { exp.getOperand(), CPPASTLiteralExpression.INT_ZERO };
|
|
||||||
else
|
|
||||||
args = new IASTExpression[] { exp.getOperand() };
|
|
||||||
|
|
||||||
IType type = exp.getOperand().getExpressionType();
|
|
||||||
type = SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE);
|
type = SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE);
|
||||||
if (!isUserDefined(type))
|
if (!isUserDefined(type))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
IASTExpression[] args;
|
||||||
|
int operator = exp.getOperator();
|
||||||
|
if (operator == IASTUnaryExpression.op_postFixDecr || operator == IASTUnaryExpression.op_postFixIncr) {
|
||||||
|
args = new IASTExpression[] { operand, CPPASTLiteralExpression.INT_ZERO };
|
||||||
|
} else {
|
||||||
|
args = new IASTExpression[] { operand };
|
||||||
|
}
|
||||||
return findOverloadedOperator(exp, args, type, op, LookupMode.LIMITED_GLOBALS);
|
return findOverloadedOperator(exp, args, type, op, LookupMode.LIMITED_GLOBALS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3076,8 +3090,8 @@ public class CPPSemantics {
|
||||||
if(op2==null){
|
if(op2==null){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
IType op1type = getNestedType(op1.getExpressionType(), TDEF | REF | CVTYPE);
|
IType op1type = getNestedType(typeOrFunctionSet(op1), TDEF | REF | CVTYPE);
|
||||||
IType op2type = getNestedType(op2.getExpressionType(), TDEF | REF | CVTYPE);
|
IType op2type = getNestedType(typeOrFunctionSet(op2), TDEF | REF | CVTYPE);
|
||||||
if (!isUserDefined(op1type) && !isUserDefined(op2type))
|
if (!isUserDefined(op1type) && !isUserDefined(op2type))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
@ -3105,14 +3119,15 @@ public class CPPSemantics {
|
||||||
* Returns the operator,() function that would apply to the two given arguments.
|
* Returns the operator,() function that would apply to the two given arguments.
|
||||||
* The lookup type of the class where the operator,() might be found must also be provided.
|
* The lookup type of the class where the operator,() might be found must also be provided.
|
||||||
*/
|
*/
|
||||||
public static ICPPFunction findOverloadedOperatorComma(IASTExpression first, IASTExpression second, final IType lookupType) {
|
public static ICPPFunction findOverloadedOperatorComma(IASTExpression first, final IType lookupType, final ValueCategory valueCat, IASTExpression second) {
|
||||||
|
IType op1type = getNestedType(lookupType, TDEF | REF | CVTYPE);
|
||||||
|
IType op2type = getNestedType(typeOrFunctionSet(second), TDEF | REF | CVTYPE);
|
||||||
|
if (!isUserDefined(op1type) && !isUserDefined(op2type))
|
||||||
|
return null;
|
||||||
|
|
||||||
IASTUnaryExpression dummy = new CPPASTUnaryExpression() {
|
IASTUnaryExpression dummy = new CPPASTUnaryExpression() {
|
||||||
@Override public IType getExpressionType() { return lookupType; }
|
@Override public IType getExpressionType() { return lookupType; }
|
||||||
@Override public IASTExpression getOperand() {
|
@Override public ValueCategory getValueCategory() { return valueCat; }
|
||||||
return new CPPASTUnaryExpression() {
|
|
||||||
@Override public IType getExpressionType() { return lookupType; }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
dummy.setParent(first);
|
dummy.setParent(first);
|
||||||
|
|
||||||
|
@ -3126,10 +3141,16 @@ public class CPPSemantics {
|
||||||
ICPPClassType callToObjectOfClassType= null;
|
ICPPClassType callToObjectOfClassType= null;
|
||||||
IType type2= null;
|
IType type2= null;
|
||||||
if (args.length >= 2 && args[1] instanceof IASTExpression) {
|
if (args.length >= 2 && args[1] instanceof IASTExpression) {
|
||||||
type2= getUltimateTypeUptoPointers(((IASTExpression) args[1]).getExpressionType());
|
type2 = typeOrFunctionSet((IASTExpression) args[1]);
|
||||||
|
type2= getNestedType(type2, TDEF | REF | CVTYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (methodLookupType instanceof ICPPUnknownType || type2 instanceof ICPPUnknownType) {
|
if (methodLookupType instanceof ICPPUnknownType || type2 instanceof ICPPUnknownType) {
|
||||||
|
if (methodLookupType instanceof FunctionSetType)
|
||||||
|
((FunctionSetType) methodLookupType).setToUnknown();
|
||||||
|
if (type2 instanceof FunctionSetType)
|
||||||
|
((FunctionSetType) type2).setToUnknown();
|
||||||
|
|
||||||
return new CPPUnknownFunction(null, operator.toCharArray());
|
return new CPPUnknownFunction(null, operator.toCharArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3308,7 +3329,7 @@ public class CPPSemantics {
|
||||||
if (type instanceof IProblemBinding)
|
if (type instanceof IProblemBinding)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return type instanceof ICPPClassType || type instanceof IEnumeration;
|
return type instanceof ICPPClassType || type instanceof IEnumeration || type instanceof ICPPUnknownType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IBinding[] findBindings(IScope scope, String name, boolean qualified) {
|
public static IBinding[] findBindings(IScope scope, String name, boolean qualified) {
|
||||||
|
|
|
@ -152,6 +152,7 @@ public class CPPTemplates {
|
||||||
private static final int PACK_SIZE_DEFER = -1;
|
private static final int PACK_SIZE_DEFER = -1;
|
||||||
private static final int PACK_SIZE_FAIL = -2;
|
private static final int PACK_SIZE_FAIL = -2;
|
||||||
private static final int PACK_SIZE_NOT_FOUND = Integer.MAX_VALUE;
|
private static final int PACK_SIZE_NOT_FOUND = Integer.MAX_VALUE;
|
||||||
|
private static final ICPPFunction[] NO_FUNCTIONS = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a class template with the given arguments. May return <code>null</code>.
|
* Instantiates a class template with the given arguments. May return <code>null</code>.
|
||||||
|
@ -1515,7 +1516,7 @@ public class CPPTemplates {
|
||||||
* empty IType array is returned if id is <code>null</code>
|
* empty IType array is returned if id is <code>null</code>
|
||||||
* @throws DOMException
|
* @throws DOMException
|
||||||
*/
|
*/
|
||||||
static public ICPPTemplateArgument[] createTemplateArgumentArray(ICPPASTTemplateId id) throws DOMException {
|
public static ICPPTemplateArgument[] createTemplateArgumentArray(ICPPASTTemplateId id) throws DOMException {
|
||||||
ICPPTemplateArgument[] result= ICPPTemplateArgument.EMPTY_ARGUMENTS;
|
ICPPTemplateArgument[] result= ICPPTemplateArgument.EMPTY_ARGUMENTS;
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
IASTNode[] params= id.getTemplateArguments();
|
IASTNode[] params= id.getTemplateArguments();
|
||||||
|
@ -1537,7 +1538,7 @@ public class CPPTemplates {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static protected void instantiateFunctionTemplates(IFunction[] functions, IType[] allFnArgs,
|
static ICPPFunction[] instantiateFunctionTemplates(ICPPFunction[] fns, IType[] allFnArgs,
|
||||||
ValueCategory[] allValueCategories, IASTName name, boolean argsContainImpliedObject) {
|
ValueCategory[] allValueCategories, IASTName name, boolean argsContainImpliedObject) {
|
||||||
boolean requireTemplate= false;
|
boolean requireTemplate= false;
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
|
@ -1552,12 +1553,13 @@ public class CPPTemplates {
|
||||||
IType[] reducedFnArgs= null;
|
IType[] reducedFnArgs= null;
|
||||||
ValueCategory[] reducedValueCategories= null;
|
ValueCategory[] reducedValueCategories= null;
|
||||||
ICPPTemplateArgument[] tmplArgs= null;
|
ICPPTemplateArgument[] tmplArgs= null;
|
||||||
for (int i = 0; i < functions.length; i++) {
|
ICPPFunction[] result= fns;
|
||||||
IFunction func = functions[i];
|
int idx= 0;
|
||||||
|
for (int i = 0; i < fns.length; i++) {
|
||||||
|
final ICPPFunction func = fns[i];
|
||||||
|
ICPPFunction rf= null;
|
||||||
if (func instanceof ICPPFunctionTemplate) {
|
if (func instanceof ICPPFunctionTemplate) {
|
||||||
ICPPFunctionTemplate template= (ICPPFunctionTemplate) func;
|
ICPPFunctionTemplate template= (ICPPFunctionTemplate) func;
|
||||||
functions[i]= null;
|
|
||||||
|
|
||||||
final IType[] fnArgs;
|
final IType[] fnArgs;
|
||||||
final ValueCategory[] valueCategories;
|
final ValueCategory[] valueCategories;
|
||||||
if (argsContainImpliedObject && template instanceof ICPPMethod) {
|
if (argsContainImpliedObject && template instanceof ICPPMethod) {
|
||||||
|
@ -1583,18 +1585,16 @@ public class CPPTemplates {
|
||||||
tmplArgs = ICPPTemplateArgument.EMPTY_ARGUMENTS;
|
tmplArgs = ICPPTemplateArgument.EMPTY_ARGUMENTS;
|
||||||
try {
|
try {
|
||||||
if (fnArgs == null || containsDependentType(fnArgs)) {
|
if (fnArgs == null || containsDependentType(fnArgs)) {
|
||||||
functions[i]= CPPUnknownFunction.createForSample(template);
|
return new ICPPFunction[] {CPPUnknownFunction.createForSample(template)};
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (name instanceof ICPPASTTemplateId && !(template instanceof ICPPConstructor)) {
|
if (name instanceof ICPPASTTemplateId && !(template instanceof ICPPConstructor)) {
|
||||||
tmplArgs = createTemplateArgumentArray((ICPPASTTemplateId) name);
|
tmplArgs = createTemplateArgumentArray((ICPPASTTemplateId) name);
|
||||||
if (hasDependentArgument(tmplArgs)) {
|
if (hasDependentArgument(tmplArgs)) {
|
||||||
functions[i]= CPPUnknownFunction.createForSample(template);
|
return new ICPPFunction[] {CPPUnknownFunction.createForSample(template)};
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
return;
|
return NO_FUNCTIONS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CPPTemplateParameterMap map= new CPPTemplateParameterMap(fnArgs.length);
|
CPPTemplateParameterMap map= new CPPTemplateParameterMap(fnArgs.length);
|
||||||
|
@ -1602,19 +1602,30 @@ public class CPPTemplates {
|
||||||
ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForFunctionCall(template, tmplArgs, fnArgs, valueCategories, map);
|
ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForFunctionCall(template, tmplArgs, fnArgs, valueCategories, 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;
|
rf= (ICPPFunction) instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
// try next candidate
|
// try next candidate
|
||||||
}
|
}
|
||||||
} else if (requireTemplate
|
} else if (!requireTemplate
|
||||||
&& !(func instanceof ICPPConstructor) && !(func instanceof ICPPUnknownBinding)
|
|| (func instanceof ICPPConstructor) || (func instanceof ICPPUnknownBinding)
|
||||||
&& !(func instanceof ICPPMethod && ((ICPPMethod) func).isDestructor())) {
|
|| (func instanceof ICPPMethod && ((ICPPMethod) func).isDestructor())) {
|
||||||
functions[i]= null;
|
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)
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static protected void instantiateConversionTemplates(IFunction[] functions, IType conversionType) {
|
static protected void instantiateConversionTemplates(IFunction[] functions, IType conversionType) {
|
||||||
|
@ -1653,6 +1664,42 @@ public class CPPTemplates {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
||||||
|
if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) {
|
||||||
|
name= (IASTName) name.getParent();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (isDependentType(target)) {
|
||||||
|
return CPPUnknownFunction.createForSample(template);
|
||||||
|
}
|
||||||
|
|
||||||
|
ICPPTemplateArgument[] tmplArgs;
|
||||||
|
if (name instanceof ICPPASTTemplateId && !(template instanceof ICPPConstructor)) {
|
||||||
|
tmplArgs = createTemplateArgumentArray((ICPPASTTemplateId) name);
|
||||||
|
if (hasDependentArgument(tmplArgs)) {
|
||||||
|
return CPPUnknownFunction.createForSample(template);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tmplArgs= ICPPTemplateArgument.EMPTY_ARGUMENTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
CPPTemplateParameterMap map= new CPPTemplateParameterMap(4);
|
||||||
|
ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForAddressOf(template, tmplArgs, target, map);
|
||||||
|
if (args != null) {
|
||||||
|
IBinding instance= instantiateFunctionTemplate(template, args, map);
|
||||||
|
if (instance instanceof ICPPFunction) {
|
||||||
|
return (ICPPFunction) instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (DOMException e) {
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transforms a function template for use in partial ordering, as described in the
|
* Transforms a function template for use in partial ordering, as described in the
|
||||||
* spec 14.5.5.2-3
|
* spec 14.5.5.2-3
|
||||||
|
|
|
@ -41,6 +41,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
|
||||||
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.ICPPConstructor;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
|
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.ICPPNamespace;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
||||||
|
@ -668,14 +669,18 @@ public class Conversions {
|
||||||
|
|
||||||
FunctionCost cost1= null;
|
FunctionCost cost1= null;
|
||||||
Cost cost2= null;
|
Cost cost2= null;
|
||||||
ICPPConstructor[] ctors= t.getConstructors();
|
ICPPFunction[] ctors= t.getConstructors();
|
||||||
CPPTemplates.instantiateFunctionTemplates(ctors, new IType[]{source}, new ValueCategory[] {valueCat}, null, false);
|
ctors= CPPTemplates.instantiateFunctionTemplates(ctors, new IType[]{source}, new ValueCategory[] {valueCat}, null, false);
|
||||||
|
|
||||||
for (ICPPConstructor ctor : ctors) {
|
for (ICPPFunction f : ctors) {
|
||||||
|
if (!(f instanceof ICPPConstructor) || f instanceof IProblemBinding)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ICPPConstructor ctor= (ICPPConstructor) f;
|
||||||
// Note: the special case of initializing a temporary to be bound to the first parameter
|
// Note: the special case of initializing a temporary to be bound to the first parameter
|
||||||
// of a copy constructor called with a single argument in the context of direct-initialization
|
// of a copy constructor called with a single argument in the context of direct-initialization
|
||||||
// is (more naturally) handled in initializationByConversionForDirectReference.
|
// is (more naturally) handled in initializationByConversionForDirectReference.
|
||||||
if (ctor != null && !(ctor instanceof IProblemBinding) && !ctor.isExplicit()) {
|
if (!ctor.isExplicit()) {
|
||||||
final ICPPFunctionType ft = ctor.getType();
|
final ICPPFunctionType ft = ctor.getType();
|
||||||
final IType[] ptypes = ft.getParameterTypes();
|
final IType[] ptypes = ft.getParameterTypes();
|
||||||
FunctionCost c1;
|
FunctionCost c1;
|
||||||
|
|
|
@ -89,6 +89,7 @@ public class Cost {
|
||||||
private ReferenceBinding fReferenceBinding;
|
private ReferenceBinding fReferenceBinding;
|
||||||
|
|
||||||
private boolean fCouldNarrow;
|
private boolean fCouldNarrow;
|
||||||
|
private ICPPFunction fSelectedFunction; // For targeted functions
|
||||||
|
|
||||||
public Cost(IType s, IType t, Rank rank) {
|
public Cost(IType s, IType t, Rank rank) {
|
||||||
source = s;
|
source = s;
|
||||||
|
@ -266,4 +267,15 @@ public class Cost {
|
||||||
public ICPPFunction getUserDefinedConversion() {
|
public ICPPFunction getUserDefinedConversion() {
|
||||||
return fUserDefinedConversion;
|
return fUserDefinedConversion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores a selected function. Used when resolving targeted functions.
|
||||||
|
*/
|
||||||
|
public void setSelectedFunction(ICPPFunction function) {
|
||||||
|
fSelectedFunction= function;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICPPFunction getSelectedFunction() {
|
||||||
|
return fSelectedFunction;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -15,7 +15,12 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
|
||||||
|
|
||||||
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.ValueCategory;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
|
@ -78,4 +83,45 @@ public class ExpressionTypes {
|
||||||
}
|
}
|
||||||
return prvalueType(r);
|
return prvalueType(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IType typeOrFunctionSet(IASTExpression e) {
|
||||||
|
FunctionSetType fs= getFunctionSetType(e);
|
||||||
|
if (fs != null) {
|
||||||
|
return fs;
|
||||||
|
}
|
||||||
|
return e.getExpressionType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ValueCategory valueCat(IASTExpression e) {
|
||||||
|
FunctionSetType fs= getFunctionSetType(e);
|
||||||
|
if (fs != null)
|
||||||
|
return fs.getValueCategory();
|
||||||
|
return e.getValueCategory();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FunctionSetType getFunctionSetType(IASTExpression e) {
|
||||||
|
boolean addressOf= false;
|
||||||
|
while (e instanceof IASTUnaryExpression) {
|
||||||
|
final IASTUnaryExpression unary = (IASTUnaryExpression) e;
|
||||||
|
final int op= unary.getOperator();
|
||||||
|
if (op == IASTUnaryExpression.op_bracketedPrimary) {
|
||||||
|
e= unary.getOperand();
|
||||||
|
} else if (!addressOf && op == IASTUnaryExpression.op_amper) {
|
||||||
|
addressOf= true;
|
||||||
|
e= unary.getOperand();
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e instanceof IASTIdExpression) {
|
||||||
|
IASTIdExpression idexpr= (IASTIdExpression) e;
|
||||||
|
final IASTName name = idexpr.getName();
|
||||||
|
IBinding b= name.resolvePreBinding();
|
||||||
|
if (b instanceof CPPFunctionSet) {
|
||||||
|
return new FunctionSetType(((CPPFunctionSet) b).getBindings(), name, addressOf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* FunctionSetType.java
|
||||||
|
* Created on Sep 14, 2010
|
||||||
|
*
|
||||||
|
* Copyright 2010 Wind River Systems, Inc. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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.PRVALUE;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownFunction;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used during overload resolution as a place-holder for function sets.
|
||||||
|
*/
|
||||||
|
public class FunctionSetType implements IType {
|
||||||
|
|
||||||
|
private ICPPFunction[] fFunctionSet;
|
||||||
|
private boolean fPointerType;
|
||||||
|
private IASTName fName;
|
||||||
|
|
||||||
|
public FunctionSetType(ICPPFunction[] functions, IASTName name, boolean addressOf) {
|
||||||
|
fName= name;
|
||||||
|
fFunctionSet= functions;
|
||||||
|
fPointerType= addressOf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSameType(IType type) {
|
||||||
|
return type == this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object clone() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueCategory getValueCategory() {
|
||||||
|
return fPointerType ? PRVALUE : LVALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cost costForTarget(IType paramType) {
|
||||||
|
IBinding result = CPPSemantics.resolveTargetedFunction(paramType, fName, fFunctionSet);
|
||||||
|
if (result instanceof ICPPFunction && !(result instanceof IProblemBinding)) {
|
||||||
|
Cost c= new Cost(paramType, paramType, Rank.IDENTITY);
|
||||||
|
c.setSelectedFunction((ICPPFunction) result);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
return Cost.NO_CONVERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void applySelectedFunction(ICPPFunction selectedFunction) {
|
||||||
|
if (selectedFunction != null) {
|
||||||
|
fName.setBinding(selectedFunction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICPPFunction[] getFunctionSet() {
|
||||||
|
return fFunctionSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToUnknown() {
|
||||||
|
fName.setBinding(new CPPUnknownFunction(null, fName.toCharArray()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,6 +15,7 @@
|
||||||
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.ExpressionTypes.valueCategoryFromReturnType;
|
||||||
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getSimplifiedType;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -509,8 +510,9 @@ public class LookupData {
|
||||||
for (int i = 0; i < exprs.length; i++) {
|
for (int i = 0; i < exprs.length; i++) {
|
||||||
IASTInitializerClause e = exprs[i];
|
IASTInitializerClause e = exprs[i];
|
||||||
if (e instanceof IASTExpression) {
|
if (e instanceof IASTExpression) {
|
||||||
IType etype= ((IASTExpression) e).getExpressionType();
|
// Find function set when taking an address of a function
|
||||||
functionArgTypes[i]= SemanticUtil.getSimplifiedType(etype);
|
final IType t = ExpressionTypes.typeOrFunctionSet((IASTExpression) e);
|
||||||
|
functionArgTypes[i]= getSimplifiedType(t);
|
||||||
} else if (e instanceof ICPPASTInitializerList) {
|
} else if (e instanceof ICPPASTInitializerList) {
|
||||||
functionArgTypes[i]= new InitializerListType((ICPPASTInitializerList) e);
|
functionArgTypes[i]= new InitializerListType((ICPPASTInitializerList) e);
|
||||||
}
|
}
|
||||||
|
@ -535,7 +537,7 @@ public class LookupData {
|
||||||
for (int i = 0; i < args.length; i++) {
|
for (int i = 0; i < args.length; i++) {
|
||||||
final IASTInitializerClause arg = args[i];
|
final IASTInitializerClause arg = args[i];
|
||||||
if (arg instanceof IASTExpression) {
|
if (arg instanceof IASTExpression) {
|
||||||
functionArgValueCategories[i]= ((IASTExpression) arg).getValueCategory();
|
functionArgValueCategories[i] = ExpressionTypes.valueCat((IASTExpression) arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -118,6 +118,87 @@ public class TemplateArgumentDeduction {
|
||||||
return result.toArray(new ICPPTemplateArgument[result.size()]);
|
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 (!deduct.fromType(par, arg, false))
|
||||||
|
return null;
|
||||||
|
if (!map.mergeToExplicit(deduct.fDeducedArgs))
|
||||||
|
return null;
|
||||||
|
if (!verifyDeduction(tmplParams, map, true))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
par= CPPTemplates.instantiateType(par, map, -1, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (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)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
result.add(deducedArg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toArray(new ICPPTemplateArgument[result.size()]);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deduce arguments for a user defined conversion template
|
* Deduce arguments for a user defined conversion template
|
||||||
* 14.8.2.3
|
* 14.8.2.3
|
||||||
|
|
Loading…
Add table
Reference in a new issue