diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index 47fa031d0a6..8fda8c26a4b 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -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 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); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java index ee4b59aa2d4..cec6727ac1e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java @@ -125,7 +125,7 @@ public class CPPASTFieldReference extends ASTNode implements ICPPASTFieldReferen // collect the function bindings List functionBindings = new ArrayList(); try { - CPPSemantics.getChainedMemberAccessOperatorReturnType(this, functionBindings); + CPPSemantics.getFieldOwnerType(this, functionBindings); } catch (DOMException e) { return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java index 27593666465..474dd539fd7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java @@ -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); } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java index 31e53e9c2f6..fa8f0214044 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java @@ -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: diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index 8005644e6e4..e4f690818e2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -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 operator->() 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 functionBindings) throws DOMException { + public static IType getFieldOwnerType(ICPPASTFieldReference fieldReference, Collection 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); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 7f15d18e676..e5e75aa8b01 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index b21c6d35227..137d0cb8bbf 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -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()); } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java index a35c4e5993a..08b31c432b7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java @@ -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); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java index 4b550831c52..ae45620150b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java @@ -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 null. */ - 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]; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java index 176a7887e71..e8839b8afab 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java @@ -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(); }