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

Bug 472436 - Track whether an EvalID involves a pointer dereference

Change-Id: If09ff059180bd7bdc50a73d13377838a24ed121f
Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
This commit is contained in:
Nathan Ridge 2015-07-12 23:21:42 -04:00 committed by Sergey Prigogin
parent df76958d18
commit 515b275a48
5 changed files with 58 additions and 13 deletions

View file

@ -8008,11 +8008,30 @@ public class AST2TemplateTests extends AST2TestBase {
// S s; // S s;
// auto waldo = bar(&s); // auto waldo = bar(&s);
// } // }
public void testDependentFieldReference_472436() throws Exception { public void testDependentFieldReference_472436a() throws Exception {
BindingAssertionHelper helper = getAssertionHelper(); BindingAssertionHelper helper = getAssertionHelper();
helper.assertVariableType("waldo", CommonCPPTypes.int_); helper.assertVariableType("waldo", CommonCPPTypes.int_);
} }
// struct T {
// int foo;
// };
// struct S {
// T* other;
// };
//
// template <typename T>
// 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 <typename> // template <typename>
// struct Bind {}; // struct Bind {};
// template <typename Func, typename ... BoundArgs> // template <typename Func, typename ... BoundArgs>

View file

@ -301,7 +301,7 @@ public class CPPASTFieldReference extends ASTNode
return EvalFixed.INCOMPLETE; 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 @Override

View file

@ -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.IBinding;
import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IFunction; 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.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
@ -64,15 +65,19 @@ public class EvalID extends CPPDependentEvaluation {
private final IBinding fNameOwner; private final IBinding fNameOwner;
private final boolean fAddressOf; private final boolean fAddressOf;
private final boolean fQualified; private final boolean fQualified;
private final boolean fIsPointerDeref;
private final ICPPTemplateArgument[] fTemplateArgs; private final ICPPTemplateArgument[] fTemplateArgs;
public EvalID(ICPPEvaluation fieldOwner, IBinding nameOwner, char[] simpleID, boolean addressOf, public EvalID(ICPPEvaluation fieldOwner, IBinding nameOwner, char[] simpleID, boolean addressOf,
boolean qualified, ICPPTemplateArgument[] templateArgs, IASTNode pointOfDefinition) { boolean qualified, boolean isPointerDeref, ICPPTemplateArgument[] templateArgs,
this(fieldOwner, nameOwner, simpleID, addressOf, qualified, templateArgs, findEnclosingTemplate(pointOfDefinition)); IASTNode pointOfDefinition) {
this(fieldOwner, nameOwner, simpleID, addressOf, qualified, isPointerDeref, templateArgs,
findEnclosingTemplate(pointOfDefinition));
} }
public EvalID(ICPPEvaluation fieldOwner, IBinding nameOwner, char[] simpleID, boolean addressOf, 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); super(templateDefinition);
if (simpleID == null) if (simpleID == null)
throw new NullPointerException("simpleID"); //$NON-NLS-1$ throw new NullPointerException("simpleID"); //$NON-NLS-1$
@ -81,6 +86,7 @@ public class EvalID extends CPPDependentEvaluation {
fNameOwner= nameOwner; fNameOwner= nameOwner;
fAddressOf= addressOf; fAddressOf= addressOf;
fQualified= qualified; fQualified= qualified;
fIsPointerDeref= isPointerDeref;
fTemplateArgs= templateArgs; fTemplateArgs= templateArgs;
} }
@ -106,6 +112,10 @@ public class EvalID extends CPPDependentEvaluation {
public boolean isQualified() { public boolean isQualified() {
return fQualified; return fQualified;
} }
public boolean isPointerDeref() {
return fIsPointerDeref;
}
/** /**
* Returns the template arguments, or {@code null} if there are no template arguments. * 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; firstBytes |= ITypeMarshalBuffer.FLAG2;
if (fTemplateArgs != null) if (fTemplateArgs != null)
firstBytes |= ITypeMarshalBuffer.FLAG3; firstBytes |= ITypeMarshalBuffer.FLAG3;
if (fIsPointerDeref)
firstBytes |= ITypeMarshalBuffer.FLAG4;
buffer.putShort(firstBytes); buffer.putShort(firstBytes);
buffer.marshalEvaluation(fFieldOwner, false); buffer.marshalEvaluation(fFieldOwner, false);
@ -181,6 +193,7 @@ public class EvalID extends CPPDependentEvaluation {
public static ISerializableEvaluation unmarshal(short firstBytes, ITypeMarshalBuffer buffer) throws CoreException { public static ISerializableEvaluation unmarshal(short firstBytes, ITypeMarshalBuffer buffer) throws CoreException {
final boolean addressOf= (firstBytes & ITypeMarshalBuffer.FLAG1) != 0; final boolean addressOf= (firstBytes & ITypeMarshalBuffer.FLAG1) != 0;
final boolean qualified= (firstBytes & ITypeMarshalBuffer.FLAG2) != 0; final boolean qualified= (firstBytes & ITypeMarshalBuffer.FLAG2) != 0;
final boolean isPointerDeref= (firstBytes & ITypeMarshalBuffer.FLAG4) != 0;
ICPPEvaluation fieldOwner= (ICPPEvaluation) buffer.unmarshalEvaluation(); ICPPEvaluation fieldOwner= (ICPPEvaluation) buffer.unmarshalEvaluation();
char[] name= buffer.getCharArray(); char[] name= buffer.getCharArray();
IBinding nameOwner= buffer.unmarshalBinding(); IBinding nameOwner= buffer.unmarshalBinding();
@ -193,7 +206,8 @@ public class EvalID extends CPPDependentEvaluation {
} }
} }
IBinding templateDefinition= buffer.unmarshalBinding(); 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) { public static ICPPEvaluation create(IASTIdExpression expr) {
@ -238,7 +252,7 @@ public class EvalID extends CPPDependentEvaluation {
} }
return new EvalID(fieldOwner, owner, name.getSimpleID(), isAddressOf(expr), 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. * 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()) { if (fieldOwner != null && !fieldOwner.isTypeDependent()) {
IType fieldOwnerType = fieldOwner.getTypeOrFunctionSet(point); 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 fieldOwnerClassTypeCV = SemanticUtil.getNestedType(fieldOwnerType, TDEF | REF);
IType fieldOwnerClassType = SemanticUtil.getNestedType(fieldOwnerClassTypeCV, CVTYPE); IType fieldOwnerClassType = SemanticUtil.getNestedType(fieldOwnerClassTypeCV, CVTYPE);
if (fieldOwnerClassType instanceof ICPPClassType) { 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 @Override
@ -377,7 +400,8 @@ public class EvalID extends CPPDependentEvaluation {
ICPPEvaluation fieldOwner = fFieldOwner.computeForFunctionCall(parameterMap, context.recordStep()); ICPPEvaluation fieldOwner = fFieldOwner.computeForFunctionCall(parameterMap, context.recordStep());
if (fieldOwner == fFieldOwner) if (fieldOwner == fFieldOwner)
return this; 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, private ICPPEvaluation resolveName(ICPPClassType nameOwner, ICPPTemplateArgument[] templateArgs,

View file

@ -399,7 +399,8 @@ public class CPPCompositesFactory extends AbstractCompositeFactory {
ICPPTemplateArgument[] c2 = TemplateInstanceUtil.convert(this, c); ICPPTemplateArgument[] c2 = TemplateInstanceUtil.convert(this, c);
if (a != a2 || b != b2 || c != c2 || templateDefinition != compositeTemplateDefinition) 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; return e;
} }
if (eval instanceof EvalInitList) { if (eval instanceof EvalInitList) {

View file

@ -265,10 +265,11 @@ public class PDOM extends PlatformObject implements IPDOM {
* *
* CDT 8.8 development (versions not supported on the 8.7.x branch) * CDT 8.8 development (versions not supported on the 8.7.x branch)
* 190.0 - Signature change for methods with ref-qualifiers, bug 470014. * 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 MIN_SUPPORTED_VERSION= version(191, 0);
private static final int MAX_SUPPORTED_VERSION= version(190, Short.MAX_VALUE); private static final int MAX_SUPPORTED_VERSION= version(191, Short.MAX_VALUE);
private static final int DEFAULT_VERSION = version(190, 0); private static final int DEFAULT_VERSION = version(191, 0);
private static int version(int major, int minor) { private static int version(int major, int minor) {
return (major << 16) + minor; return (major << 16) + minor;