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 0866ecbb462..6d9b5d86261 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 @@ -6759,4 +6759,61 @@ public class AST2CPPTests extends AST2BaseTest { parseAndCheckBindings(code, ParserLanguage.CPP); } + + // class X { + // public: + // int f; + // void m(int) {}; + // void cm(int) const {}; + // static int sf; + // static void sm(int) {}; + // }; + // int X::sf; + // + // void mpr(int X::* p){} + // void mpr(void (X::* q)(int)){} + // void mprc(void (X::* q)(int) const){} + // void mprcp(void (X::** q)(int) const){} + // void pr(int * p){} + // void pr(void (*q)(int)){} + // + // void testxxx() { + // void (X::* ptr)(int) const= &X::cm; + // mpr(&X::f); + // mpr(&X::m); + // mprc(&X::cm); + // mprcp(&ptr); + // pr(&X::sf); + // pr(&(X::sf)); + // pr(&X::sm); + // pr(&(X::sm)); + // + // // invalid constructs: + // mpr(&(X::f)); // cannot use parenthesis + // mpr(&(X::m)); // cannot use parenthesis + // mpr(&X::sf); // sf is static + // mpr(&X::sm); // sm is static + // mpr(&X::cm); // cm is const + // mprc(&X::m); // m is not const + // } + public void testMemberPtrs_264479() throws Exception { + final String code = getAboveComment(); + BindingAssertionHelper ba= new BindingAssertionHelper(code, true); + ba.assertNonProblem("mpr(&X::f)", 3); + ba.assertNonProblem("mpr(&X::m)", 3); + ba.assertNonProblem("mprc(&X::cm)", 4); + ba.assertNonProblem("mprcp(&ptr)", 5); + ba.assertNonProblem("pr(&X::sf)", 2); + ba.assertNonProblem("pr(&(X::sf))", 2); + ba.assertNonProblem("pr(&X::sm)", 2); + ba.assertNonProblem("pr(&(X::sm))", 2); + + ba.assertProblem("mpr(&(X::f))", 3); + ba.assertProblem("mpr(&(X::m))", 3); + ba.assertProblem("mpr(&X::sf)", 3); + ba.assertProblem("mpr(&X::sm)", 3); + ba.assertProblem("mpr(&X::cm)", 3); + ba.assertProblem("mprc(&X::m)", 4); + } + } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMCBugsTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMCBugsTest.java index f2e60ce8b6a..74688b175c4 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMCBugsTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMCBugsTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 Symbian Software Systems and others. + * Copyright (c) 2007, 2009 Symbian 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 @@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.IPDOMManager; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunctionType; +import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.index.IndexFilter; @@ -94,7 +95,7 @@ public class PDOMCBugsTest extends BaseTestCase { IFunctionType ft= (IFunctionType) type; assertEquals("int (int)", ASTTypeUtil.getType(ft)); } else { - assertTrue("expected ITypedef, got "+type, type == null || type instanceof ITypedef); + assertTrue("expected ITypedef, got "+type, type == null || type instanceof ITypedef || type instanceof IPointerType); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java index 1776d7fdb55..ce18011b09d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java @@ -11,6 +11,8 @@ *******************************************************************************/ package org.eclipse.cdt.core.dom.ast; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; + import java.util.LinkedList; import org.eclipse.cdt.core.dom.ast.c.ICArrayType; @@ -20,7 +22,9 @@ import org.eclipse.cdt.core.dom.ast.c.ICQualifierType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; @@ -89,7 +93,7 @@ public class ASTTypeUtil { if (parameters.length == 0) { return false; } else if (parameters.length == 1) { - IType ultimateType = SemanticUtil.getUltimateTypeViaTypedefs(parameters[0].getType()); + IType ultimateType = SemanticUtil.getNestedType(parameters[0].getType(), TDEF); if (ultimateType instanceof IBasicType) { if (((IBasicType) ultimateType).getType() == IBasicType.t_void) { @@ -387,9 +391,17 @@ public class ASTTypeUtil { if (temp != null && !temp.equals(EMPTY_STRING)) { result.append(temp); needSpace = false; } + if (type instanceof ICPPFunctionType) { + ICPPFunctionType ft= (ICPPFunctionType) type; + needSpace= appendCVQ(result, needSpace, ft.isConst(), ft.isVolatile()); + } } catch (DOMException e) { } } else if (type instanceof IPointerType) { + if (type instanceof ICPPPointerToMemberType) { + result.append(getTypeString(((ICPPPointerToMemberType) type).getMemberOfClass(), normalize)); + result.append(Keywords.cpCOLONCOLON); + } result.append(Keywords.cpSTAR); needSpace = true; if (type instanceof IGPPPointerType) { @@ -408,18 +420,8 @@ public class ASTTypeUtil { } } - if (((IPointerType) type).isConst()) { - if (needSpace) { - result.append(SPACE); needSpace = false; - } - result.append(Keywords.CONST); needSpace = true; - } - if (((IPointerType) type).isVolatile()) { - if (needSpace) { - result.append(SPACE); needSpace = false; - } - result.append(Keywords.VOLATILE); needSpace = true; - } + IPointerType pt= (IPointerType) type; + needSpace= appendCVQ(result, needSpace, pt.isConst(), pt.isVolatile()); } else if (type instanceof IQualifierType) { if (type instanceof ICQualifierType) { if (((ICQualifierType) type).isRestrict()) { @@ -431,18 +433,8 @@ public class ASTTypeUtil { } } - if (((IQualifierType) type).isConst()) { - if (needSpace) { - result.append(SPACE); needSpace = false; - } - result.append(Keywords.CONST); needSpace = true; - } - if (((IQualifierType) type).isVolatile()) { - if (needSpace) { - result.append(SPACE); needSpace = false; - } - result.append(Keywords.VOLATILE); needSpace = true; - } + IQualifierType qt= (IQualifierType) type; + needSpace= appendCVQ(result, needSpace, qt.isConst(), qt.isVolatile()); } else if (type instanceof ITypedef) { result.append(((ITypedef) type).getNameCharArray()); } @@ -450,6 +442,23 @@ public class ASTTypeUtil { return result.toString(); } + private static boolean appendCVQ(StringBuilder target, boolean needSpace, final boolean isConst, + final boolean isVolatile) { + if (isConst) { + if (needSpace) { + target.append(SPACE); needSpace = false; + } + target.append(Keywords.CONST); needSpace = true; + } + if (isVolatile) { + if (needSpace) { + target.append(SPACE); needSpace = false; + } + target.append(Keywords.VOLATILE); needSpace = true; + } + return needSpace; + } + /** * Returns the normalized string representation of the type. * @see #getType(IType, boolean) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPFunctionType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPFunctionType.java index bee57c14464..237875b3f4c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPFunctionType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPFunctionType.java @@ -8,6 +8,7 @@ * Contributors: * Andrew Niefer (IBM) - Initial API and implementation * Sergey Prigogin (Google) + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.core.dom.ast.cpp; @@ -23,7 +24,10 @@ public interface ICPPFunctionType extends IFunctionType { /** * Returns type of implicit this. parameter, or null, if the function * is not a class method or a static method. + * @deprecated function types don't relate to this pointers at all. + * @noreference This method is not intended to be referenced by clients. */ + @Deprecated public IPointerType getThisType(); /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPMember.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPMember.java index 651edf3e1de..903de6237f6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPMember.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPMember.java @@ -7,10 +7,12 @@ * * Contributors: * Doug Schaefer (IBM) - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.core.dom.ast.cpp; import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IType; /** * Represents a member of a class. Adds in the visibility attribute. @@ -20,16 +22,30 @@ import org.eclipse.cdt.core.dom.ast.DOMException; */ public interface ICPPMember extends ICPPBinding { + public static final int v_private = ICPPASTVisibilityLabel.v_private; + public static final int v_protected = ICPPASTVisibilityLabel.v_protected; + public static final int v_public = ICPPASTVisibilityLabel.v_public; + /** - * The visibility. + * Returns the accessibility of the member. */ public int getVisibility() throws DOMException; - public static final int v_private = ICPPASTVisibilityLabel.v_private; - - public static final int v_protected = ICPPASTVisibilityLabel.v_protected; - - public static final int v_public = ICPPASTVisibilityLabel.v_public; + /** + * Same as {@link #getOwner()}. + */ public ICPPClassType getClassOwner() throws DOMException; + + /** + * Returns whether this is a static member or not. + * @since 5.1 + */ + public boolean isStatic() throws DOMException; + + /** + * Returns the type of the member (function type or type of field) + * @since 5.1 + */ + public IType getType() throws DOMException; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java index c573c58e418..f31fc1efda4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java @@ -1,29 +1,37 @@ /******************************************************************************* - * 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM - Initial API and implementation + * John Camelon (IBM) - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVQ; +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.IASTExpression; +import org.eclipse.cdt.core.dom.ast.IASTIdExpression; +import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IArrayType; +import org.eclipse.cdt.core.dom.ast.IBinding; +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.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; @@ -33,7 +41,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; /** - * @author jcamelon + * Unary expression in c++ */ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpression, IASTAmbiguityParent { @@ -118,15 +126,14 @@ public class CPPASTUnaryExpression extends ASTNode implements return CPPVisitor.get_type_info(this); } - IType type= getOperand().getExpressionType(); - type = SemanticUtil.getUltimateTypeViaTypedefs(type); - + final IASTExpression operand = getOperand(); if (op == IASTUnaryExpression.op_star) { + IType type= operand.getExpressionType(); + type = SemanticUtil.getNestedType(type, TDEF | REF | CVQ); + if (type instanceof IProblemBinding) { + return type; + } try { - type = SemanticUtil.getUltimateTypeUptoPointers(type); - if (type instanceof IProblemBinding) { - return type; - } if (type instanceof ICPPClassType) { ICPPFunction operator= CPPSemantics.findOperator(this, (ICPPClassType) type); if (operator != null) { @@ -137,37 +144,47 @@ public class CPPASTUnaryExpression extends ASTNode implements } else if (type instanceof ICPPUnknownType) { return CPPUnknownClass.createUnnamedInstance(); } - return new ProblemBinding(this, IProblemBinding.SEMANTIC_INVALID_TYPE, - this.getRawSignature().toCharArray()); } catch (DOMException e) { return e.getProblem(); } - } else if (op == IASTUnaryExpression.op_amper) { - if (type instanceof ICPPReferenceType) { - try { - type = ((ICPPReferenceType) type).getType(); - } catch (DOMException e) { - } + return new ProblemBinding(this, IProblemBinding.SEMANTIC_INVALID_TYPE, this.getRawSignature().toCharArray()); + } + if (op == IASTUnaryExpression.op_amper) { + IASTNode child= operand; + boolean inParenthesis= false; + while (child instanceof IASTUnaryExpression && ((IASTUnaryExpression) child).getOperator() == IASTUnaryExpression.op_bracketedPrimary) { + child= ((IASTUnaryExpression) child).getOperand(); + inParenthesis= true; } - if (type instanceof ICPPFunctionType) { - ICPPFunctionType functionType = (ICPPFunctionType) type; - IPointerType thisType = functionType.getThisType(); - if (thisType != null) { - IType nestedType; + if (child instanceof IASTIdExpression) { + IASTName name= ((IASTIdExpression) child).getName(); + IBinding b= name.resolveBinding(); + if (b instanceof ICPPMember) { + ICPPMember member= (ICPPMember) b; try { - nestedType = thisType.getType(); - while (nestedType instanceof ITypeContainer) { - nestedType = ((ITypeContainer) nestedType).getType(); + if (name instanceof ICPPASTQualifiedName) { + if (!member.isStatic()) { + if (!inParenthesis) { + return new CPPPointerToMemberType(member.getType(), member.getClassOwner(), false, false); + } else if (member instanceof IFunction) { + return new ProblemBinding(operand, IProblemBinding.SEMANTIC_INVALID_TYPE, operand.getRawSignature().toCharArray()); + } + } } } catch (DOMException e) { return e.getProblem(); } - return new CPPPointerToMemberType(type, nestedType, thisType.isConst(), thisType - .isVolatile()); } } + + IType type= operand.getExpressionType(); + type = SemanticUtil.getNestedType(type, TDEF | REF); return new CPPPointerType(type); - } else if (type instanceof CPPBasicType) { + } + + IType type= operand.getExpressionType(); + type = SemanticUtil.getNestedType(type, TDEF | REF); + if (type instanceof CPPBasicType) { ((CPPBasicType) type).setFromExpression(this); } return type; 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 14af89dc84c..9b486c8a59a 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 @@ -33,7 +33,6 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IParameter; -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; @@ -126,8 +125,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { if (!ia.hasUserDeclaredCopyAssignmentOperator()) { //copy assignment operator: A& operator = (const A &) IType refType = new CPPReferenceType(clsType); - IPointerType thisType= new CPPPointerType(clsType); - ICPPFunctionType ft= CPPVisitor.createImplicitFunctionType(refType, ps, thisType); + ICPPFunctionType ft= CPPVisitor.createImplicitFunctionType(refType, ps, false, false); ICPPMethod m = new CPPImplicitMethod(this, OverloadableOperator.ASSIGN.toCharArray(), ft, ps); implicits[i++] = m; addBinding(m); @@ -136,8 +134,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { if (!ia.hasUserDeclaredDestructor()) { //destructor: ~A() // 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); + ICPPFunctionType ft= CPPVisitor.createImplicitFunctionType(new CPPBasicType(IBasicType.t_unspecified, 0), voidPs, true, true); char[] dtorName = CharArrayUtils.concat("~".toCharArray(), className); //$NON-NLS-1$ ICPPMethod m = new CPPImplicitMethod(this, dtorName, ft, voidPs); implicits[i++] = m; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionType.java index be757316b9f..2d4654a9f7e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionType.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 @@ -26,7 +26,8 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; public class CPPFunctionType implements ICPPFunctionType { private IType[] parameters; private IType returnType; - private IPointerType thisType; + private boolean isConst; + private boolean isVolatile; /** * @param returnType @@ -37,10 +38,11 @@ public class CPPFunctionType implements ICPPFunctionType { this.parameters = types; } - public CPPFunctionType(IType returnType, IType[] types, IPointerType thisType) { + public CPPFunctionType(IType returnType, IType[] types, boolean isConst, boolean isVolatile) { this.returnType = returnType; this.parameters = types; - this.thisType = thisType; + this.isConst = isConst; + this.isVolatile= isVolatile; } public boolean isSameType(IType o) { @@ -66,11 +68,11 @@ public class CPPFunctionType implements ICPPFunctionType { try { if (parameters.length == 1 && fps.length == 0) { - IType p0= SemanticUtil.getUltimateTypeViaTypedefs(parameters[0]); + IType p0= SemanticUtil.getNestedType(parameters[0], SemanticUtil.TDEF); if (!(p0 instanceof IBasicType) || ((IBasicType) p0).getType() != IBasicType.t_void) return false; } else if (fps.length == 1 && parameters.length == 0) { - IType p0= SemanticUtil.getUltimateTypeViaTypedefs(fps[0]); + IType p0= SemanticUtil.getNestedType(fps[0], SemanticUtil.TDEF); if (!(p0 instanceof IBasicType) || ((IBasicType) p0).getType() != IBasicType.t_void) return false; } else if (parameters.length != fps.length) { @@ -119,19 +121,17 @@ public class CPPFunctionType implements ICPPFunctionType { return t; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.ICPPFunctionType#getThisType() - */ + @Deprecated public IPointerType getThisType() { - return thisType; + return null; } public final boolean isConst() { - return thisType != null && thisType.isConst(); + return isConst; } public final boolean isVolatile() { - return thisType != null && thisType.isVolatile(); + return isVolatile; } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitConstructor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitConstructor.java index 1551c93a42f..dcaac232717 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitConstructor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitConstructor.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 @@ -30,7 +30,7 @@ public class CPPImplicitConstructor extends CPPImplicitMethod implements ICPPCon private static ICPPFunctionType createFunctionType(ICPPClassScope scope, IParameter[] params) { IType returnType= new CPPBasicType(IBasicType.t_unspecified, 0); - return CPPVisitor.createImplicitFunctionType(returnType, params, null); + return CPPVisitor.createImplicitFunctionType(returnType, params, false, false); } public boolean isExplicit() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerToMemberType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerToMemberType.java index 0b0bff4afc5..6ef4f9e2493 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerToMemberType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerToMemberType.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2008 IBM Corporation and others. + * Copyright (c) 2005, 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 @@ -19,9 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; -import org.eclipse.cdt.internal.core.index.IIndexType; /** * Models pointer to members. @@ -48,16 +46,16 @@ public class CPPPointerToMemberType extends CPPPointerType implements ICPPPointe public boolean isSameType(IType o) { if (o == this) return true; - if (o instanceof ITypedef || o instanceof IIndexType) + if (o instanceof ITypedef) return o.isSameType(this); + if (!(o instanceof ICPPPointerToMemberType)) + return false; + if (!super.isSameType(o)) return false; - if (!(o instanceof CPPPointerToMemberType)) - return false; - - CPPPointerToMemberType pt = (CPPPointerToMemberType) o; + ICPPPointerToMemberType pt = (ICPPPointerToMemberType) o; IType cls = pt.getMemberOfClass(); if (cls != null) return cls.isSameType(getMemberOfClass()); @@ -88,14 +86,4 @@ public class CPPPointerToMemberType extends CPPPointerType implements ICPPPointe } return classType; } - - @Override - public boolean isConst() { - return super.isConst() || (getType() instanceof ICPPFunctionType && ((ICPPFunctionType) getType()).isConst()); - } - - @Override - public boolean isVolatile() { - return super.isVolatile() || (getType() instanceof ICPPFunctionType && ((ICPPFunctionType) getType()).isVolatile()); - } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerType.java index 8d77a99de83..37564fc540b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerType.java @@ -1,29 +1,27 @@ /******************************************************************************* - * 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM Corporation - initial API and implementation + * Andrew Niefer (IBM Corporation) - initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ -/* - * Created on Dec 10, 2004 - */ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; +import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTPointer; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; -import org.eclipse.cdt.internal.core.index.IIndexType; /** - * @author aniefer + * Pointers in c++ */ public class CPPPointerType implements IPointerType, ITypeContainer { protected IType type = null; @@ -59,18 +57,25 @@ public class CPPPointerType implements IPointerType, ITypeContainer { public boolean isSameType(IType o) { if (o == this) return true; - if (o instanceof ITypedef || o instanceof IIndexType) + if (o instanceof ITypedef) return o.isSameType(this); - if (!(o instanceof CPPPointerType)) + if (!(o instanceof IPointerType)) + return false; + + if (this instanceof ICPPPointerToMemberType != o instanceof ICPPPointerToMemberType) return false; if (type == null) return false; - CPPPointerType pt = (CPPPointerType) o; - if (isConst == pt.isConst && isVolatile == pt.isVolatile) - return type.isSameType(pt.getType()); + IPointerType pt = (IPointerType) o; + if (isConst == pt.isConst() && isVolatile == pt.isVolatile()) { + try { + return type.isSameType(pt.getType()); + } catch (DOMException e) { + } + } return false; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index a9f105a2c34..54b2e119688 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -14,6 +14,8 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateType; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateTypeUptoPointers; @@ -442,8 +444,13 @@ public class CPPSemantics { if (parent instanceof ICPPASTFunctionDeclarator) { data.functionParameters = ((ICPPASTFunctionDeclarator)parent).getParameters(); } else if (parent instanceof IASTIdExpression) { - ASTNodeProperty prop = parent.getPropertyInParent(); - if (prop == IASTFunctionCallExpression.FUNCTION_NAME) { + IASTNode grand= parent.getParent(); + while (grand instanceof IASTUnaryExpression + && ((IASTUnaryExpression) grand).getOperator() == IASTUnaryExpression.op_bracketedPrimary) { + parent= grand; + grand = grand.getParent(); + } + if (parent.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME) { parent = parent.getParent(); IASTExpression exp = ((IASTFunctionCallExpression)parent).getParameterExpression(); if (exp instanceof IASTExpressionList) @@ -453,14 +460,22 @@ public class CPPSemantics { else data.functionParameters = IASTExpression.EMPTY_EXPRESSION_ARRAY; } - } else if (parent instanceof ICPPASTFieldReference && parent.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME) { - IASTExpression exp = ((IASTFunctionCallExpression)parent.getParent()).getParameterExpression(); - if (exp instanceof IASTExpressionList) - data.functionParameters = ((IASTExpressionList) exp).getExpressions(); - else if (exp != null) - data.functionParameters = new IASTExpression[] { exp }; - else - data.functionParameters = IASTExpression.EMPTY_EXPRESSION_ARRAY; + } else if (parent instanceof ICPPASTFieldReference) { + IASTNode grand= parent.getParent(); + while (grand instanceof IASTUnaryExpression + && ((IASTUnaryExpression) grand).getOperator() == IASTUnaryExpression.op_bracketedPrimary) { + parent= grand; + grand = grand.getParent(); + } + if (parent.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME) { + IASTExpression exp = ((IASTFunctionCallExpression)parent.getParent()).getParameterExpression(); + if (exp instanceof IASTExpressionList) + data.functionParameters = ((IASTExpressionList) exp).getExpressions(); + else if (exp != null) + data.functionParameters = new IASTExpression[] { exp }; + else + data.functionParameters = IASTExpression.EMPTY_EXPRESSION_ARRAY; + } } else if (parent instanceof ICPPASTNamedTypeSpecifier && parent.getParent() instanceof IASTTypeId) { IASTTypeId typeId = (IASTTypeId) parent.getParent(); if (typeId.getParent() instanceof ICPPASTNewExpression) { @@ -1833,7 +1848,7 @@ public class CPPSemantics { // check for parameter of type void IType[] argTypes= getSourceParameterTypes(funcArgs); if (argTypes.length == 1) { - IType t= SemanticUtil.getUltimateTypeViaTypedefs(argTypes[0]); + IType t= getNestedType(argTypes[0], TDEF); if (t instanceof IBasicType && ((IBasicType)t).getType() == IBasicType.t_void) { numArgs= 0; } @@ -1862,7 +1877,7 @@ public class CPPSemantics { int numPars = params.length; if (numArgs < 2 && numPars == 1) { // check for void - IType t = SemanticUtil.getUltimateTypeViaTypedefs(params[0].getType()); + IType t = getNestedType(params[0].getType(), TDEF); if (t instanceof IBasicType && ((IBasicType)t).getType() == IBasicType.t_void) numPars= 0; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 95de08cb786..1f82f836d7b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -754,17 +754,18 @@ public class CPPTemplates { if (tpMap == null) return type; - if (type instanceof IFunctionType) { + if (type instanceof ICPPFunctionType) { + final ICPPFunctionType ft = (ICPPFunctionType) type; IType ret = null; IType[] params = null; - final IType r = ((IFunctionType) type).getReturnType(); + final IType r = ft.getReturnType(); ret = instantiateType(r, tpMap, within); - IType[] ps = ((IFunctionType) type).getParameterTypes(); + IType[] ps = ft.getParameterTypes(); params = instantiateTypes(ps, tpMap, within); if (ret == r && params == ps) { return type; } - return new CPPFunctionType(ret, params, ((ICPPFunctionType) type).getThisType()); + return new CPPFunctionType(ret, params, ft.isConst(), ft.isVolatile()); } if (type instanceof ICPPTemplateParameter) { @@ -1800,7 +1801,7 @@ public class CPPTemplates { @Override public ICPPFunctionType getType() { if (type == null) { - type = CPPVisitor.createImplicitFunctionType(new CPPBasicType(IBasicType.t_void, 0), functionParameters, null); + type = CPPVisitor.createImplicitFunctionType(new CPPBasicType(IBasicType.t_void, 0), functionParameters, false, false); } return type; } 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 f6a658146fd..dc8be73fb1a 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 @@ -67,7 +67,6 @@ import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.ILabel; import org.eclipse.cdt.core.dom.ast.IParameter; -import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IScope; @@ -118,7 +117,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope; 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.ICPPNamespace; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; @@ -1493,7 +1491,7 @@ public class CPPVisitor extends ASTQueries { * Generate a function type for an implicit function. * NOTE: This does not correctly handle parameters with typedef types. */ - public static ICPPFunctionType createImplicitFunctionType(IType returnType, IParameter[] parameters, IPointerType thisType) { + public static ICPPFunctionType createImplicitFunctionType(IType returnType, IParameter[] parameters, boolean isConst, boolean isVolatile) { IType[] pTypes = new IType[parameters.length]; IType pt = null; @@ -1518,7 +1516,7 @@ public class CPPVisitor extends ASTQueries { pTypes[i] = pt; } - return new CPPFunctionType(returnType, pTypes, thisType); + return new CPPFunctionType(returnType, pTypes, isConst, isVolatile); } private static IType createType(IType returnType, ICPPASTFunctionDeclarator fnDtor) { @@ -1547,30 +1545,11 @@ public class CPPVisitor extends ASTQueries { returnType = getPointerTypes(returnType, fnDtor); } - IScope scope = fnDtor.getFunctionScope(); - IType thisType= getThisType(scope); - IASTDeclarator nested = fnDtor.getNestedDeclarator(); - if (thisType == null && nested != null) { - IType pts= getPointerTypes(new CPPBasicType(-1,-1), nested); - if (pts instanceof ICPPPointerToMemberType) { - thisType= new CPPPointerType(((ICPPPointerToMemberType)pts).getMemberOfClass()); - } - } - if (thisType instanceof IPointerType) { - try { - IType classType = ((IPointerType) thisType).getType(); - // 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 { - thisType = null; - } - IType type = new CPPFunctionType(returnType, pTypes, (IPointerType) thisType); + // a destructor can be called for const and volatile objects + final char[] lookupKey = name.getLookupKey(); + final boolean isDestructor= lookupKey.length > 0 && lookupKey[0]=='~'; + IType type = new CPPFunctionType(returnType, pTypes, isDestructor || fnDtor.isConst(), isDestructor || fnDtor.isVolatile()); + final IASTDeclarator nested = fnDtor.getNestedDeclarator(); if (nested != null) { return createType(type, nested); } 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 85734bb0c30..ea69bb34791 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 @@ -64,18 +64,18 @@ public class Conversions { public static Cost checkImplicitConversionSequence(IASTExpression sourceExp, IType source, IType target, boolean allowUDC, boolean isImpliedObject) throws DOMException { allowUDC &= !isImpliedObject; - target= getNestedType(target, TYPEDEFS); - source= getNestedType(source, TYPEDEFS); + target= getNestedType(target, TDEF); + source= getNestedType(source, TDEF); if (target instanceof ICPPReferenceType) { // [8.5.3-5] initialization of a reference - IType cv1T1= getNestedType(target, TYPEDEFS | REFERENCES); + IType cv1T1= getNestedType(target, TDEF | REF); boolean lvalue= sourceExp == null || !CPPVisitor.isRValue(sourceExp); if (source instanceof ICPPReferenceType) - source= getNestedType(source, TYPEDEFS | REFERENCES); + source= getNestedType(source, TDEF | REF); - IType T2= getNestedType(source, TYPEDEFS | REFERENCES | QUALIFIERS | PTR_QUALIFIERS); + IType T2= getNestedType(source, TDEF | REF | CVQ | PTR_CVQ); // [8.5.3-5] Is an lvalue (but is not a bit-field), and "cv1 T1" is reference-compatible with "cv2 T2," if (lvalue) { @@ -131,7 +131,7 @@ public class Conversions { if (conv!= null && !ambiguousConversionOperator) { IType newSource= conv.getType().getReturnType(); if (newSource instanceof ICPPReferenceType) { // require an lvalue - IType cvT2= getNestedType(newSource, TYPEDEFS | REFERENCES); + IType cvT2= getNestedType(newSource, TDEF | REF); Cost cost= isReferenceCompatible(cv1T1, cvT2); if (cost != null) { if (isImpliedObject) { @@ -161,7 +161,7 @@ public class Conversions { // If T1 is reference-related to T2, cv1 must be the same cv-qualification as, // or greater cv-qualification than, cv2; otherwise, the program is ill-formed. - IType T1= getNestedType(cv1T1, TYPEDEFS | REFERENCES | QUALIFIERS | PTR_QUALIFIERS); + IType T1= getNestedType(cv1T1, TDEF | REF | CVQ | PTR_CVQ); boolean illformed= isReferenceRelated(T1, T2) >= 0 && compareQualifications(cv1T1, source) < 0; // We must do a non-reference initialization @@ -248,19 +248,19 @@ public class Conversions { * @return inheritance distance, or -1, if cv1t1 is not reference-related to cv2t2 */ private static final int isReferenceRelated(IType cv1Target, IType cv2Source) throws DOMException { - IType t= SemanticUtil.getNestedType(cv1Target, TYPEDEFS | REFERENCES); - IType s= SemanticUtil.getNestedType(cv2Source, TYPEDEFS | REFERENCES); + IType t= SemanticUtil.getNestedType(cv1Target, TDEF | REF); + IType s= SemanticUtil.getNestedType(cv2Source, TDEF | REF); // The way cv-qualification is currently modeled means // we must cope with IPointerType objects separately. if (t instanceof IPointerType && s instanceof IPointerType) { - t= SemanticUtil.getNestedType(((IPointerType) t).getType(), TYPEDEFS | REFERENCES); - s= SemanticUtil.getNestedType(((IPointerType) s).getType(), TYPEDEFS | REFERENCES); + t= SemanticUtil.getNestedType(((IPointerType) t).getType(), TDEF | REF); + s= SemanticUtil.getNestedType(((IPointerType) s).getType(), TDEF | REF); } else { if (t instanceof IQualifierType) - t= SemanticUtil.getNestedType(((IQualifierType) t).getType(), TYPEDEFS | REFERENCES); + t= SemanticUtil.getNestedType(((IQualifierType) t).getType(), TDEF | REF); if (s instanceof IQualifierType) - s= SemanticUtil.getNestedType(((IQualifierType) s).getType(), TYPEDEFS | REFERENCES); + s= SemanticUtil.getNestedType(((IQualifierType) s).getType(), TDEF | REF); if (t instanceof ICPPClassType && s instanceof ICPPClassType) { return calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, s, t); @@ -441,7 +441,7 @@ public class Conversions { return 1; } - tbase= getNestedType(tbase, TYPEDEFS); + tbase= getNestedType(tbase, TDEF); if (tbase instanceof ICPPClassType) { int n= calculateInheritanceDepth(maxdepth - 1, tbase, ancestorToFind); if (n > 0) @@ -464,17 +464,17 @@ public class Conversions { private static final boolean lvalue_to_rvalue(final Cost cost) throws DOMException { // target should not be a reference here. boolean isConverted= false; - IType target = getNestedType(cost.target, REFERENCES | TYPEDEFS); - IType source= getNestedType(cost.source, TYPEDEFS); + IType target = getNestedType(cost.target, REF | TDEF); + IType source= getNestedType(cost.source, TDEF); // 4.1 lvalue to rvalue - IType srcRValue= getNestedType(source, REFERENCES | TYPEDEFS); + IType srcRValue= getNestedType(source, REF | TDEF); if (source instanceof ICPPReferenceType) { // 4.1 lvalue of non-function and non-array if (!(srcRValue instanceof IFunctionType) && !(srcRValue instanceof IArrayType)) { // 4.1 if T is a non-class type, the type of the rvalue is the cv-unqualified version of T - IType unqualifiedSrcRValue= getNestedType(srcRValue, QUALIFIERS | PTR_QUALIFIERS | TYPEDEFS | REFERENCES); + IType unqualifiedSrcRValue= getNestedType(srcRValue, CVQ | PTR_CVQ | TDEF | REF); if (unqualifiedSrcRValue instanceof ICPPClassType) { if (isCompleteType(unqualifiedSrcRValue)) { source= srcRValue; @@ -496,7 +496,7 @@ public class Conversions { final IArrayType arrayType= (IArrayType) srcRValue; if (target instanceof IPointerType) { - final IType targetPtrTgt= getNestedType(((IPointerType) target).getType(), TYPEDEFS); + final IType targetPtrTgt= getNestedType(((IPointerType) target).getType(), TDEF); // 4.2-2 a string literal can be converted to pointer to char if (!(targetPtrTgt instanceof IQualifierType) || !((IQualifierType) targetPtrTgt).isConst()) { @@ -519,7 +519,7 @@ public class Conversions { } } if (!isConverted && (target instanceof IPointerType || target instanceof IBasicType)) { - source = new CPPPointerType(getNestedType(arrayType.getType(), TYPEDEFS)); + source = new CPPPointerType(getNestedType(arrayType.getType(), TDEF)); cost.rank= Cost.LVALUE_OR_QUALIFICATION_RANK; isConverted= true; } @@ -527,7 +527,7 @@ public class Conversions { // 4.3 function to pointer conversion if (!isConverted && target instanceof IPointerType) { - final IType targetPtrTgt= getNestedType(((IPointerType) target).getType(), TYPEDEFS); + final IType targetPtrTgt= getNestedType(((IPointerType) target).getType(), TDEF); if (targetPtrTgt instanceof IFunctionType && srcRValue instanceof IFunctionType) { source = new CPPPointerType(source); cost.rank= Cost.LVALUE_OR_QUALIFICATION_RANK; @@ -537,9 +537,9 @@ public class Conversions { // this should actually be done in 'checkImplicitConversionSequence', see 13.3.3.1-6 and 8.5.14 // 8.5.14 cv-qualifiers can be ignored for non-class types - IType unqualifiedTarget= getNestedType(target, QUALIFIERS | PTR_QUALIFIERS | TYPEDEFS | REFERENCES); + IType unqualifiedTarget= getNestedType(target, CVQ | PTR_CVQ | TDEF | REF); if (!(unqualifiedTarget instanceof ICPPClassType)) { - IType unqualifiedSource= getNestedType(source, QUALIFIERS | PTR_QUALIFIERS | TYPEDEFS | REFERENCES); + IType unqualifiedSource= getNestedType(source, CVQ | PTR_CVQ | TDEF | REF); if (!(unqualifiedSource instanceof ICPPClassType)) { source= unqualifiedSource; target= unqualifiedTarget; @@ -569,8 +569,8 @@ public class Conversions { boolean constInEveryCV2k = true; boolean firstPointer= true; while (true) { - s= getNestedType(s, TYPEDEFS | REFERENCES); - t= getNestedType(t, TYPEDEFS | REFERENCES); + s= getNestedType(s, TDEF | REF); + t= getNestedType(t, TDEF | REF); if (s instanceof IPointerType && t instanceof IPointerType) { final int cmp= compareQualifications(t, s); // is t more qualified than s? if (cmp < 0 || (cmp > 0 && !constInEveryCV2k)) { @@ -610,8 +610,8 @@ public class Conversions { } else if (cmp != 0) { cost.qualification= Cost.CONVERSION_RANK; } - s= getNestedType(s, QUALIFIERS | TYPEDEFS | REFERENCES); - t= getNestedType(t, QUALIFIERS | TYPEDEFS | REFERENCES); + s= getNestedType(s, CVQ | TDEF | REF); + t= getNestedType(t, CVQ | TDEF | REF); } return s != null && t != null && s.isSameType(t); @@ -730,7 +730,7 @@ public class Conversions { IPointerType srcPtr= (IPointerType) s; // 4.10-2 an rvalue of type "pointer to cv T", where T is an object type can be // converted to an rvalue of type "pointer to cv void" - IType tgtPtrTgt= getNestedType(tgtPtr.getType(), TYPEDEFS | QUALIFIERS | REFERENCES); + IType tgtPtrTgt= getNestedType(tgtPtr.getType(), TDEF | CVQ | REF); if (tgtPtrTgt instanceof IBasicType && ((IBasicType) tgtPtrTgt).getType() == IBasicType.t_void) { cost.rank = Cost.CONVERSION_RANK; cost.conversion = 1; @@ -745,7 +745,7 @@ public class Conversions { if (!tIsPtrToMember && !sIsPtrToMember) { // 4.10-3 An rvalue of type "pointer to cv D", where D is a class type can be converted // to an rvalue of type "pointer to cv B", where B is a base class of D. - IType srcPtrTgt= getNestedType(srcPtr.getType(), TYPEDEFS | QUALIFIERS | REFERENCES); + IType srcPtrTgt= getNestedType(srcPtr.getType(), TDEF | CVQ | REF); if (tgtPtrTgt instanceof ICPPClassType && srcPtrTgt instanceof ICPPClassType) { int depth= calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, srcPtrTgt, tgtPtrTgt); if (depth == -1) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java index d6f39b00e1f..27fea74bf40 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java @@ -51,10 +51,13 @@ public class SemanticUtil { // Cache of overloadable operator names for fast lookup. Used by isConversionOperator. private static final CharArraySet cas= new CharArraySet(OverloadableOperator.values().length); - static final int TYPEDEFS = 0x1; - static final int REFERENCES = 0x2; - static final int QUALIFIERS = 0x4; - static final int PTR_QUALIFIERS= 0x8; + public static final int TDEF = 0x01; + public static final int REF = 0x02; + public static final int CVQ = 0x04; + public static final int PTR_CVQ= 0x08; + public static final int PTR= 0x10; + public static final int MPTR= 0x20; + public static final int ARRAY= 0x40; static { final int OPERATOR_SPC= OPERATOR_CHARS.length + 1; @@ -163,106 +166,69 @@ public class SemanticUtil { * @return the deepest type in a type container sequence */ public static IType getUltimateType(IType type, boolean stopAtPointerToMember) { - try { - while (true) { - if (type instanceof ITypedef) { - IType tt= ((ITypedef) type).getType(); - if (tt == null) - return type; - type= tt; - } else if (type instanceof IQualifierType) { - type= ((IQualifierType) type).getType(); - } else if (stopAtPointerToMember && type instanceof ICPPPointerToMemberType) { - return type; - } else if (type instanceof IPointerType) { - type= ((IPointerType) type).getType(); - } else if (type instanceof IArrayType) { - type= ((IArrayType) type).getType(); - } else if (type instanceof ICPPReferenceType) { - type= ((ICPPReferenceType) type).getType(); - } else { - return type; - } - } - } catch (DOMException e) { - return e.getProblem(); - } + if (stopAtPointerToMember) + return getNestedType(type, TDEF | CVQ | PTR | ARRAY | REF); + return getNestedType(type, TDEF | CVQ | PTR | ARRAY | MPTR | REF); } /** - * Descends into type containers, stopping at pointer or + * Descends into type containers, stopping at array, pointer or * pointer-to-member types. * @param type * @return the ultimate type contained inside the specified type */ public static IType getUltimateTypeUptoPointers(IType type) { - try { - while (true) { - if (type instanceof ITypedef) { - IType tt= ((ITypedef) type).getType(); - if (tt == null) - return type; - type= tt; - } else if (type instanceof IQualifierType) { - type = ((IQualifierType) type).getType(); - } else if (type instanceof ICPPReferenceType) { - type = ((ICPPReferenceType) type).getType(); - } else { - return type; - } - } - } catch (DOMException e) { - return e.getProblem(); - } + return getNestedType(type, TDEF | REF | CVQ); } - /** - * Descends into a typedef sequence. - */ - public static IType getUltimateTypeViaTypedefs(IType type) { - return getNestedType(type, TYPEDEFS); - } - /** * Descends into typedefs, references, etc. as specified by options. */ public static IType getNestedType(IType type, int options) { - boolean typedefs= (options & TYPEDEFS) != 0; - boolean refs= (options & REFERENCES) != 0; - boolean qualifiers= (options & QUALIFIERS) != 0; - boolean ptrQualifiers= (options & PTR_QUALIFIERS) != 0; + boolean tdef= (options & TDEF) != 0; + boolean ptrcvq= (options & PTR_CVQ) != 0; + boolean ptr= (options & PTR) != 0; + boolean mptr= (options & MPTR) != 0; + assert !(ptrcvq && (ptr || mptr)); try { while (true) { IType t= null; - if (typedefs && type instanceof ITypedef) { + if (type instanceof IPointerType) { + final boolean isMbrPtr = type instanceof ICPPPointerToMemberType; + if ((ptr && !isMbrPtr) || (mptr && isMbrPtr)) { + t= ((IPointerType) type).getType(); + } else if (ptrcvq) { + if (type instanceof CPPPointerType) { + return ((CPPPointerType) type).stripQualifiers(); + } + IPointerType p= (IPointerType) type; + if (p.isConst() || p.isVolatile()) { + if (p instanceof ICPPPointerToMemberType) { + final IType memberOfClass = ((ICPPPointerToMemberType) p).getMemberOfClass(); + if (memberOfClass instanceof ICPPClassType) + return new CPPPointerToMemberType(p.getType(), memberOfClass, false, false); + } else { + return new CPPPointerType(p.getType(), false, false); + } + } + } + } else if (tdef && type instanceof ITypedef) { t= ((ITypedef) type).getType(); - } else if (refs && type instanceof ICPPReferenceType) { - t= ((ICPPReferenceType) type).getType(); } else if (type instanceof IQualifierType) { final IQualifierType qt = (IQualifierType) type; - if (qualifiers) { + if (((options & CVQ) != 0)) { t= qt.getType(); - } else if (typedefs) { + } else if (tdef) { IType temp= qt.getType(); if (temp instanceof ITypedef) { - temp= getNestedType(temp, TYPEDEFS); + temp= getNestedType(temp, TDEF); return addQualifiers(temp, qt.isConst(), qt.isVolatile()); } } - } else if (ptrQualifiers && type instanceof IPointerType) { - if (type instanceof CPPPointerType) { - return ((CPPPointerType) type).stripQualifiers(); - } - IPointerType ptr= (IPointerType) type; - if (ptr.isConst() || ptr.isVolatile()) { - if (ptr instanceof ICPPPointerToMemberType) { - final IType memberOfClass = ((ICPPPointerToMemberType) ptr).getMemberOfClass(); - if (memberOfClass instanceof ICPPClassType) - return new CPPPointerToMemberType(ptr.getType(), memberOfClass, false, false); - } else { - return new CPPPointerType(ptr.getType(), false, false); - } - } + } else if ((options & ARRAY) != 0 && type instanceof IArrayType) { + t= ((IArrayType) type).getType(); + } else if ((options & REF) != 0 && type instanceof ICPPReferenceType) { + t= ((ICPPReferenceType) type).getType(); } if (t == null) return type; @@ -279,17 +245,18 @@ public class SemanticUtil { */ static IType getSimplifiedType(IType type) { try { - if (type instanceof IFunctionType) { + if (type instanceof ICPPFunctionType) { + final ICPPFunctionType ft = (ICPPFunctionType) type; IType ret = null; IType[] params = null; - final IType r = ((IFunctionType) type).getReturnType(); + final IType r = ft.getReturnType(); ret = getSimplifiedType(r); - IType[] ps = ((IFunctionType) type).getParameterTypes(); + IType[] ps = ft.getParameterTypes(); params = getSimplifiedTypes(ps); if (ret == r && params == ps) { return type; } - return new CPPFunctionType(ret, params, ((ICPPFunctionType) type).getThisType()); + return new CPPFunctionType(ret, params, ft.isConst(), ft.isVolatile()); } if (type instanceof ITypedef) { @@ -386,7 +353,7 @@ public class SemanticUtil { */ public static IType adjustParameterType(final IType pt, boolean forFunctionType) { // bug 239975 - IType t= SemanticUtil.getUltimateTypeViaTypedefs(pt); + IType t= SemanticUtil.getNestedType(pt, TDEF); try { if (t instanceof IArrayType) { IArrayType at = (IArrayType) t; @@ -402,7 +369,7 @@ public class SemanticUtil { //8.3.5-3 //Any cv-qualifier modifying a parameter type is deleted. if (forFunctionType && (t instanceof IQualifierType || t instanceof IPointerType)) { - return SemanticUtil.getNestedType(t, TYPEDEFS | QUALIFIERS | PTR_QUALIFIERS); + return SemanticUtil.getNestedType(t, TDEF | CVQ | PTR_CVQ); } return pt; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CPPPointerToMemberTypeClone.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CPPPointerToMemberTypeClone.java new file mode 100644 index 00000000000..ac3df8a3974 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CPPPointerToMemberTypeClone.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.index; + +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; + +public class CPPPointerToMemberTypeClone extends PointerTypeClone implements ICPPPointerToMemberType { + public CPPPointerToMemberTypeClone(ICPPPointerToMemberType pointer) { + super(pointer); + } + + public IType getMemberOfClass() { + return ((ICPPPointerToMemberType) delegate).getMemberOfClass(); + } + + @Override + public Object clone() { + return new CPPPointerToMemberTypeClone((ICPPPointerToMemberType) delegate); + } + + @Override + public boolean isSameType(IType o) { + if (o instanceof ITypedef) + return o.isSameType(this); + + if (!(o instanceof ICPPPointerToMemberType)) + return false; + + if (!super.isSameType(o)) + return false; + + ICPPPointerToMemberType pt = (ICPPPointerToMemberType) o; + IType cls = pt.getMemberOfClass(); + if (cls != null) + return cls.isSameType(getMemberOfClass()); + + return false; + } +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/PointerTypeClone.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/PointerTypeClone.java index 87761d34ef0..0d71eafa0fd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/PointerTypeClone.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/PointerTypeClone.java @@ -1,12 +1,13 @@ /******************************************************************************* - * Copyright (c) 2007 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * QNX - Initial API and implementation + * QNX - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.index; @@ -14,6 +15,7 @@ import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; /** @@ -49,6 +51,9 @@ public class PointerTypeClone implements IPointerType, ITypeContainer, IIndexTyp if (!(type instanceof IPointerType)) return false; + if (this instanceof ICPPPointerToMemberType != type instanceof ICPPPointerToMemberType) + return false; + IPointerType rhs = (IPointerType) type; try { if (isConst() == rhs.isConst() && isVolatile() == rhs.isVolatile()) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFunctionType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFunctionType.java index afa40da2ba6..67830a7f43e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFunctionType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFunctionType.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 Symbian Software Systems and others. + * Copyright (c) 2007, 2009 Symbian 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 @@ -22,8 +22,9 @@ public class CompositeCPPFunctionType extends CompositeFunctionType implements I super(rtype, cf); } + @Deprecated public IPointerType getThisType() { - return ((ICPPFunctionType) type).getThisType(); + return null; } public boolean isConst() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPPointerToMemberType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPPointerToMemberType.java index 0fc43b47822..d765fe21d45 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPPointerToMemberType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPPointerToMemberType.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 Symbian Software Systems and others. + * Copyright (c) 2007, 2009 Symbian 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 @@ -14,6 +14,7 @@ package org.eclipse.cdt.internal.core.index.composite.cpp; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; +import org.eclipse.cdt.internal.core.index.CPPPointerToMemberTypeClone; import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; import org.eclipse.cdt.internal.core.index.composite.CompositePointerType; import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; @@ -28,4 +29,9 @@ class CompositeCPPPointerToMemberType extends CompositePointerType implements IC IIndexFragmentBinding rbinding = (IIndexFragmentBinding) ((ICPPPointerToMemberType) type).getMemberOfClass(); return (IType) cf.getCompositeBinding(rbinding); } + + @Override + public Object clone() { + return new CPPPointerToMemberTypeClone(this); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMPointerType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMPointerType.java index 056c129b0a7..2c056a2410f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMPointerType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMPointerType.java @@ -6,7 +6,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * QNX - Initial API and implementation + * Doug Schaefer (QNX) - Initial API and implementation * Markus Schorn (Wind River Systems) * IBM Corporation *******************************************************************************/ @@ -19,6 +19,7 @@ import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; import org.eclipse.cdt.internal.core.index.IIndexBindingConstants; @@ -28,7 +29,7 @@ import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.core.runtime.CoreException; /** - * @author Doug Schaefer + * Pointer types for c and c++. */ public class PDOMPointerType extends PDOMNode implements IPointerType, ITypeContainer, IIndexType { @@ -118,9 +119,12 @@ public class PDOMPointerType extends PDOMNode implements IPointerType, if( type instanceof ITypedef ) return ((ITypedef)type).isSameType( this ); - if( !( type instanceof IPointerType )) - return false; - + if (!(type instanceof IPointerType)) + return false; + + if (this instanceof ICPPPointerToMemberType != type instanceof ICPPPointerToMemberType) + return false; + IPointerType rhs = (IPointerType) type; try { if (isConst() == rhs.isConst() && isVolatile() == rhs.isVolatile()) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCFunctionType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCFunctionType.java index 5a0bf4a5c35..7d20cf1975e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCFunctionType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCFunctionType.java @@ -123,11 +123,11 @@ public class PDOMCFunctionType extends PDOMNode implements IIndexType, IFunction IType[] params1= getParameterTypes(); IType[] params2= ft.getParameterTypes(); if (params1.length == 1 && params2.length == 0) { - IType p0= SemanticUtil.getUltimateTypeViaTypedefs(params1[0]); + IType p0= SemanticUtil.getNestedType(params1[0], SemanticUtil.TDEF); if (!(p0 instanceof IBasicType) || ((IBasicType) p0).getType() != IBasicType.t_void) return false; } else if (params2.length == 1 && params1.length == 0) { - IType p0= SemanticUtil.getUltimateTypeViaTypedefs(params2[0]); + IType p0= SemanticUtil.getNestedType(params2[0], SemanticUtil.TDEF); if (!(p0 instanceof IBasicType) || ((IBasicType) p0).getType() != IBasicType.t_void) return false; } else if (params1.length != params2.length) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCTypedef.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCTypedef.java index f2511457364..5f748cc780f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCTypedef.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCTypedef.java @@ -6,7 +6,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * QNX - Initial API and implementation + * Doug Schaefer (QNX) - Initial API and implementation * Markus Schorn (Wind River Systems) * IBM Corporation *******************************************************************************/ @@ -29,7 +29,7 @@ import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.core.runtime.CoreException; /** - * @author Doug Schaefer + * Typedefs for c */ class PDOMCTypedef extends PDOMBinding implements ITypedef, ITypeContainer, IIndexType { @@ -145,6 +145,11 @@ class PDOMCTypedef extends PDOMBinding implements ITypedef, ITypeContainer, IInd return false; } + @Override + protected String toStringBase() { + return getName() + ": " + super.toStringBase(); //$NON-NLS-1$ + } + public void setType(IType type) {fail();} @Override public Object clone() {fail(); return null;} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionType.java index 887520f5410..9d52cc2dcb9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionType.java @@ -11,7 +11,6 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.cpp; -import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBasicType; @@ -28,6 +27,7 @@ import org.eclipse.core.runtime.CoreException; public class PDOMCPPFunctionType extends PDOMCFunctionType implements ICPPFunctionType { private static IType FALLBACK_RETURN_TYPE= new CPPBasicType(IBasicType.t_void, 0); static ICPPFunctionType FALLBACK= new ICPPFunctionType() { + @Deprecated public IPointerType getThisType() { return null; } @@ -56,15 +56,16 @@ public class PDOMCPPFunctionType extends PDOMCFunctionType implements ICPPFuncti * Offset for this type of this function (relative to * the beginning of the record). */ - private static final int THIS_TYPE= PDOMCFunctionType.RECORD_SIZE; + private static final int CV= PDOMCFunctionType.RECORD_SIZE; /** * The size in bytes of a PDOMCFunctionType record in the database. */ @SuppressWarnings("hiding") - private static final int RECORD_SIZE= PDOMCFunctionType.RECORD_SIZE + 4; + private static final int RECORD_SIZE= PDOMCFunctionType.RECORD_SIZE + 1; IPointerType thisType; // Cached value + int cvq= -1; // Cached value protected PDOMCPPFunctionType(PDOMLinkage linkage, int offset) { super(linkage, offset); @@ -73,36 +74,37 @@ public class PDOMCPPFunctionType extends PDOMCFunctionType implements ICPPFuncti protected PDOMCPPFunctionType(PDOMLinkage linkage, PDOMNode parent, ICPPFunctionType type) throws CoreException { super(linkage, parent, type); - setThisType(type.getThisType()); + setcvq(type.isConst(), type.isVolatile()); } - private void setThisType(IPointerType type) throws CoreException { - PDOMNode typeNode = getLinkage().addType(this, type); - if (typeNode != null) { - getDB().putInt(record + THIS_TYPE, typeNode.getRecord()); - } + private void setcvq(boolean isConst, boolean isVolatile) throws CoreException { + int v= (isConst ? 1 : 0) + (isVolatile ? 2 : 0); + getDB().putByte(record + CV, (byte) v); } + @Deprecated public IPointerType getThisType() { - if (thisType == null) { - try { - PDOMNode node = getLinkage().getNode(getDB().getInt(record + THIS_TYPE)); - if (node instanceof IPointerType) { - thisType = (IPointerType) node; - } - } catch (CoreException e) { - CCorePlugin.log(e); - } - } - return thisType; + return null; } public final boolean isConst() { - return getThisType() != null && getThisType().isConst(); + readcvq(); + return (cvq & 1) != 0; + } + + private void readcvq() { + if (cvq == -1) { + try { + cvq= getDB().getByte(record + CV); + } catch (CoreException e) { + cvq= 0; + } + } } public final boolean isVolatile() { - return getThisType() != null && getThisType().isVolatile(); + readcvq(); + return (cvq & 2) != 0; } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPPointerToMemberType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPPointerToMemberType.java index a6c4f341fe6..598df8c37ab 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPPointerToMemberType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPPointerToMemberType.java @@ -10,20 +10,23 @@ * Bryan Wilkinson (QNX) * Sergey Prigogin (Google) *******************************************************************************/ - package org.eclipse.cdt.internal.core.pdom.dom.cpp; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; +import org.eclipse.cdt.internal.core.index.CPPPointerToMemberTypeClone; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; -import org.eclipse.cdt.internal.core.index.PointerTypeClone; import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMPointerType; import org.eclipse.core.runtime.CoreException; +/** + * Pointer to member type + */ class PDOMCPPPointerToMemberType extends PDOMPointerType implements ICPPPointerToMemberType { private static final int TYPE = PDOMPointerType.RECORD_SIZE; @SuppressWarnings("hiding") @@ -69,23 +72,27 @@ class PDOMCPPPointerToMemberType extends PDOMPointerType implements ICPPPointerT } @Override - public Object clone() { - return new PDOMCPPPointerToMemberTypeClone(this); + public boolean isSameType(IType o) { + if (o instanceof ITypedef) + return o.isSameType(this); + + if (!(o instanceof ICPPPointerToMemberType)) + return false; + + if (!super.isSameType(o)) + return false; + + ICPPPointerToMemberType pt = (ICPPPointerToMemberType) o; + IType cls = pt.getMemberOfClass(); + if (cls != null) + return cls.isSameType(getMemberOfClass()); + + return false; } - private static class PDOMCPPPointerToMemberTypeClone extends PointerTypeClone implements ICPPPointerToMemberType { - public PDOMCPPPointerToMemberTypeClone(ICPPPointerToMemberType pointer) { - super(pointer); - } - - public IType getMemberOfClass() { - return ((ICPPPointerToMemberType) delegate).getMemberOfClass(); - } - - @Override - public Object clone() { - return new PDOMCPPPointerToMemberTypeClone((ICPPPointerToMemberType) delegate); - } + @Override + public Object clone() { + return new CPPPointerToMemberTypeClone(this); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTypedef.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTypedef.java index dfea4efe94c..e5cb94aacdf 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTypedef.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTypedef.java @@ -6,7 +6,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * QNX - Initial API and implementation + * Doug Schaefer (QNX) - Initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.cpp; @@ -29,7 +29,7 @@ import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.core.runtime.CoreException; /** - * @author Doug Schaefer + * Typedefs for c++ */ class PDOMCPPTypedef extends PDOMCPPBinding implements ITypedef, ITypeContainer, IIndexType { @@ -152,6 +152,11 @@ class PDOMCPPTypedef extends PDOMCPPBinding implements ITypedef, ITypeContainer, } return false; } + + @Override + protected String toStringBase() { + return getName() + ": " + super.toStringBase(); //$NON-NLS-1$ + } public void setType(IType type) { fail(); }