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 5a9382e02e0..0160043c732 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 @@ -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()); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionBugs.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionBugs.java index 6f4f78fa8a0..38eb0c788e7 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionBugs.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionBugs.java @@ -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]; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java index 3110a45bb56..f6e9a016d34 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java @@ -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 && diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index 891d3311728..147293f5d19 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -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 { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java index 2d911eebda6..0cbb3183570 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java @@ -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; 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 05f11fd8b9a..6e37637815d 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 @@ -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; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexCPPSignatureUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexCPPSignatureUtil.java index a85415731ed..4f02f48e614 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexCPPSignatureUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexCPPSignatureUtil.java @@ -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(); }