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:
parent
cd6f234947
commit
cd662e1910
7 changed files with 144 additions and 49 deletions
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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 ){
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
|
@ -86,6 +86,9 @@ public class ParserUtil
|
|||
catch( IOException e )
|
||||
{
|
||||
}
|
||||
catch( IllegalStateException e )
|
||||
{
|
||||
}
|
||||
return InternalParserUtil.createFileReader(finalPath);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue