1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-09-10 12:03:16 +02:00

Performance and memory fixes for resolving bindings

This commit is contained in:
Andrew Niefer 2005-02-28 22:17:27 +00:00
parent cd6f234947
commit cd662e1910
7 changed files with 144 additions and 49 deletions

View file

@ -13,9 +13,12 @@
*/ */
package org.eclipse.cdt.core.dom.ast.cpp; package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.IASTName;
/** /**
* @author aniefer * @author aniefer
*/ */
public interface ICPPNamespaceScope extends ICPPScope { public interface ICPPNamespaceScope extends ICPPScope {
boolean isFullyResolved( IASTName name );
} }

View file

@ -59,6 +59,25 @@ public class ArrayUtil {
return array; return array;
} }
static public int [] setInt( int[] array, int idx, int val ){
if( array == null ){
array = new int [ DEFAULT_LENGTH > idx + 1 ? DEFAULT_LENGTH : idx + 1];
array[idx] = val;
return array;
}
if( array.length <= idx ){
int newLen = array.length * 2;
while( newLen <= idx ) newLen *=2;
int [] temp = new int [newLen];
System.arraycopy( array, 0, temp, 0, array.length );
array = temp;
}
array[idx] = val;
return array;
}
static public Object [] append( Object[] array, Object obj ){ static public Object [] append( Object[] array, Object obj ){
return append( Object.class, array, obj ); return append( Object.class, array, obj );
} }

View file

@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IASTVisitor.BaseVisitorAction; import org.eclipse.cdt.core.dom.ast.IASTVisitor.BaseVisitorAction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisitor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisitor;
@ -84,6 +85,8 @@ public class CPPNamespace implements ICPPNamespace, ICPPBinding {
} }
public int processDeclaration( IASTDeclaration declaration ){ public int processDeclaration( IASTDeclaration declaration ){
if( declaration instanceof ICPPASTLinkageSpecification )
return PROCESS_CONTINUE;
return PROCESS_SKIP; return PROCESS_SKIP;
} }
} }
@ -94,6 +97,8 @@ public class CPPNamespace implements ICPPNamespace, ICPPBinding {
IASTNode node = nsDef.getParent(); IASTNode node = nsDef.getParent();
ICPPASTVisitor visitor = (ICPPASTVisitor) node.getTranslationUnit().getVisitor(); ICPPASTVisitor visitor = (ICPPASTVisitor) node.getTranslationUnit().getVisitor();
while( node instanceof ICPPASTLinkageSpecification )
node = node.getParent();
if( node instanceof IASTTranslationUnit ) if( node instanceof IASTTranslationUnit )
visitor.visitTranslationUnit( collector ); visitor.visitTranslationUnit( collector );
else if( node instanceof ICPPASTNamespaceDefinition ){ else if( node instanceof ICPPASTNamespaceDefinition ){

View file

@ -13,21 +13,43 @@
*/ */
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPSemantics.LookupData;
/** /**
* @author aniefer * @author aniefer
*/ */
public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{ public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{
private CharArrayObjectMap bindings = CharArrayObjectMap.EMPTY_MAP; private static class ScopeMap extends CharArrayObjectMap {
private boolean checkForAdditionalBindings = true; private boolean[] resolvedTable;
public ScopeMap( int initialSize ) {
super( initialSize );
resolvedTable = new boolean[capacity()];
}
protected void resize(int size) {
boolean[] oldResolvedTable = resolvedTable;
resolvedTable = new boolean[size];
System.arraycopy(oldResolvedTable, 0, resolvedTable, 0, oldResolvedTable.length);
super.resize(size);
}
public boolean isFullyResolved( char [] name ){
int i = lookup(name, 0, name.length);
if( i >= 0 )
return resolvedTable[i];
return false;
}
public void setFullyResolved( char [] name ){
int i = lookup(name, 0, name.length);
if( i >= 0 )
resolvedTable[i] = true;
}
}
private ScopeMap bindings = null;
//private boolean checkForAdditionalBindings = true;
public CPPNamespaceScope( IASTNode physicalNode ) { public CPPNamespaceScope( IASTNode physicalNode ) {
super( physicalNode ); super( physicalNode );
@ -36,8 +58,8 @@ public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#addBinding(org.eclipse.cdt.core.dom.ast.IBinding) * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#addBinding(org.eclipse.cdt.core.dom.ast.IBinding)
*/ */
public void addBinding(IBinding binding) { public void addBinding(IBinding binding) {
if( bindings == CharArrayObjectMap.EMPTY_MAP ) if( bindings == null )
bindings = new CharArrayObjectMap(1); bindings = new ScopeMap(1);
char [] c = binding.getNameCharArray(); char [] c = binding.getNameCharArray();
Object o = bindings.get( c ); Object o = bindings.get( c );
if( o != null ){ if( o != null ){
@ -48,22 +70,22 @@ public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{
} }
} else { } else {
bindings.put( c, binding ); bindings.put( c, binding );
if( checkForAdditionalBindings ){ // if( checkForAdditionalBindings ){
//need to ensure we have all bindings that correspond to this char[] // //need to ensure we have all bindings that correspond to this char[]
checkForAdditionalBindings = false; // checkForAdditionalBindings = false;
LookupData data = new LookupData( c ); // LookupData data = new LookupData( c );
try { // try {
data.foundItems = CPPSemantics.lookupInScope( data, this, null, null ); // data.foundItems = CPPSemantics.lookupInScope( data, this, null, null );
} catch ( DOMException e ) { // } catch ( DOMException e ) {
} // }
if( data.foundItems != null ){ // if( data.foundItems != null ){
IASTName [] ns = (IASTName[]) data.foundItems; // IASTName [] ns = (IASTName[]) data.foundItems;
for( int i = 0; i < ns.length && ns[i] != null; i++ ){ // for( int i = 0; i < ns.length && ns[i] != null; i++ ){
ns[i].resolveBinding(); // ns[i].resolveBinding();
} // }
} // }
checkForAdditionalBindings = true; // checkForAdditionalBindings = true;
} // }
} }
} }
@ -72,6 +94,9 @@ public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{
*/ */
public IBinding getBinding( IASTName name ) { public IBinding getBinding( IASTName name ) {
char [] c = name.toCharArray(); char [] c = name.toCharArray();
if( bindings == null )
return null;
Object obj = bindings.get( c ); Object obj = bindings.get( c );
if( obj != null ){ if( obj != null ){
if( obj instanceof IBinding[] ){ if( obj instanceof IBinding[] ){
@ -88,4 +113,15 @@ public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{
// TODO Auto-generated method stub // TODO Auto-generated method stub
return null; return null;
} }
public void setFullyResolved( IASTName name ){
if( bindings != null )
bindings.setFullyResolved( name.toCharArray() );
}
public boolean isFullyResolved( IASTName name ){
if( bindings != null )
return bindings.isFullyResolved( name.toCharArray() );
return false;
}
} }

View file

@ -647,7 +647,9 @@ public class CPPSemantics {
ArrayWrapper directives = null; ArrayWrapper directives = null;
if( !data.usingDirectivesOnly ){ if( !data.usingDirectivesOnly ){
IBinding binding = data.prefixLookup ? null : scope.getBinding( data.astName ); IBinding binding = data.prefixLookup ? null : scope.getBinding( data.astName );
if( binding == null || !( CPPSemantics.declaredBefore( binding, data.astName ) || if( binding == null ||
(scope instanceof ICPPNamespaceScope && !((ICPPNamespaceScope) scope).isFullyResolved( data.astName ) ) ||
!( CPPSemantics.declaredBefore( binding, data.astName ) ||
(scope instanceof ICPPClassScope && data.checkWholeClassScope()) ) ) (scope instanceof ICPPClassScope && data.checkWholeClassScope()) ) )
{ {
directives = new ArrayWrapper(); directives = new ArrayWrapper();
@ -900,12 +902,20 @@ public class CPPSemantics {
int idx = -1; int idx = -1;
boolean checkWholeClassScope = ( scope instanceof ICPPClassScope ) && data.checkWholeClassScope(); boolean checkWholeClassScope = ( scope instanceof ICPPClassScope ) && data.checkWholeClassScope();
IASTNode item = ( nodes != null ? (nodes.length > 0 ? nodes[++idx] : null ) : parent ); IASTNode item = ( nodes != null ? (nodes.length > 0 ? nodes[++idx] : null ) : parent );
IASTNode [][] nodeStack = null;
int [] nodeIdxStack = null;
int nodeStackPos = -1;
while( item != null ) { while( item != null ) {
if( item instanceof ICPPASTLinkageSpecification ){ if( item instanceof ICPPASTLinkageSpecification ){
nodes = (IASTNode[]) ArrayUtil.replace( IASTDeclaration.class, nodes, idx, ((ICPPASTLinkageSpecification)item).getDeclarations() ); IASTDeclaration [] decls = ((ICPPASTLinkageSpecification)item).getDeclarations();
if( decls != null && decls.length > 0 ){
nodeStack = (IASTNode[][]) ArrayUtil.append( IASTNode[].class, nodeStack, nodes );
nodeIdxStack = ArrayUtil.setInt( nodeIdxStack, ++nodeStackPos, idx );
nodes = ((ICPPASTLinkageSpecification)item).getDeclarations();
idx = 0;
item = nodes[idx]; item = nodes[idx];
} }
}
if( !checkWholeClassScope && blockItem != null && ((ASTNode)item).getOffset() > ((ASTNode) blockItem).getOffset() ) if( !checkWholeClassScope && blockItem != null && ((ASTNode)item).getOffset() > ((ASTNode) blockItem).getOffset() )
break; break;
@ -930,7 +940,7 @@ public class CPPSemantics {
item = nodes[idx]; item = nodes[idx];
} else { } else {
item = null; item = null;
nullItem: while( item == null ){
if( namespaceIdx > -1 ) { if( namespaceIdx > -1 ) {
//check all definitions of this namespace //check all definitions of this namespace
while( namespaceIdx > -1 && namespaceDefs.length > ++namespaceIdx ){ while( namespaceIdx > -1 && namespaceDefs.length > ++namespaceIdx ){
@ -951,6 +961,17 @@ public class CPPSemantics {
break; break;
} }
} }
if( item == null && nodeStackPos >= 0 ){
nodes = nodeStack[nodeStackPos];
nodeStack[nodeStackPos] = null;
idx = nodeIdxStack[nodeStackPos--];
if( ++idx >= nodes.length )
continue;
item = nodes[idx];
}
break;
}
} }
} }
return found; return found;
@ -991,9 +1012,9 @@ public class CPPSemantics {
IASTDeclaration declaration = null; IASTDeclaration declaration = null;
if( node instanceof IASTDeclaration ) if( node instanceof IASTDeclaration )
declaration = (IASTDeclaration) node; declaration = (IASTDeclaration) node;
if( node instanceof IASTDeclarationStatement ) else if( node instanceof IASTDeclarationStatement )
declaration = ((IASTDeclarationStatement)node).getDeclaration(); declaration = ((IASTDeclarationStatement)node).getDeclaration();
else if( node instanceof IASTForStatement ) else if( node instanceof IASTForStatement && checkAux )
declaration = ((IASTForStatement)node).getInitDeclaration(); declaration = ((IASTForStatement)node).getInitDeclaration();
else if( node instanceof IASTParameterDeclaration && !data.typesOnly() ){ else if( node instanceof IASTParameterDeclaration && !data.typesOnly() ){
IASTParameterDeclaration parameterDeclaration = (IASTParameterDeclaration) node; IASTParameterDeclaration parameterDeclaration = (IASTParameterDeclaration) node;
@ -1010,7 +1031,7 @@ public class CPPSemantics {
if( declaration instanceof IASTSimpleDeclaration ){ if( declaration instanceof IASTSimpleDeclaration ){
IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration; IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration;
if( !data.typesOnly() ) { if( !data.typesOnly() || simpleDeclaration.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef ) {
IASTDeclarator [] declarators = simpleDeclaration.getDeclarators(); IASTDeclarator [] declarators = simpleDeclaration.getDeclarators();
for( int i = 0; i < declarators.length; i++ ){ for( int i = 0; i < declarators.length; i++ ){
IASTDeclarator declarator = declarators[i]; IASTDeclarator declarator = declarators[i];
@ -1195,9 +1216,15 @@ public class CPPSemantics {
Object [] items = (Object[]) data.foundItems; Object [] items = (Object[]) data.foundItems;
for( int i = 0; i < items.length && items[i] != null; i++ ){ for( int i = 0; i < items.length && items[i] != null; i++ ){
Object o = items[i]; Object o = items[i];
if( o instanceof IASTName ) if( o instanceof IASTName ){
temp = ((IASTName) o).resolveBinding(); temp = ((IASTName) o).resolveBinding();
else if( o instanceof IBinding ){ if( temp == null )
continue;
IScope scope = temp.getScope();
if( scope instanceof CPPNamespaceScope ){
((CPPNamespaceScope)scope).setFullyResolved( (IASTName) o );
}
} else if( o instanceof IBinding ){
temp = (IBinding) o; temp = (IBinding) o;
if( !( temp instanceof ICPPMember ) && !declaredBefore( temp, name ) ) if( !( temp instanceof ICPPMember ) && !declaredBefore( temp, name ) )
continue; continue;

View file

@ -312,7 +312,7 @@ public class CPPVisitor implements ICPPASTVisitor {
if( elabType.getKind() != IASTElaboratedTypeSpecifier.k_enum ) if( elabType.getKind() != IASTElaboratedTypeSpecifier.k_enum )
binding = new CPPClassType( elabType.getName() ); binding = new CPPClassType( elabType.getName() );
scope.addBinding( binding ); scope.addBinding( binding );
} else { } else if( binding instanceof ICPPClassType ){
((CPPClassType)binding).addDeclaration( elabType ); ((CPPClassType)binding).addDeclaration( elabType );
} }
} catch ( DOMException e ) { } catch ( DOMException e ) {
@ -643,6 +643,8 @@ public class CPPVisitor implements ICPPASTVisitor {
return parent; return parent;
} else if( parent instanceof IASTExpression ){ } else if( parent instanceof IASTExpression ){
IASTNode p = parent.getParent(); IASTNode p = parent.getParent();
if( p instanceof IASTForStatement )
return parent;
if( p instanceof IASTStatement ) if( p instanceof IASTStatement )
return p; return p;
} else if ( parent instanceof IASTStatement || parent instanceof IASTTranslationUnit ) { } else if ( parent instanceof IASTStatement || parent instanceof IASTTranslationUnit ) {

View file

@ -86,6 +86,9 @@ public class ParserUtil
catch( IOException e ) catch( IOException e )
{ {
} }
catch( IllegalStateException e )
{
}
return InternalParserUtil.createFileReader(finalPath); return InternalParserUtil.createFileReader(finalPath);
} }