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

-Pointer to Members

-refactor getContainingScope and getContainingBlockItem to use less recursion
This commit is contained in:
Andrew Niefer 2005-02-14 19:36:32 +00:00
parent 0db65d300f
commit b9742041fa
7 changed files with 271 additions and 106 deletions

View file

@ -51,6 +51,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; 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.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.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserLanguage;
@ -1439,5 +1440,76 @@ public class AST2CPPTests extends AST2BaseTest {
assertEquals( 9, col.size() ); assertEquals( 9, col.size() );
} }
public void testPointerToMemberType() throws Exception {
IASTTranslationUnit tu = parse( "struct S; int S::* pm;", ParserLanguage.CPP );
CPPNameCollector col = new CPPNameCollector();
CPPVisitor.visitTranslationUnit(tu, col);
assertEquals( 4, col.size() );
IVariable pm = (IVariable) col.getName(3).resolveBinding();
ICPPClassType S = (ICPPClassType) col.getName(0).resolveBinding();
IType t = pm.getType();
assertNotNull( t );
assertTrue( t instanceof ICPPPointerToMemberType );
ICPPClassType cls = ((ICPPPointerToMemberType)t).getMemberOfClass();
assertSame( S, cls );
assertTrue( ((ICPPPointerToMemberType)t).getType() instanceof IBasicType );
}
public void testBug_PM_() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("struct S { int i ; } *s; \n"); //$NON-NLS-1$
buffer.append("int S::* pm = &S::i; \n"); //$NON-NLS-1$
buffer.append("void f() { \n"); //$NON-NLS-1$
buffer.append(" s->*pm = 1; \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
CPPNameCollector col = new CPPNameCollector();
CPPVisitor.visitTranslationUnit(tu, col);
IBinding ref = col.getName(11).resolveBinding();
IVariable pm = (IVariable) col.getName(5).resolveBinding();
assertSame( pm, ref );
}
public void testBug_PM_2() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("struct S { \n"); //$NON-NLS-1$
buffer.append(" int i; \n"); //$NON-NLS-1$
buffer.append(" S* f(); \n"); //$NON-NLS-1$
buffer.append("} *s; \n"); //$NON-NLS-1$
buffer.append("S* (S::* pm) () = &S::f; \n"); //$NON-NLS-1$
buffer.append("void foo() { \n"); //$NON-NLS-1$
buffer.append(" (s->*pm)()->i; \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
CPPNameCollector col = new CPPNameCollector();
CPPVisitor.visitTranslationUnit(tu, col);
ICPPClassType S = (ICPPClassType) col.getName(0).resolveBinding();
IVariable pm = (IVariable) col.getName(8).resolveBinding();
IField i = (IField) col.getName(1).resolveBinding();
ICPPMethod f = (ICPPMethod) col.getName(3).resolveBinding();
IType t = pm.getType();
assertTrue( t instanceof ICPPPointerToMemberType );
IFunctionType ft = (IFunctionType) ((ICPPPointerToMemberType)t).getType();
ICPPClassType ST = (ICPPClassType) ((ICPPPointerToMemberType)t).getMemberOfClass();
assertTrue( ft.getReturnType() instanceof IPointerType );
assertSame( ST, ((IPointerType)ft.getReturnType()).getType() );
assertSame( S, ST );
assertInstances(col, S, 5);
assertInstances(col, pm, 2);
assertInstances(col, i, 2);
assertInstances(col, f, 3);
}
} }

View file

@ -14,12 +14,11 @@
*/ */
package org.eclipse.cdt.core.dom.ast.cpp; package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IPointerType;
/** /**
* @author aniefer * @author aniefer
*/ */
public interface ICPPPointerToMemberType extends IPointerType { public interface ICPPPointerToMemberType extends IPointerType {
public IBinding getMemberOfClass(); public ICPPClassType getMemberOfClass();
} }

View file

@ -10,14 +10,14 @@
**********************************************************************/ **********************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
/** /**
* @author jcamelon * @author jcamelon
*/ */
public class CPPASTBinaryExpression extends CPPASTNode implements public class CPPASTBinaryExpression extends CPPASTNode implements
IASTBinaryExpression { ICPPASTBinaryExpression {
private int op; private int op;
private IASTExpression operand1; private IASTExpression operand1;

View file

@ -15,6 +15,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.List; import java.util.List;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
@ -40,11 +41,55 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
/** /**
* @author aniefer * @author aniefer
*/ */
public class CPPClassType implements ICPPClassType, ICPPBinding { public class CPPClassType implements ICPPClassType, ICPPBinding {
public static class CPPClassTypeProblem extends ProblemBinding implements ICPPClassType{
public CPPClassTypeProblem( int id, char[] arg ) {
super( id, arg );
}
public ICPPBase[] getBases() throws DOMException {
throw new DOMException( this );
}
public IField[] getFields() throws DOMException {
throw new DOMException( this );
}
public List getDeclaredFields() throws DOMException {
throw new DOMException( this );
}
public List getMethods() throws DOMException {
throw new DOMException( this );
}
public List getAllDeclaredMethods() throws DOMException {
throw new DOMException( this );
}
public List getDeclaredMethods() throws DOMException {
throw new DOMException( this );
}
public ICPPConstructor[] getConstructors() throws DOMException {
throw new DOMException( this );
}
public int getKey() throws DOMException {
throw new DOMException( this );
}
public IField findField(String name) throws DOMException {
throw new DOMException( this );
}
public IScope getCompositeScope() throws DOMException {
throw new DOMException( this );
}
public IScope getParent() throws DOMException {
throw new DOMException( this );
}
public List find(String name) throws DOMException {
throw new DOMException( this );
}
}
private ICPPASTCompositeTypeSpecifier definition; private ICPPASTCompositeTypeSpecifier definition;
private ICPPASTElaboratedTypeSpecifier [] declarations; private ICPPASTElaboratedTypeSpecifier [] declarations;

View file

@ -0,0 +1,61 @@
/*
* Created on Feb 11, 2005
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType;
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.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
/**
* @author aniefer
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class CPPPointerToMemberType extends CPPPointerType implements
ICPPPointerToMemberType {
private ICPPClassType clsType = null;
/**
* @param type
* @param operator
*/
public CPPPointerToMemberType(IType type, ICPPASTPointerToMember operator) {
super(type, operator);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType#getMemberOfClass()
*/
public ICPPClassType getMemberOfClass() {
if( clsType == null ){
ICPPASTPointerToMember pm = (ICPPASTPointerToMember) operator;
IASTName name = pm.getName();
if( name instanceof ICPPASTQualifiedName ){
IASTName [] ns = ((ICPPASTQualifiedName)name).getNames();
if( ns.length > 1 )
name = ns[ ns.length - 2 ];
else
name = ns[ ns.length - 1 ];
}
IBinding binding = name.resolveBinding();
if( binding instanceof ICPPClassType ){
clsType = (ICPPClassType) binding;
} else {
clsType = new CPPClassType.CPPClassTypeProblem( IProblemBinding.SEMANTIC_INVALID_TYPE, name.toCharArray() );
}
}
return clsType;
}
}

View file

@ -23,8 +23,8 @@ import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
* @author aniefer * @author aniefer
*/ */
public class CPPPointerType implements IPointerType, ITypeContainer { public class CPPPointerType implements IPointerType, ITypeContainer {
private IASTPointer operator = null; protected IASTPointer operator = null;
private IType type = null; protected IType type = null;
/** /**
* @param type * @param type
* @param operator * @param operator

View file

@ -470,41 +470,50 @@ public class CPPVisitor {
public static IScope getContainingScope( IASTNode node ){ public static IScope getContainingScope( IASTNode node ){
if( node == null ) if( node == null )
return null; return null;
if( node instanceof IASTName ) while( node != null ){
if( node instanceof IASTName ){
return getContainingScope( (IASTName) node ); return getContainingScope( (IASTName) node );
else if( node instanceof IASTDeclaration ) } else if( node instanceof IASTDeclaration ){
return getContainingScope( (IASTDeclaration) node ); IASTNode parent = node.getParent();
else if( node instanceof IASTStatement ) if( parent instanceof IASTTranslationUnit ){
return ((IASTTranslationUnit)parent).getScope();
} else if( parent instanceof IASTDeclarationStatement ){
return getContainingScope( (IASTStatement) parent );
} else if( parent instanceof IASTForStatement ){
return ((IASTForStatement)parent).getScope();
} else if( parent instanceof IASTCompositeTypeSpecifier ){
return ((IASTCompositeTypeSpecifier)parent).getScope();
} else if( parent instanceof ICPPASTNamespaceDefinition ) {
return ((ICPPASTNamespaceDefinition)parent).getScope();
}
} else if( node instanceof IASTStatement ){
return getContainingScope( (IASTStatement) node ); return getContainingScope( (IASTStatement) node );
else if( node instanceof IASTDeclSpecifier ) } else if( node instanceof IASTTypeId ){
return getContainingScope( (IASTDeclSpecifier) node ); node = node.getParent();
else if( node instanceof IASTParameterDeclaration ) } else if( node instanceof IASTParameterDeclaration ){
return getContainingScope( (IASTParameterDeclaration) node ); ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) node.getParent();
else if( node instanceof IASTExpression ) ASTNodeProperty prop = dtor.getPropertyInParent();
return getContainingScope( (IASTExpression) node ); if( prop == IASTSimpleDeclaration.DECLARATOR || prop == IASTFunctionDefinition.DECLARATOR )
else if( node instanceof IASTEnumerator ){ return dtor.getFunctionScope();
//put the enumerators in the same scope as the enumeration } else if( node instanceof IASTExpression ){
return getContainingScope( (IASTEnumerationSpecifier) node.getParent() ); IASTNode parent = node.getParent();
}
return getContainingScope( node.getParent() );
}
public static IScope getContainingScope( IASTExpression expression ){
IASTNode parent = expression.getParent();
if( parent instanceof IASTForStatement ){ if( parent instanceof IASTForStatement ){
return ((IASTForStatement)parent).getScope(); return ((IASTForStatement)parent).getScope();
} else if( parent instanceof IASTCompoundStatement ){ } else if( parent instanceof IASTCompoundStatement ){
return ((IASTCompoundStatement)parent).getScope(); return ((IASTCompoundStatement)parent).getScope();
} else if( parent instanceof ICPPASTConstructorChainInitializer ){ } else if( parent instanceof ICPPASTConstructorChainInitializer ){
IASTNode node = getContainingBlockItem( parent.getParent() ); IASTNode temp = getContainingBlockItem( parent.getParent() );
if( node instanceof IASTFunctionDefinition ){ if( temp instanceof IASTFunctionDefinition ){
IASTCompoundStatement body = (IASTCompoundStatement) ((IASTFunctionDefinition)node).getBody(); IASTCompoundStatement body = (IASTCompoundStatement) ((IASTFunctionDefinition)temp).getBody();
return body.getScope(); return body.getScope();
} }
} }
return getContainingScope( parent );
} }
node = node.getParent();
}
return null;
}
public static IScope getContainingScope( IASTName name ){ public static IScope getContainingScope( IASTName name ){
IASTNode parent = name.getParent(); IASTNode parent = name.getParent();
try { try {
@ -538,26 +547,6 @@ public class CPPVisitor {
} }
return getContainingScope( parent ); return getContainingScope( parent );
} }
/**
* @param declaration
* @return
*/
public static IScope getContainingScope(IASTDeclaration declaration) {
IASTNode parent = declaration.getParent();
if( parent instanceof IASTTranslationUnit ){
return ((IASTTranslationUnit)parent).getScope();
} else if( parent instanceof IASTDeclarationStatement ){
return getContainingScope( (IASTStatement) parent );
} else if( parent instanceof IASTForStatement ){
return ((IASTForStatement)parent).getScope();
} else if( parent instanceof IASTCompositeTypeSpecifier ){
return ((IASTCompositeTypeSpecifier)parent).getScope();
} else if( parent instanceof ICPPASTNamespaceDefinition ) {
return ((ICPPASTNamespaceDefinition)parent).getScope();
}
return null;
}
public static IScope getContainingScope( IASTStatement statement ){ public static IScope getContainingScope( IASTStatement statement ){
IASTNode parent = statement.getParent(); IASTNode parent = statement.getParent();
@ -588,33 +577,11 @@ public class CPPVisitor {
return scope; return scope;
} }
public static IScope getContainingScope( IASTDeclSpecifier typeSpec ){
IASTNode parent = typeSpec.getParent();
if( parent instanceof IASTSimpleDeclaration )
return getContainingScope( (IASTSimpleDeclaration) parent );
else if( parent instanceof IASTTypeId )
return getContainingScope( parent.getParent() );
return getContainingScope( parent );
}
/**
* @param parameterDeclaration
* @return
*/
public static IScope getContainingScope(IASTParameterDeclaration parameterDeclaration) {
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) parameterDeclaration.getParent();
ASTNodeProperty prop = dtor.getPropertyInParent();
if( prop == IASTSimpleDeclaration.DECLARATOR || prop == IASTFunctionDefinition.DECLARATOR )
return dtor.getFunctionScope();
return getContainingScope( dtor );
}
public static IASTNode getContainingBlockItem( IASTNode node ){ public static IASTNode getContainingBlockItem( IASTNode node ){
IASTNode parent = node.getParent(); IASTNode parent = node.getParent();
if( parent == null ) if( parent == null )
return null; return null;
while( parent != null ) {
if( parent instanceof IASTDeclaration ){ if( parent instanceof IASTDeclaration ){
IASTNode p = parent.getParent(); IASTNode p = parent.getParent();
if( p instanceof IASTDeclarationStatement ) if( p instanceof IASTDeclarationStatement )
@ -629,18 +596,27 @@ public class CPPVisitor {
} else if( parent instanceof IASTFunctionDeclarator ){ } else if( parent instanceof IASTFunctionDeclarator ){
return node; return node;
} }
node = parent;
return getContainingBlockItem( parent ); parent = node.getParent();
}
return null;
} }
static private IBinding resolveBinding( IASTNode node ){ static private IBinding resolveBinding( IASTNode node ){
while( node != null ) {
if( node instanceof IASTIdExpression ){ if( node instanceof IASTIdExpression ){
return CPPSemantics.resolveBinding( ((IASTIdExpression)node).getName() ); return CPPSemantics.resolveBinding( ((IASTIdExpression)node).getName() );
} else if( node instanceof ICPPASTFieldReference ){ } else if( node instanceof ICPPASTFieldReference ){
return CPPSemantics.resolveBinding( ((ICPPASTFieldReference)node).getFieldName() ); return CPPSemantics.resolveBinding( ((ICPPASTFieldReference)node).getFieldName() );
} else if( node instanceof IASTFunctionCallExpression ){ } else if( node instanceof IASTFunctionCallExpression ){
return resolveBinding( ((IASTFunctionCallExpression)node).getFunctionNameExpression() ); node = ((IASTFunctionCallExpression)node).getFunctionNameExpression();
} else if( node instanceof IASTUnaryExpression ){
node = ((IASTUnaryExpression)node).getOperand();
} else if( node instanceof IASTBinaryExpression ){
node = ((IASTBinaryExpression)node).getOperand2();
} }
}
return null; return null;
} }
@ -1487,7 +1463,9 @@ public class CPPVisitor {
private static IType getPointerTypes( IType type, IASTDeclarator declarator ){ private static IType getPointerTypes( IType type, IASTDeclarator declarator ){
IASTPointerOperator [] ptrOps = declarator.getPointerOperators(); IASTPointerOperator [] ptrOps = declarator.getPointerOperators();
for( int i = ptrOps.length - 1; i >= 0; i-- ){ for( int i = ptrOps.length - 1; i >= 0; i-- ){
if( ptrOps[i] instanceof IASTPointer ) if( ptrOps[i] instanceof ICPPASTPointerToMember )
type = new CPPPointerToMemberType( type, (ICPPASTPointerToMember) ptrOps[i] );
else if( ptrOps[i] instanceof IASTPointer )
type = new CPPPointerType( type, (IASTPointer) ptrOps[i] ); type = new CPPPointerType( type, (IASTPointer) ptrOps[i] );
else if( ptrOps[i] instanceof ICPPASTReferenceOperator ) else if( ptrOps[i] instanceof ICPPASTReferenceOperator )
type = new CPPReferenceType( type ); type = new CPPReferenceType( type );
@ -1652,7 +1630,17 @@ public class CPPVisitor {
} catch ( DOMException e ) { } catch ( DOMException e ) {
return e.getProblem(); return e.getProblem();
} }
} else if( binding instanceof IVariable ){
try {
IType t = ((IVariable)binding).getType();
if( t instanceof IPointerType && ((IPointerType)t).getType() instanceof IFunctionType ){
IFunctionType ftype = (IFunctionType) ((IPointerType)t).getType();
if( ftype != null )
return ftype.getReturnType();
}
} catch( DOMException e ){
return e.getProblem();
}
} }
} }
else if( expression instanceof IASTUnaryExpression ) else if( expression instanceof IASTUnaryExpression )