mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 14:42:11 +02:00
Change scope caching to improve performance
This commit is contained in:
parent
b733817bab
commit
1741ff8c15
10 changed files with 419 additions and 356 deletions
|
@ -13,12 +13,28 @@
|
|||
*/
|
||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
*/
|
||||
public interface ICPPNamespaceScope extends ICPPScope {
|
||||
boolean isFullyResolved( IASTName name );
|
||||
|
||||
/**
|
||||
* Add an IASTNode that nominates another namespace to this scope
|
||||
* Most commonly, ICPPASTUsingDirectives, but in the case of unnamed namespaces,
|
||||
* it could be an ICPPASTNamespaceDefinition
|
||||
* @param directive
|
||||
*/
|
||||
public void addUsingDirective( IASTNode directive ) throws DOMException;
|
||||
|
||||
/**
|
||||
* Get the IASTNodes that have been added to this scope to nominate other
|
||||
* namespaces during lookup. (ICPPASTUsingDirective or ICPPASTNamespaceDefinition)
|
||||
* @return
|
||||
*/
|
||||
public IASTNode[] getUsingDirectives() throws DOMException;
|
||||
|
||||
}
|
||||
|
|
|
@ -19,10 +19,43 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
|
|||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
|
||||
/**
|
||||
* The ICPPScope serves as a mechanism for caching IASTNames and
|
||||
* bindings to speed up resolution.
|
||||
*
|
||||
* @author aniefer
|
||||
*/
|
||||
public interface ICPPScope extends IScope {
|
||||
|
||||
public void addBinding( IBinding binding ) throws DOMException;
|
||||
public IBinding getBinding( IASTName name ) throws DOMException;
|
||||
/**
|
||||
* Add an IASTName to be cached in this scope
|
||||
* @param name
|
||||
* @throws DOMException
|
||||
*/
|
||||
public void addName( IASTName name ) throws DOMException;
|
||||
|
||||
/**
|
||||
* Get the binding that the given name would resolve to in this scope.
|
||||
* Could return null if there is no matching binding in this scope,
|
||||
* or if resolve == false and the appropriate binding has not yet been
|
||||
* resolved.
|
||||
*
|
||||
* @param name
|
||||
* @param resolve : whether or not to resolve the matching binding if it
|
||||
* has not been so already.
|
||||
* @return : the binding in this scope that matches the name, or null
|
||||
* @throws DOMException
|
||||
*/
|
||||
public IBinding getBinding( IASTName name, boolean resolve ) throws DOMException;
|
||||
|
||||
/**
|
||||
* Set whether or not all the names in this scope have been cached
|
||||
* @param b
|
||||
*/
|
||||
public void setFullyCached(boolean b) throws DOMException;
|
||||
|
||||
/**
|
||||
* whether or not this scope's cache contains all the names
|
||||
* @return
|
||||
*/
|
||||
public boolean isFullyCached() throws DOMException;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,8 @@ public class ArrayUtil {
|
|||
* @return
|
||||
*/
|
||||
static public Object [] append( Class c, Object[] array, Object obj ){
|
||||
if( obj == null )
|
||||
return array;
|
||||
if( array == null || array.length == 0){
|
||||
array = (Object[]) Array.newInstance( c, DEFAULT_LENGTH );
|
||||
array[0] = obj;
|
||||
|
|
|
@ -16,7 +16,6 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
|
@ -111,7 +110,7 @@ public class CPPASTTemplateId extends CPPASTNode implements ICPPASTTemplateId {
|
|||
*/
|
||||
public IBinding resolveBinding() {
|
||||
// TODO templates not yet supported
|
||||
return new ProblemBinding( -1, templateName.toCharArray() );
|
||||
return new CPPScope.CPPTemplateProblem( -1, templateName.toCharArray() );
|
||||
}
|
||||
|
||||
public IBinding[] resolvePrefix() {
|
||||
|
|
|
@ -15,6 +15,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
|||
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
|
@ -32,15 +33,13 @@ 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.ObjectSet;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPSemantics.LookupData;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
*/
|
||||
public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
||||
private CharArrayObjectMap bindings = CharArrayObjectMap.EMPTY_MAP;
|
||||
private ICPPConstructor [] constructors = null;
|
||||
boolean checkForAdditionalBindings = true;
|
||||
private ObjectSet constructorBindings = ObjectSet.EMPTY_SET;
|
||||
private ObjectSet constructorNames = ObjectSet.EMPTY_SET;
|
||||
|
||||
public CPPClassScope( ICPPASTCompositeTypeSpecifier physicalNode ) {
|
||||
super( physicalNode );
|
||||
|
@ -61,15 +60,22 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
|||
return;
|
||||
}
|
||||
|
||||
char [] className = compTypeSpec.getName().toCharArray();
|
||||
IASTName name = compTypeSpec.getName();
|
||||
if( name instanceof ICPPASTQualifiedName ){
|
||||
IASTName [] ns = ((ICPPASTQualifiedName) name).getNames();
|
||||
name = ns[ ns.length - 1 ];
|
||||
}
|
||||
|
||||
checkForAdditionalBindings = false;
|
||||
IBinding binding = compTypeSpec.getName().resolveBinding();
|
||||
if( !(binding instanceof ICPPClassType ) )
|
||||
return;
|
||||
ICPPClassType clsType = (ICPPClassType) binding;
|
||||
|
||||
char [] className = name.toCharArray();
|
||||
|
||||
//default constructor: A()
|
||||
addBinding( new CPPImplicitConstructor( this, className, IParameter.EMPTY_PARAMETER_ARRAY ) );
|
||||
|
||||
ICPPClassType clsType = (ICPPClassType) compTypeSpec.getName().resolveBinding();
|
||||
|
||||
//copy constructor: A( const A & )
|
||||
IType pType = new CPPReferenceType( new CPPQualifierType( clsType, true, false ) );
|
||||
IParameter [] ps = new IParameter [] { new CPPParameter( pType ) };
|
||||
|
@ -82,8 +88,6 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
|||
//destructor: ~A()
|
||||
char [] dtorName = CharArrayUtils.concat( "~".toCharArray(), className ); //$NON-NLS-1$
|
||||
addBinding( new CPPImplicitMethod( this, dtorName, new CPPBasicType( IBasicType.t_unspecified, 0 ), IParameter.EMPTY_PARAMETER_ARRAY ) );
|
||||
|
||||
checkForAdditionalBindings = true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -91,99 +95,82 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
|||
*/
|
||||
public void addBinding(IBinding binding) {
|
||||
if( binding instanceof ICPPConstructor ){
|
||||
addConstructor( (ICPPConstructor) binding );
|
||||
addConstructor( binding );
|
||||
return;
|
||||
}
|
||||
if( bindings == CharArrayObjectMap.EMPTY_MAP )
|
||||
if( bindings == null )
|
||||
bindings = new CharArrayObjectMap(1);
|
||||
char [] c = binding.getNameCharArray();
|
||||
Object o = bindings.get( c );
|
||||
if( o != null ){
|
||||
if( o instanceof IBinding[] ){
|
||||
bindings.put( c, ArrayUtil.append( IBinding.class, (Object[]) o, binding ) );
|
||||
if( o instanceof Object[] ){
|
||||
bindings.put( c, ArrayUtil.append( Object.class, (Object[]) o, binding ) );
|
||||
} else {
|
||||
bindings.put( c, new IBinding[] { (IBinding) o, binding } );
|
||||
bindings.put( c, new Object[] { o, binding } );
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addConstructor( ICPPConstructor constructor ){
|
||||
if( constructors == null )
|
||||
constructors = new ICPPConstructor[ 2 ];
|
||||
|
||||
int i = 0;
|
||||
for( ; i < constructors.length; i++ ){
|
||||
if( constructors[i] == null ){
|
||||
constructors[i] = constructor;
|
||||
public void addName(IASTName name) {
|
||||
IASTNode parent = name.getParent();
|
||||
if( parent instanceof IASTDeclarator ){
|
||||
if( CPPVisitor.isConstructor( this, (IASTDeclarator) parent ) ){
|
||||
addConstructor( name );
|
||||
return;
|
||||
}
|
||||
}
|
||||
ICPPConstructor [] temp = new ICPPConstructor[ constructors.length * 2 ];
|
||||
System.arraycopy( constructors, 0, temp, 0, constructors.length );
|
||||
temp[ constructors.length ] = constructor;
|
||||
constructors = temp;
|
||||
super.addName( name );
|
||||
}
|
||||
|
||||
private void addConstructor( Object constructor ){
|
||||
if( constructor instanceof IBinding ){
|
||||
if( constructorBindings == ObjectSet.EMPTY_SET )
|
||||
constructorBindings = new ObjectSet( 2 );
|
||||
|
||||
constructorBindings.put( constructor );
|
||||
} else {
|
||||
if( constructorNames == ObjectSet.EMPTY_SET )
|
||||
constructorNames = new ObjectSet( 2 );
|
||||
|
||||
constructorNames.put( constructor );
|
||||
}
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#getBinding(int, char[])
|
||||
*/
|
||||
public IBinding getBinding( IASTName name ) throws DOMException {
|
||||
public IBinding getBinding( IASTName name, boolean resolve ) throws DOMException {
|
||||
char [] c = name.toCharArray();
|
||||
|
||||
ICPPASTCompositeTypeSpecifier compType = (ICPPASTCompositeTypeSpecifier) getPhysicalNode();
|
||||
if( CharArrayUtils.equals( c, compType.getName().toCharArray() ) ){
|
||||
IASTName compName = compType.getName();
|
||||
if( compName instanceof ICPPASTQualifiedName ){
|
||||
IASTName [] ns = ((ICPPASTQualifiedName)compName).getNames();
|
||||
compName = ns[ ns.length - 1 ];
|
||||
}
|
||||
if( CharArrayUtils.equals( c, compName.toCharArray() ) ){
|
||||
if( isConstructorReference( name ) ){
|
||||
if( constructors == null )
|
||||
return null;
|
||||
return CPPSemantics.resolveAmbiguities( name, constructors );
|
||||
// if( constructors == null )
|
||||
// return null;
|
||||
return CPPSemantics.resolveAmbiguities( name, getConstructors( resolve ) );
|
||||
}
|
||||
//9.2 ... The class-name is also inserted into the scope of the class itself
|
||||
return compType.getName().resolveBinding();
|
||||
}
|
||||
|
||||
Object obj = bindings.get( c );
|
||||
if( obj != null ){
|
||||
if( obj instanceof IBinding[] ){
|
||||
obj = CPPSemantics.resolveAmbiguities( name, (IBinding[]) obj );
|
||||
}
|
||||
}
|
||||
return (IBinding) obj;
|
||||
return super.getBinding( name, resolve );
|
||||
}
|
||||
|
||||
protected ICPPConstructor [] getConstructors(){
|
||||
if( constructors == null ){
|
||||
constructors = new ICPPConstructor[0];
|
||||
return constructors;
|
||||
protected ICPPConstructor [] getConstructors( boolean forceResolve ){
|
||||
if( forceResolve && constructorNames.size() > 0 ){
|
||||
Object [] names = constructorNames.keyArray();
|
||||
for( int i = 0; i < names.length; i++ ){
|
||||
ICPPConstructor ctor = (ICPPConstructor) ((IASTName)names[i]).resolveBinding();
|
||||
constructorBindings.put( ctor );
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for( ; i < constructors.length; i++ )
|
||||
if( constructors[i] == null )
|
||||
break;
|
||||
if( i < constructors.length ){
|
||||
ICPPConstructor[] temp = new ICPPConstructor[ i ];
|
||||
System.arraycopy( constructors, 0, temp, 0, i );
|
||||
constructors = temp;
|
||||
constructorNames.clear();
|
||||
}
|
||||
|
||||
return constructors;
|
||||
return (ICPPConstructor[]) ArrayUtil.trim( ICPPConstructor.class, constructorBindings.keyArray(), true);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -193,30 +180,9 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
|||
char [] n = name.toCharArray();
|
||||
ICPPASTCompositeTypeSpecifier compType = (ICPPASTCompositeTypeSpecifier) getPhysicalNode();
|
||||
if( CharArrayUtils.equals( n, compType.getName().toCharArray() ) ){
|
||||
return (IBinding[]) ArrayUtil.addAll( IBinding.class, null, getConstructors() );
|
||||
return (IBinding[]) ArrayUtil.addAll( IBinding.class, null, getConstructors( true ) );
|
||||
}
|
||||
if( bindings != null && bindings.containsKey( n ) ){
|
||||
Object o = bindings.get( n );
|
||||
if( o instanceof IBinding[] )
|
||||
return (IBinding[]) ArrayUtil.trim( IBinding.class, (Object[]) o );
|
||||
return new IBinding[] { (IBinding) o };
|
||||
}
|
||||
LookupData data = new LookupData( n );
|
||||
try {
|
||||
data.foundItems = CPPSemantics.lookupInScope( data, this, null, null );
|
||||
} catch ( DOMException e ) {
|
||||
}
|
||||
|
||||
if( data.foundItems != null ){
|
||||
IASTName [] ns = (IASTName[]) data.foundItems;
|
||||
ObjectSet set = new ObjectSet( ns.length );
|
||||
for( int i = 0; i < ns.length && ns[i] != null; i++ ){
|
||||
set.put( ns[i].resolveBinding() );
|
||||
}
|
||||
return (IBinding[]) ArrayUtil.trim( IBinding.class, set.keyArray(), true );
|
||||
}
|
||||
|
||||
return new IBinding[0];
|
||||
return super.find( name );
|
||||
}
|
||||
|
||||
private boolean isConstructorReference( IASTName name ){
|
||||
|
|
|
@ -388,7 +388,7 @@ public class CPPClassType implements ICPPClassType, ICPPBinding {
|
|||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getConstructors()
|
||||
*/
|
||||
public ICPPConstructor[] getConstructors() {
|
||||
public ICPPConstructor[] getConstructors() throws DOMException {
|
||||
if( definition == null ){
|
||||
checkForDefinition();
|
||||
if( definition == null ){
|
||||
|
@ -397,23 +397,24 @@ public class CPPClassType implements ICPPClassType, ICPPBinding {
|
|||
}
|
||||
|
||||
ICPPClassScope scope = (ICPPClassScope) getCompositeScope();
|
||||
if( scope.isFullyCached() )
|
||||
return ((CPPClassScope)scope).getConstructors( true );
|
||||
|
||||
IASTDeclaration [] members = getCompositeTypeSpecifier().getMembers();
|
||||
for( int i = 0; i < members.length; i++ ){
|
||||
if( members[i] instanceof IASTSimpleDeclaration ){
|
||||
IASTDeclarator [] dtors = ((IASTSimpleDeclaration)members[i]).getDeclarators();
|
||||
for( int j = 0; j < dtors.length; j++ ){
|
||||
if( dtors[j] == null ) break;
|
||||
if( CPPVisitor.isConstructor( scope, dtors[j] ) )
|
||||
dtors[j].getName().resolveBinding();
|
||||
scope.addName( dtors[j].getName() );
|
||||
}
|
||||
} else if( members[i] instanceof IASTFunctionDefinition ){
|
||||
IASTDeclarator dtor = ((IASTFunctionDefinition)members[i]).getDeclarator();
|
||||
if( CPPVisitor.isConstructor( scope, dtor ) )
|
||||
dtor.getName().resolveBinding();
|
||||
scope.addName( dtor.getName() );
|
||||
}
|
||||
}
|
||||
|
||||
return ((CPPClassScope)scope).getConstructors();
|
||||
return ((CPPClassScope)scope).getConstructors( true );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
|
|
@ -13,122 +13,30 @@
|
|||
*/
|
||||
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.core.parser.util.ObjectSet;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPSemantics.LookupData;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
*/
|
||||
public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{
|
||||
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;
|
||||
IASTNode[] usings = null;
|
||||
|
||||
public CPPNamespaceScope( IASTNode physicalNode ) {
|
||||
super( physicalNode );
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#addBinding(org.eclipse.cdt.core.dom.ast.IBinding)
|
||||
*/
|
||||
public void addBinding(IBinding binding) {
|
||||
if( bindings == null )
|
||||
bindings = new ScopeMap(1);
|
||||
char [] c = binding.getNameCharArray();
|
||||
Object o = bindings.get( c );
|
||||
if( o != null ){
|
||||
if( o instanceof IBinding[] ){
|
||||
bindings.put( c, ArrayUtil.append( IBinding.class, (Object[]) o, binding ) );
|
||||
} else {
|
||||
bindings.put( c, new IBinding[] { (IBinding) o, binding } );
|
||||
}
|
||||
} else {
|
||||
bindings.put( c, binding );
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#getBinding(int, char[])
|
||||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope#getUsingDirectives()
|
||||
*/
|
||||
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[] ){
|
||||
obj = CPPSemantics.resolveAmbiguities( name, (IBinding[]) obj );
|
||||
public IASTNode[] getUsingDirectives() {
|
||||
return (IASTNode[]) ArrayUtil.trim( IASTNode.class, usings, true );
|
||||
}
|
||||
}
|
||||
return (IBinding) obj;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String)
|
||||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope#addUsingDirective(org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective)
|
||||
*/
|
||||
public IBinding[] find(String name) {
|
||||
char [] n = name.toCharArray();
|
||||
if( bindings != null && bindings.isFullyResolved( n ) ){
|
||||
Object o = bindings.get( n );
|
||||
if( o instanceof IBinding[] )
|
||||
return (IBinding[]) ArrayUtil.trim( IBinding.class, (Object[]) o );
|
||||
return new IBinding[] { (IBinding) o };
|
||||
}
|
||||
LookupData data = new LookupData( n );
|
||||
try {
|
||||
data.foundItems = CPPSemantics.lookupInScope( data, this, null, null );
|
||||
} catch ( DOMException e ) {
|
||||
}
|
||||
|
||||
if( data.foundItems != null ){
|
||||
IASTName [] ns = (IASTName[]) data.foundItems;
|
||||
ObjectSet set = new ObjectSet( ns.length );
|
||||
for( int i = 0; i < ns.length && ns[i] != null; i++ ){
|
||||
set.put( ns[i].resolveBinding() );
|
||||
}
|
||||
return (IBinding[]) ArrayUtil.trim( IBinding.class, set.keyArray(), true );
|
||||
}
|
||||
|
||||
return new IBinding[0];
|
||||
}
|
||||
|
||||
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;
|
||||
public void addUsingDirective(IASTNode directive) {
|
||||
usings = (IASTNode[]) ArrayUtil.append( IASTNode.class, usings, directive );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,8 +18,14 @@ 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.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPCompositeBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
|
||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
|
||||
import org.eclipse.cdt.core.parser.util.ObjectSet;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPSemantics.LookupData;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
|
@ -29,11 +35,11 @@ abstract public class CPPScope implements ICPPScope{
|
|||
public CPPScopeProblem( int id, char[] arg ) {
|
||||
super( id, arg );
|
||||
}
|
||||
public void addBinding( IBinding binding ) throws DOMException {
|
||||
public void addName( IASTName name ) throws DOMException {
|
||||
throw new DOMException( this );
|
||||
}
|
||||
|
||||
public IBinding getBinding( IASTName name ) throws DOMException {
|
||||
public IBinding getBinding( IASTName name, boolean resolve ) throws DOMException {
|
||||
throw new DOMException( this );
|
||||
}
|
||||
|
||||
|
@ -44,6 +50,16 @@ abstract public class CPPScope implements ICPPScope{
|
|||
public IBinding[] find( String name ) throws DOMException {
|
||||
throw new DOMException( this );
|
||||
}
|
||||
public void setFullyCached(boolean b) {
|
||||
}
|
||||
public boolean isFullyCached() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public static class CPPTemplateProblem extends CPPScopeProblem {
|
||||
public CPPTemplateProblem(int id, char[] arg) {
|
||||
super(id, arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -62,4 +78,113 @@ abstract public class CPPScope implements ICPPScope{
|
|||
public IASTNode getPhysicalNode() throws DOMException{
|
||||
return physicalNode;
|
||||
}
|
||||
|
||||
protected CharArrayObjectMap bindings = null;
|
||||
|
||||
public void addName(IASTName name) {
|
||||
if( bindings == null )
|
||||
bindings = new CharArrayObjectMap(1);
|
||||
char [] c = name.toCharArray();
|
||||
Object o = bindings.get( c );
|
||||
if( o != null ){
|
||||
if( o instanceof ObjectSet ){
|
||||
((ObjectSet)o).put( name );
|
||||
//bindings.put( c, ArrayUtil.append( Object.class, (Object[]) o, name ) );
|
||||
} else {
|
||||
ObjectSet temp = new ObjectSet( 2 );
|
||||
temp.put( o );
|
||||
temp.put( name );
|
||||
bindings.put( c, temp );
|
||||
}
|
||||
} else {
|
||||
bindings.put( c, name );
|
||||
}
|
||||
}
|
||||
|
||||
public IBinding getBinding(IASTName name, boolean forceResolve) throws DOMException {
|
||||
char [] c = name.toCharArray();
|
||||
if( bindings == null )
|
||||
return null;
|
||||
|
||||
Object obj = bindings.get( c );
|
||||
if( obj != null ){
|
||||
if( obj instanceof ObjectSet ) {
|
||||
if( forceResolve )
|
||||
return CPPSemantics.resolveAmbiguities( name, ((ObjectSet) obj).keyArray() );
|
||||
IBinding [] bs = null;
|
||||
Object [] os = ((ObjectSet) obj).keyArray();
|
||||
for( int i = 0; i < os.length; i++ ){
|
||||
if( os[i] instanceof IASTName ){
|
||||
IASTName n = (IASTName) os[i];
|
||||
if( n instanceof ICPPASTQualifiedName ){
|
||||
IASTName [] ns = ((ICPPASTQualifiedName)n).getNames();
|
||||
n = ns[ ns.length - 1 ];
|
||||
}
|
||||
bs = (IBinding[]) ArrayUtil.append( IBinding.class, bs, ((CPPASTName)n).getBinding() );
|
||||
} else
|
||||
bs = (IBinding[]) ArrayUtil.append( IBinding.class, bs, os[i] );
|
||||
}
|
||||
return CPPSemantics.resolveAmbiguities( name, bs );
|
||||
} else if( obj instanceof IASTName ){
|
||||
IBinding binding = null;
|
||||
if( forceResolve && obj != name )
|
||||
binding = ((IASTName)obj).resolveBinding();
|
||||
else {
|
||||
IASTName n = (IASTName) obj;
|
||||
if( n instanceof ICPPASTQualifiedName ){
|
||||
IASTName [] ns = ((ICPPASTQualifiedName)n).getNames();
|
||||
n = ns[ ns.length - 1 ];
|
||||
}
|
||||
binding = ((CPPASTName)n).getBinding();
|
||||
}
|
||||
if( binding instanceof ICPPCompositeBinding ){
|
||||
return CPPSemantics.resolveAmbiguities( name, ((ICPPCompositeBinding)binding).getBindings() );
|
||||
}
|
||||
return binding;
|
||||
}
|
||||
return (IBinding) obj;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean isfull = false;
|
||||
public void setFullyCached( boolean full ){
|
||||
isfull = full;
|
||||
}
|
||||
|
||||
public boolean isFullyCached(){
|
||||
return isfull;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String)
|
||||
*/
|
||||
public IBinding[] find(String name) throws DOMException {
|
||||
char [] n = name.toCharArray();
|
||||
if( isFullyCached() ){
|
||||
if( bindings != null ) {
|
||||
Object o = bindings.get( n );
|
||||
if( o instanceof IBinding[] )
|
||||
return (IBinding[]) ArrayUtil.trim( IBinding.class, (Object[]) o );
|
||||
return new IBinding[] { (IBinding) o };
|
||||
}
|
||||
} else {
|
||||
LookupData data = new LookupData( n );
|
||||
try {
|
||||
data.foundItems = CPPSemantics.lookupInScope( data, this, null, null );
|
||||
} catch ( DOMException e ) {
|
||||
}
|
||||
|
||||
if( data.foundItems != null ){
|
||||
IASTName [] ns = (IASTName[]) data.foundItems;
|
||||
ObjectSet set = new ObjectSet( ns.length );
|
||||
for( int i = 0; i < ns.length && ns[i] != null; i++ ){
|
||||
set.put( ns[i].resolveBinding() );
|
||||
}
|
||||
return (IBinding[]) ArrayUtil.trim( IBinding.class, set.keyArray(), true );
|
||||
}
|
||||
}
|
||||
|
||||
return new IBinding[0];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,6 @@ import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
||||
|
@ -199,7 +198,8 @@ public class CPPSemantics {
|
|||
} else if( p1 instanceof ICPPASTQualifiedName && p2 instanceof ICPPASTNamedTypeSpecifier ){
|
||||
IASTNode p3 = p2.getParent();
|
||||
return p3 instanceof IASTTypeId && p3.getParent() instanceof ICPPASTNewExpression;
|
||||
}
|
||||
} else if( p1 instanceof IASTFunctionCallExpression || p2 instanceof IASTFunctionCallExpression )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
public boolean qualified(){
|
||||
|
@ -437,7 +437,7 @@ public class CPPSemantics {
|
|||
IBinding [] ctors = cls.getConstructors();
|
||||
if( ctors.length > 0 && !(ctors[0] instanceof IProblemBinding) ){
|
||||
//then use the class scope to resolve which one.
|
||||
binding = ((ICPPClassScope)cls.getCompositeScope()).getBinding( data.astName );
|
||||
binding = ((ICPPClassScope)cls.getCompositeScope()).getBinding( data.astName, true );
|
||||
}
|
||||
} catch ( DOMException e ) {
|
||||
binding = e.getProblem();
|
||||
|
@ -451,23 +451,7 @@ public class CPPSemantics {
|
|||
if( binding != null && !( binding instanceof IProblemBinding ) ){
|
||||
if( data.forDefinition() ){
|
||||
addDefinition( binding, data.astName );
|
||||
} else if( data.forUsingDeclaration() ){
|
||||
IASTNode node = CPPVisitor.getContainingBlockItem( data.astName );
|
||||
ICPPScope scope = (ICPPScope) CPPVisitor.getContainingScope( node );
|
||||
try {
|
||||
if( binding instanceof ICPPCompositeBinding ){
|
||||
IBinding [] bs = ((ICPPCompositeBinding)binding).getBindings();
|
||||
for( int i = 0; i < bs.length; i++ ) {
|
||||
scope.addBinding( bs[i] );
|
||||
}
|
||||
} else {
|
||||
scope.addBinding( binding );
|
||||
}
|
||||
} catch ( DOMException e ) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if( binding == null )
|
||||
binding = new ProblemBinding(IProblemBinding.SEMANTIC_NAME_NOT_FOUND, data.name );
|
||||
|
@ -651,17 +635,30 @@ public class CPPSemantics {
|
|||
|
||||
ArrayWrapper directives = null;
|
||||
if( !data.usingDirectivesOnly ){
|
||||
IBinding binding = data.prefixLookup ? null : scope.getBinding( data.astName );
|
||||
if( binding == null ||
|
||||
(scope instanceof ICPPNamespaceScope && !((ICPPNamespaceScope) scope).isFullyResolved( data.astName ) ) ||
|
||||
!( CPPSemantics.declaredBefore( binding, data.astName ) ||
|
||||
if( scope.isFullyCached() && !data.prefixLookup ){
|
||||
IBinding binding = data.prefixLookup ? null : scope.getBinding( data.astName, true );
|
||||
if( binding != null &&
|
||||
( CPPSemantics.declaredBefore( binding, data.astName ) ||
|
||||
(scope instanceof ICPPClassScope && data.checkWholeClassScope()) ) )
|
||||
{
|
||||
directives = new ArrayWrapper();
|
||||
mergeResults( data, lookupInScope( data, scope, blockItem, directives ), true );
|
||||
} else {
|
||||
mergeResults( data, binding, true );
|
||||
}
|
||||
} else {
|
||||
mergeResults( data, lookupInScope( data, scope, blockItem, null ), true );
|
||||
}
|
||||
|
||||
if( !data.hasResults() && scope instanceof ICPPNamespaceScope ){
|
||||
directives = new ArrayWrapper();
|
||||
directives.array = ((ICPPNamespaceScope) scope).getUsingDirectives();
|
||||
if( directives.array != null ){
|
||||
for( int i = 0; i < directives.array.length; i++ ){
|
||||
if( !CPPSemantics.declaredBefore( directives.array[i], blockItem ) ){
|
||||
directives.array[i] = null;
|
||||
directives.array = ArrayUtil.trim( IASTNode.class, directives.array );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !data.ignoreUsingDirectives ) {
|
||||
|
@ -943,26 +940,29 @@ public class CPPSemantics {
|
|||
item = nodes[idx];
|
||||
}
|
||||
}
|
||||
if( !checkWholeClassScope && blockItem != null && ((ASTNode)item).getOffset() > ((ASTNode) blockItem).getOffset() )
|
||||
break;
|
||||
|
||||
if( item != blockItem || data.includeBlockItem( item ) ){
|
||||
if( !data.ignoreUsingDirectives &&
|
||||
( item instanceof ICPPASTUsingDirective ||
|
||||
if( item instanceof ICPPASTUsingDirective ||
|
||||
(item instanceof ICPPASTNamespaceDefinition &&
|
||||
((ICPPASTNamespaceDefinition)item).getName().toCharArray().length == 0) ) )
|
||||
((ICPPASTNamespaceDefinition)item).getName().toCharArray().length == 0) )
|
||||
{
|
||||
if( usingDirectives != null )
|
||||
usingDirectives.array = ArrayUtil.append( usingDirectives.array, item );
|
||||
if( scope instanceof ICPPNamespaceScope )
|
||||
((ICPPNamespaceScope)scope).addUsingDirective( item );
|
||||
} else {
|
||||
possible = collectResult( data, scope, item, (item == parent) );
|
||||
if( possible != null && (checkWholeClassScope || declaredBefore( possible, data.astName )) ){
|
||||
if( possible != null &&
|
||||
(checkWholeClassScope || declaredBefore( possible, data.astName )) &&
|
||||
(item != blockItem || data.includeBlockItem( item )) )
|
||||
|
||||
{
|
||||
if( data.considerConstructors ||
|
||||
!( possible.getParent() instanceof IASTDeclarator &&
|
||||
CPPVisitor.isConstructor( scope, (IASTDeclarator) possible.getParent() ) ) )
|
||||
{
|
||||
found = (IASTName[]) ArrayUtil.append( IASTName.class, found, possible );
|
||||
}
|
||||
}
|
||||
}
|
||||
if( item == blockItem && !checkWholeClassScope )
|
||||
break;
|
||||
|
||||
if( idx > -1 && ++idx < nodes.length ){
|
||||
item = nodes[idx];
|
||||
} else {
|
||||
|
@ -1001,6 +1001,8 @@ public class CPPSemantics {
|
|||
}
|
||||
}
|
||||
}
|
||||
scope.setFullyCached( true );
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
|
@ -1022,12 +1024,32 @@ public class CPPSemantics {
|
|||
}
|
||||
data.visited.put( temp );
|
||||
ArrayWrapper usings = new ArrayWrapper();
|
||||
IASTName[] found = lookupInScope( data, temp, null, usings );
|
||||
mergeResults( data, found, false );
|
||||
|
||||
boolean found = false;
|
||||
if( temp.isFullyCached() && !data.prefixLookup ){
|
||||
IBinding binding = temp.getBinding( data.astName, true );
|
||||
if( binding != null &&
|
||||
( CPPSemantics.declaredBefore( binding, data.astName ) ||
|
||||
(scope instanceof ICPPClassScope && data.checkWholeClassScope()) ) )
|
||||
{
|
||||
mergeResults( data, binding, true );
|
||||
found = true;
|
||||
}
|
||||
} else {
|
||||
IASTName [] f = lookupInScope( data, temp, null, null );
|
||||
if( f != null ) {
|
||||
mergeResults( data, f, true );
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( !found && temp instanceof ICPPNamespaceScope ){
|
||||
usings.array = ((ICPPNamespaceScope) temp).getUsingDirectives();
|
||||
}
|
||||
|
||||
//only consider the transitive using directives if we are an unqualified
|
||||
//lookup, or we didn't find the name in decl
|
||||
if( usings.array != null && usings.array.length > 0 && (!data.qualified() || found == null ) ){
|
||||
if( usings.array != null && usings.array.length > 0 && (!data.qualified() || !found ) ){
|
||||
transitives = ArrayUtil.addAll( Object.class, transitives, usings.array );
|
||||
}
|
||||
}
|
||||
|
@ -1035,7 +1057,7 @@ public class CPPSemantics {
|
|||
return transitives;
|
||||
}
|
||||
|
||||
static private IASTName collectResult( CPPSemantics.LookupData data, ICPPScope scope, IASTNode node, boolean checkAux ){
|
||||
static private IASTName collectResult( CPPSemantics.LookupData data, ICPPScope scope, IASTNode node, boolean checkAux ) throws DOMException{
|
||||
IASTDeclaration declaration = null;
|
||||
if( node instanceof IASTDeclaration )
|
||||
declaration = (IASTDeclaration) node;
|
||||
|
@ -1049,6 +1071,7 @@ public class CPPSemantics {
|
|||
while( dtor.getNestedDeclarator() != null )
|
||||
dtor = dtor.getNestedDeclarator();
|
||||
IASTName declName = dtor.getName();
|
||||
scope.addName( declName );
|
||||
if( nameMatches( data, declName.toCharArray() ) ) {
|
||||
return declName;
|
||||
}
|
||||
|
@ -1058,52 +1081,53 @@ public class CPPSemantics {
|
|||
|
||||
if( declaration instanceof IASTSimpleDeclaration ){
|
||||
IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration;
|
||||
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];
|
||||
while( declarator.getNestedDeclarator() != null )
|
||||
declarator = declarator.getNestedDeclarator();
|
||||
if( data.considerConstructors || !CPPVisitor.isConstructor( scope, declarator ) ){
|
||||
IASTName declaratorName = declarator.getName();
|
||||
scope.addName( declaratorName );
|
||||
if( !data.typesOnly || simpleDeclaration.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef ) {
|
||||
if( nameMatches( data, declaratorName.toCharArray() ) ) {
|
||||
return declaratorName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//decl spec
|
||||
IASTDeclSpecifier declSpec = simpleDeclaration.getDeclSpecifier();
|
||||
if( declSpec instanceof IASTElaboratedTypeSpecifier ){
|
||||
if( declarators.length == 0 && declSpec instanceof IASTElaboratedTypeSpecifier ){
|
||||
IASTName elabName = ((IASTElaboratedTypeSpecifier)declSpec).getName();
|
||||
scope.addName( elabName );
|
||||
if( nameMatches( data, elabName.toCharArray() ) ) {
|
||||
return elabName;
|
||||
}
|
||||
} else if( declSpec instanceof ICPPASTCompositeTypeSpecifier ){
|
||||
IASTName compName = ((IASTCompositeTypeSpecifier)declSpec).getName();
|
||||
scope.addName( compName );
|
||||
if( nameMatches( data, compName.toCharArray() ) ) {
|
||||
return compName;
|
||||
}
|
||||
} else if( declSpec instanceof IASTEnumerationSpecifier ){
|
||||
IASTEnumerationSpecifier enumeration = (IASTEnumerationSpecifier) declSpec;
|
||||
IASTName eName = enumeration.getName();
|
||||
scope.addName( eName );
|
||||
if( nameMatches( data, eName.toCharArray() ) ) {
|
||||
return eName;
|
||||
}
|
||||
if( !data.typesOnly ) {
|
||||
//check enumerators too
|
||||
IASTEnumerator [] list = enumeration.getEnumerators();
|
||||
for( int i = 0; i < list.length; i++ ) {
|
||||
IASTEnumerator enumerator = list[i];
|
||||
if( enumerator == null ) break;
|
||||
eName = enumerator.getName();
|
||||
if( nameMatches( data, eName.toCharArray() ) ) {
|
||||
scope.addName( eName );
|
||||
if( !data.typesOnly && nameMatches( data, eName.toCharArray() ) ) {
|
||||
return eName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if( declaration instanceof ICPPASTUsingDeclaration ){
|
||||
ICPPASTUsingDeclaration using = (ICPPASTUsingDeclaration) declaration;
|
||||
IASTName name = using.getName();
|
||||
|
@ -1111,21 +1135,21 @@ public class CPPSemantics {
|
|||
IASTName [] ns = ((ICPPASTQualifiedName)name).getNames();
|
||||
name = ns[ ns.length - 1 ];
|
||||
}
|
||||
scope.addName( name );
|
||||
if( nameMatches( data, name.toCharArray() ) ) {
|
||||
return name;
|
||||
}
|
||||
} else if( declaration instanceof ICPPASTNamespaceDefinition ){
|
||||
IASTName namespaceName = ((ICPPASTNamespaceDefinition) declaration).getName();
|
||||
scope.addName( namespaceName );
|
||||
if( nameMatches( data, namespaceName.toCharArray() ) )
|
||||
return namespaceName;
|
||||
} else if( declaration instanceof ICPPASTNamespaceAlias ){
|
||||
IASTName alias = ((ICPPASTNamespaceAlias) declaration).getAlias();
|
||||
scope.addName( alias );
|
||||
if( nameMatches( data, alias.toCharArray() ) )
|
||||
return alias;
|
||||
}
|
||||
|
||||
if( data.typesOnly )
|
||||
return null;
|
||||
} else
|
||||
|
||||
if( declaration instanceof IASTFunctionDefinition ){
|
||||
IASTFunctionDefinition functionDef = (IASTFunctionDefinition) declaration;
|
||||
|
@ -1133,29 +1157,12 @@ public class CPPSemantics {
|
|||
|
||||
//check the function itself
|
||||
IASTName declName = declarator.getName();
|
||||
if( data.considerConstructors || !CPPVisitor.isConstructor( scope, declarator ) ){
|
||||
if( nameMatches( data, declName.toCharArray() ) ) {
|
||||
scope.addName( declName );
|
||||
|
||||
if( !data.typesOnly && nameMatches( data, declName.toCharArray() ) ) {
|
||||
return declName;
|
||||
}
|
||||
}
|
||||
if( checkAux ) {
|
||||
//check the parameters
|
||||
if ( declarator instanceof IASTStandardFunctionDeclarator ) {
|
||||
IASTParameterDeclaration [] parameters = ((IASTStandardFunctionDeclarator)declarator).getParameters();
|
||||
for( int i = 0; i < parameters.length; i++ ){
|
||||
IASTParameterDeclaration parameterDeclaration = parameters[i];
|
||||
if( parameterDeclaration == null ) break;
|
||||
IASTDeclarator dtor = parameterDeclaration.getDeclarator();
|
||||
while( dtor.getNestedDeclarator() != null )
|
||||
dtor = dtor.getNestedDeclarator();
|
||||
declName = dtor.getName();
|
||||
if( nameMatches( data, declName.toCharArray() ) ) {
|
||||
return declName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -1176,12 +1183,15 @@ public class CPPSemantics {
|
|||
}
|
||||
}
|
||||
|
||||
static protected IBinding resolveAmbiguities( IASTName name, IBinding[] bindings ){
|
||||
bindings = (IBinding[]) ArrayUtil.trim( IBinding.class, bindings );
|
||||
static protected IBinding resolveAmbiguities( IASTName name, Object[] bindings ){
|
||||
bindings = ArrayUtil.trim( Object.class, bindings );
|
||||
if( bindings == null || bindings.length == 0 )
|
||||
return null;
|
||||
else if( bindings.length == 1 )
|
||||
return bindings[ 0 ];
|
||||
else if( bindings.length == 1 ){
|
||||
if( bindings[0] instanceof IASTName )
|
||||
return ((IASTName) bindings[ 0 ]).resolveBinding();
|
||||
return (IBinding) bindings[0];
|
||||
}
|
||||
|
||||
LookupData data = createLookupData( name, false );
|
||||
data.foundItems = bindings;
|
||||
|
@ -1206,7 +1216,7 @@ public class CPPSemantics {
|
|||
nd = (ASTNode) cpp.getDefinition();
|
||||
else
|
||||
return true;
|
||||
} else if( obj instanceof IASTName ) {
|
||||
} else if( obj instanceof ASTNode ){
|
||||
nd = (ASTNode) obj;
|
||||
}
|
||||
if( nd != null ){
|
||||
|
@ -1222,10 +1232,13 @@ public class CPPSemantics {
|
|||
} else {
|
||||
pointOfDecl = nd.getOffset() + nd.getLength();
|
||||
}
|
||||
} else if( prop == ICPPASTNamespaceAlias.ALIAS_NAME ){
|
||||
nd = (ASTNode) nd.getParent();
|
||||
pointOfDecl = nd.getOffset() + nd.getLength();
|
||||
} else
|
||||
pointOfDecl = nd.getOffset();
|
||||
|
||||
return ( pointOfDecl <= ((ASTNode)node).getOffset() );
|
||||
return ( pointOfDecl < ((ASTNode)node).getOffset() );
|
||||
|
||||
}
|
||||
return false;
|
||||
|
@ -1243,24 +1256,23 @@ public class CPPSemantics {
|
|||
Object [] items = (Object[]) data.foundItems;
|
||||
for( int i = 0; i < items.length && items[i] != null; i++ ){
|
||||
Object o = items[i];
|
||||
boolean declaredBefore = declaredBefore( o, name );
|
||||
if( !data.checkWholeClassScope() && !declaredBefore )
|
||||
continue;
|
||||
if( o instanceof IASTName ){
|
||||
temp = ((IASTName) o).resolveBinding();
|
||||
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;
|
||||
|
||||
} else
|
||||
continue;
|
||||
|
||||
if( !( temp instanceof ICPPMember ) && !declaredBefore )
|
||||
continue;
|
||||
if( temp instanceof ICPPCompositeBinding ){
|
||||
IBinding [] bindings = ((ICPPCompositeBinding) temp).getBindings();
|
||||
//data.foundItems = ArrayUtil.addAll( Object.class, data.foundItems, bindings );
|
||||
mergeResults( data, bindings, false );
|
||||
items = (Object[]) data.foundItems;
|
||||
continue;
|
||||
|
@ -1301,15 +1313,6 @@ public class CPPSemantics {
|
|||
if( type != null ) {
|
||||
if( data.typesOnly || (obj == null && fns == null) )
|
||||
return type;
|
||||
// IScope typeScope = type.getScope();
|
||||
// if( obj != null && obj.getScope() != typeScope ){
|
||||
// return new ProblemBinding( IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.name );
|
||||
// } else if( fns != null ){
|
||||
// for( int i = 0; i < fns.length && fns[i] != null; i++ ){
|
||||
// if( ((IBinding)fns[i]).getScope() != typeScope )
|
||||
// return new ProblemBinding( IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.name );
|
||||
// }
|
||||
// }
|
||||
}
|
||||
if( fns != null){
|
||||
if( obj != null )
|
||||
|
@ -1455,7 +1458,6 @@ public class CPPSemantics {
|
|||
|
||||
IType source = null; //parameter we are called with
|
||||
IType target = null; //function's parameter
|
||||
// ITypeInfo voidInfo = null; //used to compare f() and f(void)
|
||||
|
||||
int comparison;
|
||||
Cost cost = null; //the cost of converting source to target
|
||||
|
|
|
@ -153,9 +153,9 @@ public class CPPVisitor implements ICPPASTVisitor {
|
|||
{
|
||||
binding = CPPSemantics.resolveBinding( name );
|
||||
if( binding instanceof IProblemBinding && parent instanceof ICPPASTQualifiedName ){
|
||||
if( ((IProblemBinding)binding).getID() == IProblemBinding.SEMANTIC_NAME_NOT_FOUND ){
|
||||
//if( ((IProblemBinding)binding).getID() == IProblemBinding.SEMANTIC_NAME_NOT_FOUND ){
|
||||
parent = parent.getParent();
|
||||
}
|
||||
//}
|
||||
} else {
|
||||
return binding;
|
||||
}
|
||||
|
@ -190,10 +190,10 @@ public class CPPVisitor implements ICPPASTVisitor {
|
|||
IASTName name = gotoStatement.getName();
|
||||
IBinding binding;
|
||||
try {
|
||||
binding = functionScope.getBinding( name );
|
||||
binding = functionScope.getBinding( name, false );
|
||||
if( binding == null ){
|
||||
binding = new CPPLabel( gotoStatement.getName() );
|
||||
functionScope.addBinding( binding );
|
||||
binding = new CPPLabel( name );
|
||||
functionScope.addName( name );
|
||||
}
|
||||
} catch ( DOMException e ) {
|
||||
binding = e.getProblem();
|
||||
|
@ -207,12 +207,12 @@ public class CPPVisitor implements ICPPASTVisitor {
|
|||
IASTName name = labelStatement.getName();
|
||||
IBinding binding;
|
||||
try {
|
||||
binding = functionScope.getBinding( name );
|
||||
binding = functionScope.getBinding( name, false );
|
||||
if( binding == null ){
|
||||
binding = new CPPLabel( labelStatement.getName() );
|
||||
functionScope.addBinding( binding );
|
||||
binding = new CPPLabel( name );
|
||||
functionScope.addName( name );
|
||||
} else {
|
||||
((CPPLabel)binding).setLabelStatement( labelStatement.getName() );
|
||||
((CPPLabel)binding).setLabelStatement( name );
|
||||
}
|
||||
} catch ( DOMException e ) {
|
||||
binding = e.getProblem();
|
||||
|
@ -225,10 +225,10 @@ public class CPPVisitor implements ICPPASTVisitor {
|
|||
ICPPScope scope = (ICPPScope) getContainingScope( enumerator );
|
||||
IBinding enumtor;
|
||||
try {
|
||||
enumtor = scope.getBinding( enumerator.getName() );
|
||||
enumtor = scope.getBinding( enumerator.getName(), false );
|
||||
if( enumtor == null ){
|
||||
enumtor = new CPPEnumerator( enumerator.getName() );
|
||||
scope.addBinding( enumtor );
|
||||
scope.addName( enumerator.getName() );
|
||||
}
|
||||
} catch ( DOMException e ) {
|
||||
enumtor = e.getProblem();
|
||||
|
@ -242,10 +242,10 @@ public class CPPVisitor implements ICPPASTVisitor {
|
|||
ICPPScope scope = (ICPPScope) getContainingScope( specifier );
|
||||
IBinding enumeration;
|
||||
try {
|
||||
enumeration = scope.getBinding( specifier.getName() );
|
||||
enumeration = scope.getBinding( specifier.getName(), false );
|
||||
if( enumeration == null ){
|
||||
enumeration = new CPPEnumeration( specifier.getName() );
|
||||
scope.addBinding( enumeration );
|
||||
scope.addName( specifier.getName() );
|
||||
}
|
||||
} catch ( DOMException e ) {
|
||||
enumeration = e.getProblem();
|
||||
|
@ -307,11 +307,12 @@ public class CPPVisitor implements ICPPASTVisitor {
|
|||
}
|
||||
}
|
||||
try {
|
||||
binding = scope.getBinding( elabType.getName() );
|
||||
binding = scope.getBinding( elabType.getName(), false );
|
||||
if( binding == null ){
|
||||
if( elabType.getKind() != IASTElaboratedTypeSpecifier.k_enum )
|
||||
if( elabType.getKind() != IASTElaboratedTypeSpecifier.k_enum ){
|
||||
binding = new CPPClassType( elabType.getName() );
|
||||
scope.addBinding( binding );
|
||||
scope.addName( elabType.getName() );
|
||||
}
|
||||
} else if( binding instanceof ICPPClassType ){
|
||||
((CPPClassType)binding).addDeclaration( elabType );
|
||||
}
|
||||
|
@ -330,10 +331,10 @@ public class CPPVisitor implements ICPPASTVisitor {
|
|||
ICPPScope scope = (ICPPScope) getContainingScope( name );
|
||||
IBinding binding;
|
||||
try {
|
||||
binding = scope.getBinding( compType.getName() );
|
||||
binding = scope.getBinding( compType.getName(), false );
|
||||
if( binding == null || !(binding instanceof ICPPClassType) ){
|
||||
binding = new CPPClassType( compType.getName() );
|
||||
scope.addBinding( binding );
|
||||
scope.addName( compType.getName() );
|
||||
} else {
|
||||
((CPPClassType)binding).addDefinition( compType );
|
||||
}
|
||||
|
@ -349,10 +350,10 @@ public class CPPVisitor implements ICPPASTVisitor {
|
|||
ICPPScope scope = (ICPPScope) getContainingScope( namespaceDef );
|
||||
IBinding binding;
|
||||
try {
|
||||
binding = scope.getBinding( namespaceDef.getName() );
|
||||
binding = scope.getBinding( namespaceDef.getName(), false );
|
||||
if( binding == null ){
|
||||
binding = new CPPNamespace( namespaceDef.getName() );
|
||||
scope.addBinding( binding );
|
||||
scope.addName( namespaceDef.getName() );
|
||||
}
|
||||
} catch ( DOMException e ) {
|
||||
binding = e.getProblem();
|
||||
|
@ -377,6 +378,12 @@ public class CPPVisitor implements ICPPASTVisitor {
|
|||
while( declarator.getNestedDeclarator() != null )
|
||||
declarator = declarator.getNestedDeclarator();
|
||||
|
||||
IASTName name = declarator.getName();
|
||||
if( name instanceof ICPPASTQualifiedName ){
|
||||
IASTName [] ns = ((ICPPASTQualifiedName)name).getNames();
|
||||
name = ns[ ns.length - 1 ];
|
||||
}
|
||||
|
||||
while( parent instanceof IASTDeclarator ){
|
||||
parent = parent.getParent();
|
||||
}
|
||||
|
@ -402,7 +409,7 @@ public class CPPVisitor implements ICPPASTVisitor {
|
|||
|
||||
IBinding binding;
|
||||
try {
|
||||
binding = ( scope != null ) ? scope.getBinding( declarator.getName() ) : null;
|
||||
binding = ( scope != null ) ? scope.getBinding( declarator.getName(), false ) : null;
|
||||
} catch ( DOMException e ) {
|
||||
binding = null;
|
||||
}
|
||||
|
@ -470,7 +477,7 @@ public class CPPVisitor implements ICPPASTVisitor {
|
|||
|
||||
if( scope != null && binding != null ){
|
||||
try {
|
||||
scope.addBinding( binding );
|
||||
scope.addName( name );
|
||||
} catch ( DOMException e1 ) {
|
||||
}
|
||||
}
|
||||
|
@ -591,6 +598,10 @@ public class CPPVisitor implements ICPPASTVisitor {
|
|||
return ((ICPPClassType)binding).getCompositeScope();
|
||||
} else if( binding instanceof ICPPNamespace ){
|
||||
return ((ICPPNamespace)binding).getNamespaceScope();
|
||||
} else if( binding instanceof IProblemBinding ){
|
||||
if( binding instanceof ICPPScope )
|
||||
return (IScope) binding;
|
||||
return new CPPScope.CPPScopeProblem( -1, names[i-1].toCharArray() );
|
||||
}
|
||||
}
|
||||
else if( ((ICPPASTQualifiedName)parent).isFullyQualified() )
|
||||
|
|
Loading…
Add table
Reference in a new issue