1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 09:25:31 +02:00

disambiguate methods by cvness, bug 238409.

This commit is contained in:
Markus Schorn 2009-01-23 13:08:28 +00:00
parent 23d43b4d7d
commit 5d1c767a34
7 changed files with 117 additions and 16 deletions

View file

@ -6501,4 +6501,62 @@ public class AST2CPPTests extends AST2BaseTest {
g1= bh.assertNonProblem("f(char)", 1);
assertSame(g1, g2);
}
// class A {
// public:
// void foo() const volatile;
// void foo() volatile;
// void foo() const;
// void foo();
// void bar() const volatile;
// void bar() volatile;
// void bar() const;
// void bar();
// };
// void A::foo() const volatile { bar();/*1*/ }
// void A::foo() volatile { bar();/*2*/ }
// void A::foo() const { bar();/*3*/ }
// void A::foo() { bar();/*4*/ }
// void test() {
// A a;
// const A ca;
// volatile A va;
// const volatile A cva;
// cva.bar();/*5*/
// va.bar();/*6*/
// ca.bar();/*7*/
// a.bar();/*8*/
// }
public void testMemberFunctionDisambiguationByCVness_238409() throws Exception {
final String code= getAboveComment();
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
ICPPMethod bar_cv= bh.assertNonProblem("bar();/*1*/", 3, ICPPMethod.class);
ICPPMethod bar_v= bh.assertNonProblem("bar();/*2*/", 3, ICPPMethod.class);
ICPPMethod bar_c= bh.assertNonProblem("bar();/*3*/", 3, ICPPMethod.class);
ICPPMethod bar= bh.assertNonProblem("bar();/*4*/", 3, ICPPMethod.class);
ICPPFunctionType bar_cv_ft= bar_cv.getType();
ICPPFunctionType bar_v_ft= bar_v.getType();
ICPPFunctionType bar_c_ft= bar_c.getType();
ICPPFunctionType bar_ft= bar.getType();
assertTrue(bar_cv_ft.isConst()); assertTrue(bar_cv_ft.isVolatile());
assertTrue(!bar_v_ft.isConst()); assertTrue(bar_v_ft.isVolatile());
assertTrue(bar_c_ft.isConst()); assertTrue(!bar_c_ft.isVolatile());
assertTrue(!bar_ft.isConst()); assertTrue(!bar_ft.isVolatile());
bar_cv= bh.assertNonProblem("bar();/*5*/", 3, ICPPMethod.class);
bar_v= bh.assertNonProblem("bar();/*6*/", 3, ICPPMethod.class);
bar_c= bh.assertNonProblem("bar();/*7*/", 3, ICPPMethod.class);
bar= bh.assertNonProblem("bar();/*8*/", 3, ICPPMethod.class);
bar_cv_ft= bar_cv.getType();
bar_v_ft= bar_v.getType();
bar_c_ft= bar_c.getType();
bar_ft= bar.getType();
assertTrue(bar_cv_ft.isConst()); assertTrue(bar_cv_ft.isVolatile());
assertTrue(!bar_v_ft.isConst()); assertTrue(bar_v_ft.isVolatile());
assertTrue(bar_c_ft.isConst()); assertTrue(!bar_c_ft.isVolatile());
assertTrue(!bar_ft.isConst()); assertTrue(!bar_ft.isVolatile());
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2008 Wind River Systems, Inc. and others.
* Copyright (c) 2006, 2009 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -844,7 +844,17 @@ public class IndexCPPBindingResolutionBugs extends IndexBindingResolutionTestBas
// void A::foo() volatile { bar();/*2*/ }
// void A::foo() const { bar();/*3*/ }
// void A::foo() { bar();/*4*/ }
public void _testMemberFunctionDisambiguationByCVness_238409() throws Exception {
// void test() {
// A a;
// const A ca;
// volatile A va;
// const volatile A cva;
// cva.bar();/*5*/
// va.bar();/*6*/
// ca.bar();/*7*/
// a.bar();/*8*/
// }
public void testMemberFunctionDisambiguationByCVness_238409() throws Exception {
ICPPMethod bar_cv= getBindingFromASTName("bar();/*1*/", 3, ICPPMethod.class);
ICPPMethod bar_v= getBindingFromASTName("bar();/*2*/", 3, ICPPMethod.class);
ICPPMethod bar_c= getBindingFromASTName("bar();/*3*/", 3, ICPPMethod.class);
@ -858,6 +868,20 @@ public class IndexCPPBindingResolutionBugs extends IndexBindingResolutionTestBas
assertTrue(!bar_v_ft.isConst()); assertTrue(bar_v_ft.isVolatile());
assertTrue(bar_c_ft.isConst()); assertTrue(!bar_c_ft.isVolatile());
assertTrue(!bar_ft.isConst()); assertTrue(!bar_ft.isVolatile());
bar_cv= getBindingFromASTName("bar();/*5*/", 3, ICPPMethod.class);
bar_v= getBindingFromASTName("bar();/*6*/", 3, ICPPMethod.class);
bar_c= getBindingFromASTName("bar();/*7*/", 3, ICPPMethod.class);
bar= getBindingFromASTName("bar();/*8*/", 3, ICPPMethod.class);
bar_cv_ft= bar_cv.getType();
bar_v_ft= bar_v.getType();
bar_c_ft= bar_c.getType();
bar_ft= bar.getType();
assertTrue(bar_cv_ft.isConst()); assertTrue(bar_cv_ft.isVolatile());
assertTrue(!bar_v_ft.isConst()); assertTrue(bar_v_ft.isVolatile());
assertTrue(bar_c_ft.isConst()); assertTrue(!bar_c_ft.isVolatile());
assertTrue(!bar_ft.isConst()); assertTrue(!bar_ft.isVolatile());
}
// typedef char t[12];

View file

@ -55,6 +55,7 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.ObjectSet;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
@ -133,7 +134,8 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
if (!ia.hasUserDeclaredDestructor()) {
//destructor: ~A()
IPointerType thisType= new CPPPointerType(clsType);
// a destructor can be called for const and volatile objects
IPointerType thisType= new CPPPointerType(new CPPQualifierType(clsType, true, true));
ICPPFunctionType ft= CPPVisitor.createImplicitFunctionType(new CPPBasicType(IBasicType.t_unspecified, 0), voidPs, thisType);
char[] dtorName = CharArrayUtils.concat("~".toCharArray(), className); //$NON-NLS-1$
ICPPMethod m = new CPPImplicitMethod(this, dtorName, ft, voidPs);
@ -456,7 +458,7 @@ class ImplicitsAnalysis {
}
boolean nameEquals= false;
char[] dtorname= CPPVisitor.findInnermostDeclarator(dcltor).getName().getLookupKey();
char[] dtorname= ASTQueries.findInnermostDeclarator(dcltor).getName().getLookupKey();
if (constructor) {
nameEquals= CharArrayUtils.equals(dtorname, name);
} else {
@ -489,7 +491,7 @@ class ImplicitsAnalysis {
if (dcltor instanceof ICPPASTFunctionDeclarator == false)
continue;
final char[] nchars= CPPVisitor.findInnermostDeclarator(dcltor).getName().getLookupKey();
final char[] nchars= ASTQueries.findInnermostDeclarator(dcltor).getName().getLookupKey();
if (!CharArrayUtils.equals(nchars, OverloadableOperator.ASSIGN.toCharArray()))
continue;
@ -510,7 +512,7 @@ class ImplicitsAnalysis {
*/
private static boolean paramHasTypeReferenceToTheAssociatedClassType(IASTParameterDeclaration dec, String name) {
boolean result= false;
IASTDeclarator pdtor= CPPVisitor.findTypeRelevantDeclarator(dec.getDeclarator());
IASTDeclarator pdtor= ASTQueries.findTypeRelevantDeclarator(dec.getDeclarator());
if (pdtor.getPointerOperators().length == 1 &&
pdtor.getPointerOperators()[0] instanceof ICPPASTReferenceOperator &&
pdtor.getParent() == dec &&

View file

@ -1535,7 +1535,12 @@ public class CPPVisitor extends ASTQueries {
if (thisType instanceof IPointerType) {
try {
IType classType = ((IPointerType) thisType).getType();
thisType = new CPPPointerType(classType, fnDtor.isConst(), fnDtor.isVolatile());
// a destructor can be called for const and volatile objects
final char[] lookupKey = name.getLookupKey();
final boolean isDestructor= lookupKey.length > 0 && lookupKey[0]=='~';
final boolean isConst = isDestructor || fnDtor.isConst();
final boolean isVolatile = isDestructor || fnDtor.isVolatile();
thisType = new CPPPointerType(classType, isConst, isVolatile);
} catch (DOMException e) {
}
} else {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others.
* Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -46,7 +46,6 @@ import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
import org.eclipse.core.runtime.CoreException;
@ -832,9 +831,6 @@ public class Conversions {
private static final boolean isCompleteType(IType type) {
type= getUltimateType(type, false);
if (type instanceof ICPPClassType) {
if (type instanceof ICPPInternalBinding) {
return (((ICPPInternalBinding) type).getDefinition() != null);
}
if (type instanceof IIndexFragmentBinding) {
try {
return ((IIndexFragmentBinding) type).hasDefinition();
@ -842,6 +838,11 @@ public class Conversions {
CCorePlugin.log(ce);
}
}
try {
return ((ICPPClassType) type).getCompositeScope() != null;
} catch (DOMException e) {
return false;
}
}
return true;

View file

@ -394,9 +394,10 @@ public class LookupData {
if (prop == IASTFieldReference.FIELD_NAME) {
ICPPASTFieldReference fieldRef = (ICPPASTFieldReference) tempNameParent;
IType implied= CPPSemantics.getChainedMemberAccessOperatorReturnType(fieldRef);
implied= SemanticUtil.getUltimateTypeUptoPointers(implied);
if (fieldRef.isPointerDereference() && implied instanceof IPointerType) {
return ((IPointerType)implied).getType();
if (fieldRef.isPointerDereference()) {
implied= SemanticUtil.getUltimateTypeUptoPointers(implied);
if (implied instanceof IPointerType)
return ((IPointerType)implied).getType();
}
return implied;
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2008 QNX Software Systems and others.
* Copyright (c) 2007, 2009 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -21,6 +21,9 @@ import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.core.runtime.CoreException;
@ -56,6 +59,13 @@ public class IndexCPPSignatureUtil {
IFunction function = (IFunction) binding;
buffer.append(getFunctionParameterString((function.getType())));
}
if (binding instanceof ICPPMethod && !(binding instanceof ICPPConstructor)) {
ICPPFunctionType ft = ((ICPPMethod) binding).getType();
if (ft.isConst())
buffer.append('c');
if (ft.isVolatile())
buffer.append('v');
}
return buffer.toString();
}