diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNamespaceScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNamespaceScope.java index 1375212dde3..a4521317d13 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNamespaceScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNamespaceScope.java @@ -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; + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPScope.java index f457631b13e..e302b5cfdba 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPScope.java @@ -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; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java index d9db697c17b..34c62ceee4b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java index 2a7b04db704..26a29eb1ec5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java @@ -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() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java index cbfbb2a86ff..55816dce098 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java @@ -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; - return; - } - } - ICPPConstructor [] temp = new ICPPConstructor[ constructors.length * 2 ]; - System.arraycopy( constructors, 0, temp, 0, constructors.length ); - temp[ constructors.length ] = constructor; - constructors = temp; + public void addName(IASTName name) { + IASTNode parent = name.getParent(); + if( parent instanceof IASTDeclarator ){ + if( CPPVisitor.isConstructor( this, (IASTDeclarator) parent ) ){ + addConstructor( name ); + return; + } + } + 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; - } - - 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; - } - - 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 ); + } + constructorNames.clear(); + } + 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 ){ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java index 08012971c3f..4e868cf0840 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java @@ -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) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java index 87abfc9ad4a..76a22c32eff 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java @@ -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 ) { + 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 ); - } - } - return (IBinding) obj; + public IASTNode[] getUsingDirectives() { + return (IASTNode[]) ArrayUtil.trim( IASTNode.class, usings, true ); } - /* (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 ); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java index aa4ed396a51..94ef18c1aef 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java @@ -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]; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java index 22654f8681e..b0e2369cfb8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java @@ -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,16 +635,29 @@ 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 ) || - (scope instanceof ICPPClassScope && data.checkWholeClassScope()) ) ) - { - directives = new ArrayWrapper(); - mergeResults( data, lookupInScope( data, scope, blockItem, directives ), true ); + 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()) ) ) + { + mergeResults( data, binding, true ); + } } else { - mergeResults( data, binding, true ); + 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 ); + } + } + } } } @@ -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 || - (item instanceof ICPPASTNamespaceDefinition && - ((ICPPASTNamespaceDefinition)item).getName().toCharArray().length == 0) ) ) + + if( item instanceof ICPPASTUsingDirective || + (item instanceof ICPPASTNamespaceDefinition && + ((ICPPASTNamespaceDefinition)item).getName().toCharArray().length == 0) ) + { + if( scope instanceof ICPPNamespaceScope ) + ((ICPPNamespaceScope)scope).addUsingDirective( item ); + } else { + possible = collectResult( data, scope, item, (item == parent) ); + if( possible != null && + (checkWholeClassScope || declaredBefore( possible, data.astName )) && + (item != blockItem || data.includeBlockItem( item )) ) + { - if( usingDirectives != null ) - usingDirectives.array = ArrayUtil.append( usingDirectives.array, item ); - } else { - possible = collectResult( data, scope, item, (item == parent) ); - if( possible != null && (checkWholeClassScope || declaredBefore( possible, data.astName )) ){ - found = (IASTName[]) ArrayUtil.append( IASTName.class, found, possible ); + 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,50 +1081,51 @@ 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(); - if( nameMatches( data, declaratorName.toCharArray() ) ) { - return declaratorName; - } + IASTDeclarator [] declarators = simpleDeclaration.getDeclarators(); + for( int i = 0; i < declarators.length; i++ ){ + IASTDeclarator declarator = declarators[i]; + while( declarator.getNestedDeclarator() != null ) + declarator = declarator.getNestedDeclarator(); + 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() ) ) { - return eName; - } - } + //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(); + scope.addName( eName ); + if( !data.typesOnly && nameMatches( data, eName.toCharArray() ) ) { + return eName; + } } } } else if( declaration instanceof ICPPASTUsingDeclaration ){ @@ -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,27 +1157,10 @@ public class CPPSemantics { //check the function itself IASTName declName = declarator.getName(); - if( data.considerConstructors || !CPPVisitor.isConstructor( scope, declarator ) ){ - if( 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; - } - } - } + scope.addName( declName ); + + if( !data.typesOnly && nameMatches( data, declName.toCharArray() ) ) { + return declName; } } @@ -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 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java index f828a38c181..5e5805f01b0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java @@ -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(); @@ -370,13 +371,19 @@ public class CPPVisitor implements ICPPASTVisitor { } private static IBinding createBinding( IASTDeclarator declarator ){ IASTNode parent = declarator.getParent(); - + if( parent instanceof IASTTypeId ) return CPPSemantics.resolveBinding( declarator.getName() ); 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() )