1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-09-10 12:03:16 +02:00

Bindings for members

This commit is contained in:
Andrew Niefer 2004-12-02 19:40:14 +00:00
parent 198c40a795
commit 3c6b029ae7
12 changed files with 244 additions and 39 deletions

View file

@ -14,10 +14,13 @@
package org.eclipse.cdt.core.parser.tests.ast2;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
@ -28,6 +31,7 @@ import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
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.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.parser.ParserLanguage;
@ -184,5 +188,57 @@ public class AST2CPPTests extends AST2BaseTest {
assertSame( A, A2 );
}
public void testMemberReference() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append( "class A { void f(); int i; }; \n" ); //$NON-NLS-1$
buffer.append( "void A::f() { i; } \n" ); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
IASTSimpleDeclaration decl = (IASTSimpleDeclaration) tu.getDeclarations()[0];
assertEquals( decl.getDeclarators().length, 0 );
IASTCompositeTypeSpecifier comp = (IASTCompositeTypeSpecifier) decl.getDeclSpecifier();
IASTName name_A = comp.getName();
decl = (IASTSimpleDeclaration) comp.getMembers()[0];
IASTDeclarator dtor = decl.getDeclarators()[0];
IASTName name_f1 = dtor.getName();
decl = (IASTSimpleDeclaration) comp.getMembers()[1];
dtor = decl.getDeclarators()[0];
IASTName name_i = dtor.getName();
IASTFunctionDefinition def = (IASTFunctionDefinition) tu.getDeclarations()[1];
IASTFunctionDeclarator fdtor = def.getDeclarator();
ICPPASTQualifiedName name_f2 = (ICPPASTQualifiedName) fdtor.getName();
IASTCompoundStatement compound = (IASTCompoundStatement) def.getBody();
IASTExpressionStatement statement = (IASTExpressionStatement) compound.getStatements()[0];
IASTIdExpression idExp = (IASTIdExpression) statement.getExpression();
IASTName name_i2 = idExp.getName();
ICPPClassType A = (ICPPClassType) name_A.resolveBinding();
ICPPMethod f1 = (ICPPMethod) name_f1.resolveBinding();
ICPPMethod f2 = (ICPPMethod) name_f2.resolveBinding();
ICPPField i1 = (ICPPField) name_i.resolveBinding();
ICPPField i2 = (ICPPField) name_i2.resolveBinding();
IASTName[] names = name_f2.getNames();
assertEquals( names.length, 2 );
IASTName qn1 = names[0];
IASTName qn2 = names[1];
ICPPClassType A2 = (ICPPClassType) qn1.resolveBinding();
ICPPMethod f3 = (ICPPMethod) qn2.resolveBinding();
assertNotNull( A );
assertNotNull( f1 );
assertNotNull( i1 );
assertSame( f1, f2 );
assertSame( f2, f3 );
assertSame( A, A2 );
assertSame( i1, i2 );
}
}

View file

@ -49,4 +49,6 @@ public interface IASTFunctionDefinition extends IASTDeclaration {
public void setBody( IASTStatement statement );
public IScope getScope();
}

View file

@ -13,6 +13,8 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.c.ICFunctionScope;
/**
* @author jcamelon
@ -23,6 +25,7 @@ public class CASTFunctionDefinition extends CASTNode implements
private IASTDeclSpecifier declSpecifier;
private IASTFunctionDeclarator declarator;
private IASTStatement bodyStatement;
private ICFunctionScope scope;
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition#getDeclSpecifier()
@ -66,4 +69,13 @@ public class CASTFunctionDefinition extends CASTNode implements
bodyStatement = statement;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition#getScope()
*/
public IScope getScope() {
if( scope == null )
scope = new CFunctionScope( this );
return scope;
}
}

View file

@ -30,16 +30,12 @@ public class CFunction implements IFunction {
private IASTFunctionDeclarator [] declarators = null;
private IASTFunctionDeclarator definition;
final private IScope functionScope;
public CFunction( IASTFunctionDeclarator declarator ){
if( declarator.getParent() instanceof IASTFunctionDefinition )
definition = declarator;
else {
declarators = new IASTFunctionDeclarator [] { declarator };
}
this.functionScope = new CFunctionScope( this );
}
public IASTNode getPhysicalNode(){
@ -118,7 +114,11 @@ public class CFunction implements IFunction {
* @see org.eclipse.cdt.core.dom.ast.IFunction#getFunctionScope()
*/
public IScope getFunctionScope() {
return functionScope;
if( definition != null ){
IASTFunctionDefinition def = (IASTFunctionDefinition) definition.getParent();
return def.getScope();
}
return null;
}
// public IASTDeclaration getDeclaration(){

View file

@ -15,8 +15,6 @@ import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
@ -33,10 +31,10 @@ import org.eclipse.cdt.internal.core.parser2.c.CVisitor.BaseVisitorAction;
* @author aniefer
*/
public class CFunctionScope implements ICFunctionScope {
private final CFunction function;
private final IASTFunctionDefinition function;
private CharArrayObjectMap bindings = CharArrayObjectMap.EMPTY_MAP;
public CFunctionScope( CFunction function ){
public CFunctionScope( IASTFunctionDefinition function ){
this.function = function;
}
@ -66,9 +64,7 @@ public class CFunctionScope implements ICFunctionScope {
public IScope getBodyScope(){
IASTFunctionDeclarator fdtor = (IASTFunctionDeclarator) function.getPhysicalNode();
IASTFunctionDefinition fdef = (IASTFunctionDefinition) fdtor.getParent();
IASTStatement statement = fdef.getBody();
IASTStatement statement = function.getBody();
if( statement instanceof IASTCompoundStatement ){
return ((IASTCompoundStatement)statement).getScope();
}
@ -90,9 +86,7 @@ public class CFunctionScope implements ICFunctionScope {
public List getLabels(){
FindLabelsAction action = new FindLabelsAction();
IASTFunctionDeclarator dtor = (IASTFunctionDeclarator) function.getPhysicalNode();
if( dtor.getParent() instanceof IASTFunctionDefinition )
CVisitor.visitDeclaration( (IASTDeclaration) dtor.getParent(), action );
CVisitor.visitDeclaration( function, action );
List list = new ArrayList();
for( int i = 0; i < action.labels.size(); i++ ){

View file

@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.parser2.cpp;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
/**
* @author jcamelon
@ -37,6 +38,7 @@ public class CPPASTCompoundStatement extends CPPASTNode implements
private IASTStatement [] statements = null;
private ICPPScope scope = null;
private static final int DEFAULT_STATEMENT_LIST_SIZE = 8;
@ -72,8 +74,9 @@ public class CPPASTCompoundStatement extends CPPASTNode implements
* @see org.eclipse.cdt.core.dom.ast.IASTCompoundStatement#resolveScope()
*/
public IScope getScope() {
// TODO Auto-generated method stub
return null;
if( scope == null )
scope = new CPPBlockScope( this );
return scope;
}
}

View file

@ -14,6 +14,8 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope;
/**
* @author jcamelon
@ -24,6 +26,7 @@ public class CPPASTFunctionDefinition extends CPPASTNode implements
private IASTDeclSpecifier declSpecifier;
private IASTFunctionDeclarator declarator;
private IASTStatement bodyStatement;
private ICPPFunctionScope scope;
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition#getDeclSpecifier()
@ -67,5 +70,14 @@ public class CPPASTFunctionDefinition extends CPPASTNode implements
bodyStatement = statement;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition#getScope()
*/
public IScope getScope() {
if( scope == null )
scope = new CPPFunctionScope( this );
return scope;
}
}

View file

@ -14,13 +14,21 @@
package org.eclipse.cdt.internal.core.parser2.cpp;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
/**
* @author aniefer
*/
public class CPPField extends CPPVariable implements IField {
public class CPPField extends CPPVariable implements ICPPField {
public CPPField( IASTDeclarator declarator ){
super( declarator );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPMember#getVisibility()
*/
public int getVisibility() {
// TODO Auto-generated method stub
return 0;
}
}

View file

@ -36,6 +36,26 @@ public class CPPFunction implements IFunction {
else
declarations = new IASTFunctionDeclarator [] { declarator };
}
public void addDefinition( IASTFunctionDeclarator dtor ){
definition = dtor;
}
public void addDeclaration( IASTFunctionDeclarator dtor ){
if( declarations == null ){
declarations = new IASTFunctionDeclarator [] { dtor };
return;
}
for( int i = 0; i < declarations.length; i++ ){
if( declarations[i] == null ){
declarations[i] = dtor;
return;
}
}
IASTFunctionDeclarator [] tmp = new IASTFunctionDeclarator[ declarations.length * 2 ];
System.arraycopy( declarations, 0, tmp, 0, declarations.length );
tmp[ declarations.length ] = dtor;
declarations = tmp;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IFunction#getParameters()
*/
@ -48,8 +68,8 @@ public class CPPFunction implements IFunction {
* @see org.eclipse.cdt.core.dom.ast.IFunction#getFunctionScope()
*/
public IScope getFunctionScope() {
// TODO Auto-generated method stub
return null;
IASTFunctionDefinition def = (IASTFunctionDefinition) definition.getParent();
return def.getScope();
}
/* (non-Javadoc)

View file

@ -0,0 +1,70 @@
/*******************************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
/*
* Created on Dec 1, 2004
*/
package org.eclipse.cdt.internal.core.parser2.cpp;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
/**
* @author aniefer
*/
public class CPPFunctionScope extends CPPScope implements ICPPFunctionScope {
/**
* @param physicalNode
*/
public CPPFunctionScope(IASTFunctionDefinition physicalNode) {
super(physicalNode);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#addBinding(org.eclipse.cdt.core.dom.ast.IBinding)
*/
public void addBinding(IBinding binding) {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#getBinding(int, char[])
*/
public IBinding getBinding(int namespaceType, char[] name) {
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String)
*/
public List find(String name) {
// TODO Auto-generated method stub
return null;
}
public IScope getParent() {
IASTFunctionDefinition fn = (IASTFunctionDefinition) getPhysicalNode();
IFunction function = (IFunction) fn.getDeclarator().getName().resolveBinding();
if( function instanceof ICPPMethod ){
return function.getScope();
}
return super.getParent();
}
}

View file

@ -13,6 +13,7 @@
*/
package org.eclipse.cdt.internal.core.parser2.cpp;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
@ -32,4 +33,7 @@ public class CPPMethod extends CPPFunction implements ICPPMethod {
return 0;
}
public IScope getScope() {
return CPPVisitor.getContainingScope( declarations != null ? declarations[0] : definition );
}
}

View file

@ -28,6 +28,7 @@ import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
@ -54,7 +55,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.core.parser.util.ObjectSet;
import org.eclipse.cdt.internal.core.parser.pst.ISymbol;
import org.eclipse.cdt.internal.core.parser2.c.CASTFunctionDeclarator;
/**
@ -67,17 +67,19 @@ public class CPPVisitor {
*/
public static IBinding createBinding(IASTName name) {
IASTNode parent = name.getParent();
if( parent instanceof ICPPASTCompositeTypeSpecifier ){
if( parent instanceof IASTNamedTypeSpecifier ||
parent instanceof ICPPASTQualifiedName )
{
return resolveBinding( name );
} else if( parent instanceof IASTIdExpression ){
return resolveBinding( parent );
} else if( parent instanceof ICPPASTCompositeTypeSpecifier ){
return createBinding( (ICPPASTCompositeTypeSpecifier) parent );
} else if( parent instanceof IASTDeclarator ){
return createBinding( (IASTDeclarator) parent );
} else if( parent instanceof ICPPASTElaboratedTypeSpecifier ){
return createBinding( (ICPPASTElaboratedTypeSpecifier) parent );
} else if( parent instanceof IASTNamedTypeSpecifier ||
parent instanceof ICPPASTQualifiedName )
{
return resolveBinding( name );
}
}
return null;
}
@ -235,6 +237,9 @@ public class CPPVisitor {
private static IASTNode getContainingBlockItem( IASTNode node ){
IASTNode parent = node.getParent();
if( parent == null )
return null;
if( parent instanceof IASTDeclaration ){
IASTNode p = parent.getParent();
if( p instanceof IASTDeclarationStatement )
@ -252,13 +257,19 @@ public class CPPVisitor {
return getContainingBlockItem( parent );
}
static private IBinding resolveBinding( IASTNode node ){
if( node instanceof IASTIdExpression ){
return resolveBinding( ((IASTIdExpression)node).getName() );
}
return null;
}
static protected class LookupData
{
public char[] name;
public ObjectMap usingDirectives;
public ObjectMap usingDirectives = ObjectMap.EMPTY_MAP;
public ObjectSet visited = ObjectSet.EMPTY_SET; //used to ensure we don't visit things more than once
public ObjectSet inheritanceChain; //used to detect circular inheritance
public ISymbol templateMember; //to assit with template member defs
public boolean qualified = false;
public boolean ignoreUsingDirectives = false;
@ -283,10 +294,24 @@ public class CPPVisitor {
//TODO
if( data.foundItems != null && data.foundItems.size() == 1 ){
IASTName found = (IASTName) data.foundItems.get(0);
return found.resolveBinding();
IBinding binding = found.resolveBinding();
if( data.forDefinition ){
addDefinition( binding, name );
}
return binding;
}
return null;
}
private static void addDefinition( IBinding binding, IASTName name ){
if( binding instanceof IFunction ){
IASTNode node = name.getParent();
if( node instanceof ICPPASTQualifiedName )
node = node.getParent();
if( node instanceof IASTFunctionDeclarator ){
((CPPFunction)binding).addDefinition( (IASTFunctionDeclarator) node );
}
}
}
static private LookupData createLookupData( IASTName name ){
LookupData data = new LookupData( name.toCharArray() );
IASTNode parent = name.getParent();
@ -379,10 +404,9 @@ public class CPPVisitor {
static private void lookup( LookupData data, IASTName name ){
IASTNode node = name;
while( node != null ){
ICPPScope scope = (ICPPScope) getContainingScope( node );
while( scope != null ){
IASTNode blockItem = getContainingBlockItem( node );
ICPPScope scope = (ICPPScope) getContainingScope( node );
List directives = null;
if( !data.usingDirectivesOnly )
directives = lookupInScope( data, scope, blockItem );
@ -396,7 +420,7 @@ public class CPPVisitor {
if( directives != null && directives.size() != 0 )
processDirectives( data, scope, directives );
while( data.usingDirectives != null && data.usingDirectives.get( scope ) != null ){
while( !data.usingDirectives.isEmpty() && data.usingDirectives.get( scope ) != null ){
transitives = lookupInNominated( data, scope, null );
if( !data.qualified || data.foundItems == null ){
@ -420,6 +444,7 @@ public class CPPVisitor {
if( data.qualified && !data.usingDirectives.isEmpty() )
data.usingDirectivesOnly = true;
node = blockItem.getParent();
scope = (ICPPScope) scope.getParent();
}
}
@ -445,11 +470,10 @@ public class CPPVisitor {
//data.usingDirectives is a map from enclosing scope to a list
//of namespaces to consider when we reach that enclosing scope
ICPPScope [] list = ( data.usingDirectives == null )
? null : (ICPPScope []) data.usingDirectives.get( enclosing );
ICPPScope [] list = data.usingDirectives.isEmpty() ? null : (ICPPScope []) data.usingDirectives.get( enclosing );
if( list == null ){
list = new ICPPScope [] { enclosing, null };
if( data.usingDirectives == null ){
if( data.usingDirectives == ObjectMap.EMPTY_MAP ){
data.usingDirectives = new ObjectMap(2);
}
data.usingDirectives.put( enclosing, list );
@ -526,7 +550,7 @@ public class CPPVisitor {
}
static private List lookupInNominated( LookupData data, ICPPScope scope, List transitives ){
if( data.usingDirectives == null )
if( data.usingDirectives.isEmpty() )
return transitives;
List directives = null;