mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Label bindings in the new parser
This commit is contained in:
parent
c20d990dc3
commit
8d0a12de55
4 changed files with 166 additions and 8 deletions
|
@ -37,6 +37,7 @@ import org.eclipse.cdt.core.dom.ast.IEnumeration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IEnumerator;
|
import org.eclipse.cdt.core.dom.ast.IEnumerator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IFunction;
|
import org.eclipse.cdt.core.dom.ast.IFunction;
|
||||||
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
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.IParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IQualifierType;
|
import org.eclipse.cdt.core.dom.ast.IQualifierType;
|
||||||
|
@ -963,12 +964,42 @@ public class CompleteParser2Tests extends TestCase {
|
||||||
|
|
||||||
public void testSimpleWhileStatement() throws Exception
|
public void testSimpleWhileStatement() throws Exception
|
||||||
{
|
{
|
||||||
parse( "const bool T = true; void foo() { int x = 0; while( T ) { ++x; if( x == 100 ) break; } }"); //$NON-NLS-1$
|
IASTTranslationUnit tu = parse( "const bool T = true; void foo() { int x = 0; while( T ) { ++x; if( x == 100 ) break; } }"); //$NON-NLS-1$
|
||||||
|
CPPNameCollector col = new CPPNameCollector();
|
||||||
|
CPPVisitor.visitTranslationUnit( tu, col );
|
||||||
|
|
||||||
|
assertEquals( col.size(), 6 );
|
||||||
|
IVariable T = (IVariable) col.getName(0).resolveBinding();
|
||||||
|
IVariable x = (IVariable) col.getName(2).resolveBinding();
|
||||||
|
assertInstances( col, T, 2 );
|
||||||
|
assertInstances( col, x, 3 );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSimpleSwitchStatement() throws Exception
|
public void testSimpleSwitchStatement() throws Exception
|
||||||
{
|
{
|
||||||
parse( "const int x = 5; const int y = 10; void foo() { switch( x ) { case 1: break; case 2: goto blah; case y: continue; default: break;} }"); //$NON-NLS-1$
|
IASTTranslationUnit tu = parse( "const int x = 5; const int y = 10; " + //$NON-NLS-1$
|
||||||
|
"void foo() { " + //$NON-NLS-1$
|
||||||
|
" while( true ) { " + //$NON-NLS-1$
|
||||||
|
" switch( x ) { " + //$NON-NLS-1$
|
||||||
|
" case 1: break; " + //$NON-NLS-1$
|
||||||
|
" case 2: goto blah; " + //$NON-NLS-1$
|
||||||
|
" case y: continue; " + //$NON-NLS-1$
|
||||||
|
" default: break; " + //$NON-NLS-1$
|
||||||
|
" } " + //$NON-NLS-1$
|
||||||
|
" } " + //$NON-NLS-1$
|
||||||
|
" blah : ; " + //$NON-NLS-1$
|
||||||
|
"} "); //$NON-NLS-1$
|
||||||
|
CPPNameCollector col = new CPPNameCollector();
|
||||||
|
CPPVisitor.visitTranslationUnit( tu, col );
|
||||||
|
|
||||||
|
assertEquals( col.size(), 7 );
|
||||||
|
IVariable x = (IVariable) col.getName(0).resolveBinding();
|
||||||
|
IVariable y = (IVariable) col.getName(1).resolveBinding();
|
||||||
|
ILabel blah = (ILabel) col.getName(4).resolveBinding();
|
||||||
|
assertNotNull( blah );
|
||||||
|
assertInstances( col, x, 2 );
|
||||||
|
assertInstances( col, y, 2 );
|
||||||
|
assertInstances( col, blah, 2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSimpleDoStatement() throws Exception
|
public void testSimpleDoStatement() throws Exception
|
||||||
|
|
|
@ -19,15 +19,19 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IFunction;
|
import org.eclipse.cdt.core.dom.ast.IFunction;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.ILabel;
|
||||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
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.ICPPFunctionScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||||
|
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author aniefer
|
* @author aniefer
|
||||||
*/
|
*/
|
||||||
public class CPPFunctionScope extends CPPScope implements ICPPFunctionScope {
|
public class CPPFunctionScope extends CPPScope implements ICPPFunctionScope {
|
||||||
|
|
||||||
|
private CharArrayObjectMap labels = CharArrayObjectMap.EMPTY_MAP;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param physicalNode
|
* @param physicalNode
|
||||||
*/
|
*/
|
||||||
|
@ -35,20 +39,26 @@ public class CPPFunctionScope extends CPPScope implements ICPPFunctionScope {
|
||||||
super(physicalNode);
|
super(physicalNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#addBinding(org.eclipse.cdt.core.dom.ast.IBinding)
|
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#addBinding(org.eclipse.cdt.core.dom.ast.IBinding)
|
||||||
*/
|
*/
|
||||||
public void addBinding(IBinding binding) {
|
public void addBinding(IBinding binding) {
|
||||||
// TODO Auto-generated method stub
|
//3.3.4 only labels have function scope
|
||||||
|
if( !( binding instanceof ILabel ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( labels == CharArrayObjectMap.EMPTY_MAP )
|
||||||
|
labels = new CharArrayObjectMap( 2 );
|
||||||
|
|
||||||
|
labels.put( binding.getNameCharArray(), binding );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#getBinding(int, char[])
|
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#getBinding(int, char[])
|
||||||
*/
|
*/
|
||||||
public IBinding getBinding( IASTName name ) {
|
public IBinding getBinding( IASTName name ) {
|
||||||
// TODO Auto-generated method stub
|
return (IBinding) labels.get( name.toCharArray() );
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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 Jan 14, 2005
|
||||||
|
*/
|
||||||
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.ILabel;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author aniefer
|
||||||
|
*/
|
||||||
|
public class CPPLabel implements ILabel {
|
||||||
|
private IASTStatement statement;
|
||||||
|
/**
|
||||||
|
* @param gotoStatement
|
||||||
|
*/
|
||||||
|
public CPPLabel( IASTStatement statement ) {
|
||||||
|
this.statement = statement;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.core.dom.ast.ILabel#getLabelStatement()
|
||||||
|
*/
|
||||||
|
public IASTLabelStatement getLabelStatement() {
|
||||||
|
if( statement instanceof IASTLabelStatement )
|
||||||
|
return (IASTLabelStatement) statement;
|
||||||
|
|
||||||
|
// TODO find label statement
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.core.dom.ast.IBinding#getName()
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
if( statement instanceof IASTLabelStatement )
|
||||||
|
return ((IASTLabelStatement) statement).getName().toString();
|
||||||
|
|
||||||
|
return ((IASTGotoStatement) statement).getName().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray()
|
||||||
|
*/
|
||||||
|
public char[] getNameCharArray() {
|
||||||
|
if( statement instanceof IASTLabelStatement )
|
||||||
|
return ((IASTLabelStatement) statement).getName().toCharArray();
|
||||||
|
|
||||||
|
return ((IASTGotoStatement) statement).getName().toCharArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.core.dom.ast.IBinding#getScope()
|
||||||
|
*/
|
||||||
|
public IScope getScope() {
|
||||||
|
return CPPVisitor.getContainingScope( statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.core.dom.ast.IBinding#getPhysicalNode()
|
||||||
|
*/
|
||||||
|
public IASTNode getPhysicalNode() {
|
||||||
|
return statement;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param labelStatement
|
||||||
|
*/
|
||||||
|
public void setLabelStatement( IASTLabelStatement labelStatement ) {
|
||||||
|
statement = labelStatement;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -77,7 +77,6 @@ import org.eclipse.cdt.core.dom.ast.IScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
|
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
|
||||||
import org.eclipse.cdt.core.dom.ast.c.ICFunctionScope;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
|
||||||
|
@ -107,6 +106,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope;
|
||||||
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.ICPPScope;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||||
|
@ -149,10 +149,39 @@ public class CPPVisitor {
|
||||||
return createBinding( (IASTEnumerationSpecifier) parent );
|
return createBinding( (IASTEnumerationSpecifier) parent );
|
||||||
} else if( parent instanceof IASTEnumerator ){
|
} else if( parent instanceof IASTEnumerator ){
|
||||||
return createBinding( (IASTEnumerator) parent );
|
return createBinding( (IASTEnumerator) parent );
|
||||||
|
} else if( parent instanceof IASTGotoStatement ){
|
||||||
|
return createBinding( (IASTGotoStatement) parent );
|
||||||
|
} else if( parent instanceof IASTLabelStatement ){
|
||||||
|
return createBinding( (IASTLabelStatement) parent );
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IBinding createBinding( IASTGotoStatement gotoStatement ) {
|
||||||
|
ICPPFunctionScope functionScope = (ICPPFunctionScope) getContainingScope( gotoStatement );
|
||||||
|
IASTName name = gotoStatement.getName();
|
||||||
|
IBinding binding = functionScope.getBinding( name );
|
||||||
|
if( binding == null ){
|
||||||
|
binding = new CPPLabel( gotoStatement );
|
||||||
|
functionScope.addBinding( binding );
|
||||||
|
}
|
||||||
|
return binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IBinding createBinding( IASTLabelStatement labelStatement ) {
|
||||||
|
ICPPFunctionScope functionScope = (ICPPFunctionScope) getContainingScope( labelStatement );
|
||||||
|
IASTName name = labelStatement.getName();
|
||||||
|
IBinding binding = functionScope.getBinding( name );
|
||||||
|
if( binding == null ){
|
||||||
|
binding = new CPPLabel( labelStatement );
|
||||||
|
functionScope.addBinding( binding );
|
||||||
|
} else {
|
||||||
|
((CPPLabel)binding).setLabelStatement( labelStatement );
|
||||||
|
}
|
||||||
|
return binding;
|
||||||
|
}
|
||||||
|
|
||||||
private static IBinding createBinding( IASTEnumerator enumerator ) {
|
private static IBinding createBinding( IASTEnumerator enumerator ) {
|
||||||
ICPPScope scope = (ICPPScope) getContainingScope( enumerator );
|
ICPPScope scope = (ICPPScope) getContainingScope( enumerator );
|
||||||
IBinding enumtor = scope.getBinding( enumerator.getName() );
|
IBinding enumtor = scope.getBinding( enumerator.getName() );
|
||||||
|
@ -395,7 +424,7 @@ public class CPPVisitor {
|
||||||
|
|
||||||
if( statement instanceof IASTGotoStatement || statement instanceof IASTLabelStatement ){
|
if( statement instanceof IASTGotoStatement || statement instanceof IASTLabelStatement ){
|
||||||
//labels have function scope
|
//labels have function scope
|
||||||
while( scope != null && !(scope instanceof ICFunctionScope) ){
|
while( scope != null && !(scope instanceof ICPPFunctionScope) ){
|
||||||
scope = scope.getParent();
|
scope = scope.getParent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue