mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-25 18:05:33 +02:00
Parser2 : fixed some stuff, added some more stuff
(visit initializers, add a kind of tag namespace for resolving structs)
This commit is contained in:
parent
bf7b23eb9e
commit
d72d34cf02
3 changed files with 153 additions and 25 deletions
|
@ -615,6 +615,39 @@ public class AST2Tests extends TestCase {
|
|||
assertSame( structA_3, structA_4 );
|
||||
}
|
||||
|
||||
public void testStructureNamespace() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append( "struct x {}; \n" ); //$NON-NLS-1$
|
||||
buffer.append( "void f( int x ) { \n" ); //$NON-NLS-1$
|
||||
buffer.append( " struct x i; \n" ); //$NON-NLS-1$
|
||||
buffer.append( "} \n" ); //$NON-NLS-1$
|
||||
|
||||
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C );
|
||||
|
||||
IASTSimpleDeclaration declaration = (IASTSimpleDeclaration) tu.getDeclarations().get(0);
|
||||
IASTCompositeTypeSpecifier typeSpec = (IASTCompositeTypeSpecifier) declaration.getDeclSpecifier();
|
||||
IASTName x_1 = typeSpec.getName();
|
||||
|
||||
IASTFunctionDefinition fdef = (IASTFunctionDefinition) tu.getDeclarations().get(1);
|
||||
IASTParameterDeclaration param = (IASTParameterDeclaration) fdef.getDeclarator().getParameters().get(0);
|
||||
IASTName x_2 = param.getDeclarator().getName();
|
||||
|
||||
IASTCompoundStatement compound = (IASTCompoundStatement) fdef.getBody();
|
||||
IASTDeclarationStatement declStatement = (IASTDeclarationStatement) compound.getStatements().get(0);
|
||||
declaration = (IASTSimpleDeclaration) declStatement.getDeclaration();
|
||||
IASTElaboratedTypeSpecifier elab = (IASTElaboratedTypeSpecifier) declaration.getDeclSpecifier();
|
||||
IASTName x_3 = elab.getName();
|
||||
|
||||
ICompositeType x1 = (ICompositeType) x_1.resolveBinding();
|
||||
IVariable x2 = (IVariable) x_2.resolveBinding();
|
||||
ICompositeType x3 = (ICompositeType) x_3.resolveBinding();
|
||||
|
||||
assertNotNull( x1 );
|
||||
assertNotNull( x2 );
|
||||
assertSame( x1, x3 );
|
||||
assertNotSame( x2, x3 );
|
||||
|
||||
}
|
||||
public void testFunctionParameters() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append( "void f( int a ); \n"); //$NON-NLS-1$
|
||||
|
@ -911,6 +944,66 @@ public class AST2Tests extends TestCase {
|
|||
assertInstances( collector, vz, 3);
|
||||
assertInstances( collector, a, 4);
|
||||
assertInstances( collector, b, 2);
|
||||
assertInstances( collector, c, 3);
|
||||
assertInstances( collector, c, 4);
|
||||
}
|
||||
|
||||
public void testGCC20000205() throws Exception{
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append( "static int f( int a ) { \n"); //$NON-NLS-1$
|
||||
buffer.append( " if( a == 0 ) \n"); //$NON-NLS-1$
|
||||
buffer.append( " return 0; \n"); //$NON-NLS-1$
|
||||
buffer.append( " do \n"); //$NON-NLS-1$
|
||||
buffer.append( " if( a & 128 ) \n"); //$NON-NLS-1$
|
||||
buffer.append( " return 1; \n"); //$NON-NLS-1$
|
||||
buffer.append( " while( f(0) ); \n"); //$NON-NLS-1$
|
||||
buffer.append( " return 0; \n"); //$NON-NLS-1$
|
||||
buffer.append( "} \n"); //$NON-NLS-1$
|
||||
|
||||
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C );
|
||||
|
||||
NameCollector collector = new NameCollector();
|
||||
CVisitor.visitTranslationUnit( tu, collector );
|
||||
|
||||
assertEquals( collector.size(), 5 );
|
||||
IFunction f = (IFunction) collector.getName( 0 ).resolveBinding();
|
||||
IVariable a = (IVariable) collector.getName( 1 ).resolveBinding();
|
||||
|
||||
assertInstances( collector, f, 2 );
|
||||
assertInstances( collector, a, 3 );
|
||||
}
|
||||
|
||||
public void testGCC20000217() throws Exception{
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append( "unsigned short int showbug( unsigned short int * a, \n"); //$NON-NLS-1$
|
||||
buffer.append( " unsigned short int * b ) { \n"); //$NON-NLS-1$
|
||||
buffer.append( " *a += *b - 8; \n"); //$NON-NLS-1$
|
||||
buffer.append( " return (*a >= 8 ); \n"); //$NON-NLS-1$
|
||||
buffer.append( "} \n"); //$NON-NLS-1$
|
||||
buffer.append( "int main(){ \n"); //$NON-NLS-1$
|
||||
buffer.append( " unsigned short int x = 0; \n"); //$NON-NLS-1$
|
||||
buffer.append( " unsigned short int y = 10; \n"); //$NON-NLS-1$
|
||||
buffer.append( " if( showbug( &x, &y ) != 0 ) \n"); //$NON-NLS-1$
|
||||
buffer.append( " return -1; \n"); //$NON-NLS-1$
|
||||
buffer.append( " return 0; \n"); //$NON-NLS-1$
|
||||
buffer.append( "} \n"); //$NON-NLS-1$
|
||||
|
||||
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C );
|
||||
NameCollector collector = new NameCollector();
|
||||
CVisitor.visitTranslationUnit( tu, collector );
|
||||
|
||||
assertEquals( collector.size(), 12 );
|
||||
|
||||
IFunction showBug = (IFunction) collector.getName( 0 ).resolveBinding();
|
||||
IVariable a = (IVariable) collector.getName( 1 ).resolveBinding();
|
||||
IVariable b = (IVariable) collector.getName( 2 ).resolveBinding();
|
||||
IVariable x = (IVariable) collector.getName( 7 ).resolveBinding();
|
||||
IVariable y = (IVariable) collector.getName( 8 ).resolveBinding();
|
||||
|
||||
assertInstances( collector, showBug, 2 );
|
||||
assertInstances( collector, a, 3 );
|
||||
assertInstances( collector, b, 2 );
|
||||
assertInstances( collector, x, 2 );
|
||||
assertInstances( collector, y, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ public class CStructure implements ICompositeType {
|
|||
if( node instanceof IASTSimpleDeclaration ){
|
||||
List declarators = ((IASTSimpleDeclaration)node).getDeclarators();
|
||||
for( int j = 0; j < declarators.size(); j++ ){
|
||||
IASTDeclarator declarator = (IASTDeclarator) declarators.get(i);
|
||||
IASTDeclarator declarator = (IASTDeclarator) declarators.get(j);
|
||||
if( name.equals( declarator.getName().toString() ) ){
|
||||
IBinding binding = declarator.getName().resolveBinding();
|
||||
if( binding instanceof IField )
|
||||
|
|
|
@ -34,6 +34,9 @@ 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.IASTIfStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializerList;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
|
@ -71,6 +74,7 @@ public class CVisitor {
|
|||
public static abstract class BaseVisitorAction {
|
||||
public boolean processNames = false;
|
||||
public boolean processDeclarations = false;
|
||||
public boolean processInitializers = false;
|
||||
public boolean processParameterDeclarations = false;
|
||||
public boolean processDeclarators = false;
|
||||
public boolean processDeclSpecifiers = false;
|
||||
|
@ -83,6 +87,7 @@ public class CVisitor {
|
|||
*/
|
||||
public boolean processName( IASTName name ) { return true; }
|
||||
public boolean processDeclaration( IASTDeclaration declaration ){ return true; }
|
||||
public boolean processInitializer( IASTInitializer initializer ){ return true; }
|
||||
public boolean processParameterDeclaration( IASTParameterDeclaration parameterDeclaration ) { return true; }
|
||||
public boolean processDeclarator( IASTDeclarator declarator ) { return true; }
|
||||
public boolean processDeclSpecifier( IASTDeclSpecifier declSpec ){return true; }
|
||||
|
@ -101,10 +106,11 @@ public class CVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
//Scopes
|
||||
private static final int COMPLETE = 1;
|
||||
private static final int CURRENT_SCOPE = 2;
|
||||
|
||||
//lookup bits
|
||||
private static final int COMPLETE = 0;
|
||||
private static final int CURRENT_SCOPE = 1;
|
||||
private static final int TAGS = 2;
|
||||
|
||||
static protected void createBinding( CASTName name ){
|
||||
IBinding binding = null;
|
||||
IASTNode parent = name.getParent();
|
||||
|
@ -154,15 +160,15 @@ public class CVisitor {
|
|||
IASTSimpleDeclaration declaration = (IASTSimpleDeclaration) parent;
|
||||
if( declaration.getDeclarators().size() == 0 ){
|
||||
//forward declaration
|
||||
IBinding binding = resolveBinding( elabTypeSpec, CURRENT_SCOPE );
|
||||
IBinding binding = resolveBinding( elabTypeSpec, CURRENT_SCOPE | TAGS );
|
||||
if( binding == null )
|
||||
binding = new CStructure( elabTypeSpec );
|
||||
return binding;
|
||||
}
|
||||
return resolveBinding( elabTypeSpec );
|
||||
return resolveBinding( elabTypeSpec, COMPLETE | TAGS );
|
||||
} else if( parent instanceof IASTTypeId ){
|
||||
IASTNode blockItem = getContainingBlockItem( parent );
|
||||
return findBinding( blockItem, (CASTName) elabTypeSpec.getName(), COMPLETE );
|
||||
return findBinding( blockItem, (CASTName) elabTypeSpec.getName(), COMPLETE | TAGS );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -245,25 +251,25 @@ public class CVisitor {
|
|||
protected static IBinding resolveBinding( IASTNode node ){
|
||||
return resolveBinding( node, COMPLETE );
|
||||
}
|
||||
protected static IBinding resolveBinding( IASTNode node, int scopeDepth ){
|
||||
protected static IBinding resolveBinding( IASTNode node, int bits ){
|
||||
if( node instanceof IASTFunctionDefinition ){
|
||||
IASTFunctionDefinition functionDef = (IASTFunctionDefinition) node;
|
||||
IASTFunctionDeclarator functionDeclartor = functionDef.getDeclarator();
|
||||
IASTName name = functionDeclartor.getName();
|
||||
IASTNode blockItem = getContainingBlockItem( node );
|
||||
return findBinding( blockItem, (CASTName) name, scopeDepth );
|
||||
return findBinding( blockItem, (CASTName) name, bits );
|
||||
} else if( node instanceof IASTIdExpression ){
|
||||
IASTNode blockItem = getContainingBlockItem( node );
|
||||
return findBinding( blockItem, (CASTName) ((IASTIdExpression)node).getName(), scopeDepth );
|
||||
return findBinding( blockItem, (CASTName) ((IASTIdExpression)node).getName(), bits );
|
||||
} else if( node instanceof ICASTTypedefNameSpecifier ){
|
||||
IASTNode blockItem = getContainingBlockItem( node );
|
||||
return findBinding( blockItem, (CASTName) ((ICASTTypedefNameSpecifier)node).getName(), scopeDepth );
|
||||
return findBinding( blockItem, (CASTName) ((ICASTTypedefNameSpecifier)node).getName(), bits );
|
||||
} else if( node instanceof ICASTElaboratedTypeSpecifier ){
|
||||
IASTNode blockItem = getContainingBlockItem( node );
|
||||
return findBinding( blockItem, (CASTName) ((ICASTElaboratedTypeSpecifier)node).getName(), scopeDepth );
|
||||
return findBinding( blockItem, (CASTName) ((ICASTElaboratedTypeSpecifier)node).getName(), bits );
|
||||
} else if( node instanceof ICASTCompositeTypeSpecifier ){
|
||||
IASTNode blockItem = getContainingBlockItem( node );
|
||||
return findBinding( blockItem, (CASTName) ((ICASTCompositeTypeSpecifier)node).getName(), scopeDepth );
|
||||
return findBinding( blockItem, (CASTName) ((ICASTCompositeTypeSpecifier)node).getName(), bits );
|
||||
} else if( node instanceof IASTParameterDeclaration ){
|
||||
IASTParameterDeclaration param = (IASTParameterDeclaration) node;
|
||||
IASTFunctionDeclarator fDtor = (IASTFunctionDeclarator) param.getParent();
|
||||
|
@ -361,7 +367,7 @@ public class CVisitor {
|
|||
return getContainingBlockItem( parent );
|
||||
}
|
||||
|
||||
protected static IBinding findBinding( IASTNode blockItem, CASTName name, int scopeDepth ){
|
||||
protected static IBinding findBinding( IASTNode blockItem, CASTName name, int bits ){
|
||||
IBinding binding = null;
|
||||
while( blockItem != null ){
|
||||
|
||||
|
@ -386,22 +392,34 @@ public class CVisitor {
|
|||
} else if( node instanceof IASTDeclaration ){
|
||||
binding = checkForBinding( (IASTDeclaration) node, name );
|
||||
}
|
||||
if( binding != null )
|
||||
return binding;
|
||||
if( binding != null ){
|
||||
if( (bits & TAGS) != 0 && !(binding instanceof ICompositeType) ||
|
||||
(bits & TAGS) == 0 && (binding instanceof ICompositeType) )
|
||||
{
|
||||
binding = null;
|
||||
} else {
|
||||
return binding;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//check the parent
|
||||
if( parent instanceof IASTDeclaration ){
|
||||
binding = checkForBinding( (IASTDeclaration) parent, name );
|
||||
if( binding != null )
|
||||
return binding;
|
||||
} else if( parent instanceof IASTStatement ){
|
||||
binding = checkForBinding( (IASTStatement) parent, name );
|
||||
if( binding != null )
|
||||
return binding;
|
||||
}
|
||||
if( binding != null ){
|
||||
if( (bits & TAGS) != 0 && !(binding instanceof ICompositeType) ||
|
||||
(bits & TAGS) == 0 && (binding instanceof ICompositeType) )
|
||||
{
|
||||
binding = null;
|
||||
} else {
|
||||
return binding;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( scopeDepth == COMPLETE )
|
||||
if( (bits & CURRENT_SCOPE) == 0 )
|
||||
blockItem = parent;
|
||||
else
|
||||
blockItem = null;
|
||||
|
@ -565,7 +583,8 @@ public class CVisitor {
|
|||
if( declarator.getNestedDeclarator() != null )
|
||||
if( !visitDeclarator( declarator.getNestedDeclarator(), action ) ) return false;
|
||||
|
||||
//TODO: if( declarator.getInitializer() != null )
|
||||
if( declarator.getInitializer() != null )
|
||||
if( !visitInitializer( declarator.getInitializer(), action ) ) return false;
|
||||
|
||||
if( declarator instanceof IASTFunctionDeclarator ){
|
||||
List list = ((IASTFunctionDeclarator)declarator).getParameters();
|
||||
|
@ -576,6 +595,21 @@ public class CVisitor {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean visitInitializer( IASTInitializer initializer, BaseVisitorAction action ){
|
||||
if( initializer == null )
|
||||
return true;
|
||||
if( action.processInitializers )
|
||||
if( !action.processInitializer( initializer ) ) return false;
|
||||
if( initializer instanceof IASTInitializerExpression ){
|
||||
if( !visitExpression( ((IASTInitializerExpression) initializer).getExpression(), action ) ) return false;
|
||||
} else if( initializer instanceof IASTInitializerList ){
|
||||
List list = ((IASTInitializerList) initializer).getInitializers();
|
||||
for( int i = 0; i < list.size(); i++ )
|
||||
if( !visitInitializer( (IASTInitializer) list.get(i), action ) ) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static boolean visitParameterDeclaration( IASTParameterDeclaration parameterDeclaration, BaseVisitorAction action ){
|
||||
if( action.processParameterDeclarations )
|
||||
if( !action.processParameterDeclaration( parameterDeclaration ) ) return false;
|
||||
|
@ -621,6 +655,7 @@ public class CVisitor {
|
|||
if( !visitExpression( ((IASTCaseStatement)statement).getExpression(), action ) ) return false;
|
||||
} else if( statement instanceof IASTDoStatement ){
|
||||
if( !visitStatement( ((IASTDoStatement)statement).getBody(), action ) ) return false;
|
||||
if( !visitExpression( ((IASTDoStatement)statement).getCondition(), action ) ) return false;
|
||||
} else if( statement instanceof IASTGotoStatement ){
|
||||
if( !visitName( ((IASTGotoStatement)statement).getName(), action ) ) return false;
|
||||
} else if( statement instanceof IASTIfStatement ){
|
||||
|
@ -684,7 +719,7 @@ public class CVisitor {
|
|||
if( !visitTypeId( ((IASTUnaryTypeIdExpression)expression).getTypeId(), action ) ) return false;
|
||||
} else if( expression instanceof ICASTTypeIdInitializerExpression ){
|
||||
if( !visitTypeId( ((ICASTTypeIdInitializerExpression)expression).getTypeId(), action ) ) return false;
|
||||
//TODO: ((ICASTTypeIdInitializerExpression)expression).getInitializer();
|
||||
if( !visitInitializer( ((ICASTTypeIdInitializerExpression)expression).getInitializer(), action ) ) return false;
|
||||
} else if( expression instanceof IGNUASTCompoundStatementExpression ){
|
||||
if( !visitStatement( ((IGNUASTCompoundStatementExpression)expression).getCompoundStatement(), action ) ) return false;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue