1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-25 01:45:33 +02:00

Reworked pointer-to-member types, bug 264479.

This commit is contained in:
Markus Schorn 2009-02-11 13:18:24 +00:00
parent fb9e22e7e4
commit 93867fa16e
26 changed files with 466 additions and 326 deletions

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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)

View file

@ -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 <code>this</code>. 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();
/**

View file

@ -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;
}

View file

@ -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;

View file

@ -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;

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
@ -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

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
@ -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() {

View file

@ -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());
}
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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 <code>cv1t1</code> is not reference-related to <code>cv2t2</code>
*/
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) {

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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()) {

View file

@ -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() {

View file

@ -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);
}
}

View file

@ -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()) {

View file

@ -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) {

View file

@ -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;}

View file

@ -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 <code>this</code> 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

View file

@ -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

View file

@ -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(); }