summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Ridge2013-03-08 03:21:43 (EST)
committerSergey Prigogin2013-03-08 19:38:25 (EST)
commit7f2273c8b804669bec8b783f60db8a15300583ee (patch)
treec32a0cc8f4218bcb2e0506a1572de67224d8944a
parentbafe78b85989f8c3d504bd9d6f5fb6388b117949 (diff)
downloadorg.eclipse.cdt-7f2273c8b804669bec8b783f60db8a15300583ee.zip
org.eclipse.cdt-7f2273c8b804669bec8b783f60db8a15300583ee.tar.gz
org.eclipse.cdt-7f2273c8b804669bec8b783f60db8a15300583ee.tar.bz2
Bug 402409 - Dependent expressions and auto type resolutionrefs/changes/57/10957/4
Change-Id: Ib4ed63ade9349c5be74305825884acac103e334b Reviewed-on: https://git.eclipse.org/r/10957 Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com> IP-Clean: Sergey Prigogin <eclipse.sprigogin@gmail.com> Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java3
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java39
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java2
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java26
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java20
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java9
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java6
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java7
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 17636ab..f33983e 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 9206fb6..99e5d58 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 5492802..6dd95c5 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 c262058..9597fa3 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 8471426..0f1fa43 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 d3f5602..da151fe 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 aa0d6e9..df5d9d8 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 9c4e566..25a7c72 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;