1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-01 06:05:24 +02:00

- fix up how we resolve function parameter bindings in C

This commit is contained in:
Andrew Niefer 2005-01-25 22:16:03 +00:00
parent ae4dff5290
commit 0a1793e33f
5 changed files with 212 additions and 151 deletions

View file

@ -46,7 +46,7 @@ import org.eclipse.cdt.core.dom.ast.c.ICBasicType;
import org.eclipse.cdt.core.dom.ast.c.ICScope;
import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.internal.core.dom.parser.c.CKnRParameter;
import org.eclipse.cdt.internal.core.dom.parser.c.CParameter;
import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
import org.eclipse.cdt.internal.core.dom.parser.c.ICBinding;
@ -215,6 +215,7 @@ public class AST2KnRTests extends AST2BaseTest {
IASTSimpleDeclaration isroot_decl = (IASTSimpleDeclaration)tu.getDeclarations()[1];
IASTFunctionDefinition isroot_def = (IASTFunctionDefinition)tu.getDeclarations()[2];
IASTName x0 = ((IASTStandardFunctionDeclarator)isroot_decl.getDeclarators()[0]).getParameters()[0].getDeclarator().getName();
IASTName x1 = ((ICASTKnRFunctionDeclarator)isroot_def.getDeclarator()).getParameterNames()[0];
IASTName x2 = ((IASTSimpleDeclaration)((ICASTKnRFunctionDeclarator)isroot_def.getDeclarator()).getParameterDeclarations()[0]).getDeclarators()[0].getName();
IASTName x3 = ((IASTIdExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)isroot_def.getBody()).getStatements()[0]).getReturnValue()).getOperand1()).getName();
@ -247,8 +248,9 @@ public class AST2KnRTests extends AST2BaseTest {
// test tu.getDeclarations(IBinding)
IASTName[] decls = tu.getDeclarations(x3.resolveBinding());
assertEquals( decls.length, 1 );
assertEquals( decls[0], x2 );
assertEquals( decls.length, 2 );
assertEquals( decls[0], x0 );
assertEquals( decls[1], x2 );
assertNotNull( ((ICScope)tu.getScope()).getBinding(ICScope.NAMESPACE_TYPE_OTHER, new String("c").toCharArray()) ); //$NON-NLS-1$
assertNotNull( ((ICScope)tu.getScope()).getBinding(ICScope.NAMESPACE_TYPE_OTHER, new String("isroot").toCharArray()) ); //$NON-NLS-1$
@ -484,6 +486,7 @@ public class AST2KnRTests extends AST2BaseTest {
IFunction f_fun1 = (IFunction)f_name1.resolveBinding();
assertEquals( f_name1.toString(), "f" ); //$NON-NLS-1$
assertEquals( f_decltor1.getParameters().length, 1 );
IASTName x0 = f_decltor1.getParameters()[0].getDeclarator().getName();
IASTName A_name2 = ((ICASTTypedefNameSpecifier)f_decltor1.getParameters()[0].getDeclSpecifier()).getName();
assertEquals( A_name2.toString(), "A" ); //$NON-NLS-1$
ITypedef A_var2 = (ITypedef)A_name2.resolveBinding();
@ -537,8 +540,9 @@ public class AST2KnRTests extends AST2BaseTest {
// test tu.getDeclarations(IBinding)
IASTName[] decls = tu.getDeclarations(x2.resolveBinding());
assertEquals( decls.length, 1 );
assertEquals( decls[0], x2 );
assertEquals( decls.length, 2 );
assertEquals( decls[0], x0 );
assertEquals( decls[1], x2 );
assertNotNull( ((ICScope)tu.getScope()).getBinding(ICScope.NAMESPACE_TYPE_TAG, new String("A_struct").toCharArray()) ); //$NON-NLS-1$
assertNotNull( ((ICScope)tu.getScope()).getBinding(ICScope.NAMESPACE_TYPE_OTHER, new String("A").toCharArray()) ); //$NON-NLS-1$
@ -603,8 +607,8 @@ public class AST2KnRTests extends AST2BaseTest {
IFunction f_fun = (IFunction)f_decltor.getName().resolveBinding();
IParameter [] f_parms = f_fun.getParameters();
assertEquals( f_parms.length, 2 );
assertEquals( ((CKnRParameter)f_parms[0]).getName(), "a" ); //$NON-NLS-1$
assertEquals( ((CKnRParameter)f_parms[1]).getName(), "b" ); //$NON-NLS-1$
assertEquals( ((CParameter)f_parms[0]).getName(), "a" ); //$NON-NLS-1$
assertEquals( ((CParameter)f_parms[1]).getName(), "b" ); //$NON-NLS-1$
}

View file

@ -1617,9 +1617,7 @@ public class AST2Tests extends AST2BaseTest {
assertEquals( decls.length, 1 );
assertEquals( decls[0], name_A1 );
decls = tu.getDeclarations(name_d.resolveBinding());
assertEquals( decls.length, 1 );
assertEquals( decls[0], name_d );
assertNull(name_d.resolveBinding());
}
public void testDesignatedInitializers() throws ParserException

View file

@ -19,6 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IParameter;
@ -32,15 +33,15 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils;
* @author aniefer
*/
public class CFunction implements IFunction, ICBinding {
private IASTFunctionDeclarator [] declarators = null;
private IASTStandardFunctionDeclarator [] declarators = null;
private IASTFunctionDeclarator definition;
IFunctionType type = null;
public CFunction( IASTFunctionDeclarator declarator ){
if( declarator.getParent() instanceof IASTFunctionDefinition )
if( declarator.getParent() instanceof IASTFunctionDefinition || declarator instanceof ICASTKnRFunctionDeclarator )
definition = declarator;
else {
declarators = new IASTFunctionDeclarator [] { declarator };
declarators = new IASTStandardFunctionDeclarator [] { (IASTStandardFunctionDeclarator) declarator };
}
}
@ -48,36 +49,26 @@ public class CFunction implements IFunction, ICBinding {
return ( definition != null ) ? definition : declarators[0];
}
public void addDeclarator( IASTFunctionDeclarator fnDeclarator ){
if( fnDeclarator instanceof IASTFunctionDefinition || fnDeclarator instanceof ICASTKnRFunctionDeclarator )
updateParameterBindings( fnDeclarator );
if( fnDeclarator.getParent() instanceof IASTFunctionDefinition || fnDeclarator instanceof ICASTKnRFunctionDeclarator )
definition = fnDeclarator;
else {
if( declarators == null ){
declarators = new IASTFunctionDeclarator[] { fnDeclarator };
declarators = new IASTStandardFunctionDeclarator[] { (IASTStandardFunctionDeclarator) fnDeclarator };
return;
}
for( int i = 0; i < declarators.length; i++ ){
if( declarators[i] == null ){
declarators[i] = fnDeclarator;
declarators[i] = (IASTStandardFunctionDeclarator) fnDeclarator;
return;
}
}
IASTFunctionDeclarator tmp [] = new IASTFunctionDeclarator [ declarators.length * 2 ];
IASTStandardFunctionDeclarator tmp [] = new IASTStandardFunctionDeclarator [ declarators.length * 2 ];
System.arraycopy( declarators, 0, tmp, 0, declarators.length );
tmp[ declarators.length ] = fnDeclarator;
tmp[ declarators.length ] = (IASTStandardFunctionDeclarator) fnDeclarator;
declarators = tmp;
}
}
// private IASTFunctionDeclarator checkForDefinition( IASTFunctionDeclarator dtor ){
// if( dtor.getParent() instanceof IASTFunctionDefinition )
// return dtor;
//
// IASTFunctionDeclarator def = CVisitor.findDefinition( dtor );
// if( def != null && def != dtor ){
// dtor = def;
// ((CASTName)dtor.getName()).setBinding( this );
// }
// return dtor;
// }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IFunction#getParameters()
@ -168,7 +159,131 @@ public class CFunction implements IFunction, ICBinding {
return type;
}
// public IASTDeclaration getDeclaration(){
// return (IASTDeclaration) declarator.getParent();
// }
public IBinding resolveParameter( IASTName paramName ){
if( ((CASTName)paramName).hasBinding() )
return paramName.resolveBinding();
IBinding binding = null;
int idx = 0;
IASTNode parent = paramName.getParent();
if( !(parent instanceof ICASTKnRFunctionDeclarator ) )
parent = parent.getParent();
ICASTKnRFunctionDeclarator fKnRDtor = null;
IASTDeclarator knrParamDtor = null;
if( parent instanceof IASTParameterDeclaration ){
IASTStandardFunctionDeclarator fdtor = (IASTStandardFunctionDeclarator) parent.getParent();
IASTParameterDeclaration [] ps = fdtor.getParameters();
for( ; idx < ps.length; idx++ ){
if( parent == ps[idx] )
break;
}
} else if( parent instanceof IASTSimpleDeclaration ){
//KnR: name in declaration list
fKnRDtor = (ICASTKnRFunctionDeclarator) parent.getParent();
IASTName [] ps = fKnRDtor.getParameterNames();
char [] n = paramName.toCharArray();
for( ; idx < ps.length; idx++ ){
if( CharArrayUtils.equals( ps[idx].toCharArray(), n ) )
break;
}
} else {
//KnR: name in name list
fKnRDtor = (ICASTKnRFunctionDeclarator) parent;
IASTName [] ps = fKnRDtor.getParameterNames();
for( ; idx < ps.length; idx++ ){
if( ps[idx] == paramName)
break;
}
knrParamDtor = getKnRParameterDeclarator( fKnRDtor, paramName );
paramName = knrParamDtor.getName();
}
//create a new binding and set it for the corresponding parameter in all known defns and decls
binding = new CParameter( paramName );
IASTParameterDeclaration temp = null;
if( definition != null ){
if( definition instanceof IASTStandardFunctionDeclarator ){
temp = ((IASTStandardFunctionDeclarator)definition).getParameters()[idx];
((CASTName)temp.getDeclarator().getName()).setBinding( binding );
} else if( definition instanceof ICASTKnRFunctionDeclarator ){
IASTName n = fKnRDtor.getParameterNames()[idx];
((CASTName)n).setBinding( binding );
IASTDeclarator dtor = getKnRParameterDeclarator( fKnRDtor, n );
if( dtor != null ){
((CASTName)dtor.getName()).setBinding( binding );
}
}
}
if( declarators != null ){
for( int j = 0; j < declarators.length && declarators[j] != null; j++ ){
if( declarators[j].getParameters().length > idx ){
temp = declarators[j].getParameters()[idx];
((CASTName)temp.getDeclarator().getName()).setBinding( binding );
}
}
}
return binding;
}
private IASTDeclarator getKnRParameterDeclarator( ICASTKnRFunctionDeclarator fKnRDtor, IASTName name ){
IASTDeclaration [] decls = fKnRDtor.getParameterDeclarations();
char [] n = name.toCharArray();
for( int i = 0; i < decls.length; i++ ){
if( !( decls[i] instanceof IASTSimpleDeclaration ) )
continue;
IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decls[i]).getDeclarators();
for( int j = 0; j < dtors.length; j++ ){
if( CharArrayUtils.equals( dtors[j].getName().toCharArray(), n ) ){
return dtors[j];
}
}
}
return null;
}
protected void updateParameterBindings( IASTFunctionDeclarator fdtor ){
CParameter temp = null;
if( fdtor instanceof IASTStandardFunctionDeclarator ){
IASTStandardFunctionDeclarator orig = (IASTStandardFunctionDeclarator) getPhysicalNode();
IASTParameterDeclaration [] ops = orig.getParameters();
IASTParameterDeclaration [] nps = ((IASTStandardFunctionDeclarator)fdtor).getParameters();
for( int i = 0; i < nps.length; i++ ){
CASTName origname = (CASTName) ops[i].getDeclarator().getName();
if( origname.hasBinding() ){
temp = (CParameter) origname.resolveBinding();
if( temp != null ){
CASTName name = (CASTName) nps[i].getDeclarator().getName();
name.setBinding( temp );
temp.addDeclaration( name );
}
}
}
} else {
IASTParameterDeclaration [] ops = declarators[0].getParameters();
IASTName [] ns = ((ICASTKnRFunctionDeclarator)fdtor).getParameterNames();
if( ops.length > 0 && ops.length != ns.length )
return; //problem
for( int i = 0; i < ops.length; i++ ){
CASTName origname = (CASTName) ops[i].getDeclarator().getName();
if( origname.hasBinding() ){
temp = (CParameter) origname.resolveBinding();
if( temp != null ){
CASTName name = (CASTName) ns[i];
name.setBinding( temp );
IASTDeclarator dtor = getKnRParameterDeclarator( (ICASTKnRFunctionDeclarator) fdtor, name );
if( dtor != null ){
((CASTName) dtor.getName()).setBinding( temp );
temp.addDeclaration( (CASTName) dtor.getName() );
}
}
}
}
}
}
}

View file

@ -11,79 +11,81 @@
**********************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.c.ICASTTypedefNameSpecifier;
import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator;
/**
* Created on Nov 5, 2004
* @author aniefer
*/
public class CParameter implements IParameter {
final private IASTParameterDeclaration parameterDeclaration;
private IASTName [] declarations;
public CParameter( IASTParameterDeclaration parameterDeclaration ){
//parameterDeclaration = checkForDefinition( parameterDeclaration );
this.parameterDeclaration = parameterDeclaration;
public CParameter( IASTName parameterName ){
this.declarations = new IASTName [] { parameterName };
}
public IASTNode getPhysicalNode(){
return parameterDeclaration;
}
// private IASTParameterDeclaration checkForDefinition( IASTParameterDeclaration paramDecl ){
// IASTFunctionDeclarator fnDtor = (IASTFunctionDeclarator) paramDecl.getParent();
// if( fnDtor.getParent() instanceof IASTFunctionDefinition )
// return paramDecl;
//
// IASTFunctionDeclarator fDef = CVisitor.findDefinition( fnDtor );
// if( fDef != null && fDef instanceof IASTFunctionDefinition ){
// int index = fnDtor.getParameters().indexOf( paramDecl );
// if( index >= 0 && index < fDef.getParameters().size() ) {
// IASTParameterDeclaration pDef = (IASTParameterDeclaration) fDef.getParameters().get( index );
// ((CASTName)pDef.getDeclarator().getName()).setBinding( this );
// paramDecl = pDef;
// }
// }
// return paramDecl;
// }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IVariable#getType()
*/
public IType getType() {
IASTDeclSpecifier declSpec = parameterDeclaration.getDeclSpecifier();
if( declSpec instanceof ICASTTypedefNameSpecifier ){
ICASTTypedefNameSpecifier nameSpec = (ICASTTypedefNameSpecifier) declSpec;
return (IType) nameSpec.getName().resolveBinding();
} else if( declSpec instanceof IASTElaboratedTypeSpecifier ){
IASTElaboratedTypeSpecifier elabTypeSpec = (IASTElaboratedTypeSpecifier) declSpec;
return (IType) elabTypeSpec.getName().resolveBinding();
}
return null;
return CVisitor.createType( declarations[0], true );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getName()
*/
public String getName() {
return parameterDeclaration.getDeclarator().getName().toString();
return declarations[0].toString();
}
public char[] getNameCharArray(){
return ((CASTName)parameterDeclaration.getDeclarator().getName()).toCharArray();
return declarations[0].toCharArray();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getScope()
*/
public IScope getScope() {
return CVisitor.getContainingScope( parameterDeclaration );
//IASTParameterDeclaration or IASTSimpleDeclaration
for( int i = 0; i < declarations.length; i++ ){
IASTNode parent = declarations[i].getParent();
if( parent instanceof ICASTKnRFunctionDeclarator ){
parent = parent.getParent();
return ((IASTCompoundStatement)((IASTFunctionDefinition)parent).getBody()).getScope();
}
IASTFunctionDeclarator fdtor = (IASTFunctionDeclarator) parent.getParent().getParent();
parent = fdtor.getParent();
if( parent instanceof IASTFunctionDefinition ) {
return ((IASTCompoundStatement)((IASTFunctionDefinition)parent).getBody()).getScope();
}
}
//TODO: if not definition, find definition
return null;
}
/**
* @param name
*/
public void addDeclaration( CASTName name ) {
for( int i = 0; i < declarations.length; i++ ){
if( declarations[i] == null ){
declarations[i] = name;
return;
}
}
IASTName [] tmp = new IASTName[ declarations.length * 2 ];
System.arraycopy( declarations, 0, tmp, 0, declarations.length );
tmp[ declarations.length ] = name;
declarations = tmp;
}
}

View file

@ -36,7 +36,6 @@ import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
@ -55,6 +54,7 @@ import org.eclipse.cdt.core.dom.ast.IASTProblemHolder;
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
@ -528,8 +528,11 @@ public class CVisitor {
} else {
binding = createBinding(declarator);
}
} else { // createBinding for one of the ICASTKnRFunctionDeclarator's parameterNames
binding = resolveKnRParameterBinding((ICASTKnRFunctionDeclarator) declarator, name);
} else { // createBinding for one of the ICASTKnRFunctionDeclarator's parameterNames
IBinding f = declarator.getName().resolveBinding();
if( f instanceof CFunction ){
binding = ((CFunction) f).resolveParameter( name );
}
if ( declarator.getParent() instanceof IASTFunctionDefinition ) {
ICScope scope = (ICScope) ((IASTCompoundStatement)((IASTFunctionDefinition)declarator.getParent()).getBody()).getScope();
@ -540,19 +543,18 @@ public class CVisitor {
} else if( parent instanceof IASTSimpleDeclaration ){
binding = createBinding( (IASTSimpleDeclaration) parent, name );
} else if( parent instanceof IASTParameterDeclaration ){
binding = createBinding( (IASTParameterDeclaration ) parent );
// C99 6.2.1-4: within the list of parameter declarations in a function definition, the
// identifier has block scope, which terminates at the end of the associated block.
parent = parent.getParent();
if ( parent instanceof IASTStandardFunctionDeclarator ) {
parent = parent.getParent();
if ( parent instanceof IASTFunctionDefinition ) {
ICScope scope = (ICScope) ((IASTCompoundStatement)((IASTFunctionDefinition)parent).getBody()).getScope();
IASTParameterDeclaration param = (IASTParameterDeclaration) parent;
IASTFunctionDeclarator fDtor = (IASTFunctionDeclarator) param.getParent();
IBinding b = fDtor.getName().resolveBinding();
if( b instanceof IFunction ){
binding = ((CFunction)b).resolveParameter( name );
parent = fDtor.getParent();
if( parent instanceof IASTFunctionDefinition ){
ICScope scope = (ICScope) ((IASTCompoundStatement)((IASTFunctionDefinition)parent).getBody()).getScope();
if ( scope != null && binding != null )
scope.addBinding(binding);
}
}
}
} else if ( parent instanceof IASTFunctionDeclarator ) {
binding = createBinding(declarator);
}
@ -634,7 +636,11 @@ public class CVisitor {
if( binding == null ){
// if the simpleDeclaration is part of a KRC function declarator, then the binding is to a KRC parameter
if ( simpleDeclaration.getParent() instanceof IASTFunctionDeclarator ) {
binding = resolveKnRParameterBinding((ICASTKnRFunctionDeclarator) simpleDeclaration.getParent(), name); // is resolveKnRParameterBinding still necessary?
IASTFunctionDeclarator fdtor = (IASTFunctionDeclarator) simpleDeclaration.getParent();
IBinding fn = fdtor.getName().resolveBinding();
if( fn instanceof CFunction ){
binding = ((CFunction)fn).resolveParameter( name );
}
} else {
binding = new CVariable( name );
}
@ -646,13 +652,6 @@ public class CVisitor {
return binding;
}
private static IBinding createBinding( IASTParameterDeclaration parameterDeclaration ){
IBinding binding = resolveBinding( parameterDeclaration, CURRENT_SCOPE );
if( binding == null )
binding = new CParameter( parameterDeclaration );
return binding;
}
protected static IBinding resolveBinding( IASTNode node ){
return resolveBinding( node, COMPLETE );
}
@ -675,23 +674,6 @@ public class CVisitor {
} else if( node instanceof ICASTCompositeTypeSpecifier ){
IASTNode blockItem = getContainingBlockItem( node );
return findBinding( blockItem, ((ICASTCompositeTypeSpecifier)node).getName(), bits );
} else if( node instanceof IASTParameterDeclaration ){
IASTParameterDeclaration param = (IASTParameterDeclaration) node;
IASTStandardFunctionDeclarator fDtor = (IASTStandardFunctionDeclarator) param.getParent();
if ( fDtor.getName().resolveBinding() instanceof IFunction ) { // possible to have IASTParameterDeclaration whose parent is an IVariable
IFunction function = (IFunction) fDtor.getName().resolveBinding();
if( ((ICBinding)function).getPhysicalNode() != fDtor ) {
IASTParameterDeclaration [] ps = fDtor.getParameters();
int index = -1;
for( index = 0; index < ps.length; index++ )
if( ps[index] == param ) break;
IParameter [] params = function.getParameters();
if( index >= 0 && index < params.length ){
return params[ index ];
}
}
}
} else if( node instanceof IASTTypeId ){
IASTTypeId typeId = (IASTTypeId) node;
IASTDeclSpecifier declSpec = typeId.getDeclSpecifier();
@ -1693,44 +1675,4 @@ public class CVisitor {
return action.getDeclarationNames();
}
private static IBinding resolveKnRParameterBinding(ICASTKnRFunctionDeclarator declarator, IASTName name) {
IASTDeclaration[] parmDeclarations = declarator.getParameterDeclarations();
if ( declarator.getName().resolveBinding() instanceof IFunction ) { // possible to have IASTParameterDeclaration whose parent is an IVariable
IFunction function = (IFunction) declarator.getName().resolveBinding();
if( ((ICBinding)function).getPhysicalNode() != declarator ) {
IASTDeclaration [] ps = declarator.getParameterDeclarations();
int index = -1;
outerLoop: for( index = 0; index < ps.length; index++ )
for (int j=0; j<parmDeclarations.length; j++)
if( ps[index] == parmDeclarations[j] ) break outerLoop;
IParameter[] params = function.getParameters();
if( index >= 0 && index < params.length ){
return params[ index ];
}
}
}
for (int i=0; i<parmDeclarations.length; i++) {
if ( parmDeclarations[i] instanceof IASTSimpleDeclaration ) {
IASTDeclarator[] decltors = ((IASTSimpleDeclaration)parmDeclarations[i]).getDeclarators();
for (int j=0; j<decltors.length; j++) {
if (CharArrayUtils.equals( decltors[j].getName().toCharArray(), name.toCharArray()) ) {
if (decltors[j].getName() instanceof CASTName && ((CASTName)decltors[j].getName()).hasBinding())
return decltors[j].getName().resolveBinding();
return new CKnRParameter( parmDeclarations[i], decltors[j].getName() );
}
}
}
}
// NOTE: without a function prototype a parameter name without a matching declaration currently resolves to a null binding
// i.e. int f(x,y) char x; {} // this compiles/runs, but does not compile when the prototype is included
return null; // nothing found
}
}