1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-09-08 11:03:28 +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;
import org.eclipse.cdt.core.dom.ast.IASTName;
/**
* @author aniefer
*/
public interface ICPPNamespaceScope extends ICPPScope {
boolean isFullyResolved( IASTName name );
}

View file

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

View file

@ -13,21 +13,43 @@
*/
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.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPSemantics.LookupData;
/**
* @author aniefer
*/
public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{
private CharArrayObjectMap bindings = CharArrayObjectMap.EMPTY_MAP;
private boolean checkForAdditionalBindings = true;
private static class ScopeMap extends CharArrayObjectMap {
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 ) {
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)
*/
public void addBinding(IBinding binding) {
if( bindings == CharArrayObjectMap.EMPTY_MAP )
bindings = new CharArrayObjectMap(1);
if( bindings == null )
bindings = new ScopeMap(1);
char [] c = binding.getNameCharArray();
Object o = bindings.get( c );
if( o != null ){
@ -48,22 +70,22 @@ public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{
}
} else {
bindings.put( c, binding );
if( checkForAdditionalBindings ){
//need to ensure we have all bindings that correspond to this char[]
checkForAdditionalBindings = false;
LookupData data = new LookupData( c );
try {
data.foundItems = CPPSemantics.lookupInScope( data, this, null, null );
} catch ( DOMException e ) {
}
if( data.foundItems != null ){
IASTName [] ns = (IASTName[]) data.foundItems;
for( int i = 0; i < ns.length && ns[i] != null; i++ ){
ns[i].resolveBinding();
}
}
checkForAdditionalBindings = true;
}
// if( checkForAdditionalBindings ){
// //need to ensure we have all bindings that correspond to this char[]
// checkForAdditionalBindings = false;
// LookupData data = new LookupData( c );
// try {
// data.foundItems = CPPSemantics.lookupInScope( data, this, null, null );
// } catch ( DOMException e ) {
// }
// if( data.foundItems != null ){
// IASTName [] ns = (IASTName[]) data.foundItems;
// for( int i = 0; i < ns.length && ns[i] != null; i++ ){
// ns[i].resolveBinding();
// }
// }
// checkForAdditionalBindings = true;
// }
}
}
@ -72,6 +94,9 @@ public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{
*/
public IBinding getBinding( IASTName name ) {
char [] c = name.toCharArray();
if( bindings == null )
return null;
Object obj = bindings.get( c );
if( obj != null ){
if( obj instanceof IBinding[] ){
@ -88,4 +113,15 @@ public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{
// TODO Auto-generated method stub
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,8 +647,10 @@ public class CPPSemantics {
ArrayWrapper directives = null;
if( !data.usingDirectivesOnly ){
IBinding binding = data.prefixLookup ? null : scope.getBinding( data.astName );
if( binding == null || !( CPPSemantics.declaredBefore( binding, data.astName ) ||
(scope instanceof ICPPClassScope && data.checkWholeClassScope())) )
if( binding == null ||
(scope instanceof ICPPNamespaceScope && !((ICPPNamespaceScope) scope).isFullyResolved( data.astName ) ) ||
!( CPPSemantics.declaredBefore( binding, data.astName ) ||
(scope instanceof ICPPClassScope && data.checkWholeClassScope()) ) )
{
directives = new ArrayWrapper();
mergeResults( data, lookupInScope( data, scope, blockItem, directives ), true );
@ -900,11 +902,19 @@ public class CPPSemantics {
int idx = -1;
boolean checkWholeClassScope = ( scope instanceof ICPPClassScope ) && data.checkWholeClassScope();
IASTNode item = ( nodes != null ? (nodes.length > 0 ? nodes[++idx] : null ) : parent );
IASTNode [][] nodeStack = null;
int [] nodeIdxStack = null;
int nodeStackPos = -1;
while( item != null ) {
if( item instanceof ICPPASTLinkageSpecification ){
nodes = (IASTNode[]) ArrayUtil.replace( IASTDeclaration.class, nodes, idx, ((ICPPASTLinkageSpecification)item).getDeclarations() );
item = nodes[idx];
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];
}
}
if( !checkWholeClassScope && blockItem != null && ((ASTNode)item).getOffset() > ((ASTNode) blockItem).getOffset() )
break;
@ -930,26 +940,37 @@ public class CPPSemantics {
item = nodes[idx];
} else {
item = null;
if( namespaceIdx > -1 ) {
//check all definitions of this namespace
while( namespaceIdx > -1 && namespaceDefs.length > ++namespaceIdx ){
nodes = ((ICPPASTNamespaceDefinition)namespaceDefs[namespaceIdx].getParent()).getDeclarations();
if( nodes.length > 0 ){
nullItem: while( item == null ){
if( namespaceIdx > -1 ) {
//check all definitions of this namespace
while( namespaceIdx > -1 && namespaceDefs.length > ++namespaceIdx ){
nodes = ((ICPPASTNamespaceDefinition)namespaceDefs[namespaceIdx].getParent()).getDeclarations();
if( nodes.length > 0 ){
idx = 0;
item = nodes[0];
break;
}
}
} else if( parent instanceof IASTCompoundStatement && nodes instanceof IASTParameterDeclaration [] ){
//function body, we were looking at parameters, now check the body itself
IASTCompoundStatement compound = (IASTCompoundStatement) parent;
nodes = compound.getStatements();
if( nodes.length > 0 ){
idx = 0;
item = nodes[0];
break;
}
}
}
} else if( parent instanceof IASTCompoundStatement && nodes instanceof IASTParameterDeclaration [] ){
//function body, we were looking at parameters, now check the body itself
IASTCompoundStatement compound = (IASTCompoundStatement) parent;
nodes = compound.getStatements();
if( nodes.length > 0 ){
idx = 0;
item = nodes[0];
break;
}
if( item == null && nodeStackPos >= 0 ){
nodes = nodeStack[nodeStackPos];
nodeStack[nodeStackPos] = null;
idx = nodeIdxStack[nodeStackPos--];
if( ++idx >= nodes.length )
continue;
item = nodes[idx];
}
break;
}
}
}
@ -991,9 +1012,9 @@ public class CPPSemantics {
IASTDeclaration declaration = null;
if( node instanceof IASTDeclaration )
declaration = (IASTDeclaration) node;
if( node instanceof IASTDeclarationStatement )
else if( node instanceof IASTDeclarationStatement )
declaration = ((IASTDeclarationStatement)node).getDeclaration();
else if( node instanceof IASTForStatement )
else if( node instanceof IASTForStatement && checkAux )
declaration = ((IASTForStatement)node).getInitDeclaration();
else if( node instanceof IASTParameterDeclaration && !data.typesOnly() ){
IASTParameterDeclaration parameterDeclaration = (IASTParameterDeclaration) node;
@ -1010,7 +1031,7 @@ public class CPPSemantics {
if( declaration instanceof IASTSimpleDeclaration ){
IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration;
if( !data.typesOnly() ) {
if( !data.typesOnly() || simpleDeclaration.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef ) {
IASTDeclarator [] declarators = simpleDeclaration.getDeclarators();
for( int i = 0; i < declarators.length; i++ ){
IASTDeclarator declarator = declarators[i];
@ -1195,9 +1216,15 @@ public class CPPSemantics {
Object [] items = (Object[]) data.foundItems;
for( int i = 0; i < items.length && items[i] != null; i++ ){
Object o = items[i];
if( o instanceof IASTName )
if( o instanceof IASTName ){
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;
if( !( temp instanceof ICPPMember ) && !declaredBefore( temp, name ) )
continue;

View file

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

View file

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