1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-29 20:05:35 +02:00

prefix lookup for C

This commit is contained in:
Andrew Niefer 2005-03-24 21:17:12 +00:00
parent a1c3367c10
commit fcfbda5c0e
4 changed files with 185 additions and 59 deletions

View file

@ -122,4 +122,10 @@ public class CharArrayObjectMap extends CharTable {
} }
} }
} }
public Object [] valueArray(){
Object [] values = new Object[ size() ];
System.arraycopy( valueTable, 0, values, 0, values.length );
return values;
}
} }

View file

@ -165,4 +165,10 @@ public class CharTable extends HashTable {
return -1; return -1;
} }
public Object [] keyArray(){
Object [] keys = new Object[ size() ];
System.arraycopy( keyTable, 0, keys, 0, keys.length );
return keys;
}
} }

View file

@ -52,8 +52,7 @@ public class CASTName extends CASTNode implements IASTName {
} }
public IBinding[] resolvePrefix() { public IBinding[] resolvePrefix() {
// TODO hook this up to the CVisitor return CVisitor.prefixLookup(this);
return null;
} }
public void setBinding( IBinding binding ){ public void setBinding( IBinding binding ){

View file

@ -52,6 +52,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.ILabel; import org.eclipse.cdt.core.dom.ast.ILabel;
@ -76,7 +77,10 @@ import org.eclipse.cdt.core.dom.ast.c.ICCompositeTypeScope;
import org.eclipse.cdt.core.dom.ast.c.ICFunctionScope; import org.eclipse.cdt.core.dom.ast.c.ICFunctionScope;
import org.eclipse.cdt.core.dom.ast.c.ICScope; import org.eclipse.cdt.core.dom.ast.c.ICScope;
import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.ObjectSet;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
@ -424,6 +428,7 @@ public class CVisitor {
private static final int CURRENT_SCOPE = 1; private static final int CURRENT_SCOPE = 1;
private static final int TAGS = 1 << 1; private static final int TAGS = 1 << 1;
private static final int INCLUDE_BLOCK_ITEM = 1 << 2; private static final int INCLUDE_BLOCK_ITEM = 1 << 2;
private static final int PREFIX_LOOKUP = 1 << 3;
//definition lookup start loc //definition lookup start loc
protected static final int AT_BEGINNING = 1; protected static final int AT_BEGINNING = 1;
@ -438,7 +443,7 @@ public class CVisitor {
} else if( parent instanceof ICASTTypedefNameSpecifier ){ } else if( parent instanceof ICASTTypedefNameSpecifier ){
binding = resolveBinding( parent ); binding = resolveBinding( parent );
} else if( parent instanceof IASTFieldReference ){ } else if( parent instanceof IASTFieldReference ){
binding = findBinding( (IASTFieldReference) parent ); binding = (IBinding) findBinding( (IASTFieldReference) parent, false );
} else if( parent instanceof IASTDeclarator ){ } else if( parent instanceof IASTDeclarator ){
binding = createBinding( (IASTDeclarator) parent, name ); binding = createBinding( (IASTDeclarator) parent, name );
} else if( parent instanceof ICASTCompositeTypeSpecifier ){ } else if( parent instanceof ICASTCompositeTypeSpecifier ){
@ -545,14 +550,22 @@ public class CVisitor {
} else if( parent instanceof IASTTypeId || parent instanceof IASTParameterDeclaration ){ } else if( parent instanceof IASTTypeId || parent instanceof IASTParameterDeclaration ){
IASTNode blockItem = getContainingBlockItem( parent ); IASTNode blockItem = getContainingBlockItem( parent );
try { try {
return findBinding( blockItem, elabTypeSpec.getName(), COMPLETE | TAGS ); return (IBinding) findBinding( blockItem, elabTypeSpec.getName(), COMPLETE | TAGS );
} catch ( DOMException e ) { } catch ( DOMException e ) {
return null; return null;
} }
} }
return null; return null;
} }
private static IBinding findBinding( IASTFieldReference fieldReference ){
/**
* if prefix == false, return an IBinding or null
* if prefix == true, return an IBinding[] or null
* @param fieldReference
* @param prefix
* @return
*/
private static Object findBinding( IASTFieldReference fieldReference, boolean prefix ){
IASTExpression fieldOwner = fieldReference.getFieldOwner(); IASTExpression fieldOwner = fieldReference.getFieldOwner();
IType type = null; IType type = null;
if( fieldOwner instanceof IASTArraySubscriptExpression ){ if( fieldOwner instanceof IASTArraySubscriptExpression ){
@ -569,6 +582,21 @@ public class CVisitor {
} }
if( type != null && type instanceof ICompositeType ){ if( type != null && type instanceof ICompositeType ){
if( prefix ){
IBinding [] result = null;
try {
char [] p = fieldReference.getFieldName().toCharArray();
IField [] fields = ((ICompositeType) type).getFields();
for ( int i = 0; i < fields.length; i++ ) {
if( CharArrayUtils.equals( fields[i].getNameCharArray(), 0, p.length, p ) ){
result = (IBinding[]) ArrayUtil.append( IBinding.class, result, fields[i] );
}
}
return ArrayUtil.trim( IBinding.class, result );
} catch ( DOMException e ) {
return new IBinding[] { e.getProblem() };
}
}
try { try {
return ((ICompositeType) type).findField( fieldReference.getFieldName().toString() ); return ((ICompositeType) type).findField( fieldReference.getFieldName().toString() );
} catch ( DOMException e ) { } catch ( DOMException e ) {
@ -846,35 +874,35 @@ public class CVisitor {
IASTName name = functionDeclartor.getName(); IASTName name = functionDeclartor.getName();
IASTNode blockItem = getContainingBlockItem( node ); IASTNode blockItem = getContainingBlockItem( node );
try { try {
return findBinding( blockItem, name, bits ); return (IBinding) findBinding( blockItem, name, bits );
} catch ( DOMException e ) { } catch ( DOMException e ) {
return null; return null;
} }
} else if( node instanceof IASTIdExpression ){ } else if( node instanceof IASTIdExpression ){
IASTNode blockItem = getContainingBlockItem( node ); IASTNode blockItem = getContainingBlockItem( node );
try { try {
return findBinding( blockItem, ((IASTIdExpression)node).getName(), bits ); return (IBinding) findBinding( blockItem, ((IASTIdExpression)node).getName(), bits );
} catch ( DOMException e ) { } catch ( DOMException e ) {
return null; return null;
} }
} else if( node instanceof ICASTTypedefNameSpecifier ){ } else if( node instanceof ICASTTypedefNameSpecifier ){
IASTNode blockItem = getContainingBlockItem( node ); IASTNode blockItem = getContainingBlockItem( node );
try { try {
return findBinding( blockItem, ((ICASTTypedefNameSpecifier)node).getName(), bits ); return (IBinding) findBinding( blockItem, ((ICASTTypedefNameSpecifier)node).getName(), bits );
} catch ( DOMException e ) { } catch ( DOMException e ) {
return null; return null;
} }
} else if( node instanceof ICASTElaboratedTypeSpecifier ){ } else if( node instanceof ICASTElaboratedTypeSpecifier ){
IASTNode blockItem = getContainingBlockItem( node ); IASTNode blockItem = getContainingBlockItem( node );
try { try {
return findBinding( blockItem, ((ICASTElaboratedTypeSpecifier)node).getName(), bits ); return (IBinding) findBinding( blockItem, ((ICASTElaboratedTypeSpecifier)node).getName(), bits );
} catch ( DOMException e ) { } catch ( DOMException e ) {
return null; return null;
} }
} else if( node instanceof ICASTCompositeTypeSpecifier ){ } else if( node instanceof ICASTCompositeTypeSpecifier ){
IASTNode blockItem = getContainingBlockItem( node ); IASTNode blockItem = getContainingBlockItem( node );
try { try {
return findBinding( blockItem, ((ICASTCompositeTypeSpecifier)node).getName(), bits ); return (IBinding) findBinding( blockItem, ((ICASTCompositeTypeSpecifier)node).getName(), bits );
} catch ( DOMException e ) { } catch ( DOMException e ) {
return null; return null;
} }
@ -1036,8 +1064,16 @@ public class CVisitor {
return getContainingBlockItem( parent ); return getContainingBlockItem( parent );
} }
protected static IBinding findBinding( IASTNode blockItem, IASTName name, int bits ) throws DOMException{ /**
IBinding binding = null; * if (bits | PREFIX_LOOKUP) then returns IBinding []
* otherwise returns IBinding
*/
protected static Object findBinding( IASTNode blockItem, IASTName name, int bits ) throws DOMException{
boolean prefix = ( bits & PREFIX_LOOKUP ) != 0;
Object binding = prefix ? new ObjectSet( 2 ) : null;
CharArrayObjectMap prefixMap = prefix ? new CharArrayObjectMap(2) : null;
while( blockItem != null ){ while( blockItem != null ){
IASTNode parent = blockItem.getParent(); IASTNode parent = blockItem.getParent();
@ -1073,6 +1109,9 @@ public class CVisitor {
boolean typesOnly = (bits & TAGS) != 0; boolean typesOnly = (bits & TAGS) != 0;
boolean includeBlockItem = (bits & INCLUDE_BLOCK_ITEM) != 0; boolean includeBlockItem = (bits & INCLUDE_BLOCK_ITEM) != 0;
if( prefix )
scope = null;
if( scope != null && scope.isFullyCached() ){ if( scope != null && scope.isFullyCached() ){
try { try {
binding = scope.getBinding( name, true ); binding = scope.getBinding( name, true );
@ -1083,14 +1122,14 @@ public class CVisitor {
return binding; return binding;
} else { } else {
IASTName result = null; Object result = null;
if( nodes != null ){ if( nodes != null ){
int idx = -1; int idx = -1;
IASTNode node = ( nodes != null ? (nodes.length > 0 ? nodes[++idx] : null ) : parent ); IASTNode node = ( nodes != null ? (nodes.length > 0 ? nodes[++idx] : null ) : parent );
while( node != null ) { while( node != null ) {
IASTName candidate = null; Object candidate = null;
try { try {
candidate = checkForBinding( scope, node, name, typesOnly ); candidate = checkForBinding( scope, node, name, typesOnly, prefixMap );
} catch ( DOMException e ) { } catch ( DOMException e ) {
continue; continue;
} }
@ -1119,7 +1158,7 @@ public class CVisitor {
} else { } else {
try { try {
result = checkForBinding( scope, parent, name, typesOnly ); result = checkForBinding( scope, parent, name, typesOnly, prefixMap );
} catch ( DOMException e ) { } catch ( DOMException e ) {
} }
} }
@ -1129,8 +1168,9 @@ public class CVisitor {
} catch ( DOMException e ) { } catch ( DOMException e ) {
} }
} }
if( result != null ) if( result != null ){
return result.resolveBinding(); return ((IASTName)result).resolveBinding();
}
} }
if( (bits & CURRENT_SCOPE) == 0 ) if( (bits & CURRENT_SCOPE) == 0 )
blockItem = parent; blockItem = parent;
@ -1140,7 +1180,14 @@ public class CVisitor {
if( blockItem instanceof IASTTranslationUnit ) if( blockItem instanceof IASTTranslationUnit )
break; break;
} }
if( prefixMap != null ){
IBinding [] result = null;
Object [] vals = prefixMap.valueArray();
for ( int i = 0; i < vals.length; i++ ) {
result = (IBinding[]) ArrayUtil.append( IBinding.class, result, ((IASTName) vals[i]).resolveBinding() );
}
return ArrayUtil.trim( IBinding.class, result );
}
if( blockItem != null) if( blockItem != null)
return externalBinding( (IASTTranslationUnit) blockItem, name ); return externalBinding( (IASTTranslationUnit) blockItem, name );
@ -1163,22 +1210,30 @@ public class CVisitor {
return external; return external;
} }
private static IASTName checkForBinding( ICScope scope, IASTDeclSpecifier declSpec, IASTName name, boolean typesOnly ) throws DOMException{ private static IASTName checkForBinding( ICScope scope, IASTDeclSpecifier declSpec, IASTName name, boolean typesOnly, CharArrayObjectMap prefixMap ) throws DOMException{
IASTName tempName = null; IASTName tempName = null;
IASTName resultName = null;
char [] n = name.toCharArray();
if( declSpec instanceof ICASTElaboratedTypeSpecifier ){ if( declSpec instanceof ICASTElaboratedTypeSpecifier ){
tempName = ((ICASTElaboratedTypeSpecifier)declSpec).getName(); tempName = ((ICASTElaboratedTypeSpecifier)declSpec).getName();
if( scope != null ) if( scope != null )
scope.addName( tempName ); scope.addName( tempName );
if( typesOnly && CharArrayUtils.equals( tempName.toCharArray(), name.toCharArray() ) ){ if( typesOnly ){
return tempName; if( prefixMap != null )
prefixMap = (CharArrayObjectMap) collectResult( tempName, n, prefixMap );
else if( collectResult( tempName, n, prefixMap ) != null )
resultName = tempName;
} }
} else if( declSpec instanceof ICASTCompositeTypeSpecifier ){ } else if( declSpec instanceof ICASTCompositeTypeSpecifier ){
tempName = ((ICASTCompositeTypeSpecifier)declSpec).getName(); tempName = ((ICASTCompositeTypeSpecifier)declSpec).getName();
if( scope != null ) if( scope != null )
scope.addName( tempName ); scope.addName( tempName );
if( typesOnly && CharArrayUtils.equals( tempName.toCharArray(), name.toCharArray() ) ){
return tempName; if( typesOnly ){
if( prefixMap != null )
prefixMap = (CharArrayObjectMap) collectResult( tempName, n, prefixMap );
else if( collectResult( tempName, n, prefixMap ) != null )
resultName = tempName;
} }
//also have to check for any nested structs //also have to check for any nested structs
IASTDeclaration [] nested = ((ICASTCompositeTypeSpecifier)declSpec).getMembers(); IASTDeclaration [] nested = ((ICASTCompositeTypeSpecifier)declSpec).getMembers();
@ -1186,9 +1241,10 @@ public class CVisitor {
if( nested[i] instanceof IASTSimpleDeclaration ){ if( nested[i] instanceof IASTSimpleDeclaration ){
IASTDeclSpecifier d = ((IASTSimpleDeclaration)nested[i]).getDeclSpecifier(); IASTDeclSpecifier d = ((IASTSimpleDeclaration)nested[i]).getDeclSpecifier();
if( d instanceof ICASTCompositeTypeSpecifier ) { if( d instanceof ICASTCompositeTypeSpecifier ) {
IASTName temp = checkForBinding( scope, d, name, typesOnly ); Object obj = checkForBinding( scope, d, name, typesOnly, prefixMap );
if( temp != null ) if( prefixMap == null && resultName == null ){
return temp; resultName = (IASTName) obj;
}
} }
} }
} }
@ -1197,8 +1253,11 @@ public class CVisitor {
tempName = enumeration.getName(); tempName = enumeration.getName();
if( scope != null ) if( scope != null )
scope.addName( tempName ); scope.addName( tempName );
if( typesOnly && CharArrayUtils.equals( tempName.toCharArray(), name.toCharArray() ) ){ if( typesOnly ){
return tempName; if( prefixMap != null )
prefixMap = (CharArrayObjectMap) collectResult( tempName, n, prefixMap );
else if( collectResult( tempName, n, prefixMap ) != null )
resultName = tempName;
} }
//check enumerators //check enumerators
IASTEnumerator [] list = ((ICASTEnumerationSpecifier) declSpec).getEnumerators(); IASTEnumerator [] list = ((ICASTEnumerationSpecifier) declSpec).getEnumerators();
@ -1208,15 +1267,28 @@ public class CVisitor {
tempName = enumerator.getName(); tempName = enumerator.getName();
if( scope != null ) if( scope != null )
scope.addName( tempName ); scope.addName( tempName );
if( !typesOnly && CharArrayUtils.equals( tempName.toCharArray(), name.toCharArray() ) ){ if( !typesOnly ){
return tempName; if( prefixMap != null )
prefixMap = (CharArrayObjectMap) collectResult( tempName, n, prefixMap );
else if( collectResult( tempName, n, prefixMap ) != null )
resultName = tempName;
} }
} }
} }
return null; return resultName;
} }
private static IASTName checkForBinding( ICScope scope, IASTParameterDeclaration paramDecl, IASTName name, boolean typesOnly ) throws DOMException{ private static Object collectResult( IASTName candidate, char[] name, CharArrayObjectMap prefixMap ){
char [] c = candidate.toCharArray();
if( prefixMap == null && CharArrayUtils.equals( c, name ) ){
return candidate;
} else if( prefixMap != null && CharArrayUtils.equals( c, 0, name.length, name ) && !prefixMap.containsKey( c ) ){
prefixMap.put( c, candidate );
}
return prefixMap;
}
private static IASTName checkForBinding( ICScope scope, IASTParameterDeclaration paramDecl, IASTName name, boolean typesOnly, CharArrayObjectMap prefixMap ) throws DOMException{
if( paramDecl == null ) return null; if( paramDecl == null ) return null;
IASTDeclarator dtor = paramDecl.getDeclarator(); IASTDeclarator dtor = paramDecl.getDeclarator();
@ -1226,33 +1298,43 @@ public class CVisitor {
IASTName tempName = dtor.getName(); IASTName tempName = dtor.getName();
if( scope != null ) if( scope != null )
scope.addName( tempName ); scope.addName( tempName );
if( !typesOnly && CharArrayUtils.equals( tempName.toCharArray(), name.toCharArray() ) ){
return tempName;
}
if( typesOnly ){ if( !typesOnly ) {
return checkForBinding( scope, paramDecl.getDeclSpecifier(), name, typesOnly ); char [] c = tempName.toCharArray();
} char [] n = name.toCharArray();
if( prefixMap == null && CharArrayUtils.equals( c, n ) )
return tempName;
else if( prefixMap != null && CharArrayUtils.equals( c, 0, n.length, n ) && !prefixMap.containsKey( c ) )
prefixMap.put( c, tempName );
} else {
return checkForBinding( scope, paramDecl.getDeclSpecifier(), name, typesOnly, prefixMap );
}
return null; return null;
} }
private static IASTName checkForBinding( ICScope scope, IASTNode node, IASTName name, boolean typesOnly ) throws DOMException{ /**
* if not a prefix lookup, returns IASTName
* if doing prefix lookup, results are in prefixMap, returns null
*/
private static IASTName checkForBinding( ICScope scope, IASTNode node, IASTName name, boolean typesOnly, CharArrayObjectMap prefixMap ) throws DOMException{
if( node instanceof IASTDeclaration ){ if( node instanceof IASTDeclaration ){
return checkForBinding( scope, (IASTDeclaration) node, name, typesOnly ); return checkForBinding( scope, (IASTDeclaration) node, name, typesOnly, prefixMap );
} else if( node instanceof IASTParameterDeclaration ){ } else if( node instanceof IASTParameterDeclaration ){
return checkForBinding( scope, (IASTParameterDeclaration) node, name, typesOnly ); return checkForBinding( scope, (IASTParameterDeclaration) node, name, typesOnly, prefixMap );
} else if( node instanceof IASTDeclarationStatement ){ } else if( node instanceof IASTDeclarationStatement ){
return checkForBinding( scope, ((IASTDeclarationStatement)node).getDeclaration(), name, typesOnly ); return checkForBinding( scope, ((IASTDeclarationStatement)node).getDeclaration(), name, typesOnly, prefixMap );
} else if( node instanceof IASTForStatement ){ } else if( node instanceof IASTForStatement ){
IASTForStatement forStatement = (IASTForStatement) node; IASTForStatement forStatement = (IASTForStatement) node;
if( forStatement.getInitDeclaration() != null ){ if( forStatement.getInitDeclaration() != null ){
return checkForBinding( scope, forStatement.getInitDeclaration(), name, typesOnly ); return checkForBinding( scope, forStatement.getInitDeclaration(), name, typesOnly, prefixMap );
} }
} }
return null; return null;
} }
private static IASTName checkForBinding( ICScope scope, IASTDeclaration declaration, IASTName name, boolean typesOnly ) throws DOMException{ private static IASTName checkForBinding( ICScope scope, IASTDeclaration declaration, IASTName name, boolean typesOnly, CharArrayObjectMap prefixMap ) throws DOMException{
char [] n = name.toCharArray();
IASTName tempName = null; IASTName tempName = null;
IASTName resultName = null;
if( declaration instanceof IASTSimpleDeclaration ){ if( declaration instanceof IASTSimpleDeclaration ){
IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration; IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration;
IASTDeclarator [] declarators = simpleDeclaration.getDeclarators(); IASTDeclarator [] declarators = simpleDeclaration.getDeclarators();
@ -1265,13 +1347,17 @@ public class CVisitor {
if( scope != null ) if( scope != null )
scope.addName( tempName ); scope.addName( tempName );
if( !typesOnly && CharArrayUtils.equals( tempName.toCharArray(), name.toCharArray() ) ){ if( !typesOnly ){
return tempName; if( prefixMap != null )
prefixMap = (CharArrayObjectMap) collectResult( tempName, n, prefixMap );
else if( collectResult( tempName, n, prefixMap ) != null )
resultName = tempName;
} }
} }
tempName = checkForBinding( scope, simpleDeclaration.getDeclSpecifier(), name, typesOnly ); tempName = checkForBinding( scope, simpleDeclaration.getDeclSpecifier(), name, typesOnly, prefixMap );
if( tempName != null ){ if( prefixMap == null && tempName != null ){
return tempName; resultName = tempName;
} }
} else if( !typesOnly && declaration instanceof IASTFunctionDefinition ){ } else if( !typesOnly && declaration instanceof IASTFunctionDefinition ){
IASTFunctionDefinition functionDef = (IASTFunctionDefinition) declaration; IASTFunctionDefinition functionDef = (IASTFunctionDefinition) declaration;
@ -1280,16 +1366,21 @@ public class CVisitor {
tempName = dtor.getName(); tempName = dtor.getName();
if( scope != null ) if( scope != null )
scope.addName( tempName ); scope.addName( tempName );
if( !typesOnly && CharArrayUtils.equals( tempName.toCharArray(), name.toCharArray() ) ){
return tempName; if( !typesOnly ){
if( prefixMap != null )
prefixMap = (CharArrayObjectMap) collectResult( tempName, n, prefixMap );
else if( collectResult( tempName, n, prefixMap ) != null )
resultName = tempName;
} }
tempName = checkForBinding( scope, functionDef.getDeclSpecifier(), name, typesOnly ); tempName = checkForBinding( scope, functionDef.getDeclSpecifier(), name, typesOnly, prefixMap );
if( tempName != null ){ if( prefixMap == null && tempName != null ){
return tempName; resultName = tempName;
} }
} }
return null;
return resultName;
} }
protected static IASTDeclarator findDefinition( IASTDeclarator declarator, int beginAtLoc ){ protected static IASTDeclarator findDefinition( IASTDeclarator declarator, int beginAtLoc ){
@ -1639,14 +1730,38 @@ public class CVisitor {
{ {
IASTDeclaration [] declarations = ((IASTTranslationUnit)startingPoint).getDeclarations(); IASTDeclaration [] declarations = ((IASTTranslationUnit)startingPoint).getDeclarations();
if( declarations.length > 0 ) if( declarations.length > 0 )
return findBinding( declarations[declarations.length - 1], name, COMPLETE | INCLUDE_BLOCK_ITEM ); return (IBinding) findBinding( declarations[declarations.length - 1], name, COMPLETE | INCLUDE_BLOCK_ITEM );
} }
if( startingPoint instanceof IASTCompoundStatement ) if( startingPoint instanceof IASTCompoundStatement )
{ {
IASTStatement [] statements = ((IASTCompoundStatement)startingPoint).getStatements(); IASTStatement [] statements = ((IASTCompoundStatement)startingPoint).getStatements();
if( statements.length > 0 ) if( statements.length > 0 )
return findBinding( statements[ statements.length - 1 ], name, COMPLETE | INCLUDE_BLOCK_ITEM ); return (IBinding) findBinding( statements[ statements.length - 1 ], name, COMPLETE | INCLUDE_BLOCK_ITEM );
} }
return null; return null;
} }
public static IBinding [] prefixLookup( IASTName name ){
ASTNodeProperty prop = name.getPropertyInParent();
IBinding [] result = null;
if( prop == IASTFieldReference.FIELD_NAME ){
result = (IBinding[]) findBinding( (IASTFieldReference) name.getParent(), true );
} else {
int bits = PREFIX_LOOKUP;
if( prop == IASTElaboratedTypeSpecifier.TYPE_NAME ){
bits |= TAGS;
} else if( prop == IASTIdExpression.ID_NAME ){
bits |= INCLUDE_BLOCK_ITEM;
}
IASTNode blockItem = getContainingBlockItem( name );
try {
result = (IBinding[]) findBinding( blockItem, name, bits );
} catch ( DOMException e ) {
}
}
return (IBinding[]) ArrayUtil.trim( IBinding.class, result );
}
} }