From 515b275a48fc385aaccde4f92c0d02d920d784f9 Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Sun, 12 Jul 2015 23:21:42 -0400 Subject: [PATCH] Bug 472436 - Track whether an EvalID involves a pointer dereference Change-Id: If09ff059180bd7bdc50a73d13377838a24ed121f Signed-off-by: Nathan Ridge --- .../core/parser/tests/ast2/AST2TemplateTests.java | 21 +++++++++++- .../core/dom/parser/cpp/CPPASTFieldReference.java | 2 +- .../core/dom/parser/cpp/semantics/EvalID.java | 38 ++++++++++++++++++---- .../index/composite/cpp/CPPCompositesFactory.java | 3 +- .../org/eclipse/cdt/internal/core/pdom/PDOM.java | 7 ++-- 5 files changed, 58 insertions(+), 13 deletions(-) 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 383cc4d..42f4469 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 @@ -8008,11 +8008,30 @@ public class AST2TemplateTests extends AST2TestBase { // S s; // auto waldo = bar(&s); // } - public void testDependentFieldReference_472436() throws Exception { + public void testDependentFieldReference_472436a() throws Exception { BindingAssertionHelper helper = getAssertionHelper(); helper.assertVariableType("waldo", CommonCPPTypes.int_); } + // struct T { + // int foo; + // }; + // struct S { + // T* other; + // }; + // + // template + // auto bar(T t) -> decltype(t->other->foo); + // + // int main() { + // S s; + // auto waldo = bar(&s); + // } + public void testDependentFieldReference_472436b() throws Exception { + BindingAssertionHelper helper = getAssertionHelper(); + helper.assertVariableType("waldo", CommonCPPTypes.int_); + } + // template // struct Bind {}; // template 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 aca4eab..8701c17 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 @@ -301,7 +301,7 @@ public class CPPASTFieldReference extends ASTNode return EvalFixed.INCOMPLETE; } } - return new EvalID(ownerEval, qualifier, fName.getSimpleID(), false, true, args, this); + return new EvalID(ownerEval, qualifier, fName.getSimpleID(), false, true, fIsDeref, args, this); } @Override 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 e89cdf1..bcb2f42 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 @@ -30,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IFunction; +import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; @@ -64,15 +65,19 @@ public class EvalID extends CPPDependentEvaluation { private final IBinding fNameOwner; private final boolean fAddressOf; private final boolean fQualified; + private final boolean fIsPointerDeref; private final ICPPTemplateArgument[] fTemplateArgs; public EvalID(ICPPEvaluation fieldOwner, IBinding nameOwner, char[] simpleID, boolean addressOf, - boolean qualified, ICPPTemplateArgument[] templateArgs, IASTNode pointOfDefinition) { - this(fieldOwner, nameOwner, simpleID, addressOf, qualified, templateArgs, findEnclosingTemplate(pointOfDefinition)); + boolean qualified, boolean isPointerDeref, ICPPTemplateArgument[] templateArgs, + IASTNode pointOfDefinition) { + this(fieldOwner, nameOwner, simpleID, addressOf, qualified, isPointerDeref, templateArgs, + findEnclosingTemplate(pointOfDefinition)); } public EvalID(ICPPEvaluation fieldOwner, IBinding nameOwner, char[] simpleID, boolean addressOf, - boolean qualified, ICPPTemplateArgument[] templateArgs, IBinding templateDefinition) { + boolean qualified, boolean isPointerDeref, ICPPTemplateArgument[] templateArgs, + IBinding templateDefinition) { super(templateDefinition); if (simpleID == null) throw new NullPointerException("simpleID"); //$NON-NLS-1$ @@ -81,6 +86,7 @@ public class EvalID extends CPPDependentEvaluation { fNameOwner= nameOwner; fAddressOf= addressOf; fQualified= qualified; + fIsPointerDeref= isPointerDeref; fTemplateArgs= templateArgs; } @@ -106,6 +112,10 @@ public class EvalID extends CPPDependentEvaluation { public boolean isQualified() { return fQualified; } + + public boolean isPointerDeref() { + return fIsPointerDeref; + } /** * Returns the template arguments, or {@code null} if there are no template arguments. @@ -164,6 +174,8 @@ public class EvalID extends CPPDependentEvaluation { firstBytes |= ITypeMarshalBuffer.FLAG2; if (fTemplateArgs != null) firstBytes |= ITypeMarshalBuffer.FLAG3; + if (fIsPointerDeref) + firstBytes |= ITypeMarshalBuffer.FLAG4; buffer.putShort(firstBytes); buffer.marshalEvaluation(fFieldOwner, false); @@ -181,6 +193,7 @@ public class EvalID extends CPPDependentEvaluation { public static ISerializableEvaluation unmarshal(short firstBytes, ITypeMarshalBuffer buffer) throws CoreException { final boolean addressOf= (firstBytes & ITypeMarshalBuffer.FLAG1) != 0; final boolean qualified= (firstBytes & ITypeMarshalBuffer.FLAG2) != 0; + final boolean isPointerDeref= (firstBytes & ITypeMarshalBuffer.FLAG4) != 0; ICPPEvaluation fieldOwner= (ICPPEvaluation) buffer.unmarshalEvaluation(); char[] name= buffer.getCharArray(); IBinding nameOwner= buffer.unmarshalBinding(); @@ -193,7 +206,8 @@ public class EvalID extends CPPDependentEvaluation { } } IBinding templateDefinition= buffer.unmarshalBinding(); - return new EvalID(fieldOwner, nameOwner, name, addressOf, qualified, args, templateDefinition); + return new EvalID(fieldOwner, nameOwner, name, addressOf, qualified, isPointerDeref, args, + templateDefinition); } public static ICPPEvaluation create(IASTIdExpression expr) { @@ -238,7 +252,7 @@ public class EvalID extends CPPDependentEvaluation { } return new EvalID(fieldOwner, owner, name.getSimpleID(), isAddressOf(expr), - name instanceof ICPPASTQualifiedName, templateArgs, expr); + name instanceof ICPPASTQualifiedName, false, templateArgs, expr); } /** * 9.3.1-3 Transformation to class member access within a non-static member function. @@ -357,6 +371,14 @@ public class EvalID extends CPPDependentEvaluation { if (fieldOwner != null && !fieldOwner.isTypeDependent()) { IType fieldOwnerType = fieldOwner.getTypeOrFunctionSet(point); + if (fIsPointerDeref) { + fieldOwnerType = SemanticUtil.getSimplifiedType(fieldOwnerType); + if (fieldOwnerType instanceof IPointerType) { + fieldOwnerType = ((IPointerType) fieldOwnerType).getType(); + } else { + return EvalFixed.INCOMPLETE; + } + } IType fieldOwnerClassTypeCV = SemanticUtil.getNestedType(fieldOwnerType, TDEF | REF); IType fieldOwnerClassType = SemanticUtil.getNestedType(fieldOwnerClassTypeCV, CVTYPE); if (fieldOwnerClassType instanceof ICPPClassType) { @@ -366,7 +388,8 @@ public class EvalID extends CPPDependentEvaluation { } } - return new EvalID(fieldOwner, nameOwner, fName, fAddressOf, fQualified, templateArgs, getTemplateDefinition()); + return new EvalID(fieldOwner, nameOwner, fName, fAddressOf, fQualified, fIsPointerDeref, templateArgs, + getTemplateDefinition()); } @Override @@ -377,7 +400,8 @@ public class EvalID extends CPPDependentEvaluation { ICPPEvaluation fieldOwner = fFieldOwner.computeForFunctionCall(parameterMap, context.recordStep()); if (fieldOwner == fFieldOwner) return this; - return new EvalID(fieldOwner, fNameOwner, fName, fAddressOf, fQualified, fTemplateArgs, getTemplateDefinition()); + return new EvalID(fieldOwner, fNameOwner, fName, fAddressOf, fQualified, fIsPointerDeref, + fTemplateArgs, getTemplateDefinition()); } private ICPPEvaluation resolveName(ICPPClassType nameOwner, ICPPTemplateArgument[] templateArgs, 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 6c1ac68..d5a39a0 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 @@ -399,7 +399,8 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { ICPPTemplateArgument[] c2 = TemplateInstanceUtil.convert(this, c); if (a != a2 || b != b2 || c != c2 || templateDefinition != compositeTemplateDefinition) - e= new EvalID(a2, b2, e.getName(), e.isAddressOf(), e.isQualified(), c2, compositeTemplateDefinition); + e= new EvalID(a2, b2, e.getName(), e.isAddressOf(), e.isQualified(), e.isPointerDeref(), c2, + compositeTemplateDefinition); return e; } if (eval instanceof EvalInitList) { 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 9d4b757..4ee4af7 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 @@ -265,10 +265,11 @@ public class PDOM extends PlatformObject implements IPDOM { * * CDT 8.8 development (versions not supported on the 8.7.x branch) * 190.0 - Signature change for methods with ref-qualifiers, bug 470014. + * 191.0 - Added EvalID.fIsPointerDeref, bug 472436. */ - private static final int MIN_SUPPORTED_VERSION= version(190, 0); - private static final int MAX_SUPPORTED_VERSION= version(190, Short.MAX_VALUE); - private static final int DEFAULT_VERSION = version(190, 0); + private static final int MIN_SUPPORTED_VERSION= version(191, 0); + private static final int MAX_SUPPORTED_VERSION= version(191, Short.MAX_VALUE); + private static final int DEFAULT_VERSION = version(191, 0); private static int version(int major, int minor) { return (major << 16) + minor; -- 2.7.4