From 04303cfd0e3958cd7f085a5fd136d9d23cc34ec2 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Wed, 25 Aug 2010 14:24:17 +0000 Subject: [PATCH] Bug 323599: Type of id-expression denoting a field access. --- .../core/parser/tests/ast2/AST2CPPTests.java | 20 ++++++++++++++ .../dom/parser/cpp/CPPASTFieldReference.java | 27 +++++++++++-------- .../dom/parser/cpp/CPPASTIdExpression.java | 20 +++++++++++++- 3 files changed, 55 insertions(+), 12 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 e3e677b1312..9d61487821c 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 @@ -8876,4 +8876,24 @@ public class AST2CPPTests extends AST2BaseTest { assertEquals("MyType &", ASTTypeUtil.getType(g.getType().getParameterTypes()[0], false)); assertEquals("int &", ASTTypeUtil.getType(g.getType().getParameterTypes()[0], true)); } + + // class container { + // public: + // void constBegin() const; + // void begin(); + // }; + // struct test { + // void test_func() const { + // cnt.constBegin(); //ref + // cnt.begin(); //ref + // } + // container cnt; + // }; + public void testConstMember_323599() throws Exception { + String code= getAboveComment(); + BindingAssertionHelper bh= new BindingAssertionHelper(code, true); + IFunction f= bh.assertNonProblem("constBegin(); //ref", 10); + bh.assertProblem("begin(); //ref", 5); + } + } 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 7b97950b06a..ee4b59aa2d4 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 @@ -210,17 +210,7 @@ public class CPPASTFieldReference extends ASTNode implements ICPPASTFieldReferen e1= ((IPointerType) e1).getType(); } } - CVQualifier cvq1 = SemanticUtil.getCVQualifier(e1); - if (((ICPPField) binding).isMutable()) { - // Remove const, add union of volatile. - CVQualifier cvq2 = SemanticUtil.getCVQualifier(e2); - if (cvq2.isConst()) { - e2= SemanticUtil.getNestedType(e2, ALLCVQ | TDEF | REF); - } - e2= SemanticUtil.addQualifiers(e2, false, cvq1.isVolatile() || cvq2.isVolatile()); - } else { - e2= SemanticUtil.addQualifiers(e2, cvq1.isConst(), cvq1.isVolatile()); - } + e2 = addQualifiersForAccess((ICPPField) binding, e2, e1); } return SemanticUtil.mapToAST(e2, this); } else if (binding instanceof IEnumerator) { @@ -238,6 +228,21 @@ public class CPPASTFieldReference extends ASTNode implements ICPPASTFieldReferen return null; } + public static IType addQualifiersForAccess(ICPPField field, IType fieldType, IType ownerType) throws DOMException { + CVQualifier cvq1 = SemanticUtil.getCVQualifier(ownerType); + if (field.isMutable()) { + // Remove const, add union of volatile. + CVQualifier cvq2 = SemanticUtil.getCVQualifier(fieldType); + if (cvq2.isConst()) { + fieldType= SemanticUtil.getNestedType(fieldType, ALLCVQ | TDEF | REF); + } + fieldType= SemanticUtil.addQualifiers(fieldType, false, cvq1.isVolatile() || cvq2.isVolatile()); + } else { + fieldType= SemanticUtil.addQualifiers(fieldType, cvq1.isConst(), cvq1.isVolatile()); + } + return fieldType; + } + public boolean isLValue() { if (isPointerDereference()) 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 0b983c2a361..27593666465 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,6 +12,10 @@ *******************************************************************************/ 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; @@ -21,10 +25,12 @@ import org.eclipse.cdt.core.dom.ast.ICPPASTCompletionContext; import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IProblemBinding; +import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; @@ -92,7 +98,19 @@ public class CPPASTIdExpression extends ASTNode implements IASTIdExpression, ICP IBinding binding = name.resolvePreBinding(); try { if (binding instanceof IVariable) { - return SemanticUtil.mapToAST(((IVariable) binding).getType(), this); + final IVariable var = (IVariable) binding; + IType type= SemanticUtil.mapToAST(var.getType(), this); + 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); + } + } + } + return type; } else if (binding instanceof IEnumerator) { IType type= ((IEnumerator) binding).getType(); if (type instanceof ICPPEnumeration) {