diff options
8 files changed, 81 insertions, 31 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 17636abb0f8..f33983ef204 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -263,8 +263,7 @@ public class AST2CPPTests extends AST2TestBase { assertEquals(defNames.length, j); } - @Override - protected void assertSameType(IType first, IType second){ + protected static void assertSameType(IType first, IType second){ assertNotNull(first); assertNotNull(second); assertTrue("Expected types to be the same, but first was: '" + first.toString() + "' and second was: '" + second + "'", first.isSameType(second)); 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 9206fb6ae1e..99e5d589507 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 @@ -5880,19 +5880,38 @@ public class AST2TemplateTests extends AST2TestBase { // int* begin(); // }; // - // template<class Container> - // auto begin(Container cont) -> decltype(cont.begin()); + // template <class Container> + // auto begin1(Container cont) -> decltype(cont.begin()); + // + // template <class Container> + // auto begin2(Container& cont) -> decltype(cont.begin()); // // vector v; - // auto x = begin(v); - public void testResolvingAutoTypeWithDependentExpression_402409() throws Exception { + // auto x1 = begin1(v); + // auto x2 = begin2(v); + public void testResolvingAutoTypeWithDependentExpression_402409a() throws Exception { BindingAssertionHelper helper = new BindingAssertionHelper(getAboveComment(), true); - ICPPVariable x = helper.assertNonProblem("x", ICPPVariable.class); - IType xType = x.getType(); - assertInstance(xType, CPPPointerType.class); - IType xTypeInner = ((CPPPointerType) xType).getType(); - assertInstance(xTypeInner, ICPPBasicType.class); - assertEquals(Kind.eInt, ((ICPPBasicType) xTypeInner).getKind()); + ICPPVariable x1 = helper.assertNonProblem("x1", ICPPVariable.class); + ICPPVariable x2 = helper.assertNonProblem("x2", ICPPVariable.class); + IType pointerToInt = new CPPPointerType(new CPPBasicType(Kind.eInt, 0)); + assertSameType(pointerToInt, x1.getType()); + assertSameType(pointerToInt, x2.getType()); + } + + // struct vector { + // int* begin(); + // const int* begin() const; + // }; + // + // template<class Container> + // auto begin(Container cont) -> decltype(cont.begin()); + // + // int main() { + // vector v; + // begin(v); + // } + public void testResolvingAutoTypeWithDependentExpression_402409b() throws Exception { + parseAndCheckBindings(); } // void foo(int, int); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java index 54928023f80..6dd95c5dce1 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java @@ -377,7 +377,7 @@ public class AST2TestBase extends BaseTestCase { assertEquals(num, count); } - protected void assertSameType(IType expected, IType actual) { + protected static void assertSameType(IType expected, IType actual) { assertNotNull(expected); assertNotNull(actual); assertTrue("Expected same types, but the types were: '" + diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java index c2620582117..9597fa30445 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java @@ -41,14 +41,20 @@ import org.eclipse.core.runtime.CoreException; public class EvalFunctionSet extends CPPDependentEvaluation { private final CPPFunctionSet fFunctionSet; private final boolean fAddressOf; + + // Where an EvalFunctionSet is created for an expression of the form 'obj.member_function', + // the type of 'obj' (needed for correct overload resolution of 'member_function' later). + // Otherwise null. + private final IType fImpliedObjectType; - public EvalFunctionSet(CPPFunctionSet set, boolean addressOf, IASTNode pointOfDefinition) { - this(set, addressOf, findEnclosingTemplate(pointOfDefinition)); + public EvalFunctionSet(CPPFunctionSet set, boolean addressOf, IType impliedObjectType, IASTNode pointOfDefinition) { + this(set, addressOf, impliedObjectType, findEnclosingTemplate(pointOfDefinition)); } - public EvalFunctionSet(CPPFunctionSet set, boolean addressOf, IBinding templateDefinition) { + public EvalFunctionSet(CPPFunctionSet set, boolean addressOf, IType impliedObjectType, IBinding templateDefinition) { super(templateDefinition); fFunctionSet= set; fAddressOf= addressOf; + fImpliedObjectType= impliedObjectType; } public CPPFunctionSet getFunctionSet() { @@ -58,6 +64,10 @@ public class EvalFunctionSet extends CPPDependentEvaluation { public boolean isAddressOf() { return fAddressOf; } + + public IType getImpliedObjectType() { + return fImpliedObjectType; + } @Override public boolean isInitializerList() { @@ -126,6 +136,7 @@ public class EvalFunctionSet extends CPPDependentEvaluation { buffer.marshalTemplateArgument(arg); } } + buffer.marshalType(fImpliedObjectType); marshalTemplateDefinition(buffer); } @@ -144,8 +155,9 @@ public class EvalFunctionSet extends CPPDependentEvaluation { args[i]= buffer.unmarshalTemplateArgument(); } } + IType impliedObjectType= buffer.unmarshalType(); IBinding templateDefinition= buffer.unmarshalBinding(); - return new EvalFunctionSet(new CPPFunctionSet(bindings, args, null), addressOf, templateDefinition); + return new EvalFunctionSet(new CPPFunctionSet(bindings, args, null), addressOf, impliedObjectType, templateDefinition); } @Override @@ -177,9 +189,11 @@ public class EvalFunctionSet extends CPPDependentEvaluation { originalFunctions[i], point); } } + // No need to instantiate the implied object type. An EvalFunctioNSet should only be created + // with an implied object type when that type is not dependent. if (Arrays.equals(arguments, originalArguments) && functions == originalFunctions) return this; - return new EvalFunctionSet(new CPPFunctionSet(functions, arguments, null), fAddressOf, getTemplateDefinition()); + return new EvalFunctionSet(new CPPFunctionSet(functions, arguments, null), fAddressOf, fImpliedObjectType, getTemplateDefinition()); } @Override @@ -201,6 +215,8 @@ public class EvalFunctionSet extends CPPDependentEvaluation { LookupData data = new LookupData(functions[0].getNameCharArray(), fFunctionSet.getTemplateArguments(), point); data.setFunctionArguments(false, args); + if (fImpliedObjectType != null) + data.setImpliedObjectType(fImpliedObjectType); try { IBinding binding = CPPSemantics.resolveFunction(data, functions, true); if (binding instanceof ICPPFunction && !(binding instanceof ICPPUnknownBinding)) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java index 84714260582..0f1fa436813 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java @@ -15,6 +15,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.PRVALUE; 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.REF; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType; import org.eclipse.cdt.core.dom.ast.DOMException; @@ -190,7 +192,7 @@ public class EvalID extends CPPDependentEvaluation { if (binding instanceof IProblemBinding || binding instanceof IType || binding instanceof ICPPConstructor) return EvalFixed.INCOMPLETE; if (binding instanceof CPPFunctionSet) { - return new EvalFunctionSet((CPPFunctionSet) binding, isAddressOf(expr), expr); + return new EvalFunctionSet((CPPFunctionSet) binding, isAddressOf(expr), null, expr); } if (binding instanceof ICPPUnknownBinding) { ICPPTemplateArgument[] templateArgs = null; @@ -207,7 +209,7 @@ public class EvalID extends CPPDependentEvaluation { CPPDeferredFunction deferredFunction = (CPPDeferredFunction) binding; if (deferredFunction.getCandidates() != null) { CPPFunctionSet functionSet = new CPPFunctionSet(deferredFunction.getCandidates(), templateArgs, null); - return new EvalFunctionSet(functionSet, isAddressOf(expr), expr); + return new EvalFunctionSet(functionSet, isAddressOf(expr), null, expr); } } @@ -320,15 +322,16 @@ public class EvalID extends CPPDependentEvaluation { return this; if (nameOwner instanceof ICPPClassType) { - ICPPEvaluation eval = resolveName((ICPPClassType) nameOwner, templateArgs, point); + ICPPEvaluation eval = resolveName((ICPPClassType) nameOwner, templateArgs, null, point); if (eval != null) return eval; } if (fieldOwner != null && !fieldOwner.isTypeDependent()) { IType fieldOwnerType = fieldOwner.getTypeOrFunctionSet(point); - if (fieldOwnerType instanceof ICPPClassType) { - ICPPEvaluation eval = resolveName((ICPPClassType) fieldOwnerType, templateArgs, point); + IType fieldOwnerClassType = SemanticUtil.getNestedType(fieldOwnerType, TDEF | REF | CVTYPE); + if (fieldOwnerClassType instanceof ICPPClassType) { + ICPPEvaluation eval = resolveName((ICPPClassType) fieldOwnerClassType, templateArgs, fieldOwnerType, point); if (eval != null) return eval; } @@ -349,7 +352,7 @@ public class EvalID extends CPPDependentEvaluation { } private ICPPEvaluation resolveName(ICPPClassType nameOwner, ICPPTemplateArgument[] templateArgs, - IASTNode point) { + IType impliedObjectType, IASTNode point) { LookupData data = new LookupData(fName, templateArgs, point); data.qualified = fQualified; try { @@ -360,7 +363,8 @@ public class EvalID extends CPPDependentEvaluation { if (bindings.length > 1 && bindings[0] instanceof ICPPFunction) { ICPPFunction[] functions = new ICPPFunction[bindings.length]; System.arraycopy(bindings, 0, functions, 0, bindings.length); - return new EvalFunctionSet(new CPPFunctionSet(functions, templateArgs, null), fAddressOf, getTemplateDefinition()); + return new EvalFunctionSet(new CPPFunctionSet(functions, templateArgs, null), fAddressOf, + impliedObjectType, getTemplateDefinition()); } IBinding binding = bindings.length == 1 ? bindings[0] : null; if (binding instanceof IEnumerator) { @@ -368,7 +372,7 @@ public class EvalID extends CPPDependentEvaluation { } else if (binding instanceof ICPPMember) { return new EvalMemberAccess(nameOwner, ValueCategory.PRVALUE, binding, false, getTemplateDefinition()); } else if (binding instanceof CPPFunctionSet) { - return new EvalFunctionSet((CPPFunctionSet) binding, fAddressOf, getTemplateDefinition()); + return new EvalFunctionSet((CPPFunctionSet) binding, fAddressOf, impliedObjectType, getTemplateDefinition()); } return null; } 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 d3f5602b7e4..da151fec236 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 @@ -358,6 +358,15 @@ public class LookupData extends ScopeLookupData { } return fImpliedObjectType; } + + /** + * Explicitly set the implied object type. + * This is for use in cases where implied object type cannot + * be determined automatically because there is no lookup name. + */ + public void setImpliedObjectType(IType impliedObjectType) { + fImpliedObjectType = impliedObjectType; + } private IType determineImpliedObjectType() { IASTName tn = getLookupName(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java index aa0d6e90467..df5d9d8c559 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java @@ -332,11 +332,13 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { final CPPFunctionSet fset = e.getFunctionSet(); ICPPFunction[] a = fset.getBindings(); ICPPTemplateArgument[] b = fset.getTemplateArguments(); + IType c = e.getImpliedObjectType(); ICPPFunction[] a2 = getCompositeFunctionArray(a); ICPPTemplateArgument[] b2 = TemplateInstanceUtil.convert(this, b); - if (a != a2 || b != b2 || templateDefinition != templateDefinition2) - e= new EvalFunctionSet(new CPPFunctionSet(a2, b2, null), e.isAddressOf(), templateDefinition2); + IType c2 = getCompositeType(c); + if (a != a2 || b != b2 || c != c2 || templateDefinition != templateDefinition2) + e= new EvalFunctionSet(new CPPFunctionSet(a2, b2, null), e.isAddressOf(), c2, templateDefinition2); return e; } if (eval instanceof EvalID) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index 9c4e5668329..25a7c72a7b2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -234,10 +234,11 @@ public class PDOM extends PlatformObject implements IPDOM { * 140.1 - Mechanism for tagging nodes with extended data, bug 400020 * 141.0 - Storing enclosing template bindings for evaluations, bug 399829. * 142.0 - Changed marshalling of evaluations to allow more than 15 evaluation kinds, bug 401479. + * 143.0 - Store implied object type in EvalFunctionSet, bug 402409. */ - private static final int MIN_SUPPORTED_VERSION= version(142, 0); - private static final int MAX_SUPPORTED_VERSION= version(142, Short.MAX_VALUE); - private static final int DEFAULT_VERSION = version(142, 0); + private static final int MIN_SUPPORTED_VERSION= version(143, 0); + private static final int MAX_SUPPORTED_VERSION= version(143, Short.MAX_VALUE); + private static final int DEFAULT_VERSION = version(143, 0); private static int version(int major, int minor) { return (major << 16) + minor; |