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:
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;
|
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 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ){
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -647,8 +647,10 @@ 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 ICPPClassScope && data.checkWholeClassScope())) )
|
(scope instanceof ICPPNamespaceScope && !((ICPPNamespaceScope) scope).isFullyResolved( data.astName ) ) ||
|
||||||
|
!( CPPSemantics.declaredBefore( binding, data.astName ) ||
|
||||||
|
(scope instanceof ICPPClassScope && data.checkWholeClassScope()) ) )
|
||||||
{
|
{
|
||||||
directives = new ArrayWrapper();
|
directives = new ArrayWrapper();
|
||||||
mergeResults( data, lookupInScope( data, scope, blockItem, directives ), true );
|
mergeResults( data, lookupInScope( data, scope, blockItem, directives ), true );
|
||||||
|
@ -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;
|
||||||
|
|
|
@ -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 ) {
|
||||||
|
|
|
@ -86,6 +86,9 @@ public class ParserUtil
|
||||||
catch( IOException e )
|
catch( IOException e )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
catch( IllegalStateException e )
|
||||||
|
{
|
||||||
|
}
|
||||||
return InternalParserUtil.createFileReader(finalPath);
|
return InternalParserUtil.createFileReader(finalPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue