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:
parent
ae4dff5290
commit
0a1793e33f
5 changed files with 212 additions and 151 deletions
|
@ -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$
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue