1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

- Add basic ambiguity resolution

- start using offsets to aid in traversing different scopes.
- set some offsets on some physical nodes as I notice them
This commit is contained in:
Andrew Niefer 2004-12-08 16:35:10 +00:00
parent 7bef09d931
commit 494a85849b
4 changed files with 158 additions and 36 deletions

View file

@ -341,4 +341,56 @@ public class AST2CPPTests extends AST2BaseTest {
assertInstances( collector, BC, 2 );
assertInstances( collector, f ,1 );
}
public void testNameHiding() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append( "int A; \n"); //$NON-NLS-1$
buffer.append( "class A {}; \n"); //$NON-NLS-1$
buffer.append( "void f() { \n"); //$NON-NLS-1$
buffer.append( " A++; \n"); //$NON-NLS-1$
buffer.append( " class A a; \n"); //$NON-NLS-1$
buffer.append( "} \n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
CPPNameCollector collector = new CPPNameCollector();
CPPVisitor.visitTranslationUnit( tu, collector );
assertEquals( collector.size(), 6 );
IVariable vA = (IVariable) collector.getName( 0 ).resolveBinding();
ICompositeType cA = (ICompositeType) collector.getName( 1 ).resolveBinding();
IVariable a = (IVariable) collector.getName( 5 ).resolveBinding();
assertSame( a.getType(), cA );
assertInstances( collector, vA, 2 );
assertInstances( collector, cA, 2 );
}
public void testBlockTraversal() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append( "class A { void f(); }; \n" ); //$NON-NLS-1$
buffer.append( "class B; \n" ); //$NON-NLS-1$
buffer.append( "void A::f() { \n" ); //$NON-NLS-1$
buffer.append( " B b; \n" ); //$NON-NLS-1$
buffer.append( "} \n" ); //$NON-NLS-1$
buffer.append( "int B; \n" ); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
CPPNameCollector collector = new CPPNameCollector();
CPPVisitor.visitTranslationUnit( tu, collector );
assertEquals( collector.size(), 9 );
ICompositeType A = (ICompositeType) collector.getName( 0 ).resolveBinding();
ICPPMethod f = (ICPPMethod) collector.getName( 1 ).resolveBinding();
ICompositeType B = (ICompositeType) collector.getName( 2 ).resolveBinding();
IVariable b = (IVariable) collector.getName( 7 ).resolveBinding();
IVariable B2 = (IVariable) collector.getName( 8 ).resolveBinding();
assertSame( b.getType(), B );
assertInstances( collector, A, 2 );
assertInstances( collector, f, 3 );
assertInstances( collector, B, 2 );
assertInstances( collector, b, 1 );
assertInstances( collector, B2, 1 );
}
}

View file

@ -1344,6 +1344,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
lastTokenOfExpression = consume(IToken.tSEMI);
expressionStatement = createExpressionStatement();
expressionStatement.setExpression( expression );
((ASTNode)expressionStatement).setOffset(mark.getOffset());
expression.setParent( expressionStatement );
expression.setPropertyInParent( IASTExpressionStatement.EXPFRESSION );
} catch (BacktrackException b) {
@ -1358,6 +1359,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
IASTDeclaration d = declaration();
ds = createDeclarationStatement();
ds.setDeclaration(d);
((ASTNode)ds).setOffset(mark.getOffset());
d.setParent( ds );
d.setPropertyInParent( IASTDeclarationStatement.DECLARATION );
}

View file

@ -97,6 +97,7 @@ 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.parser.pst.ITypeInfo;
import org.eclipse.cdt.internal.core.parser2.ASTNode;
/**
* @author aniefer
@ -127,6 +128,16 @@ public class CPPVisitor {
}
private static IBinding createBinding( ICPPASTElaboratedTypeSpecifier elabType ){
IASTNode parent = elabType.getParent();
if( parent instanceof IASTSimpleDeclaration ){
IASTDeclarator [] dtors = ((IASTSimpleDeclaration)parent).getDeclarators();
if( dtors.length > 0 ){
IBinding binding = resolveBinding( elabType.getName() );
if( binding != null )
return binding;
}
}
ICPPScope scope = (ICPPScope) getContainingScope( elabType );
CPPClassType binding = (CPPClassType) scope.getBinding( 0, elabType.getName().toCharArray() );
if( binding == null ){
@ -308,13 +319,12 @@ public class CPPVisitor {
if( p instanceof IASTDeclarationStatement )
return p;
return parent;
}
//if parent is something that can contain a declaration
else if ( parent instanceof IASTCompoundStatement ||
parent instanceof IASTTranslationUnit ||
parent instanceof IASTForStatement )
{
return node;
} else if( parent instanceof IASTExpression ){
IASTNode p = parent.getParent();
if( p instanceof IASTStatement )
return parent;
} else if ( parent instanceof IASTStatement || parent instanceof IASTTranslationUnit ) {
return parent;
}
return getContainingBlockItem( parent );
@ -338,7 +348,7 @@ public class CPPVisitor {
public boolean ignoreUsingDirectives = false;
public boolean usingDirectivesOnly = false;
public boolean forDefinition = false;
public boolean typesOnly = false;
public List foundItems = null;
public LookupData( char[] n ){
@ -354,11 +364,10 @@ public class CPPVisitor {
lookup( data, name );
//3: resolve ambiguities
//TODO
if( data.foundItems != null && data.foundItems.size() == 1 ){
IASTName found = (IASTName) data.foundItems.get(0);
IASTName found = resolveAmbiguities( data, name );
if( found != null ) {
IBinding binding = found.resolveBinding();
if( data.forDefinition ){
if( binding != null && data.forDefinition ){
addDefinition( binding, name );
}
return binding;
@ -386,23 +395,71 @@ public class CPPVisitor {
}
} else if( parent instanceof IASTDeclarator ){
data.forDefinition = true;
} else if ( parent instanceof ICPPASTBaseSpecifier ) {
//filter out non-type names
} else if ( parent instanceof ICPPASTBaseSpecifier ||
parent instanceof ICPPASTElaboratedTypeSpecifier)
{
data.typesOnly = true;
}
return data;
}
static private IASTName collectResult( LookupData data, IASTNode declaration, boolean checkAux ){
static private IASTName resolveAmbiguities( LookupData data, IASTName name ) {
if( data.foundItems == null || data.foundItems.size() == 0 )
return null;
if( data.foundItems.size() == 1 ){
return (IASTName) data.foundItems.get(0);
}
IASTName type = null;
IASTName obj = null;
for( int i = 0; i < data.foundItems.size(); i++ ){
IASTName n = (IASTName) data.foundItems.get( i );
IASTNode parent = n.getParent();
if( parent instanceof IASTDeclarator ){
if( obj == null ){
obj = n;
} else {
//TODO
}
} else if( parent instanceof ICPPASTElaboratedTypeSpecifier ||
parent instanceof IASTEnumerationSpecifier ||
parent instanceof ICPPASTCompositeTypeSpecifier )
{
if( type == null ){
type = n;
} else {
//TODO
}
}
}
if( type != null ) {
if( obj != null ){
if( obj.resolveBinding().getScope() != type.resolveBinding().getScope() ){
return null; //ambiguous
}
} else {
return type;
}
}
return obj;
}
static private IASTName collectResult( LookupData data, IASTNode node, boolean checkAux ){
IASTDeclaration declaration = null;
if( node instanceof IASTDeclaration )
declaration = (IASTDeclaration) node;
if( declaration instanceof IASTDeclarationStatement )
declaration = ((IASTDeclarationStatement)declaration).getDeclaration();
declaration = ((IASTDeclarationStatement)node).getDeclaration();
else if( declaration instanceof IASTForStatement )
declaration = ((IASTForStatement)declaration).getInitDeclaration();
declaration = ((IASTForStatement)node).getInitDeclaration();
if( declaration == null )
return null;
if( declaration instanceof IASTSimpleDeclaration ){
IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration;
if( !data.typesOnly ) {
IASTDeclarator [] declarators = simpleDeclaration.getDeclarators();
for( int i = 0; i < declarators.length; i++ ){
IASTDeclarator declarator = declarators[i];
@ -411,6 +468,7 @@ public class CPPVisitor {
return declaratorName;
}
}
}
//decl spec
IASTDeclSpecifier declSpec = simpleDeclaration.getDeclSpecifier();
@ -430,6 +488,7 @@ public class CPPVisitor {
if( CharArrayUtils.equals( eName.toCharArray(), data.name ) ){
return eName;
}
if( !data.typesOnly ) {
//check enumerators too
IASTEnumerator [] list = enumeration.getEnumerators();
for( int i = 0; i < list.length; i++ ) {
@ -440,9 +499,13 @@ public class CPPVisitor {
return eName;
}
}
}
} else if( declaration instanceof IASTFunctionDefinition ){
}
}
if( data.typesOnly )
return null;
if( declaration instanceof IASTFunctionDefinition ){
IASTFunctionDefinition functionDef = (IASTFunctionDefinition) declaration;
IASTFunctionDeclarator declarator = functionDef.getDeclarator();
@ -472,6 +535,7 @@ public class CPPVisitor {
if( CharArrayUtils.equals( namespaceName.toCharArray(), data.name ) )
return namespaceName;
}
return null;
}
static private void lookup( LookupData data, IASTName name ){
@ -480,6 +544,9 @@ public class CPPVisitor {
ICPPScope scope = (ICPPScope) getContainingScope( node );
while( scope != null ){
IASTNode blockItem = getContainingBlockItem( node );
if( scope.getPhysicalNode() != blockItem.getParent() )
blockItem = node;
List directives = null;
if( !data.usingDirectivesOnly ){
directives = new ArrayList(2);
@ -523,7 +590,7 @@ public class CPPVisitor {
data.usingDirectivesOnly = true;
if( blockItem != null )
node = blockItem.getParent();
node = blockItem;
scope = (ICPPScope) scope.getParent();
}
}
@ -697,7 +764,7 @@ public class CPPVisitor {
IASTNode item = ( nodes != null ? (nodes.length > 0 ? nodes[++idx] : null ) : parent );
while( item != null ) {
if( item == null || item == blockItem )
if( item == null || item == blockItem || ( blockItem != null && ((ASTNode)item).getOffset() > ((ASTNode) blockItem).getOffset() ))
break;
if( item instanceof ICPPASTUsingDirective && !data.ignoreUsingDirectives ) {

View file

@ -2398,6 +2398,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
subName = createTemplateID( segments[i] );
subName.setParent( result );
subName.setPropertyInParent( ICPPASTQualifiedName.SEGMENT_NAME );
((ASTNode)subName).setOffset( segments[i].getStartOffset() );
result.addName( subName );
}