From afeb157d1f229a0e4f8d3d42a950694874cbb1f3 Mon Sep 17 00:00:00 2001 From: Andrew Niefer Date: Thu, 18 Nov 2004 16:33:04 +0000 Subject: [PATCH] Bindings for ILabels, more general visitor, Scope interfaces for C --- .../cdt/core/parser/tests/ast2/AST2Tests.java | 42 ++++ .../cdt/core/dom/ast/c/ICBlockScope.java | 24 ++ .../cdt/core/dom/ast/c/ICFileScope.java | 24 ++ .../dom/ast/c/ICFunctionPrototypeScope.java | 24 ++ .../cdt/core/dom/ast/c/ICFunctionScope.java | 24 ++ .../core/parser2/c/CASTTranslationUnit.java | 5 +- .../CFileScope.java} | 5 +- .../internal/core/parser2/c/CFunction.java | 20 +- .../core/parser2/c/CFunctionScope.java | 37 ++- .../cdt/internal/core/parser2/c/CLabel.java | 53 +++++ .../internal/core/parser2/c/CStructure.java | 22 +- .../cdt/internal/core/parser2/c/CVisitor.java | 222 +++++++++++++----- .../core/parser2/c/GNUCSourceParser.java | 1 + 13 files changed, 420 insertions(+), 83 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICBlockScope.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICFileScope.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICFunctionPrototypeScope.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICFunctionScope.java rename core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/{CompilationUnit.java => c/CFileScope.java} (85%) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CLabel.java diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java index ef6e38c401c..463a68df86f 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java @@ -10,6 +10,7 @@ **********************************************************************/ package org.eclipse.cdt.core.parser.tests.ast2; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -45,6 +46,7 @@ import org.eclipse.cdt.core.dom.ast.IASTUnaryTypeIdExpression; import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IFunction; +import org.eclipse.cdt.core.dom.ast.ILabel; import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.ITypedef; @@ -815,4 +817,44 @@ public class AST2Tests extends TestCase { assertNotNull( x1 ); assertSame( x1, x2 ); } + + static class NameCollector extends CVisitor.BaseVisitorAction { + { + processNames = true; + } + public List nameList = new ArrayList(); + public boolean processName( IASTName name ){ + nameList.add( name ); + return true; + } + public IASTName getName( int idx ){ + if( idx < 0 || idx >= nameList.size() ) + return null; + return (IASTName) nameList.get( idx ); + } + public int size() { return nameList.size(); } + } + public void testLabels() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("void f() { \n"); //$NON-NLS-1$ + buffer.append(" while( 1 ) { \n"); //$NON-NLS-1$ + buffer.append(" if( 1 ) \n"); //$NON-NLS-1$ + buffer.append(" goto end; \n"); //$NON-NLS-1$ + buffer.append(" } \n"); //$NON-NLS-1$ + buffer.append(" end: ; \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(), 3 ); + IFunction function = (IFunction) collector.getName( 0 ).resolveBinding(); + ILabel label_1 = (ILabel) collector.getName( 1 ).resolveBinding(); + ILabel label_2 = (ILabel) collector.getName( 2 ).resolveBinding(); + assertNotNull( function ); + assertNotNull( label_1 ); + assertEquals( label_1, label_2 ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICBlockScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICBlockScope.java new file mode 100644 index 00000000000..c82330ad0d4 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICBlockScope.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * 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 Nov 17, 2004 + */ +package org.eclipse.cdt.core.dom.ast.c; + +import org.eclipse.cdt.core.dom.ast.IScope; + +/** + * @author aniefer + */ +public interface ICBlockScope extends IScope { + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICFileScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICFileScope.java new file mode 100644 index 00000000000..2d2d381657a --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICFileScope.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * 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 Nov 17, 2004 + */ +package org.eclipse.cdt.core.dom.ast.c; + +import org.eclipse.cdt.core.dom.ast.IScope; + +/** + * @author aniefer + */ +public interface ICFileScope extends IScope { + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICFunctionPrototypeScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICFunctionPrototypeScope.java new file mode 100644 index 00000000000..b78316f3459 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICFunctionPrototypeScope.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * 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 Nov 17, 2004 + */ +package org.eclipse.cdt.core.dom.ast.c; + +import org.eclipse.cdt.core.dom.ast.IScope; + +/** + * @author aniefer + */ +public interface ICFunctionPrototypeScope extends IScope { + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICFunctionScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICFunctionScope.java new file mode 100644 index 00000000000..95b3842a8a6 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/c/ICFunctionScope.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * 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 Nov 17, 2004 + */ +package org.eclipse.cdt.core.dom.ast.c; + +import org.eclipse.cdt.core.dom.ast.IScope; + +/** + * @author aniefer + */ +public interface ICFunctionScope extends IScope { + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CASTTranslationUnit.java index 79a15161502..54c4e84ab7d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CASTTranslationUnit.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CASTTranslationUnit.java @@ -17,7 +17,6 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IScope; -import org.eclipse.cdt.internal.core.parser2.CompilationUnit; /** * @author jcamelon @@ -30,7 +29,7 @@ public class CASTTranslationUnit extends CASTNode implements IASTTranslationUnit private int currentIndex = 0; //Binding - private CompilationUnit compilationUnit = null; + private CFileScope compilationUnit = null; public void addDeclaration( IASTDeclaration d ) { @@ -81,7 +80,7 @@ public class CASTTranslationUnit extends CASTNode implements IASTTranslationUnit */ public IScope getScope() { if( compilationUnit == null ) - compilationUnit = new CompilationUnit(); + compilationUnit = new CFileScope(); return compilationUnit; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/CompilationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CFileScope.java similarity index 85% rename from core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/CompilationUnit.java rename to core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CFileScope.java index 9a1283529bd..b979216d9b8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/CompilationUnit.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CFileScope.java @@ -8,16 +8,17 @@ * Contributors: * IBM Rational Software - Initial API and implementation **********************************************************************/ -package org.eclipse.cdt.internal.core.parser2; +package org.eclipse.cdt.internal.core.parser2.c; import java.util.List; import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.c.ICFileScope; /** * @author aniefer */ -public class CompilationUnit implements IScope { +public class CFileScope implements ICFileScope{ /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IScope#getParent() diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CFunction.java index d65059cde53..538db97153d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CFunction.java @@ -35,16 +35,16 @@ public class CFunction implements IFunction { this.functionScope = new CFunctionScope( this ); } - private IASTFunctionDeclarator checkForDefinition( IASTFunctionDeclarator declarator ){ - if( declarator.getParent() instanceof IASTFunctionDefinition ) - return declarator; + private IASTFunctionDeclarator checkForDefinition( IASTFunctionDeclarator dtor ){ + if( dtor.getParent() instanceof IASTFunctionDefinition ) + return dtor; - IASTFunctionDeclarator decl = CVisitor.findDefinition( declarator ); - if( decl != null && decl != declarator ){ - declarator = decl; - ((CASTName)declarator.getName()).setBinding( this ); + IASTFunctionDeclarator def = CVisitor.findDefinition( dtor ); + if( def != null && def != dtor ){ + dtor = def; + ((CASTName)dtor.getName()).setBinding( this ); } - return declarator; + return dtor; } /* (non-Javadoc) @@ -83,4 +83,8 @@ public class CFunction implements IFunction { public IScope getFunctionScope() { return functionScope; } + + public IASTDeclaration getDeclaration(){ + return (IASTDeclaration) declarator.getParent(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CFunctionScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CFunctionScope.java index 44e2076ec42..a0053e9f468 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CFunctionScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CFunctionScope.java @@ -11,15 +11,21 @@ **********************************************************************/ package org.eclipse.cdt.internal.core.parser2.c; +import java.util.ArrayList; import java.util.List; +import org.eclipse.cdt.core.dom.ast.IASTLabelStatement; +import org.eclipse.cdt.core.dom.ast.IASTStatement; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.c.ICFunctionScope; +import org.eclipse.cdt.internal.core.parser2.c.CVisitor.BaseVisitorAction; /** * Created on Nov 8, 2004 * @author aniefer */ -public class CFunctionScope implements IScope { +public class CFunctionScope implements ICFunctionScope { private final CFunction function; public CFunctionScope( CFunction function ){ @@ -40,4 +46,33 @@ public class CFunctionScope implements IScope { return null; } + public List getLabels(){ + FindLabelsAction action = new FindLabelsAction(); + CVisitor.visitDeclaration( function.getDeclaration(), action ); + + List bindings = new ArrayList(); + for( int i = 0; i < action.labels.size(); i++ ){ + IASTLabelStatement labelStatement = (IASTLabelStatement) action.labels.get(i); + IBinding binding = labelStatement.getName().resolveBinding(); + if( binding != null ) + bindings.add( binding ); + } + return bindings; + } + + static private class FindLabelsAction extends BaseVisitorAction { + public List labels = new ArrayList(); + public boolean ambiguous = false; + + public FindLabelsAction(){ + processStatements = true; + } + + public boolean processStatement( IASTStatement statement ) { + if( statement instanceof IASTLabelStatement ){ + labels.add( statement ); + } + return true; + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CLabel.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CLabel.java new file mode 100644 index 00000000000..927267758e8 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CLabel.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * 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 Nov 17, 2004 + */ +package org.eclipse.cdt.internal.core.parser2.c; + +import org.eclipse.cdt.core.dom.ast.IASTLabelStatement; +import org.eclipse.cdt.core.dom.ast.ILabel; +import org.eclipse.cdt.core.dom.ast.IScope; + +/** + * @author aniefer + */ +public class CLabel implements ILabel { + + private final IASTLabelStatement labelStatement; + + public CLabel( IASTLabelStatement statement ){ + labelStatement = statement; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.ILabel#getLabelStatement() + */ + public IASTLabelStatement getLabelStatement() { + return labelStatement; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getName() + */ + public String getName() { + return labelStatement.getName().toString(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() + */ + public IScope getScope() { + return CVisitor.getContainingScope( labelStatement ); + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CStructure.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CStructure.java index 54c5ea0df11..f4af8ec6a1d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CStructure.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CStructure.java @@ -30,11 +30,11 @@ import org.eclipse.cdt.core.dom.ast.c.ICASTElaboratedTypeSpecifier; * @author aniefer */ public class CStructure implements ICompositeType { - final private IASTDeclSpecifier declSpec; + final private IASTDeclSpecifier declSpecifier; public CStructure( IASTDeclSpecifier declSpec ){ declSpec = checkForDefinition( declSpec ); - this.declSpec = declSpec; + this.declSpecifier = declSpec; } private IASTDeclSpecifier checkForDefinition( IASTDeclSpecifier declSpec ){ @@ -54,10 +54,10 @@ public class CStructure implements ICompositeType { * @see org.eclipse.cdt.core.dom.ast.IBinding#getName() */ public String getName() { - if( declSpec instanceof ICASTCompositeTypeSpecifier ) - return ((ICASTCompositeTypeSpecifier)declSpec).getName().toString(); - else if( declSpec instanceof ICASTElaboratedTypeSpecifier ) - return ((ICASTElaboratedTypeSpecifier)declSpec).getName().toString(); + if( declSpecifier instanceof ICASTCompositeTypeSpecifier ) + return ((ICASTCompositeTypeSpecifier)declSpecifier).getName().toString(); + else if( declSpecifier instanceof ICASTElaboratedTypeSpecifier ) + return ((ICASTElaboratedTypeSpecifier)declSpecifier).getName().toString(); return ""; //$NON-NLS-1$ } @@ -66,19 +66,19 @@ public class CStructure implements ICompositeType { * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() */ public IScope getScope() { - return CVisitor.getContainingScope( declSpec ); + return CVisitor.getContainingScope( declSpecifier ); } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.ICompositeType#getFields() */ public List getFields() { - if( !( declSpec instanceof ICASTCompositeTypeSpecifier ) ){ + if( !( declSpecifier instanceof ICASTCompositeTypeSpecifier ) ){ //error return null; } - ICASTCompositeTypeSpecifier compositeTypeSpec = (ICASTCompositeTypeSpecifier) declSpec; + ICASTCompositeTypeSpecifier compositeTypeSpec = (ICASTCompositeTypeSpecifier) declSpecifier; List members = compositeTypeSpec.getMembers(); int size = members.size(); List fields = new ArrayList( size ); @@ -105,12 +105,12 @@ public class CStructure implements ICompositeType { * @see org.eclipse.cdt.core.dom.ast.ICompositeType#findField(org.eclipse.cdt.core.dom.ast.IASTName) */ public IField findField(String name) { - if( !( declSpec instanceof ICASTCompositeTypeSpecifier ) ){ + if( !( declSpecifier instanceof ICASTCompositeTypeSpecifier ) ){ //error return null; } - ICASTCompositeTypeSpecifier compositeTypeSpec = (ICASTCompositeTypeSpecifier) declSpec; + ICASTCompositeTypeSpecifier compositeTypeSpec = (ICASTCompositeTypeSpecifier) declSpecifier; List members = compositeTypeSpec.getMembers(); int size = members.size(); if( size > 0 ){ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CVisitor.java index e9a7ca2ebc5..a80d52f1f8d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CVisitor.java @@ -51,6 +51,7 @@ import org.eclipse.cdt.core.dom.ast.IASTWhileStatement; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ICompositeType; 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.ITypedef; import org.eclipse.cdt.core.dom.ast.IVariable; @@ -58,6 +59,7 @@ import org.eclipse.cdt.core.dom.ast.c.ICASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICASTTypeIdInitializerExpression; import org.eclipse.cdt.core.dom.ast.c.ICASTTypedefNameSpecifier; +import org.eclipse.cdt.core.dom.ast.c.ICFunctionScope; import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression; import org.eclipse.cdt.core.parser.util.CharArrayUtils; @@ -66,7 +68,40 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils; * @author aniefer */ public class CVisitor { + public static abstract class BaseVisitorAction { + public boolean processNames = false; + public boolean processDeclarations = false; + public boolean processParameterDeclarations = false; + public boolean processDeclarators = false; + public boolean processDeclSpecifiers = false; + public boolean processExpressions = false; + public boolean processStatements = false; + public boolean processTypeIds = false; + + /** + * @return true to continue visiting, return false to stop + */ + public boolean processName( IASTName name ) { return true; } + public boolean processDeclaration( IASTDeclaration declaration ){ return true; } + public boolean processParameterDeclaration( IASTParameterDeclaration parameterDeclaration ) { return true; } + public boolean processDeclarator( IASTDeclarator declarator ) { return true; } + public boolean processDeclSpecifier( IASTDeclSpecifier declSpec ){return true; } + public boolean processExpression( IASTExpression expression ) { return true; } + public boolean processStatement( IASTStatement statement ) { return true; } + public boolean processTypeId( IASTTypeId typeId ) { return true; } + } + public static class ClearBindingAction extends BaseVisitorAction { + { + processNames = true; + } + public boolean processName(IASTName name) { + ((CASTName) name ).setBinding( null ); + return true; + } + } + + //Scopes private static final int COMPLETE = 1; private static final int CURRENT_SCOPE = 2; @@ -80,16 +115,39 @@ public class CVisitor { binding = resolveBinding( parent ); } else if( parent instanceof IASTFieldReference ){ binding = findBinding( (IASTFieldReference) parent ); - } else if( parent instanceof CASTDeclarator ){ - binding = createBinding( (CASTDeclarator) parent, name ); - } else if( parent instanceof CASTCompositeTypeSpecifier ){ - binding = createBinding( (CASTCompositeTypeSpecifier) parent ); + } else if( parent instanceof IASTDeclarator ){ + binding = createBinding( (IASTDeclarator) parent, name ); + } else if( parent instanceof ICASTCompositeTypeSpecifier ){ + binding = createBinding( (ICASTCompositeTypeSpecifier) parent ); } else if( parent instanceof ICASTElaboratedTypeSpecifier ){ binding = createBinding( (ICASTElaboratedTypeSpecifier) parent ); + } else if( parent instanceof IASTStatement ){ + binding = createBinding ( (IASTStatement) parent ); } name.setBinding( binding ); } + private static IBinding createBinding( IASTStatement statement ){ + if( statement instanceof IASTGotoStatement ){ + IScope scope = getContainingScope( statement ); + while( scope != null && !( scope instanceof ICFunctionScope) ){ + scope = scope.getParent(); + } + if( scope != null && scope instanceof ICFunctionScope ){ + CFunctionScope functionScope = (CFunctionScope) scope; + List labels = functionScope.getLabels(); + for( int i = 0; i < labels.size(); i++ ){ + ILabel label = (ILabel) labels.get(i); + if( label.getName().equals( ((IASTGotoStatement)statement).getName().toString() ) ){ + return label; + } + } + } + } else if( statement instanceof IASTLabelStatement ){ + return new CLabel( (IASTLabelStatement) statement ); + } + return null; + } private static IBinding createBinding( ICASTElaboratedTypeSpecifier elabTypeSpec ){ IASTNode parent = elabTypeSpec.getParent(); if( parent instanceof IASTSimpleDeclaration ){ @@ -253,7 +311,7 @@ public class CVisitor { public static IScope getContainingScope( IASTStatement statement ){ IASTNode parent = statement.getParent(); - if( parent instanceof IASTCompoundStatement ){ + if( parent instanceof IASTStatement ){ return getContainingScope( (IASTStatement)parent ); } else if( parent instanceof IASTFunctionDefinition ){ IASTFunctionDeclarator fnDeclarator = ((IASTFunctionDefinition) parent ).getDeclarator(); @@ -463,31 +521,49 @@ public class CVisitor { } public static void clearBindings( IASTTranslationUnit tu ){ + visitTranslationUnit( tu, new ClearBindingAction() ); + } + + public static void visitTranslationUnit( IASTTranslationUnit tu, BaseVisitorAction action ){ List decls = tu.getDeclarations(); for( int i = 0; i < decls.size(); i++ ){ - clearBindings( (IASTDeclaration) decls.get(i) ); + if( !visitDeclaration( (IASTDeclaration) decls.get(i), action ) ) return; } } - private static void clearBindings( IASTDeclaration declaration ){ + + public static boolean visitName( IASTName name, BaseVisitorAction action ){ + if( action.processNames ) + return action.processName( name ); + return true; + } + + public static boolean visitDeclaration( IASTDeclaration declaration, BaseVisitorAction action ){ + if( action.processDeclarations ) + if( !action.processDeclaration( declaration ) ) return false; + if( declaration instanceof IASTSimpleDeclaration ){ IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) declaration; - clearBindings( simpleDecl.getDeclSpecifier() ); + if( !visitDeclSpecifier( simpleDecl.getDeclSpecifier(), action ) ) return false; List list = simpleDecl.getDeclarators(); for( int i = 0; i < list.size(); i++ ){ - clearBindings( (IASTDeclarator) list.get(i) ); + if( !visitDeclarator( (IASTDeclarator) list.get(i), action ) ) return false; } } else if( declaration instanceof IASTFunctionDefinition ){ IASTFunctionDefinition fnDef = (IASTFunctionDefinition) declaration; - clearBindings( fnDef.getDeclSpecifier() ); - clearBindings( fnDef.getDeclarator() ); - clearBindings( fnDef.getBody() ); + if( !visitDeclSpecifier( fnDef.getDeclSpecifier(), action ) ) return false; + if( !visitDeclarator( fnDef.getDeclarator(), action ) ) return false; + if( !visitStatement( fnDef.getBody(), action ) ) return false; } + return true; } - private static void clearBindings( IASTDeclarator declarator ){ - ((CASTName)declarator.getName()).setBinding( null ); + public static boolean visitDeclarator( IASTDeclarator declarator, BaseVisitorAction action ){ + if( action.processDeclarators ) + if( !action.processDeclarator( declarator ) ) return false; + + if( !visitName( declarator.getName(), action ) ) return false; if( declarator.getNestedDeclarator() != null ) - clearBindings( declarator.getNestedDeclarator() ); + if( !visitDeclarator( declarator.getNestedDeclarator(), action ) ) return false; //TODO: if( declarator.getInitializer() != null ) @@ -495,94 +571,124 @@ public class CVisitor { List list = ((IASTFunctionDeclarator)declarator).getParameters(); for( int i = 0; i < list.size(); i++ ){ IASTParameterDeclaration param = (IASTParameterDeclaration) list.get(i); - clearBindings( param.getDeclarator() ); + if( !visitDeclarator( param.getDeclarator(), action ) ) return false; } } + return true; } - private static void clearBindings( IASTDeclSpecifier declSpec ){ + public static boolean visitParameterDeclaration( IASTParameterDeclaration parameterDeclaration, BaseVisitorAction action ){ + if( action.processParameterDeclarations ) + if( !action.processParameterDeclaration( parameterDeclaration ) ) return false; + + if( !visitDeclSpecifier( parameterDeclaration.getDeclSpecifier(), action ) ) return false; + if( !visitDeclarator( parameterDeclaration.getDeclarator(), action ) ) return false; + return true; + } + + public static boolean visitDeclSpecifier( IASTDeclSpecifier declSpec, BaseVisitorAction action ){ + if( action.processDeclSpecifiers ) + if( !action.processDeclSpecifier( declSpec ) ) return false; + if( declSpec instanceof ICASTCompositeTypeSpecifier ){ ICASTCompositeTypeSpecifier compTypeSpec = (ICASTCompositeTypeSpecifier) declSpec; - ((CASTName) compTypeSpec.getName()).setBinding( null ); + if( !visitName( compTypeSpec.getName(), action ) ) return false; List list = compTypeSpec.getMembers(); for( int i = 0; i < list.size(); i++ ){ - clearBindings( (IASTDeclaration) list.get(i) ); + if( !visitDeclaration( (IASTDeclaration) list.get(i), action ) ) return false; } + } else if( declSpec instanceof ICASTElaboratedTypeSpecifier ){ + if( !visitName( ((ICASTElaboratedTypeSpecifier) declSpec).getName(), action ) ) return false; + } else if( declSpec instanceof ICASTTypedefNameSpecifier ){ + if( !visitName( ((ICASTTypedefNameSpecifier) declSpec).getName(), action ) ) return false; } + return true; } - private static void clearBindings( IASTStatement statement ){ + public static boolean visitStatement( IASTStatement statement, BaseVisitorAction action ){ + if( action.processStatements ) + if( !action.processStatement( statement ) ) return false; + if( statement instanceof IASTCompoundStatement ){ List list = ((IASTCompoundStatement) statement).getStatements(); for( int i = 0; i < list.size(); i++ ){ - clearBindings( (IASTStatement) list.get(i) ); + if( !visitStatement( (IASTStatement) list.get(i), action ) ) return false; } } else if( statement instanceof IASTDeclarationStatement ){ - clearBindings( ((IASTDeclarationStatement)statement).getDeclaration() ); + if( !visitDeclaration( ((IASTDeclarationStatement)statement).getDeclaration(), action ) ) return false; } else if( statement instanceof IASTExpressionStatement ){ - clearBindings( ((IASTExpressionStatement)statement).getExpression() ); + if( !visitExpression( ((IASTExpressionStatement)statement).getExpression(), action ) ) return false; } else if( statement instanceof IASTCaseStatement ){ - clearBindings( ((IASTCaseStatement)statement).getExpression() ); + if( !visitExpression( ((IASTCaseStatement)statement).getExpression(), action ) ) return false; } else if( statement instanceof IASTDoStatement ){ - clearBindings( ((IASTDoStatement)statement).getBody() ); + if( !visitStatement( ((IASTDoStatement)statement).getBody(), action ) ) return false; } else if( statement instanceof IASTGotoStatement ){ - ((CASTName) ((IASTGotoStatement)statement).getName()).setBinding( null ); + if( !visitName( ((IASTGotoStatement)statement).getName(), action ) ) return false; } else if( statement instanceof IASTIfStatement ){ - clearBindings( ((IASTIfStatement) statement ).getCondition() ); - clearBindings( ((IASTIfStatement) statement ).getThenClause() ); - clearBindings( ((IASTIfStatement) statement ).getElseClause() ); + if( !visitExpression( ((IASTIfStatement) statement ).getCondition(), action ) ) return false; + if( !visitStatement( ((IASTIfStatement) statement ).getThenClause(), action ) ) return false; + if( !visitStatement( ((IASTIfStatement) statement ).getElseClause(), action ) ) return false; } else if( statement instanceof IASTLabelStatement ){ - ((CASTName) ((IASTLabelStatement)statement).getName()).setBinding( null ); + if( !visitName( ((IASTLabelStatement)statement).getName(), action ) ) return false; } else if( statement instanceof IASTReturnStatement ){ - clearBindings( ((IASTReturnStatement) statement ).getReturnValue() ); + if( !visitExpression( ((IASTReturnStatement) statement ).getReturnValue(), action ) ) return false; } else if( statement instanceof IASTSwitchStatement ){ - clearBindings( ((IASTSwitchStatement) statement ).getController() ); - clearBindings( ((IASTSwitchStatement) statement ).getBody() ); + if( !visitExpression( ((IASTSwitchStatement) statement ).getController(), action ) ) return false; + if( !visitStatement( ((IASTSwitchStatement) statement ).getBody(), action ) ) return false; } else if( statement instanceof IASTWhileStatement ){ - clearBindings( ((IASTWhileStatement) statement ).getCondition() ); - clearBindings( ((IASTWhileStatement) statement ).getBody() ); + if( !visitExpression( ((IASTWhileStatement) statement ).getCondition(), action ) ) return false; + if( !visitStatement( ((IASTWhileStatement) statement ).getBody(), action ) ) return false; } + return true; } - private static void clearBindings( IASTTypeId typeId ){ - clearBindings( typeId.getAbstractDeclarator() ); - clearBindings( typeId.getDeclSpecifier() ); + public static boolean visitTypeId( IASTTypeId typeId, BaseVisitorAction action ){ + if( action.processTypeIds ) + if( !action.processTypeId( typeId ) ) return false; + + if( !visitDeclarator( typeId.getAbstractDeclarator(), action ) ) return false; + if( !visitDeclSpecifier( typeId.getDeclSpecifier(), action ) ) return false; + return true; } - private static void clearBindings( IASTExpression expression ){ + public static boolean visitExpression( IASTExpression expression, BaseVisitorAction action ){ + if( action.processExpressions ) + if( !action.processExpression( expression ) ) return false; + if( expression instanceof IASTArraySubscriptExpression ){ - clearBindings( ((IASTArraySubscriptExpression)expression).getArrayExpression() ); - clearBindings( ((IASTArraySubscriptExpression)expression).getSubscriptExpression() ); + if( !visitExpression( ((IASTArraySubscriptExpression)expression).getArrayExpression(), action ) ) return false; + if( !visitExpression( ((IASTArraySubscriptExpression)expression).getSubscriptExpression(), action ) ) return false; } else if( expression instanceof IASTBinaryExpression ){ - clearBindings( ((IASTBinaryExpression)expression).getOperand1() ); - clearBindings( ((IASTBinaryExpression)expression).getOperand2() ); + if( !visitExpression( ((IASTBinaryExpression)expression).getOperand1(), action ) ) return false; + if( !visitExpression( ((IASTBinaryExpression)expression).getOperand2(), action ) ) return false; } else if( expression instanceof IASTConditionalExpression){ - clearBindings( ((IASTConditionalExpression)expression).getLogicalConditionExpression() ); - clearBindings( ((IASTConditionalExpression)expression).getNegativeResultExpression() ); - clearBindings( ((IASTConditionalExpression)expression).getPositiveResultExpression() ); + if( !visitExpression( ((IASTConditionalExpression)expression).getLogicalConditionExpression(), action ) ) return false; + if( !visitExpression( ((IASTConditionalExpression)expression).getNegativeResultExpression(), action ) ) return false; + if( !visitExpression( ((IASTConditionalExpression)expression).getPositiveResultExpression(), action ) ) return false; } else if( expression instanceof IASTExpressionList ){ List list = ((IASTExpressionList)expression).getExpressions(); for( int i = 0; i < list.size(); i++){ - clearBindings( (IASTExpression) list.get(i) ); + if( !visitExpression( (IASTExpression) list.get(i), action ) ) return false; } } else if( expression instanceof IASTFieldReference ){ - clearBindings( ((IASTFieldReference)expression).getFieldOwner() ); - ((CASTName) ((IASTFieldReference)expression).getFieldName()).setBinding( null ); + if( !visitExpression( ((IASTFieldReference)expression).getFieldOwner(), action ) ) return false; + if( !visitName( ((IASTFieldReference)expression).getFieldName(), action ) ) return false; } else if( expression instanceof IASTFunctionCallExpression ){ - clearBindings( ((IASTFunctionCallExpression)expression).getFunctionNameExpression() ); - clearBindings( ((IASTFunctionCallExpression)expression).getParameterExpression() ); + if( !visitExpression( ((IASTFunctionCallExpression)expression).getFunctionNameExpression(), action ) ) return false; + if( !visitExpression( ((IASTFunctionCallExpression)expression).getParameterExpression(), action ) ) return false; } else if( expression instanceof IASTIdExpression ){ - ((CASTName) ((IASTIdExpression)expression).getName()).setBinding( null ); + if( !visitName( ((IASTIdExpression)expression).getName(), action ) ) return false; } else if( expression instanceof IASTTypeIdExpression ){ - clearBindings( ((IASTTypeIdExpression)expression).getTypeId() ); + if( !visitTypeId( ((IASTTypeIdExpression)expression).getTypeId(), action ) ) return false; } else if( expression instanceof IASTUnaryExpression ){ - clearBindings( ((IASTUnaryExpression)expression).getOperand() ); + if( !visitExpression( ((IASTUnaryExpression)expression).getOperand(), action ) ) return false; } else if( expression instanceof IASTUnaryTypeIdExpression ){ - clearBindings( ((IASTUnaryTypeIdExpression)expression).getOperand() ); - clearBindings( ((IASTUnaryTypeIdExpression)expression).getTypeId() ); + if( !visitExpression( ((IASTUnaryTypeIdExpression)expression).getOperand(), action ) ) return false; + if( !visitTypeId( ((IASTUnaryTypeIdExpression)expression).getTypeId(), action ) ) return false; } else if( expression instanceof ICASTTypeIdInitializerExpression ){ - clearBindings( ((ICASTTypeIdInitializerExpression)expression).getTypeId() ); + if( !visitTypeId( ((ICASTTypeIdInitializerExpression)expression).getTypeId(), action ) ) return false; //TODO: ((ICASTTypeIdInitializerExpression)expression).getInitializer(); } else if( expression instanceof IGNUASTCompoundStatementExpression ){ - clearBindings( ((IGNUASTCompoundStatementExpression)expression).getCompoundStatement() ); + if( !visitStatement( ((IGNUASTCompoundStatementExpression)expression).getCompoundStatement(), action ) ) return false; } + return true; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/GNUCSourceParser.java index 52f6acf1b4b..ce2b3333153 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/GNUCSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/GNUCSourceParser.java @@ -1165,6 +1165,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { while_statement.setBody( while_body ); while_condition.setParent( while_statement ); while_condition.setPropertyInParent( IASTWhileStatement.BODY ); + while_body.setParent( while_statement ); return while_statement; case IToken.t_do: startOffset = consume(IToken.t_do).getOffset();