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

Bug 324214: Overload resolution with method template and global function.

This commit is contained in:
Markus Schorn 2010-09-01 15:44:56 +00:00
parent 53b2b45d96
commit 1e7636523a
10 changed files with 144 additions and 145 deletions

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* Andrew Niefer (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Bryan Wilkinson (QNX)
* Andrew Ferguson (Symbian)
@ -85,9 +85,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalUnknownScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
/**
* @author aniefer
*/
public class AST2TemplateTests extends AST2BaseTest {
public AST2TemplateTests() {
@ -5093,5 +5090,21 @@ public class AST2TemplateTests extends AST2BaseTest {
final String code= getAboveComment();
parseAndCheckBindings(code);
}
// struct S {
// int s;
// };
// struct X {
// template<typename T> S* operator+(T t) const {return 0;}
// };
// int* operator+(const X&, int *) {return 0;}
//
// void test() {
// X x;
// (x + 1)->s;
// }
public void testOverloadResolutionBetweenMethodTemplateAndFunction() throws Exception {
final String code= getAboveComment();
parseAndCheckBindings(code);
}
}

View file

@ -125,7 +125,7 @@ public class CPPASTFieldReference extends ASTNode implements ICPPASTFieldReferen
// collect the function bindings
List<ICPPFunction> functionBindings = new ArrayList<ICPPFunction>();
try {
CPPSemantics.getChainedMemberAccessOperatorReturnType(this, functionBindings);
CPPSemantics.getFieldOwnerType(this, functionBindings);
} catch (DOMException e) {
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
}

View file

@ -12,10 +12,6 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.PTR;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
@ -103,10 +99,9 @@ public class CPPASTIdExpression extends ASTNode implements IASTIdExpression, ICP
if (var instanceof ICPPField && !var.isStatic()) {
IScope scope= CPPVisitor.getContainingScope(name);
if (scope != null) {
IType thisType= CPPVisitor.getThisType(scope);
if (thisType != null) {
thisType= SemanticUtil.getNestedType(thisType, TDEF|REF|PTR);
type= CPPASTFieldReference.addQualifiersForAccess((ICPPField) var, type, thisType);
IType containerType= CPPVisitor.getImpliedObjectType(scope);
if (containerType != null) {
type= CPPASTFieldReference.addQualifiersForAccess((ICPPField) var, type, containerType);
}
}
}

View file

@ -95,7 +95,12 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
switch (getKind()) {
case lk_this: {
IScope scope = CPPVisitor.getContainingScope(this);
return CPPVisitor.getThisType(scope);
IType type= CPPVisitor.getImpliedObjectType(scope);
if (type == null) {
// mstodo problem type
return null;
}
return new CPPPointerType(type);
}
case lk_true:
case lk_false:

View file

@ -75,7 +75,6 @@ import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IQualifierType;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
@ -162,7 +161,6 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLiteralExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
@ -235,7 +233,7 @@ public class CPPSemantics {
}
// 1: get some context info off of the name to figure out what kind of lookup we want
LookupData data = createLookupData(name, true);
LookupData data = createLookupData(name);
try {
// 2: lookup
@ -271,7 +269,7 @@ public class CPPSemantics {
}
protected static IBinding postResolution(IBinding binding, IASTName name) {
LookupData data = createLookupData(name, true);
LookupData data = createLookupData(name);
return postResolution(binding, data);
}
@ -574,7 +572,7 @@ public class CPPSemantics {
return false;
}
public static LookupData createLookupData(IASTName name, boolean considerAssociatedScopes) {
public static LookupData createLookupData(IASTName name) {
LookupData data = new LookupData(name);
IASTNode parent = name.getParent();
@ -601,7 +599,7 @@ public class CPPSemantics {
if (parent.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME) {
parent = parent.getParent();
IASTInitializerClause[] args = ((IASTFunctionCallExpression) parent).getArguments();
data.setFunctionArguments(args);
data.setFunctionArguments(false, args);
}
} else if (parent instanceof ICPPASTFieldReference) {
IASTNode grand= parent.getParent();
@ -612,7 +610,7 @@ public class CPPSemantics {
}
if (parent.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME) {
IASTInitializerClause[] exp = ((IASTFunctionCallExpression) parent.getParent()).getArguments();
data.setFunctionArguments(exp);
data.setFunctionArguments(false, exp);
}
} else if (parent instanceof ICPPASTNamedTypeSpecifier && parent.getParent() instanceof IASTTypeId) {
IASTTypeId typeId = (IASTTypeId) parent.getParent();
@ -620,20 +618,20 @@ public class CPPSemantics {
ICPPASTNewExpression newExp = (ICPPASTNewExpression) typeId.getParent();
IASTInitializer init = newExp.getInitializer();
if (init == null) {
data.setFunctionArguments();
data.setFunctionArguments(false);
} else if (init instanceof ICPPASTConstructorInitializer) {
data.setFunctionArguments(((ICPPASTConstructorInitializer) init).getArguments());
data.setFunctionArguments(false, ((ICPPASTConstructorInitializer) init).getArguments());
} else if (init instanceof ICPPASTInitializerList) {
data.setFunctionArguments(new IASTInitializerClause[] {(ICPPASTInitializerList) init});
data.setFunctionArguments(false, (ICPPASTInitializerList) init);
}
}
} else if (parent instanceof ICPPASTConstructorChainInitializer) {
ICPPASTConstructorChainInitializer ctorinit = (ICPPASTConstructorChainInitializer) parent;
IASTInitializer init = ctorinit.getInitializer();
if (init instanceof ICPPASTConstructorInitializer) {
data.setFunctionArguments(((ICPPASTConstructorInitializer) init).getArguments());
data.setFunctionArguments(false, ((ICPPASTConstructorInitializer) init).getArguments());
} else if (init instanceof ICPPASTInitializerList) {
data.setFunctionArguments(new IASTInitializerClause[] {(ICPPASTInitializerList) init});
data.setFunctionArguments(false, (ICPPASTInitializerList) init);
}
}
@ -1695,7 +1693,7 @@ public class CPPSemantics {
}
if (name.getPropertyInParent() != STRING_LOOKUP_PROPERTY) {
LookupData data = createLookupData(name, false);
LookupData data = createLookupData(name);
data.foundItems = bindings;
try {
return resolveAmbiguities(data, name);
@ -2240,7 +2238,7 @@ public class CPPSemantics {
numPars= 0;
int numArgs = argumentCount;
if (function instanceof ICPPMethod && data.firstArgIsImpliedMethodArg)
if (function instanceof ICPPMethod && data.argsContainImpliedObject)
numArgs--;
if (def) {
@ -2290,7 +2288,8 @@ public class CPPSemantics {
}
if (!isFuncDecl || data.forExplicitFunctionSpecialization()) {
CPPTemplates.instantiateFunctionTemplates(fns, data.getFunctionArgumentTypes(), data.getFunctionArgumentLValues(), data.astName);
CPPTemplates.instantiateFunctionTemplates(fns, data.getFunctionArgumentTypes(), data.getFunctionArgumentLValues(),
data.astName, data.argsContainImpliedObject);
}
// Reduce our set of candidate functions to only those who have the right number of parameters
@ -2388,45 +2387,49 @@ public class CPPSemantics {
throws DOMException {
IType[] argTypes = data.getFunctionArgumentTypes();
BitSet isLValue= data.getFunctionArgumentLValues();
int skipArg= 0;
final ICPPFunctionType ftype= (ICPPFunctionType) fn.getType();
if (ftype == null)
return null;
IType implicitType= null;
IType implicitParameterType= null;
IType impliedObjectType= null;
final IType[] paramTypes= ftype.getParameterTypes();
if (fn instanceof ICPPMethod && !(fn instanceof ICPPConstructor)) {
implicitType = getImplicitType((ICPPMethod) fn, ftype.isConst(), ftype.isVolatile());
if (data.firstArgIsImpliedMethodArg) {
argTypes = ArrayUtil.removeFirst(argTypes);
isLValue = isLValue.get(1, isLValue.size());
implicitParameterType = getImplicitParameterType((ICPPMethod) fn, ftype.isConst(), ftype.isVolatile());
if (data.argsContainImpliedObject) {
impliedObjectType= argTypes[0];
skipArg= 1;
}
}
int k= 0;
Cost cost;
final int sourceLen= argTypes.length;
final int sourceLen= argTypes.length - skipArg;
final FunctionCost result;
if (implicitType == null) {
if (implicitParameterType == null) {
result= new FunctionCost(fn, sourceLen);
} else {
result= new FunctionCost(fn, sourceLen + 1);
boolean sourceIsLValue= true;
final IType thisType = data.getImpliedObjectArgument();
if (impliedObjectType == null) {
impliedObjectType= data.getImpliedObjectType();
}
if (fn instanceof ICPPMethod &&
(((ICPPMethod) fn).isDestructor() || ASTInternal.isStatic(fn, false))) {
// 13.3.1-4 for static member functions, the implicit object parameter always matches, no cost
cost = new Cost(thisType, implicitType, Rank.IDENTITY);
} else if (thisType == null) {
cost = new Cost(impliedObjectType, implicitParameterType, Rank.IDENTITY);
} else if (impliedObjectType == null) {
return null;
} else if (thisType.isSameType(implicitType)) {
cost = new Cost(thisType, implicitType, Rank.IDENTITY);
} else if (impliedObjectType.isSameType(implicitParameterType)) {
cost = new Cost(impliedObjectType, implicitParameterType, Rank.IDENTITY);
} else {
cost = Conversions.checkImplicitConversionSequence(implicitType, thisType, sourceIsLValue, UDCMode.noUDC, true);
cost = Conversions.checkImplicitConversionSequence(implicitParameterType, impliedObjectType, sourceIsLValue, UDCMode.noUDC, true);
if (!cost.converts()) {
if (CPPTemplates.isDependentType(implicitType) || CPPTemplates.isDependentType(thisType)) {
IType s= getNestedType(thisType, TDEF|REF|CVTYPE);
IType t= getNestedType(implicitType, TDEF|REF|CVTYPE);
if (CPPTemplates.isDependentType(implicitParameterType) || CPPTemplates.isDependentType(impliedObjectType)) {
IType s= getNestedType(impliedObjectType, TDEF|REF|CVTYPE);
IType t= getNestedType(implicitParameterType, TDEF|REF|CVTYPE);
if (SemanticUtil.calculateInheritanceDepth(s, t) >= 0)
return null;
@ -2442,11 +2445,11 @@ public class CPPSemantics {
final UDCMode udc = allowUDC ? UDCMode.deferUDC : UDCMode.noUDC;
for (int j = 0; j < sourceLen; j++) {
final IType argType= SemanticUtil.getNestedType(argTypes[j], TDEF | REF);
final IType argType= SemanticUtil.getNestedType(argTypes[j+skipArg], TDEF | REF);
if (argType == null)
return null;
final boolean sourceIsLValue = isLValue.get(j);
final boolean sourceIsLValue = isLValue.get(j+skipArg);
IType paramType;
if (j < paramTypes.length) {
@ -2477,7 +2480,7 @@ public class CPPSemantics {
return result;
}
static IType getImplicitType(ICPPMethod m, final boolean isConst, final boolean isVolatile)
static IType getImplicitParameterType(ICPPMethod m, final boolean isConst, final boolean isVolatile)
throws DOMException {
IType implicitType;
ICPPClassType owner= m.getClassOwner();
@ -2716,7 +2719,7 @@ public class CPPSemantics {
if (exp instanceof IASTIdExpression) {
IASTIdExpression idExp = (IASTIdExpression) exp;
IASTName name = idExp.getName();
LookupData data = createLookupData(name, false);
LookupData data = createLookupData(name);
try {
lookup(data, null);
} catch (DOMException e) {
@ -2769,24 +2772,22 @@ public class CPPSemantics {
* class member access operators <code>operator->()</code> calls.
* @throws DOMException
*/
public static IType getChainedMemberAccessOperatorReturnType(ICPPASTFieldReference fieldReference) throws DOMException {
return getChainedMemberAccessOperatorReturnType(fieldReference, null);
public static IType getFieldOwnerType(ICPPASTFieldReference fieldReference) throws DOMException {
return getFieldOwnerType(fieldReference, null);
}
/*
* Also collections the function bindings if requested.
*/
public static IType getChainedMemberAccessOperatorReturnType(ICPPASTFieldReference fieldReference, Collection<ICPPFunction> functionBindings) throws DOMException {
public static IType getFieldOwnerType(ICPPASTFieldReference fieldReference, Collection<ICPPFunction> functionBindings) throws DOMException {
final IASTExpression owner = fieldReference.getFieldOwner();
if (owner == null)
return null;
IType type= owner.getExpressionType();
IType type= SemanticUtil.getNestedType(owner.getExpressionType(), TDEF|REF);
if (!fieldReference.isPointerDereference())
return type;
IASTExpression[] args = {owner};
// bug 205964: as long as the type is a class type, recurse.
// Be defensive and allow a max of 10 levels.
boolean foundOperator= false;
@ -2810,26 +2811,16 @@ public class CPPSemantics {
* examine for type information.
*/
CPPASTName x= new CPPASTName();
boolean isConst= false, isVolatile= false;
if (type instanceof IQualifierType) {
isConst= ((IQualifierType) type).isConst();
isVolatile= ((IQualifierType) type).isVolatile();
}
x.setBinding(createVariable(x, uTemp, isConst, isVolatile));
IASTName arw= new CPPASTName(OverloadableOperator.ARROW.toCharArray());
IASTFieldReference innerFR= new CPPASTFieldReference(arw, new CPPASTIdExpression(x));
innerFR.setParent(fieldReference); // connect to the AST
ICPPFunction op = findOverloadedOperator(innerFR, args, uTemp, OverloadableOperator.ARROW, NonMemberMode.none);
IASTExpression arg = createArgForType(fieldReference, type);
ICPPFunction op = findOverloadedOperator(fieldReference, new IASTExpression[] {arg}, uTemp, OverloadableOperator.ARROW, NonMemberMode.none);
if (op == null)
break;
if (functionBindings != null)
functionBindings.add(op);
type= SemanticUtil.mapToAST(op.getType().getReturnType(), owner);
type= SemanticUtil.getNestedType(op.getType().getReturnType(), TDEF|REF);
type= SemanticUtil.mapToAST(type, owner);
foundOperator= true;
}
@ -2889,8 +2880,8 @@ public class CPPSemantics {
public static ICPPFunction findOverloadedOperator(ICPPASTDeleteExpression exp) {
OverloadableOperator op = OverloadableOperator.fromDeleteExpression(exp);
IASTExpression[] args = { exp.getOperand() };
IType classType = getNestedClassType(exp);
IASTExpression[] args = new IASTExpression[] {createArgForType(exp, classType)};
return findOverloadedOperator(exp, args, classType, op, NonMemberMode.all);
}
@ -2986,9 +2977,9 @@ public class CPPSemantics {
LookupData data = new LookupData(astName);
if (initializer == null) {
data.setFunctionArguments(IASTExpression.EMPTY_EXPRESSION_ARRAY);
data.setFunctionArguments(false);
} else if (initializer instanceof ICPPASTConstructorInitializer) {
data.setFunctionArguments(((ICPPASTConstructorInitializer) initializer).getArguments());
data.setFunctionArguments(false, ((ICPPASTConstructorInitializer) initializer).getArguments());
} else {
return null;
}
@ -3016,10 +3007,11 @@ public class CPPSemantics {
astName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
astName.setName(CharArrayUtils.concat("~".toCharArray(), cls.getNameCharArray())); //$NON-NLS-1$
IASTExpression arg = createArgForType(expr, cls);
LookupData data = new LookupData(astName);
data.forceQualified = true;
data.setFunctionArguments(IASTExpression.EMPTY_EXPRESSION_ARRAY);
data.setFunctionArguments(true, arg);
try {
lookup(data, scope);
IBinding binding = resolveAmbiguities(data, astName);
@ -3030,6 +3022,17 @@ public class CPPSemantics {
return null;
}
/**
* mstodo remove
*/
public static IASTExpression createArgForType(IASTNode node, IType type) {
CPPASTName x= new CPPASTName();
x.setBinding(createVariable(x, type, false, false));
final CPPASTIdExpression idExpression = new CPPASTIdExpression(x);
idExpression.setParent(node);
return idExpression;
}
public static ICPPFunction findOverloadedOperator(IASTUnaryExpression exp) {
if (exp.getOperand() == null)
return null;
@ -3121,7 +3124,7 @@ public class CPPSemantics {
methodName.setParent(parent);
methodName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
methodData = new LookupData(methodName);
methodData.setFunctionArguments(ArrayUtil.removeFirst(args));
methodData.setFunctionArguments(true, args);
methodData.forceQualified = true; // (13.3.1.2.3)
try {
@ -3143,7 +3146,7 @@ public class CPPSemantics {
funcName.setParent(parent);
funcName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
LookupData funcData = new LookupData(funcName);
funcData.setFunctionArguments(args);
funcData.setFunctionArguments(true, args);
funcData.ignoreMembers = true; // (13.3.1.2.3)
if (mode != NonMemberMode.none || callToObjectOfClassType != null) {
try {
@ -3250,7 +3253,6 @@ public class CPPSemantics {
if (methodData != null && funcData.hasResults()) {
// if there was two lookups then merge the results
mergeResults(funcData, methodData.foundItems, false);
funcData.firstArgIsImpliedMethodArg = true;
binding = resolveAmbiguities(funcData, funcName);
} else if (funcData.hasResults()) {
binding = resolveAmbiguities(funcData, funcName);
@ -3312,7 +3314,7 @@ public class CPPSemantics {
public static IBinding[] findBindingsForContentAssist(IASTName name, boolean prefixLookup,
String[] additionalNamespaces) {
LookupData data = createLookupData(name, true);
LookupData data = createLookupData(name);
data.contentAssist = true;
data.prefixLookup = prefixLookup;
data.foundItems = new CharArrayObjectMap(2);

View file

@ -1538,7 +1538,8 @@ public class CPPTemplates {
return result;
}
static protected void instantiateFunctionTemplates(IFunction[] functions, IType[] fnArgs, BitSet argIsLValue, IASTName name) {
static protected void instantiateFunctionTemplates(IFunction[] functions, IType[] allFnArgs,
BitSet allArgIsLValue, IASTName name, boolean argsContainImpliedObject) {
boolean requireTemplate= false;
if (name != null) {
if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) {
@ -1549,6 +1550,8 @@ public class CPPTemplates {
}
}
IType[] reducedFnArgs= null;
BitSet reducedIsLValue= null;
ICPPTemplateArgument[] tmplArgs= null;
for (int i = 0; i < functions.length; i++) {
IFunction func = functions[i];
@ -1556,6 +1559,26 @@ public class CPPTemplates {
ICPPFunctionTemplate template= (ICPPFunctionTemplate) func;
functions[i]= null;
final IType[] fnArgs;
final BitSet argIsLValue;
if (argsContainImpliedObject && template instanceof ICPPMethod) {
if (reducedIsLValue == null) {
if (allFnArgs != null && allFnArgs.length > 0) {
reducedFnArgs= ArrayUtil.removeFirst(allFnArgs);
}
if (allArgIsLValue == null || allArgIsLValue.length() == 0) {
reducedIsLValue= ALL_RVALUES;
} else {
reducedIsLValue= allArgIsLValue.get(1, allArgIsLValue.length());
}
}
fnArgs= reducedFnArgs;
argIsLValue= reducedIsLValue;
} else {
fnArgs= allFnArgs;
argIsLValue= allArgIsLValue;
}
// extract template arguments and parameter types.
if (tmplArgs == null || fnArgs == null) {
tmplArgs = ICPPTemplateArgument.EMPTY_ARGUMENTS;

View file

@ -1090,7 +1090,7 @@ public class CPPVisitor extends ASTQueries {
data.usesEnclosingScope= false;
}
final ICPPASTFieldReference fieldReference = (ICPPASTFieldReference) parent;
IType type = CPPSemantics.getChainedMemberAccessOperatorReturnType(fieldReference);
IType type = CPPSemantics.getFieldOwnerType(fieldReference);
if (fieldReference.isPointerDereference()) {
type= getUltimateType(type, false);
} else {
@ -1973,7 +1973,7 @@ public class CPPVisitor extends ASTQueries {
return type;
}
public static IType getThisType(IScope scope) {
public static IType getImpliedObjectType(IScope scope) {
try {
IASTNode node = null;
while (scope != null) {
@ -2008,9 +2008,7 @@ public class CPPVisitor extends ASTQueries {
if (type instanceof ICPPClassTemplate) {
type= CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) type);
}
type = SemanticUtil.addQualifiers(type, dtor.isConst(), dtor.isVolatile());
type = new CPPPointerType(type);
return type;
return SemanticUtil.addQualifiers(type, dtor.isConst(), dtor.isVolatile());
}
}
}

View file

@ -245,7 +245,7 @@ public class Conversions {
IType convertedType= ft.getReturnType();
final boolean isLValue = CPPVisitor.isLValueReference(convertedType);
if (isLValue == forLValue) { // require an lvalue or rvalue
IType implicitObjectType= CPPSemantics.getImplicitType(op, ft.isConst(), ft.isVolatile());
IType implicitObjectType= CPPSemantics.getImplicitParameterType(op, ft.isConst(), ft.isVolatile());
Cost udcCost= isReferenceCompatible(getNestedType(implicitObjectType, TDEF | REF), cv2T2, true); // expression type to implicit object type
if (udcCost != null) {
FunctionCost udcFuncCost= new FunctionCost(op, udcCost);
@ -585,7 +585,7 @@ public class Conversions {
name.setParent(initializerList);
name.setPropertyInParent(CPPSemantics.STRING_LOOKUP_PROPERTY);
final IASTInitializerClause[] expandedArgs = initializerList.getClauses();
data.setFunctionArguments(expandedArgs);
data.setFunctionArguments(false, expandedArgs);
data.fNoNarrowing= true;
// 13.3.3.1.4
@ -628,7 +628,7 @@ public class Conversions {
FunctionCost cost1= null;
Cost cost2= null;
ICPPConstructor[] ctors= t.getConstructors();
CPPTemplates.instantiateFunctionTemplates(ctors, new IType[]{source}, sourceIsLValue ? LVBITSET : RVBITSET, null);
CPPTemplates.instantiateFunctionTemplates(ctors, new IType[]{source}, sourceIsLValue ? LVBITSET : RVBITSET, null, false);
for (ICPPConstructor ctor : ctors) {
if (ctor != null && !(ctor instanceof IProblemBinding) && !ctor.isExplicit()) {
@ -674,7 +674,7 @@ public class Conversions {
final int dist = SemanticUtil.calculateInheritanceDepth(uqReturnType, t);
if (dist >= 0) {
final ICPPFunctionType ft = op.getType();
IType implicitType= CPPSemantics.getImplicitType(op, ft.isConst(), ft.isVolatile());
IType implicitType= CPPSemantics.getImplicitParameterType(op, ft.isConst(), ft.isVolatile());
final Cost udcCost = isReferenceCompatible(getNestedType(implicitType, TDEF | REF), source, true);
if (udcCost != null) {
FunctionCost c1= new FunctionCost(op, udcCost);
@ -725,7 +725,7 @@ public class Conversions {
if (isExplicitConversion && c2.getRank() != Rank.IDENTITY)
continue;
ICPPFunctionType ftype = op.getType();
IType implicitType= CPPSemantics.getImplicitType(op, ftype.isConst(), ftype.isVolatile());
IType implicitType= CPPSemantics.getImplicitParameterType(op, ftype.isConst(), ftype.isVolatile());
final Cost udcCost = isReferenceCompatible(getNestedType(implicitType, TDEF | REF), source, true);
if (udcCost != null) {
FunctionCost c1= new FunctionCost(op, udcCost);

View file

@ -21,8 +21,6 @@ import java.util.Map;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
@ -46,7 +44,6 @@ 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.ICPPASTConstructorChainInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
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.ICPPASTFieldReference;
@ -57,7 +54,6 @@ 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.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
@ -98,8 +94,8 @@ public class LookupData {
public boolean checkPointOfDecl= true;
/** For field references or qualified names, enclosing template declarations are ignored. */
public boolean usesEnclosingScope= true;
/** When computing the cost of a method call, treat the first argument as the implied method argument. */
public boolean firstArgIsImpliedMethodArg = false;
/** When computing the cost of a method call, treat the first argument as the implied object. */
public boolean argsContainImpliedObject = false;
public boolean ignoreMembers = false;
/** In list-initialization **/
public boolean fNoNarrowing= false;
@ -347,57 +343,27 @@ public class LookupData {
}
/**
* an IType[] of function arguments, including the implied object argument
* Returns the implied object type, or <code>null</code>.
*/
public IType getImpliedObjectArgument() {
public IType getImpliedObjectType() {
if (astName == null)
return null;
IASTName tempName= astName;
IASTNode tempNameParent= tempName.getParent();
while (tempNameParent instanceof IASTName) {
tempName= (IASTName) tempNameParent;
tempNameParent= tempName.getParent();
IASTName name= astName;
IASTNode nameParent= name.getParent();
while (nameParent instanceof IASTName) {
name= (IASTName) nameParent;
nameParent= name.getParent();
}
try {
final ASTNodeProperty prop = tempName.getPropertyInParent();
final ASTNodeProperty prop = name.getPropertyInParent();
if (prop == CPPSemantics.STRING_LOOKUP_PROPERTY) {
if (tempNameParent instanceof ICPPASTUnaryExpression) {
ICPPASTUnaryExpression unaryExp = (ICPPASTUnaryExpression) tempNameParent;
IASTExpression oprd= unaryExp.getOperand();
return oprd.getExpressionType();
}
if (tempNameParent instanceof ICPPASTFieldReference) {
ICPPASTFieldReference fieldRef = (ICPPASTFieldReference) tempNameParent;
IType implied = fieldRef.getFieldOwner().getExpressionType();
if (fieldRef.isPointerDereference() && implied instanceof IPointerType) {
return ((IPointerType) implied).getType();
}
return implied;
}
if (tempNameParent instanceof IASTArraySubscriptExpression) {
IASTExpression exp = ((IASTArraySubscriptExpression) tempNameParent).getArrayExpression();
return exp.getExpressionType();
}
if (tempNameParent instanceof IASTFunctionCallExpression) {
return ((IASTFunctionCallExpression) tempNameParent).getFunctionNameExpression().getExpressionType();
}
if (tempNameParent instanceof IASTBinaryExpression) {
return ((IASTBinaryExpression) tempNameParent).getOperand1().getExpressionType();
}
if (tempNameParent instanceof ICPPASTDeleteExpression) {
IType implied = ((ICPPASTDeleteExpression) tempNameParent).getOperand().getExpressionType();
if(implied instanceof IPointerType) {
return ((IPointerType) implied).getType();
}
return implied;
}
return null;
}
}
if (prop == IASTFieldReference.FIELD_NAME) {
ICPPASTFieldReference fieldRef = (ICPPASTFieldReference) tempNameParent;
IType implied= CPPSemantics.getChainedMemberAccessOperatorReturnType(fieldRef);
ICPPASTFieldReference fieldRef = (ICPPASTFieldReference) nameParent;
IType implied= CPPSemantics.getFieldOwnerType(fieldRef);
if (fieldRef.isPointerDereference()) {
implied= SemanticUtil.getUltimateTypeUptoPointers(implied);
if (implied instanceof IPointerType)
@ -406,16 +372,12 @@ public class LookupData {
return implied;
}
if (prop == IASTIdExpression.ID_NAME) {
IScope scope = CPPVisitor.getContainingScope(tempName);
IScope scope = CPPVisitor.getContainingScope(name);
if (scope instanceof ICPPClassScope) {
return ((ICPPClassScope) scope).getClassType();
}
IType implied = CPPVisitor.getThisType(scope);
if (implied instanceof IPointerType) {
return ((IPointerType) implied).getType();
}
return implied;
return CPPVisitor.getImpliedObjectType(scope);
}
if (prop == IASTDeclarator.DECLARATOR_NAME) {
if (forExplicitFunctionInstantiation()) {
@ -513,7 +475,8 @@ public class LookupData {
return false;
}
public void setFunctionArguments(IASTInitializerClause... exprs) {
public void setFunctionArguments(boolean containsImpliedObject, IASTInitializerClause... exprs) {
argsContainImpliedObject= containsImpliedObject;
functionArgs= exprs;
if (exprs.length != 0) {
IASTNode node= exprs[0];

View file

@ -703,7 +703,7 @@ class OpenDeclarationsJob extends Job implements ASTRunnable {
if (binding != null) {
sourceQualifiedName= CPPVisitor.getQualifiedName(binding);
if (binding instanceof ICPPUnknownBinding) {
LookupData data= CPPSemantics.createLookupData(sourceName, false);
LookupData data= CPPSemantics.createLookupData(sourceName);
if (data.isFunctionCall()) {
funcArgCount= data.getFunctionArgumentCount();
}