1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-09 18:56:02 +02:00

Correct usage of scopes in name-resolution, bug 259544.

This commit is contained in:
Markus Schorn 2009-01-12 16:21:19 +00:00
parent 356d9d373b
commit a9fcf919be
29 changed files with 541 additions and 429 deletions

View file

@ -2311,7 +2311,7 @@ public class AST2CPPTests extends AST2BaseTest {
assertTrue(result.contains("a3")); assertTrue(result.contains("a3"));
assertTrue(result.contains("a4")); assertTrue(result.contains("a4"));
assertTrue(result.contains("A")); assertTrue(result.contains("A"));
assertEquals(5, bs.length); assertEquals(7, bs.length); // the bindings above + 2 constructors
} }
// static void f(); // static void f();

View file

@ -6,15 +6,18 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM Corporation - initial API and implementation * Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
/*
* Created on Nov 29, 2004
*/
package org.eclipse.cdt.core.dom.ast.cpp; package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException;
/** /**
* @author aniefer * Interface for class scopes.
*
* @noimplement This interface is not intended to be implemented by clients.
* @noextend This interface is not intended to be extended by clients.
*/ */
public interface ICPPClassScope extends ICPPScope { public interface ICPPClassScope extends ICPPScope {
/** /**
@ -31,4 +34,10 @@ public interface ICPPClassScope extends ICPPScope {
* *
*/ */
public ICPPMethod[] getImplicitMethods(); public ICPPMethod[] getImplicitMethods();
/**
* Returns the array of constructors, including implicit ones.
* @since 5.1
*/
public ICPPConstructor[] getConstructors() throws DOMException;
} }

View file

@ -8,7 +8,6 @@
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser; package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
@ -18,6 +17,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.internal.core.dom.parser.c.CScope;
import org.eclipse.cdt.internal.core.dom.parser.c.ICInternalBinding; import org.eclipse.cdt.internal.core.dom.parser.c.ICInternalBinding;
import org.eclipse.cdt.internal.core.dom.parser.c.ICInternalFunction; import org.eclipse.cdt.internal.core.dom.parser.c.ICInternalFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
@ -51,15 +51,15 @@ public class ASTInternal {
} }
public static boolean isFullyCached(IScope scope) throws DOMException { public static boolean isFullyCached(IScope scope) throws DOMException {
if (scope instanceof IASTInternalScope) { if (scope instanceof CScope) {
return ((IASTInternalScope) scope).isFullyCached(); return ((CScope) scope).isFullyCached();
} }
return true; return true;
} }
public static void setFullyCached(IScope scope, boolean val) throws DOMException { public static void setFullyCached(IScope scope, boolean val) throws DOMException {
if (scope instanceof IASTInternalScope) { if (scope instanceof CScope) {
((IASTInternalScope) scope).setFullyCached(val); ((CScope) scope).setFullyCached(val);
} }
} }

View file

@ -26,16 +26,6 @@ public interface IASTInternalScope extends IScope {
*/ */
public IASTNode getPhysicalNode() throws DOMException; public IASTNode getPhysicalNode() throws DOMException;
/**
* Set whether or not all the names in this scope have been cached
*/
public void setFullyCached(boolean b) throws DOMException;
/**
* whether or not this scope's cache contains all the names
*/
public boolean isFullyCached() throws DOMException;
/** /**
* clear the name cache in this scope * clear the name cache in this scope
* @throws DOMException * @throws DOMException

View file

@ -193,19 +193,6 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
throw new DOMException(this); throw new DOMException(this);
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#setFullyCached(boolean)
*/
public void setFullyCached(boolean b) {
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#isFullyCached()
*/
public boolean isFullyCached() throws DOMException {
throw new DOMException(this);
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IType#isSameType(org.eclipse.cdt.core.dom.ast.IType) * @see org.eclipse.cdt.core.dom.ast.IType#isSameType(org.eclipse.cdt.core.dom.ast.IType)
*/ */

View file

@ -81,27 +81,45 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
return CPPSemantics.resolveAmbiguities(name, specs); return CPPSemantics.resolveAmbiguities(name, specs);
} }
public IBinding[] getBindings(IASTName name, boolean forceResolve, boolean prefixLookup, final public IBinding[] getBindings(IASTName name, boolean forceResolve, boolean prefixLookup,
IIndexFileSet fileSet) throws DOMException { IIndexFileSet fileSet) throws DOMException {
return getBindings(name, forceResolve, prefixLookup, fileSet, true);
}
public IBinding[] getBindings(IASTName name, boolean forceResolve, boolean prefixLookup,
IIndexFileSet fileSet, boolean checkPointOfDecl) throws DOMException {
char[] c = name.getLookupKey(); char[] c = name.getLookupKey();
IBinding[] result = null;
if ((!prefixLookup && CharArrayUtils.equals(c, specialClass.getNameCharArray())) || if ((!prefixLookup && CharArrayUtils.equals(c, specialClass.getNameCharArray())) ||
(prefixLookup && CharArrayUtils.equals(specialClass.getNameCharArray(), 0, c.length, c, true))) { (prefixLookup && CharArrayUtils.equals(specialClass.getNameCharArray(), 0, c.length, c, true))) {
result = new IBinding[] { specialClass }; IBinding[] result= new IBinding[] {specialClass};
if (CPPClassScope.isConstructorReference(name)) {
result = (IBinding[]) ArrayUtil.addAll(IBinding.class, result, specialClass.getConstructors());
}
result= (IBinding[]) ArrayUtil.trim(IBinding.class, result);
// specialize all but first
for (int i = 1; i < result.length; i++) {
result[i]= specialClass.specializeMember(result[i]);
}
return result;
} }
ICPPClassType specialized = specialClass.getSpecializedBinding(); ICPPClassType specialized = specialClass.getSpecializedBinding();
IScope classScope = specialized.getCompositeScope(); IScope classScope = specialized.getCompositeScope();
IBinding[] bindings = classScope != null ? if (classScope == null)
classScope.getBindings(name, forceResolve, prefixLookup, fileSet) : null; return IBinding.EMPTY_BINDING_ARRAY;
if (bindings != null) { IBinding[] bindings;
if (classScope instanceof ICPPASTInternalScope) {
bindings= ((ICPPASTInternalScope) classScope).getBindings(name, forceResolve, prefixLookup, fileSet, checkPointOfDecl);
} else {
bindings= classScope.getBindings(name, forceResolve, prefixLookup, fileSet);
}
IBinding[] result= null;
for (IBinding binding : bindings) { for (IBinding binding : bindings) {
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, specialClass.specializeMember(binding)); binding= specialClass.specializeMember(binding);
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, binding);
} }
}
return (IBinding[]) ArrayUtil.trim(IBinding.class, result); return (IBinding[]) ArrayUtil.trim(IBinding.class, result);
} }

View file

@ -220,7 +220,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
} }
if (CharArrayUtils.equals(c, compName.getLookupKey())) { if (CharArrayUtils.equals(c, compName.getLookupKey())) {
if (isConstructorReference(name)) { if (isConstructorReference(name)) {
return CPPSemantics.resolveAmbiguities(name, getConstructors(bindings, resolve, name)); return CPPSemantics.resolveAmbiguities(name, getConstructors(name, resolve));
} }
//9.2 ... The class-name is also inserted into the scope of the class itself //9.2 ... The class-name is also inserted into the scope of the class itself
return compName.resolveBinding(); return compName.resolveBinding();
@ -229,7 +229,8 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
} }
@Override @Override
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) throws DOMException { public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet,
boolean checkPointOfDecl) throws DOMException {
char[] c = name.getLookupKey(); char[] c = name.getLookupKey();
ICPPASTCompositeTypeSpecifier compType = (ICPPASTCompositeTypeSpecifier) getPhysicalNode(); ICPPASTCompositeTypeSpecifier compType = (ICPPASTCompositeTypeSpecifier) getPhysicalNode();
@ -241,7 +242,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
if ((!prefixLookup && CharArrayUtils.equals(c, compName.getLookupKey())) if ((!prefixLookup && CharArrayUtils.equals(c, compName.getLookupKey()))
|| (prefixLookup && CharArrayUtils.equals(compName.getLookupKey(), 0, c.length, c, true))) { || (prefixLookup && CharArrayUtils.equals(compName.getLookupKey(), 0, c.length, c, true))) {
if (isConstructorReference(name)) { if (isConstructorReference(name)) {
result = (IBinding[]) ArrayUtil.addAll(IBinding.class, result, getConstructors(bindings, resolve, name)); result = (IBinding[]) ArrayUtil.addAll(IBinding.class, result, getConstructors(name, resolve));
} }
//9.2 ... The class-name is also inserted into the scope of the class itself //9.2 ... The class-name is also inserted into the scope of the class itself
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, compName.resolveBinding()); result = (IBinding[]) ArrayUtil.append(IBinding.class, result, compName.resolveBinding());
@ -249,7 +250,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
return (IBinding[]) ArrayUtil.trim(IBinding.class, result); return (IBinding[]) ArrayUtil.trim(IBinding.class, result);
} }
result = (IBinding[]) ArrayUtil.addAll(IBinding.class, result, result = (IBinding[]) ArrayUtil.addAll(IBinding.class, result,
super.getBindings(name, resolve, prefixLookup, fileSet)); super.getBindings(name, resolve, prefixLookup, fileSet, checkPointOfDecl));
return (IBinding[]) ArrayUtil.trim(IBinding.class, result); return (IBinding[]) ArrayUtil.trim(IBinding.class, result);
} }
@ -263,23 +264,22 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
return true; return true;
} }
protected ICPPConstructor[] getConstructors(boolean forceResolve) { public ICPPConstructor[] getConstructors() {
return getConstructors(bindings, forceResolve, null); return getConstructors(null, true);
}
static protected ICPPConstructor[] getConstructors(CharArrayObjectMap bindings, boolean forceResolve) {
return getConstructors(bindings, forceResolve, null);
} }
@SuppressWarnings("unchecked") private ICPPConstructor[] getConstructors(IASTName forName, boolean forceResolve) {
static protected ICPPConstructor[] getConstructors(CharArrayObjectMap bindings, boolean forceResolve, IASTName forName) { populateCache();
if (bindings == null)
final CharArrayObjectMap nameMap = bindings;
if (nameMap == null)
return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY; return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY;
Object o = bindings.get(CONSTRUCTOR_KEY); Object o = nameMap.get(CONSTRUCTOR_KEY);
if (o != null) { if (o != null) {
IBinding binding = null; IBinding binding = null;
if (o instanceof ObjectSet) { if (o instanceof ObjectSet<?>) {
ObjectSet set = (ObjectSet) o; ObjectSet<?> set = (ObjectSet<?>) o;
IBinding[] bs = null; IBinding[] bs = null;
for (int i = 0; i < set.size(); i++) { for (int i = 0; i < set.size(); i++) {
Object obj = set.keyAt(i); Object obj = set.keyAt(i);
@ -297,7 +297,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
} else if (o instanceof IASTName) { } else if (o instanceof IASTName) {
if (shouldResolve(forceResolve, (IASTName) o, forName) || ((IASTName)o).getBinding() != null) { if (shouldResolve(forceResolve, (IASTName) o, forName) || ((IASTName)o).getBinding() != null) {
// always store the name, rather than the binding, such that we can properly flush the scope. // always store the name, rather than the binding, such that we can properly flush the scope.
bindings.put(CONSTRUCTOR_KEY, o); nameMap.put(CONSTRUCTOR_KEY, o);
binding = ((IASTName)o).resolveBinding(); binding = ((IASTName)o).resolveBinding();
} }
} else if (o instanceof IBinding) { } else if (o instanceof IBinding) {
@ -333,7 +333,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
if (name.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false; if (name.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false;
IASTNode node = name.getParent(); IASTNode node = name.getParent();
if (node instanceof ICPPASTTemplateId) if (node instanceof ICPPASTTemplateId)
node = node.getParent(); return false;
if (node instanceof ICPPASTQualifiedName) { if (node instanceof ICPPASTQualifiedName) {
if (((ICPPASTQualifiedName) node).getLastName() == name) if (((ICPPASTQualifiedName) node).getLastName() == name)
node = node.getParent(); node = node.getParent();

View file

@ -6,46 +6,28 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM - Initial API and implementation * Andrew Niefer (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Bryan Wilkinson (QNX) * Bryan Wilkinson (QNX)
* Andrew Ferguson (Symbian) * Andrew Ferguson (Symbian)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
/** /**
* @author aniefer * Scope for class-specializations which specializes members in a lazy manner.
*/ */
public class CPPClassSpecializationScope extends AbstractCPPClassSpecializationScope implements IASTInternalScope { public class CPPClassSpecializationScope extends AbstractCPPClassSpecializationScope implements ICPPASTInternalScope {
public CPPClassSpecializationScope(ICPPClassSpecialization specialization) { public CPPClassSpecializationScope(ICPPClassSpecialization specialization) {
super(specialization); super(specialization);
} }
public boolean isFullyCached() throws DOMException {
ICPPScope origScope = (ICPPScope) getOriginalClassType().getCompositeScope();
if (!ASTInternal.isFullyCached(origScope)) {
try {
CPPSemantics.lookupInScope(null, origScope, null);
} catch (DOMException e) {
}
}
return true;
}
// This scope does not cache its own names // This scope does not cache its own names
public void setFullyCached(boolean b) {}
public void flushCache() {} public void flushCache() {}
public void addName(IASTName name) {} public void addName(IASTName name) {}
public IASTNode getPhysicalNode() { return null; } public IASTNode getPhysicalNode() { return null; }

View file

@ -32,13 +32,13 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
@ -141,7 +141,7 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements
return null; return null;
} }
public ICPPScope getCompositeScope() { public ICPPClassScope getCompositeScope() {
if (definition == null) { if (definition == null) {
checkForDefinition(); checkForDefinition();
} }

View file

@ -281,7 +281,7 @@ public class CPPClassType extends PlatformObject implements ICPPInternalClassTyp
return scope; return scope;
} }
public IScope getCompositeScope() { public ICPPClassScope getCompositeScope() {
if (definition == null) { if (definition == null) {
checkForDefinition(); checkForDefinition();
} }
@ -291,7 +291,9 @@ public class CPPClassType extends PlatformObject implements ICPPInternalClassTyp
// fwd-declarations must be backed up from the index // fwd-declarations must be backed up from the index
if (typeInIndex != null) { if (typeInIndex != null) {
try { try {
return typeInIndex.getCompositeScope(); IScope scope = typeInIndex.getCompositeScope();
if (scope instanceof ICPPClassScope)
return (ICPPClassScope) scope;
} catch (DOMException e) { } catch (DOMException e) {
// index bindings don't throw DOMExeptions. // index bindings don't throw DOMExeptions.
} }

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM Corporation - initial API and implementation * Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -24,11 +24,10 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.index.IIndexScope; import org.eclipse.cdt.internal.core.index.IIndexScope;
/** /**
* @author aniefer * Implementation of namespace scopes, including global scope.
*/ */
public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{ public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{
ICPPUsingDirective[] usings = null; ICPPUsingDirective[] usings = null;
@ -48,9 +47,7 @@ public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope#getUsingDirectives() * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope#getUsingDirectives()
*/ */
public ICPPUsingDirective[] getUsingDirectives() throws DOMException { public ICPPUsingDirective[] getUsingDirectives() throws DOMException {
if (!isFullyCached()) { populateCache();
CPPSemantics.lookupInScope(null, this, null);
}
return (ICPPUsingDirective[]) ArrayUtil.trim( ICPPUsingDirective.class, usings, true ); return (ICPPUsingDirective[]) ArrayUtil.trim( ICPPUsingDirective.class, usings, true );
} }
/* (non-Javadoc) /* (non-Javadoc)

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM Corporation - initial API and implementation * Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Bryan Wilkinson (QNX) * Bryan Wilkinson (QNX)
* Andrew Ferguson (Symbian) * Andrew Ferguson (Symbian)
@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
@ -37,21 +38,21 @@ import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.ObjectSet; import org.eclipse.cdt.core.parser.util.ObjectSet;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.LookupData;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor;
/** /**
* @author aniefer * Base class for c++-scopes of the ast.
*/ */
abstract public class CPPScope implements ICPPScope, IASTInternalScope { abstract public class CPPScope implements ICPPScope, ICPPASTInternalScope {
private static final IProgressMonitor NPM = new NullProgressMonitor(); private static final IProgressMonitor NPM = new NullProgressMonitor();
private IASTNode physicalNode; private IASTNode physicalNode;
private boolean isfull = false; private boolean isCached = false;
protected CharArrayObjectMap bindings = null; protected CharArrayObjectMap bindings = null;
public static class CPPScopeProblem extends ProblemBinding implements ICPPScope { public static class CPPScopeProblem extends ProblemBinding implements ICPPScope {
@ -106,7 +107,7 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope {
IScope scope= this; IScope scope= this;
IASTName[] na= name.getNames(); IASTName[] na= name.getNames();
try { try {
for (int i= na.length - 2; i >= 0; i++) { for (int i= na.length - 2; i >= 0; i--) {
if (scope == null) if (scope == null)
return false; return false;
IName scopeName = scope.getScopeName(); IName scopeName = scope.getScopeName();
@ -156,15 +157,7 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope {
if (nsbinding instanceof ICPPNamespace) { if (nsbinding instanceof ICPPNamespace) {
ICPPNamespace nsbindingAdapted = (ICPPNamespace) index.adaptBinding(nsbinding); ICPPNamespace nsbindingAdapted = (ICPPNamespace) index.adaptBinding(nsbinding);
if (nsbindingAdapted!=null) { if (nsbindingAdapted!=null) {
IBinding[] bindings = nsbindingAdapted.getNamespaceScope().find(new String(nchars)); return nsbindingAdapted.getNamespaceScope().getBinding(name, forceResolve, fileSet);
if (fileSet != null) {
bindings= fileSet.filterFileLocalBindings(bindings);
}
binding= CPPSemantics.resolveAmbiguities(name, bindings);
if (binding instanceof ICPPUsingDeclaration) {
binding= CPPSemantics.resolveAmbiguities(name,
((ICPPUsingDeclaration)binding).getDelegates());
}
} }
} }
} }
@ -174,59 +167,17 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope {
} }
public IBinding getBindingInAST(IASTName name, boolean forceResolve) throws DOMException { public IBinding getBindingInAST(IASTName name, boolean forceResolve) throws DOMException {
char[] c = name.getLookupKey(); IBinding[] bs= getBindingsInAST(name, forceResolve, false, false, false);
//can't look up bindings that don't have a name
if (c.length == 0)
return null;
Object obj = bindings != null ? bindings.get(c) : null;
if (obj != null) {
if (obj instanceof ObjectSet) {
@SuppressWarnings("unchecked")
ObjectSet<Object> os = (ObjectSet<Object>) obj;
if (forceResolve)
return CPPSemantics.resolveAmbiguities(name, os.keyArray());
IBinding[] bs = null;
for (int i = 0; i < os.size(); i++) {
Object o = os.keyAt(i);
if (o instanceof IASTName) {
IASTName n = (IASTName) o;
if (n instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName)n).getNames();
n = ns[ns.length - 1];
}
bs = (IBinding[]) ArrayUtil.append(IBinding.class, bs, n.getBinding());
} else {
bs = (IBinding[]) ArrayUtil.append(IBinding.class, bs, o);
}
}
return CPPSemantics.resolveAmbiguities(name, bs); return CPPSemantics.resolveAmbiguities(name, bs);
} else if (obj instanceof IASTName) {
IBinding binding = null;
if (forceResolve && obj != name && obj != name.getParent()) {
binding = CPPSemantics.resolveAmbiguities(name, new Object[] { obj });
} else {
IASTName n = (IASTName) obj;
if (n instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName)n).getNames();
n = ns[ns.length - 1];
}
binding = n.getBinding();
}
if (binding instanceof ICPPUsingDeclaration) {
return CPPSemantics.resolveAmbiguities(name, ((ICPPUsingDeclaration)binding).getDelegates());
}
return binding;
}
return (IBinding) obj;
}
return null;
} }
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) throws DOMException {
throws DOMException { return getBindings(name, resolve, prefixLookup, fileSet, true);
IBinding[] result = getBindingsInAST(name, resolve, prefixLookup); }
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet,
boolean checkPointOfDecl) throws DOMException {
IBinding[] result = getBindingsInAST(name, resolve, prefixLookup, checkPointOfDecl, true);
final IASTTranslationUnit tu = name.getTranslationUnit(); final IASTTranslationUnit tu = name.getTranslationUnit();
if (tu != null) { if (tu != null) {
IIndex index = tu.getIndex(); IIndex index = tu.getIndex();
@ -267,16 +218,17 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope {
return (IBinding[]) ArrayUtil.trim(IBinding.class, result); return (IBinding[]) ArrayUtil.trim(IBinding.class, result);
} }
public IBinding[] getBindingsInAST(IASTName name, boolean forceResolve, boolean prefixLookup) public IBinding[] getBindingsInAST(IASTName name, boolean forceResolve, boolean prefixLookup,
throws DOMException { boolean checkPointOfDecl, boolean expandUsingDirectives) throws DOMException {
char[] c = name.getLookupKey(); populateCache();
final char[] c = name.getLookupKey();
IBinding[] result = null; IBinding[] result = null;
Object[] obj = null; Object[] obj = null;
if (prefixLookup) { if (prefixLookup) {
Object[] keys = bindings != null ? bindings.keyArray() : new Object[0]; Object[] keys = bindings != null ? bindings.keyArray() : new Object[0];
for (Object key2 : keys) { for (int i = 0; i < keys.length; i++) {
char[] key = (char[]) key2; final char[] key = (char[]) keys[i];
if (CharArrayUtils.equals(key, 0, c.length, c, true)) { if (CharArrayUtils.equals(key, 0, c.length, c, true)) {
obj = ArrayUtil.append(obj, bindings.get(key)); obj = ArrayUtil.append(obj, bindings.get(key));
} }
@ -287,45 +239,58 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope {
obj = ArrayUtil.trim(Object.class, obj); obj = ArrayUtil.trim(Object.class, obj);
for (Object element : obj) { for (Object element : obj) {
if (element instanceof ObjectSet) { if (element instanceof ObjectSet<?>) {
@SuppressWarnings("unchecked") ObjectSet<?> os= (ObjectSet<?>) element;
ObjectSet<Object> os= (ObjectSet<Object>) element;
for (int j = 0; j < os.size(); j++) { for (int j = 0; j < os.size(); j++) {
Object o = os.keyAt(j); result= addCandidate(os.keyAt(j), name, forceResolve, checkPointOfDecl, expandUsingDirectives, result);
if (o instanceof IASTName) { }
IASTName n = ((IASTName) o).getLastName();
IBinding binding = forceResolve ? n.resolveBinding() : n.getBinding();
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, binding);
} else { } else {
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, o); result = addCandidate(element, name, forceResolve, checkPointOfDecl, expandUsingDirectives, result);
}
}
} else if (element instanceof IASTName) {
IBinding binding = null;
if (forceResolve && element != name && element != name.getParent()) {
binding = ((IASTName) element).resolveBinding();
} else {
IASTName n = ((IASTName) element).getLastName();
binding = n.getBinding();
}
if (binding instanceof ICPPUsingDeclaration) {
result = (IBinding[]) ArrayUtil.addAll(IBinding.class, result,
((ICPPUsingDeclaration)binding).getDelegates());
}
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, binding);
} else {
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, element);
} }
} }
return (IBinding[]) ArrayUtil.trim(IBinding.class, result); return (IBinding[]) ArrayUtil.trim(IBinding.class, result);
} }
public void setFullyCached(boolean full) { private IBinding[] addCandidate(Object candidate, IASTName name, boolean forceResolve,
isfull = full; boolean checkPointOfDecl, boolean expandUsingDirectives, IBinding[] result) {
if (checkPointOfDecl) {
IASTTranslationUnit tu= name.getTranslationUnit();
if (!CPPSemantics.declaredBefore(candidate, name, tu != null && tu.getIndex() != null)) {
if (!(this instanceof ICPPClassScope) || ! LookupData.checkWholeClassScope(name))
return result;
}
} }
public boolean isFullyCached() { IBinding binding;
return isfull; if (candidate instanceof IASTName) {
final IASTName candName= (IASTName) candidate;
if (forceResolve && candName != name && candName != name.getParent()) {
binding = candName.resolvePreBinding();
} else {
binding = candName.getLastName().getBinding();
}
} else {
binding= (IBinding) candidate;
}
if (expandUsingDirectives && binding instanceof ICPPUsingDeclaration) {
IBinding[] delegates = ((ICPPUsingDeclaration) binding).getDelegates();
result= (IBinding[]) ArrayUtil.addAll(IBinding.class, result, delegates);
} else {
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, binding);
}
return result;
}
protected void populateCache() {
if (!isCached) {
try {
CPPSemantics.lookupInScope(null, this, null);
} catch (DOMException e) {
CCorePlugin.log(e);
}
isCached= true;
}
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -341,7 +306,7 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope {
return; return;
Object obj = bindings.get(key); Object obj = bindings.get(key);
if (obj instanceof ObjectSet) { if (obj instanceof ObjectSet<?>) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
ObjectSet<Object> set = (ObjectSet<Object>) obj; ObjectSet<Object> set = (ObjectSet<Object>) obj;
for (int i = set.size() - 1; i >= 0; i--) { for (int i = set.size() - 1; i >= 0; i--) {
@ -358,7 +323,7 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope {
(obj instanceof IASTName && ((IASTName)obj).getBinding() == binding)) { (obj instanceof IASTName && ((IASTName)obj).getBinding() == binding)) {
bindings.remove(key, 0, key.length); bindings.remove(key, 0, key.length);
} }
isfull = false; isCached = false;
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -381,7 +346,7 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope {
allBuiltins= new CharArrayObjectMap(1); allBuiltins= new CharArrayObjectMap(1);
} }
allBuiltins.put(map.keyAt(i), o); allBuiltins.put(map.keyAt(i), o);
} else if (o instanceof ObjectSet) { } else if (o instanceof ObjectSet<?>) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
final ObjectSet<Object> set= (ObjectSet<Object>) map.getAt(i); final ObjectSet<Object> set= (ObjectSet<Object>) map.getAt(i);
if (set != null) { if (set != null) {
@ -408,7 +373,7 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope {
} }
bindings= allBuiltins; bindings= allBuiltins;
} }
isfull = false; isCached = false;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -436,7 +401,7 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope {
} }
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) throws DOMException { public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) throws DOMException {
return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY); return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY, true);
} }
public IName getScopeName() throws DOMException { public IName getScopeName() throws DOMException {

View file

@ -0,0 +1,55 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
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.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
/**
* Represents a reference to a constructor (instance), which cannot be resolved because
* it depends on a template parameter. A compiler would resolve it during instantiation.
*/
public class CPPUnknownConstructor extends CPPUnknownFunction implements ICPPConstructor {
public CPPUnknownConstructor(ICPPClassType owner, IASTName name) {
super(owner, name);
}
public boolean isExplicit() throws DOMException {
return false;
}
public boolean isDestructor() throws DOMException {
return false;
}
public boolean isImplicit() {
return false;
}
public boolean isPureVirtual() throws DOMException {
return false;
}
public boolean isVirtual() throws DOMException {
return false;
}
public ICPPClassType getClassOwner() throws DOMException {
return (ICPPClassType) getOwner();
}
public int getVisibility() throws DOMException {
return v_public;
}
}

View file

@ -17,6 +17,7 @@ import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
@ -27,6 +28,9 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
public class CPPUnknownFunction extends CPPUnknownBinding implements ICPPFunction { public class CPPUnknownFunction extends CPPUnknownBinding implements ICPPFunction {
public static IFunction createForSample(IFunction sample, IASTName name) throws DOMException { public static IFunction createForSample(IFunction sample, IASTName name) throws DOMException {
if (sample instanceof ICPPConstructor)
return new CPPUnknownConstructor(((ICPPConstructor) sample).getClassOwner(), name);
return new CPPUnknownFunction(sample.getOwner(), name.getLastName()); return new CPPUnknownFunction(sample.getOwner(), name.getLastName());
} }

View file

@ -176,19 +176,6 @@ public class CPPUnknownScope implements ICPPScope, ICPPInternalUnknownScope {
return new IBinding[] {getBinding(name, resolve, fileSet)}; return new IBinding[] {getBinding(name, resolve, fileSet)};
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#setFullyCached(boolean)
*/
public void setFullyCached(boolean b) {
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#isFullyCached()
*/
public boolean isFullyCached() {
return true;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#flushCache() * @see org.eclipse.cdt.core.dom.ast.IScope#flushCache()
*/ */

View file

@ -77,6 +77,11 @@ public class ClassTypeHelper {
if (host.getDefinition() == null) { if (host.getDefinition() == null) {
host.checkForDefinition(); host.checkForDefinition();
if (host.getDefinition() == null) { if (host.getDefinition() == null) {
try {
ICPPClassType backup= getBackupDefinition(host);
if (backup != null)
return backup.getFriends();
} catch (DOMException e) {}
IASTNode[] declarations= host.getDeclarations(); IASTNode[] declarations= host.getDeclarations();
IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null;
return new IBinding[] { new ProblemBinding(node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, host.getNameCharArray()) }; return new IBinding[] { new ProblemBinding(node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, host.getNameCharArray()) };
@ -115,10 +120,30 @@ public class ClassTypeHelper {
return resultSet.keyArray(IBinding.class); return resultSet.keyArray(IBinding.class);
} }
/**
* A host maybe backed up with a definition from the index.
* @throws DOMException
*/
private static ICPPClassType getBackupDefinition(ICPPInternalClassTypeMixinHost host) throws DOMException {
ICPPClassScope scope = host.getCompositeScope();
if (scope != null) {
ICPPClassType b = scope.getClassType();
if (!(b instanceof ICPPInternalClassTypeMixinHost))
return b;
}
return null;
}
public static ICPPBase[] getBases(ICPPInternalClassTypeMixinHost host) { public static ICPPBase[] getBases(ICPPInternalClassTypeMixinHost host) {
if (host.getDefinition() == null) { if (host.getDefinition() == null) {
host.checkForDefinition(); host.checkForDefinition();
if (host.getDefinition() == null) { if (host.getDefinition() == null) {
try {
ICPPClassType backup= getBackupDefinition(host);
if (backup != null)
return backup.getBases();
} catch (DOMException e) {}
IASTNode[] declarations= host.getDeclarations(); IASTNode[] declarations= host.getDeclarations();
IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null;
return new ICPPBase[] { new CPPBaseClause.CPPBaseProblem(node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, host.getNameCharArray()) }; return new ICPPBase[] { new CPPBaseClause.CPPBaseProblem(node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, host.getNameCharArray()) };
@ -140,6 +165,12 @@ public class ClassTypeHelper {
if (host.getDefinition() == null) { if (host.getDefinition() == null) {
host.checkForDefinition(); host.checkForDefinition();
if (host.getDefinition() == null) { if (host.getDefinition() == null) {
try {
ICPPClassType backup= getBackupDefinition(host);
if (backup != null)
return backup.getDeclaredFields();
} catch (DOMException e) {}
IASTNode[] declarations= host.getDeclarations(); IASTNode[] declarations= host.getDeclarations();
IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null;
return new ICPPField[] { new CPPField.CPPFieldProblem(node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, host.getNameCharArray()) }; return new ICPPField[] { new CPPField.CPPFieldProblem(node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, host.getNameCharArray()) };
@ -272,44 +303,25 @@ public class ClassTypeHelper {
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getConstructors() * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getConstructors()
*/ */
public static ICPPConstructor[] getConstructors(ICPPInternalClassTypeMixinHost host) throws DOMException { public static ICPPConstructor[] getConstructors(ICPPInternalClassTypeMixinHost host) throws DOMException {
if (host.getDefinition() == null) { ICPPClassScope scope = host.getCompositeScope();
host.checkForDefinition(); if (scope == null) {
if (host.getDefinition() == null) {
IASTNode[] declarations= host.getDeclarations(); IASTNode[] declarations= host.getDeclarations();
IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null;
return new ICPPConstructor[] { new CPPConstructor.CPPConstructorProblem(node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, host.getNameCharArray()) }; return new ICPPConstructor[] { new CPPConstructor.CPPConstructorProblem(node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, host.getNameCharArray()) };
} }
} return scope.getConstructors();
ICPPClassScope scope = (ICPPClassScope) host.getCompositeScope();
if (ASTInternal.isFullyCached(scope))
return ((CPPClassScope)scope).getConstructors(true);
IASTDeclaration[] members = host.getCompositeTypeSpecifier().getMembers();
for (IASTDeclaration decl : members) {
if (decl instanceof ICPPASTTemplateDeclaration)
decl = ((ICPPASTTemplateDeclaration)decl).getDeclaration();
if (decl instanceof IASTSimpleDeclaration) {
IASTDeclarator[] dtors = ((IASTSimpleDeclaration)decl).getDeclarators();
for (IASTDeclarator dtor : dtors) {
if (dtor == null) break;
dtor= CPPVisitor.findInnermostDeclarator(dtor);
ASTInternal.addName(scope, dtor.getName());
}
} else if (decl instanceof IASTFunctionDefinition) {
IASTDeclarator dtor = ((IASTFunctionDefinition)decl).getDeclarator();
dtor= CPPVisitor.findInnermostDeclarator(dtor);
ASTInternal.addName(scope, dtor.getName());
}
}
return ((CPPClassScope)scope).getConstructors(true);
} }
public static ICPPClassType[] getNestedClasses(ICPPInternalClassTypeMixinHost host) { public static ICPPClassType[] getNestedClasses(ICPPInternalClassTypeMixinHost host) {
if (host.getDefinition() == null) { if (host.getDefinition() == null) {
host.checkForDefinition(); host.checkForDefinition();
if (host.getDefinition() == null) { if (host.getDefinition() == null) {
try {
ICPPClassType backup= getBackupDefinition(host);
if (backup != null)
return backup.getNestedClasses();
} catch (DOMException e) {}
IASTNode[] declarations= host.getDeclarations(); IASTNode[] declarations= host.getDeclarations();
IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null;
return new ICPPClassType[] { new CPPClassTypeProblem(node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, host.getNameCharArray()) }; return new ICPPClassType[] { new CPPClassTypeProblem(node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, host.getNameCharArray()) };

View file

@ -0,0 +1,32 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
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.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
/**
* Interface for internal c++ scopes
*/
public interface ICPPASTInternalScope extends IASTInternalScope {
/**
* Same as {@link IScope#getBindings(IASTName, boolean, boolean, IIndexFileSet)} with the
* possibility to disable checking the point of declaration. The method is used to resolve
* dependent bindings, where the points of declaration may be reversed.
*/
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup,
IIndexFileSet acceptLocalBindings, boolean checkPointOfDecl) throws DOMException;
}

View file

@ -16,7 +16,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
@ -42,11 +41,6 @@ public interface ICPPClassSpecializationScope extends ICPPClassScope {
*/ */
ICPPBase[] getBases() throws DOMException; ICPPBase[] getBases() throws DOMException;
/**
* Computes the constructors via the original class.
*/
ICPPConstructor[] getConstructors() throws DOMException;
/** /**
* Computes the methods via the original class. * Computes the methods via the original class.
*/ */

View file

@ -10,7 +10,9 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
/** /**
@ -22,6 +24,11 @@ interface ICPPInternalClassTypeMixinHost extends ICPPClassType, ICPPInternalBind
*/ */
ICPPASTCompositeTypeSpecifier getCompositeTypeSpecifier(); ICPPASTCompositeTypeSpecifier getCompositeTypeSpecifier();
/**
* {@inheritDoc}
*/
ICPPClassScope getCompositeScope() throws DOMException;
/** /**
* Ensures the ICPPInternalBinding definition is set, if this is possible. * Ensures the ICPPInternalBinding definition is set, if this is possible.
* @see ICPPInternalBinding#getDefinition() * @see ICPPInternalBinding#getDefinition()

View file

@ -146,6 +146,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClass; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClass;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownConstructor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDeclaration; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDirective; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDirective;
@ -240,7 +241,9 @@ public class CPPSemantics {
data.ignoreUsingDirectives = true; data.ignoreUsingDirectives = true;
data.forceQualified = true; data.forceQualified = true;
for (int i = 0; i < data.associated.size(); i++) { for (int i = 0; i < data.associated.size(); i++) {
lookup(data, data.associated.keyAt(i)); final IScope scope = data.associated.keyAt(i);
if (!data.visited.containsKey(scope))
lookup(data, scope);
} }
binding = resolveAmbiguities(data, data.astName); binding = resolveAmbiguities(data, data.astName);
} }
@ -314,16 +317,18 @@ public class CPPSemantics {
ICPPASTTemplateId id = (ICPPASTTemplateId) data.astName; ICPPASTTemplateId id = (ICPPASTTemplateId) data.astName;
ICPPTemplateArgument[] args = CPPTemplates.createTemplateArgumentArray(id); ICPPTemplateArgument[] args = CPPTemplates.createTemplateArgumentArray(id);
IBinding inst= CPPTemplates.instantiate((ICPPClassTemplate) cls, args); IBinding inst= CPPTemplates.instantiate((ICPPClassTemplate) cls, args);
cls = inst instanceof ICPPClassType && !(inst instanceof ICPPDeferredClassInstance) ? if (inst instanceof ICPPClassType) {
(ICPPClassType) inst : cls; cls= (ICPPClassType) inst;
} }
} }
if (cls != null) { }
if (cls instanceof ICPPDeferredClassInstance) {
binding= new CPPUnknownConstructor(cls, data.astName);
} else {
// Force resolution of constructor bindings // Force resolution of constructor bindings
IBinding[] ctors = cls.getConstructors(); final ICPPConstructor[] constructors = cls.getConstructors();
if (ctors.length > 0 && !(ctors[0] instanceof IProblemBinding)) { if (constructors.length > 0) {
// then use the class scope to resolve which one. binding= CPPSemantics.resolveAmbiguities(data.astName, constructors);
binding = ((ICPPClassScope) cls.getCompositeScope()).getBinding(data.astName, true);
} }
} }
} catch (DOMException e) { } catch (DOMException e) {
@ -354,10 +359,14 @@ public class CPPSemantics {
if (binding == null && data.skippedScope != null) { if (binding == null && data.skippedScope != null) {
if (data.functionParameters != null) { if (data.functionParameters != null) {
binding= new CPPUnknownFunction(data.skippedScope, name.getLastName()); binding= new CPPUnknownFunction(data.skippedScope, name.getLastName());
} else {
if (name.getPropertyInParent() == IASTNamedTypeSpecifier.NAME) {
binding= new CPPUnknownClass(data.skippedScope, name.getLastName());
} else { } else {
binding= new CPPUnknownBinding(data.skippedScope, name.getLastName()); binding= new CPPUnknownBinding(data.skippedScope, name.getLastName());
} }
} }
}
if (binding != null) { if (binding != null) {
if (name.getPropertyInParent() == IASTNamedTypeSpecifier.NAME && !(binding instanceof IType || binding instanceof ICPPConstructor)) { if (name.getPropertyInParent() == IASTNamedTypeSpecifier.NAME && !(binding instanceof IType || binding instanceof ICPPConstructor)) {
@ -570,7 +579,7 @@ public class CPPSemantics {
* @param scoped * @param scoped
* @return * @return
*/ */
private static Object mergePrefixResults(CharArrayObjectMap dest, Object source, boolean scoped) { private static CharArrayObjectMap mergePrefixResults(CharArrayObjectMap dest, Object source, boolean scoped) {
if (source == null) return dest; if (source == null) return dest;
CharArrayObjectMap resultMap = (dest != null) ? dest : new CharArrayObjectMap(2); CharArrayObjectMap resultMap = (dest != null) ? dest : new CharArrayObjectMap(2);
@ -643,8 +652,6 @@ public class CPPSemantics {
*/ */
static protected void lookup(LookupData data, Object start) throws DOMException{ static protected void lookup(LookupData data, Object start) throws DOMException{
final IIndexFileSet fileSet= getIndexFileSet(data); final IIndexFileSet fileSet= getIndexFileSet(data);
final boolean isIndexBased= fileSet != IIndexFileSet.EMPTY;
IASTNode blockItem= data.astName; IASTNode blockItem= data.astName;
if (blockItem == null) if (blockItem == null)
return; return;
@ -695,33 +702,11 @@ public class CPPSemantics {
blockItem = CPPVisitor.getContainingBlockItem(blockItem); blockItem = CPPVisitor.getContainingBlockItem(blockItem);
if (!data.usingDirectivesOnly) { if (!data.usingDirectivesOnly) {
if (data.contentAssist) { IBinding[] bindings= scope.getBindings(data.astName, true, data.prefixLookup, fileSet);
if (!ASTInternal.isFullyCached(scope)) { if (data.typesOnly) {
lookupInScope(data, scope, blockItem); removeObjects(bindings);
} }
// now scope is fully cached.
final IBinding[] bindings = scope.getBindings(data.astName, true, data.prefixLookup, fileSet);
mergeResults(data, bindings, true); mergeResults(data, bindings, true);
} else {
boolean done= false;
if (!ASTInternal.isFullyCached(scope)) {
final IASTName[] names= lookupInScope(data, scope, blockItem);
if (names != null) {
mergeResults(data, names, true);
done= true;
}
}
if (!done) {
// now scope is fully cached.
final IBinding binding = scope.getBinding(data.astName, true, fileSet);
if (binding != null &&
(CPPSemantics.declaredBefore(binding, data.astName, isIndexBased) ||
(scope instanceof ICPPClassScope && data.checkWholeClassScope))) {
mergeResults(data, binding, true);
}
}
}
// store using-directives found in this block or namespace for later use. // store using-directives found in this block or namespace for later use.
if ((!data.hasResults() || !data.qualified() || data.contentAssist) && scope instanceof ICPPNamespaceScope) { if ((!data.hasResults() || !data.qualified() || data.contentAssist) && scope instanceof ICPPNamespaceScope) {
@ -736,7 +721,7 @@ public class CPPSemantics {
if (uds != null && uds.length > 0) { if (uds != null && uds.length > 0) {
HashSet<ICPPNamespaceScope> handled= new HashSet<ICPPNamespaceScope>(); HashSet<ICPPNamespaceScope> handled= new HashSet<ICPPNamespaceScope>();
for (final ICPPUsingDirective ud : uds) { for (final ICPPUsingDirective ud : uds) {
if (CPPSemantics.declaredBefore(ud, data.astName, false)) { if (declaredBefore(ud, data.astName, false)) {
storeUsingDirective(data, blockScope, ud, handled); storeUsingDirective(data, blockScope, ud, handled);
} }
} }
@ -779,6 +764,26 @@ public class CPPSemantics {
} }
} }
private static void removeObjects(final IBinding[] bindings) {
final int length = bindings.length;
int pos= 0;
for (int i = 0; i < length; i++) {
final IBinding binding= bindings[i];
IBinding check= binding;
if (binding instanceof ICPPUsingDeclaration) {
IBinding[] delegates= ((ICPPUsingDeclaration) binding).getDelegates();
if (delegates.length > 0)
check= delegates[0];
}
if (check instanceof IType || check instanceof ICPPNamespace) {
bindings[pos++]= binding;
}
}
while (pos < length) {
bindings[pos++]= null;
}
}
private static ICPPTemplateScope enclosingTemplateScope(IASTNode node) { private static ICPPTemplateScope enclosingTemplateScope(IASTNode node) {
IASTNode parent= node.getParent(); IASTNode parent= node.getParent();
if (parent instanceof IASTName) { if (parent instanceof IASTName) {
@ -880,25 +885,23 @@ public class CPPSemantics {
// is circular inheritance // is circular inheritance
if (!data.inheritanceChain.containsKey(classScope)) { if (!data.inheritanceChain.containsKey(classScope)) {
//is this name define in this scope? //is this name define in this scope?
if (ASTInternal.isFullyCached(classScope)) { IBinding[] inCurrentScope= classScope.getBindings(data.astName, true, data.prefixLookup);
if (data.astName != null && !data.contentAssist) { if (data.typesOnly) {
inherited = classScope.getBinding(data.astName, true); removeObjects(inCurrentScope);
} else if (data.astName != null) {
inherited = classScope.getBindings(data.astName, true, data.prefixLookup);
} }
} else { final boolean isEmpty= inCurrentScope.length == 0 || inCurrentScope[0] == null;
inherited = lookupInScope(data, classScope, null); if (data.contentAssist) {
}
if (inherited == null || data.contentAssist) {
Object temp = lookupInParents(data, classScope, overallScope); Object temp = lookupInParents(data, classScope, overallScope);
if (inherited != null) { if (!isEmpty) {
inherited = mergePrefixResults(null, inherited, true); inherited = mergePrefixResults(null, inCurrentScope, true);
inherited = mergePrefixResults((CharArrayObjectMap)inherited, (CharArrayObjectMap)temp, true); inherited = mergePrefixResults((CharArrayObjectMap)inherited, (CharArrayObjectMap)temp, true);
} else { } else {
inherited= temp; inherited= temp;
} }
} else if (isEmpty) {
inherited= lookupInParents(data, classScope, overallScope);
} else { } else {
inherited= inCurrentScope;
visitVirtualBaseClasses(data, cls); visitVirtualBaseClasses(data, cls);
} }
} else { } else {
@ -1116,13 +1119,7 @@ public class CPPSemantics {
IASTName[] namespaceDefs = null; IASTName[] namespaceDefs = null;
int namespaceIdx = -1; int namespaceIdx = -1;
if (data.associated.containsKey(scope)) {
// we are looking in scope, remove it from the associated scopes list
data.associated.remove(scope);
}
IASTName[] found = null; IASTName[] found = null;
if (parent instanceof IASTCompoundStatement) { if (parent instanceof IASTCompoundStatement) {
IASTNode p = parent.getParent(); IASTNode p = parent.getParent();
if (p instanceof IASTFunctionDefinition) { if (p instanceof IASTFunctionDefinition) {
@ -1277,9 +1274,6 @@ public class CPPSemantics {
} }
} }
ASTInternal.setFullyCached(scope, true);
return found; return found;
} }
@ -1298,16 +1292,13 @@ public class CPPSemantics {
data.visited.put(nominated); data.visited.put(nominated);
boolean found = false; boolean found = false;
if (ASTInternal.isFullyCached(nominated)) {
IBinding[] bindings= nominated.getBindings(data.astName, true, data.prefixLookup); IBinding[] bindings= nominated.getBindings(data.astName, true, data.prefixLookup);
if (bindings != null && bindings.length > 0) { if (bindings != null && bindings.length > 0) {
mergeResults(data, bindings, true); if (data.typesOnly) {
found = true; removeObjects(bindings);
} }
} else { if (bindings[0] != null) {
IASTName[] f = lookupInScope(data, nominated, null); mergeResults(data, bindings, true);
if (f != null) {
mergeResults(data, f, true);
found = true; found = true;
} }
} }
@ -1611,9 +1602,13 @@ public class CPPSemantics {
} }
static public boolean declaredBefore(Object obj, IASTNode node, boolean indexBased) { static public boolean declaredBefore(Object obj, IASTNode node, boolean indexBased) {
if (node == null) return true; if (node == null)
if (node.getPropertyInParent() == STRING_LOOKUP_PROPERTY) return true; return true;
final int pointOfRef= ((ASTNode) node).getOffset(); final int pointOfRef= ((ASTNode) node).getOffset();
if (node.getPropertyInParent() == STRING_LOOKUP_PROPERTY && pointOfRef <= 0) {
return true;
}
ASTNode nd = null; ASTNode nd = null;
if (obj instanceof ICPPSpecialization) { if (obj instanceof ICPPSpecialization) {
@ -1627,25 +1622,9 @@ public class CPPSemantics {
// previous declaration in one of the skipped header files. For bindings that // previous declaration in one of the skipped header files. For bindings that
// are likely to be redeclared we need to assume that there is a declaration // are likely to be redeclared we need to assume that there is a declaration
// in one of the headers. // in one of the headers.
if (indexBased) { if (indexBased && acceptDeclaredAfter(cpp)) {
try {
if (cpp instanceof ICPPNamespace || cpp instanceof ICPPFunction || cpp instanceof ICPPVariable) {
IScope scope= cpp.getScope();
if (scope instanceof ICPPBlockScope == false && scope instanceof ICPPNamespaceScope) {
return true; return true;
} }
} else if (cpp instanceof ICompositeType || cpp instanceof IEnumeration) {
IScope scope= cpp.getScope();
if (scope instanceof ICPPBlockScope == false && scope instanceof ICPPNamespaceScope) {
// if this is not the definition, it may be found in a header. (bug 229571)
if (cpp.getDefinition() == null) {
return true;
}
}
}
} catch (DOMException e) {
}
}
IASTNode[] n = cpp.getDeclarations(); IASTNode[] n = cpp.getDeclarations();
if (n != null && n.length > 0) { if (n != null && n.length > 0) {
nd = (ASTNode) n[0]; nd = (ASTNode) n[0];
@ -1657,11 +1636,20 @@ public class CPPSemantics {
} }
if (nd == null) if (nd == null)
return true; return true;
} else if (obj instanceof ASTNode) { } else {
if (indexBased && obj instanceof IASTName) {
IBinding b= ((IASTName) obj).getPreBinding();
if (b instanceof ICPPInternalBinding) {
if (acceptDeclaredAfter((ICPPInternalBinding) b))
return true;
}
}
if (obj instanceof ASTNode) {
nd = (ASTNode) obj; nd = (ASTNode) obj;
} else if (obj instanceof ICPPUsingDirective) { } else if (obj instanceof ICPPUsingDirective) {
pointOfDecl= ((ICPPUsingDirective) obj).getPointOfDeclaration(); pointOfDecl= ((ICPPUsingDirective) obj).getPointOfDeclaration();
} }
}
if (pointOfDecl < 0 && nd != null) { if (pointOfDecl < 0 && nd != null) {
ASTNodeProperty prop = nd.getPropertyInParent(); ASTNodeProperty prop = nd.getPropertyInParent();
@ -1697,6 +1685,27 @@ public class CPPSemantics {
return (pointOfDecl < pointOfRef); return (pointOfDecl < pointOfRef);
} }
private static boolean acceptDeclaredAfter(ICPPInternalBinding cpp) {
try {
if (cpp instanceof ICPPNamespace || cpp instanceof ICPPFunction || cpp instanceof ICPPVariable) {
IScope scope= cpp.getScope();
if (scope instanceof ICPPBlockScope == false && scope instanceof ICPPNamespaceScope) {
return true;
}
} else if (cpp instanceof ICompositeType || cpp instanceof IEnumeration) {
IScope scope= cpp.getScope();
if (scope instanceof ICPPBlockScope == false && scope instanceof ICPPNamespaceScope) {
// if this is not the definition, it may be found in a header. (bug 229571)
if (cpp.getDefinition() == null) {
return true;
}
}
}
} catch (DOMException e) {
}
return false;
}
static private IBinding resolveAmbiguities(LookupData data, IASTName name) throws DOMException { static private IBinding resolveAmbiguities(LookupData data, IASTName name) throws DOMException {
if (!data.hasResults() || data.contentAssist) if (!data.hasResults() || data.contentAssist)
return null; return null;
@ -1710,6 +1719,7 @@ public class CPPSemantics {
IBinding obj = null; IBinding obj = null;
IBinding temp = null; IBinding temp = null;
boolean fnsFromAST= false; boolean fnsFromAST= false;
boolean fnTmplsFromAST= false;
Object[] items = (Object[]) data.foundItems; Object[] items = (Object[]) data.foundItems;
for (int i = 0; i < items.length && items[i] != null; i++) { for (int i = 0; i < items.length && items[i] != null; i++) {
@ -1768,7 +1778,18 @@ public class CPPSemantics {
if (function instanceof ICPPFunctionTemplate) { if (function instanceof ICPPFunctionTemplate) {
if (templateFns == ObjectSet.EMPTY_SET) if (templateFns == ObjectSet.EMPTY_SET)
templateFns = new ObjectSet<IFunction>(2); templateFns = new ObjectSet<IFunction>(2);
if (isFromIndex(function)) {
// accept bindings from index only, in case we have none in the AST
if (!fnTmplsFromAST) {
templateFns.put(function); templateFns.put(function);
}
} else {
if (!fnTmplsFromAST) {
templateFns.clear();
fnTmplsFromAST= true;
}
templateFns.put(function);
}
} else { } else {
if (fns == ObjectSet.EMPTY_SET) if (fns == ObjectSet.EMPTY_SET)
fns = new ObjectSet<IFunction>(2); fns = new ObjectSet<IFunction>(2);
@ -1798,8 +1819,15 @@ public class CPPSemantics {
if (type == null) { if (type == null) {
type = temp; type = temp;
} else if (type != temp && !((IType)type).isSameType((IType) temp)) { } else if (type != temp && !((IType)type).isSameType((IType) temp)) {
boolean i1= isFromIndex(type);
boolean i2= isFromIndex(temp);
if (i1 != i2) {
if (i1)
type= temp;
} else {
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.getNameCharArray()); return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.getNameCharArray());
} }
}
} else { } else {
if (obj == null) { if (obj == null) {
obj = temp; obj = temp;
@ -2611,10 +2639,13 @@ public class CPPSemantics {
astName.setName(name); astName.setName(name);
astName.setParent(ASTInternal.getPhysicalNodeOfScope(scope)); astName.setParent(ASTInternal.getPhysicalNodeOfScope(scope));
astName.setPropertyInParent(STRING_LOOKUP_PROPERTY); astName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
if (beforeNode instanceof ASTNode) {
astName.setOffsetAndLength((ASTNode) beforeNode);
}
LookupData data = new LookupData(astName); LookupData data = new LookupData(astName);
data.forceQualified = qualified; data.forceQualified = qualified;
return standardLookup(data, scope, beforeNode); return standardLookup(data, scope);
} }
public static IBinding[] findBindingsForContentAssist(IASTName name, boolean prefixLookup) { public static IBinding[] findBindingsForContentAssist(IASTName name, boolean prefixLookup) {
@ -2665,7 +2696,7 @@ public class CPPSemantics {
return (IBinding[]) ArrayUtil.trim(IBinding.class, result); return (IBinding[]) ArrayUtil.trim(IBinding.class, result);
} }
private static IBinding[] standardLookup(LookupData data, Object start, IASTNode beforeNode) { private static IBinding[] standardLookup(LookupData data, Object start) {
try { try {
lookup(data, start); lookup(data, start);
} catch (DOMException e) { } catch (DOMException e) {
@ -2676,16 +2707,9 @@ public class CPPSemantics {
if (items == null) if (items == null)
return new IBinding[0]; return new IBinding[0];
boolean indexBased= false;
if (beforeNode != null) {
IASTTranslationUnit tu= beforeNode.getTranslationUnit();
if (tu != null && tu.getIndex() != null)
indexBased= true;
}
ObjectSet<IBinding> set = new ObjectSet<IBinding>(items.length); ObjectSet<IBinding> set = new ObjectSet<IBinding>(items.length);
IBinding binding = null; IBinding binding = null;
for (Object item : items) { for (Object item : items) {
if (beforeNode == null || declaredBefore(item, beforeNode, indexBased)) {
if (item instanceof IASTName) { if (item instanceof IASTName) {
binding = ((IASTName) item).resolveBinding(); binding = ((IASTName) item).resolveBinding();
} else if (item instanceof IBinding) { } else if (item instanceof IBinding) {
@ -2704,7 +2728,6 @@ public class CPPSemantics {
} }
} }
} }
}
return set.keyArray(IBinding.class); return set.keyArray(IBinding.class);
} }

View file

@ -86,7 +86,6 @@ import org.eclipse.cdt.core.parser.util.CharArraySet;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.core.parser.util.ObjectSet; import org.eclipse.cdt.core.parser.util.ObjectSet;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope; import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
@ -124,6 +123,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClass; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClass;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalTemplateDeclaration; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalTemplateDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
@ -2043,20 +2043,16 @@ public class CPPTemplates {
} }
} else if (t instanceof ICPPClassType) { } else if (t instanceof ICPPClassType) {
IScope s = ((ICPPClassType) t).getCompositeScope(); IScope s = ((ICPPClassType) t).getCompositeScope();
if (s != null && ASTInternal.isFullyCached(s)) { if (s != null) {
// If name did not come from an AST but was created just to encapsulate
// a simple identifier, we should not use getBinding method since it may
// lead to a NullPointerException.
IASTName name= unknown.getUnknownName(); IASTName name= unknown.getUnknownName();
if (name != null) { if (name != null) {
if (name.getParent() != null) { IBinding[] candidates;
result = s.getBinding(name, true); if (s instanceof ICPPASTInternalScope) {
candidates= ((ICPPASTInternalScope) s).getBindings(name, true, false, null, false);
} else { } else {
IBinding[] bindings = s.find(name.toString()); candidates= s.getBindings(name, true, false, null);
if (bindings != null && bindings.length > 0) {
result = bindings[0];
}
} }
result= CPPSemantics.resolveAmbiguities(name, candidates);
if (unknown instanceof ICPPUnknownClassInstance && result instanceof ICPPTemplateDefinition) { if (unknown instanceof ICPPUnknownClassInstance && result instanceof ICPPTemplateDefinition) {
ICPPTemplateArgument[] newArgs = CPPTemplates.instantiateArguments(((ICPPUnknownClassInstance) unknown).getArguments(), tpMap, within); ICPPTemplateArgument[] newArgs = CPPTemplates.instantiateArguments(((ICPPUnknownClassInstance) unknown).getArguments(), tpMap, within);
if (result instanceof ICPPClassTemplate) { if (result instanceof ICPPClassTemplate) {

View file

@ -180,6 +180,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPPointerType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
import org.eclipse.cdt.internal.core.index.IIndexScope; import org.eclipse.cdt.internal.core.index.IIndexScope;
/** /**
@ -1991,6 +1992,8 @@ public class CPPVisitor extends ASTQueries {
} }
} else if (type instanceof IPointerType || type instanceof IArrayType) { } else if (type instanceof IPointerType || type instanceof IArrayType) {
return ((ITypeContainer) type).getType(); return ((ITypeContainer) type).getType();
} else if (type instanceof ICPPUnknownType) {
return CPPUnknownClass.createUnnamedInstance();
} }
return new ProblemBinding(expression, IProblemBinding.SEMANTIC_INVALID_TYPE, return new ProblemBinding(expression, IProblemBinding.SEMANTIC_INVALID_TYPE,
expression.getRawSignature().toCharArray()); expression.getRawSignature().toCharArray());

View file

@ -50,7 +50,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit;
/** /**
* Context data for IASTName lookup * Context data for IASTName lookup
*/ */
class LookupData { public class LookupData {
protected IASTName astName; protected IASTName astName;
protected CPPASTTranslationUnit tu; protected CPPASTTranslationUnit tu;
public Map<ICPPNamespaceScope, List<ICPPNamespaceScope>> usingDirectives= Collections.emptyMap(); public Map<ICPPNamespaceScope, List<ICPPNamespaceScope>> usingDirectives= Collections.emptyMap();
@ -90,7 +90,7 @@ class LookupData {
tu= (CPPASTTranslationUnit) astName.getTranslationUnit(); tu= (CPPASTTranslationUnit) astName.getTranslationUnit();
typesOnly = typesOnly(astName); typesOnly = typesOnly(astName);
considerConstructors = considerConstructors(); considerConstructors = considerConstructors();
checkWholeClassScope = checkWholeClassScope(); checkWholeClassScope = checkWholeClassScope(n);
} }
public LookupData() { public LookupData() {
@ -233,6 +233,8 @@ class LookupData {
if (p1 instanceof ICPPASTNamedTypeSpecifier && p2 instanceof IASTTypeId) { if (p1 instanceof ICPPASTNamedTypeSpecifier && p2 instanceof IASTTypeId) {
return p2.getParent() instanceof ICPPASTNewExpression; return p2.getParent() instanceof ICPPASTNewExpression;
} else if (p1 instanceof ICPPASTQualifiedName) { } else if (p1 instanceof ICPPASTQualifiedName) {
if (((ICPPASTQualifiedName) p1).getLastName() != astName)
return false;
if (p2 instanceof ICPPASTFunctionDeclarator) { if (p2 instanceof ICPPASTFunctionDeclarator) {
IASTName[] names = ((ICPPASTQualifiedName)p1).getNames(); IASTName[] names = ((ICPPASTQualifiedName)p1).getNames();
if (names.length >= 2 && names[names.length - 1] == astName) if (names.length >= 2 && names[names.length - 1] == astName)
@ -270,11 +272,11 @@ class LookupData {
return (p1 instanceof IASTIdExpression && p1.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME); return (p1 instanceof IASTIdExpression && p1.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME);
} }
private boolean checkWholeClassScope() { public static boolean checkWholeClassScope(IASTName name) {
if (astName == null) return false; if (name == null) return false;
if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return true; if (name.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return true;
IASTNode parent = astName.getParent(); IASTNode parent = name.getParent();
while (parent != null && !(parent instanceof IASTFunctionDefinition)) { while (parent != null && !(parent instanceof IASTFunctionDefinition)) {
ASTNodeProperty prop = parent.getPropertyInParent(); ASTNodeProperty prop = parent.getPropertyInParent();
if (prop == IASTParameterDeclaration.DECL_SPECIFIER || if (prop == IASTParameterDeclaration.DECL_SPECIFIER ||
@ -289,9 +291,9 @@ class LookupData {
if (parent.getPropertyInParent() != IASTCompositeTypeSpecifier.MEMBER_DECLARATION) if (parent.getPropertyInParent() != IASTCompositeTypeSpecifier.MEMBER_DECLARATION)
return false; return false;
ASTNodeProperty prop = astName.getPropertyInParent(); ASTNodeProperty prop = name.getPropertyInParent();
if (prop == ICPPASTQualifiedName.SEGMENT_NAME) if (prop == ICPPASTQualifiedName.SEGMENT_NAME)
prop = astName.getParent().getPropertyInParent(); prop = name.getParent().getPropertyInParent();
if (prop == IASTIdExpression.ID_NAME || if (prop == IASTIdExpression.ID_NAME ||
prop == IASTFieldReference.FIELD_NAME || prop == IASTFieldReference.FIELD_NAME ||
prop == ICASTFieldDesignator.FIELD_NAME || prop == ICASTFieldDesignator.FIELD_NAME ||

View file

@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Andrew Ferguson (Symbian) - Initial implementation * Andrew Ferguson (Symbian) - Initial implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.index.composite.cpp; package org.eclipse.cdt.internal.core.index.composite.cpp;
@ -17,6 +18,7 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.core.index.IIndexFileSet;
@ -51,6 +53,20 @@ class CompositeCPPClassScope extends CompositeScope implements ICPPClassScope {
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
} }
public ICPPConstructor[] getConstructors() {
try {
ICPPClassScope rscope = (ICPPClassScope) ((ICPPClassType)rbinding).getCompositeScope();
ICPPConstructor[] result = rscope.getConstructors();
for(int i=0; i<result.length; i++) {
result[i] = (ICPPConstructor) cf.getCompositeBinding((IIndexFragmentBinding)result[i]);
}
return result;
} catch (DOMException de) {
CCorePlugin.log(de);
}
return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY;
}
public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet fileSet) throws DOMException { public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet fileSet) throws DOMException {
IBinding binding = ((ICPPClassType)rbinding).getCompositeScope().getBinding(name, resolve, fileSet); IBinding binding = ((ICPPClassType)rbinding).getCompositeScope().getBinding(name, resolve, fileSet);
return processUncertainBinding(binding); return processUncertainBinding(binding);

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* QNX - Initial API and implementation * Doug Schaefer (QNX) - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Andrew Ferguson (Symbian) * Andrew Ferguson (Symbian)
*******************************************************************************/ *******************************************************************************/
@ -22,7 +22,6 @@ import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
@ -36,7 +35,7 @@ import org.eclipse.cdt.internal.core.pdom.db.IString;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
/** /**
* @author Doug Schaefer * Base class for bindings in the pdom.
*/ */
public abstract class PDOMBinding extends PDOMNamedNode implements IPDOMBinding { public abstract class PDOMBinding extends PDOMNamedNode implements IPDOMBinding {
public static final PDOMBinding[] EMPTY_PDOMBINDING_ARRAY = {}; public static final PDOMBinding[] EMPTY_PDOMBINDING_ARRAY = {};
@ -289,7 +288,7 @@ public abstract class PDOMBinding extends PDOMNamedNode implements IPDOMBinding
try { try {
PDOMNode node = this; PDOMNode node = this;
while (node != null) { while (node != null) {
if (node instanceof PDOMBinding && !(node instanceof ICPPTemplateInstance)) { if (node instanceof PDOMBinding) {
result.add(0, ((PDOMBinding)node).getName()); result.add(0, ((PDOMBinding)node).getName());
} }
node = node.getParentNode(); node = node.getParentNode();

View file

@ -11,7 +11,6 @@
* IBM Corporation * IBM Corporation
* Andrew Ferguson (Symbian) * Andrew Ferguson (Symbian)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.c; package org.eclipse.cdt.internal.core.pdom.dom.c;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
@ -106,6 +105,7 @@ class PDOMCLinkage extends PDOMLinkage implements IIndexCBindingConstants {
private PDOMBinding createBinding(PDOMNode parent, IBinding binding) throws CoreException { private PDOMBinding createBinding(PDOMNode parent, IBinding binding) throws CoreException {
PDOMBinding pdomBinding= null; PDOMBinding pdomBinding= null;
PDOMNode inheritFileLocal= parent;
if (binding instanceof IField) { // must be before IVariable if (binding instanceof IField) { // must be before IVariable
if (parent instanceof IPDOMMemberOwner) if (parent instanceof IPDOMMemberOwner)
@ -125,6 +125,7 @@ class PDOMCLinkage extends PDOMLinkage implements IIndexCBindingConstants {
IType enumeration= ((IEnumerator)binding).getType(); IType enumeration= ((IEnumerator)binding).getType();
if (enumeration instanceof IEnumeration) { if (enumeration instanceof IEnumeration) {
PDOMBinding pdomEnumeration = adaptBinding((IEnumeration) enumeration); PDOMBinding pdomEnumeration = adaptBinding((IEnumeration) enumeration);
inheritFileLocal= pdomEnumeration;
if (pdomEnumeration instanceof PDOMCEnumeration) if (pdomEnumeration instanceof PDOMCEnumeration)
pdomBinding = new PDOMCEnumerator(pdom, parent, (IEnumerator) binding, (PDOMCEnumeration)pdomEnumeration); pdomBinding = new PDOMCEnumerator(pdom, parent, (IEnumerator) binding, (PDOMCEnumeration)pdomEnumeration);
} }
@ -136,7 +137,7 @@ class PDOMCLinkage extends PDOMLinkage implements IIndexCBindingConstants {
} }
if (pdomBinding != null) { if (pdomBinding != null) {
pdomBinding.setLocalToFileRec(getLocalToFileRec(parent, binding)); pdomBinding.setLocalToFileRec(getLocalToFileRec(inheritFileLocal, binding));
parent.addChild(pdomBinding); parent.addChild(pdomBinding);
afterAddBinding(pdomBinding); afterAddBinding(pdomBinding);
} }
@ -260,12 +261,24 @@ class PDOMCLinkage extends PDOMLinkage implements IIndexCBindingConstants {
if (parent == null) { if (parent == null) {
parent= getAdaptedParent(binding); parent= getAdaptedParent(binding);
} }
PDOMNode inheritFileLocal= parent;
if (binding instanceof IEnumerator) {
try {
IType enumeration= ((IEnumerator)binding).getType();
if (enumeration instanceof IEnumeration) {
inheritFileLocal= adaptBinding((IEnumeration) enumeration);
}
} catch (DOMException e) {
CCorePlugin.log(e);
}
}
if (parent == this) { if (parent == this) {
int localToFileRec= getLocalToFileRec(null, binding); int localToFileRec= getLocalToFileRec(inheritFileLocal, binding);
return FindBinding.findBinding(getIndex(), getPDOM(), binding.getNameCharArray(), new int[] {getBindingType(binding)}, localToFileRec); return FindBinding.findBinding(getIndex(), getPDOM(), binding.getNameCharArray(), new int[] {getBindingType(binding)}, localToFileRec);
} }
if (parent instanceof IPDOMMemberOwner) { if (parent instanceof IPDOMMemberOwner) {
int localToFileRec= getLocalToFileRec(parent, binding); int localToFileRec= getLocalToFileRec(inheritFileLocal, binding);
return FindBinding.findBinding(parent, getPDOM(), binding.getNameCharArray(), new int[] {getBindingType(binding)}, localToFileRec); return FindBinding.findBinding(parent, getPDOM(), binding.getNameCharArray(), new int[] {getBindingType(binding)}, localToFileRec);
} }
return null; return null;

View file

@ -30,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexBinding;
@ -80,11 +81,7 @@ class PDOMCPPClassScope implements ICPPClassScope, IIndexScope {
return CPPSemantics.resolveAmbiguities(name, fBinding.getConstructors()); return CPPSemantics.resolveAmbiguities(name, fBinding.getConstructors());
} }
//9.2 ... The class-name is also inserted into the scope of the class itself //9.2 ... The class-name is also inserted into the scope of the class itself
if (fBinding instanceof ICPPClassTemplatePartialSpecialization) return getClassNameBinding();
return ((ICPPClassTemplatePartialSpecialization) fBinding).getPrimaryClassTemplate();
if (fBinding instanceof ICPPSpecialization)
return ((ICPPSpecialization) fBinding).getSpecializedBinding();
return fBinding;
} }
final IBinding[] candidates = getBindingsViaCache(fBinding, nameChars, IndexFilter.CPP_DECLARED_OR_IMPLICIT_NO_INSTANCE); final IBinding[] candidates = getBindingsViaCache(fBinding, nameChars, IndexFilter.CPP_DECLARED_OR_IMPLICIT_NO_INSTANCE);
@ -95,24 +92,33 @@ class PDOMCPPClassScope implements ICPPClassScope, IIndexScope {
return null; return null;
} }
private IBinding getClassNameBinding() throws DOMException {
if (fBinding instanceof ICPPClassTemplatePartialSpecialization)
return ((ICPPClassTemplatePartialSpecialization) fBinding).getPrimaryClassTemplate();
if (fBinding instanceof ICPPSpecialization)
return ((ICPPSpecialization) fBinding).getSpecializedBinding();
return fBinding;
}
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) throws DOMException { public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) throws DOMException {
IBinding[] result = null; IBinding[] result = null;
try { try {
final char[] nameChars = name.getSimpleID(); final char[] nameChars = name.getSimpleID();
if (!prefixLookup) { if (!prefixLookup) {
if (CharArrayUtils.equals(fBinding.getNameCharArray(), nameChars)) {
if (CPPClassScope.isConstructorReference(name)){
return fBinding.getConstructors();
}
return new IBinding[] {getClassNameBinding()};
}
return getBindingsViaCache(fBinding, nameChars, IndexFilter.CPP_DECLARED_OR_IMPLICIT_NO_INSTANCE); return getBindingsViaCache(fBinding, nameChars, IndexFilter.CPP_DECLARED_OR_IMPLICIT_NO_INSTANCE);
} }
// prefix lookup
BindingCollector visitor = new BindingCollector(fBinding.getLinkage(), nameChars, IndexFilter.CPP_DECLARED_OR_IMPLICIT_NO_INSTANCE, prefixLookup, !prefixLookup); BindingCollector visitor = new BindingCollector(fBinding.getLinkage(), nameChars, IndexFilter.CPP_DECLARED_OR_IMPLICIT_NO_INSTANCE, prefixLookup, !prefixLookup);
if (CharArrayUtils.equals(fBinding.getNameCharArray(), 0, nameChars.length, nameChars, true)) { if (CharArrayUtils.equals(fBinding.getNameCharArray(), 0, nameChars.length, nameChars, true)) {
// 9.2 ... The class-name is also inserted into the scope of // add the class itself, constructors will be found during the visit
// the class itself visitor.visit((IPDOMNode) getClassNameBinding());
IPDOMNode node= fBinding;
if (node instanceof ICPPClassTemplatePartialSpecialization)
node= (IPDOMNode) ((ICPPClassTemplatePartialSpecialization) fBinding).getPrimaryClassTemplate();
else if (fBinding instanceof ICPPSpecialization)
node= (IPDOMNode) ((ICPPSpecialization) fBinding).getSpecializedBinding();
visitor.visit(node);
} }
acceptViaCache(fBinding, visitor, true); acceptViaCache(fBinding, visitor, true);
result= visitor.getBindings(); result= visitor.getBindings();
@ -221,6 +227,9 @@ class PDOMCPPClassScope implements ICPPClassScope, IIndexScope {
} }
} }
public ICPPConstructor[] getConstructors() throws DOMException {
return fBinding.getConstructors();
}
public IIndexScope getParent() { public IIndexScope getParent() {
return fBinding.getScope(); return fBinding.getScope();

View file

@ -295,6 +295,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
PDOMBinding createBinding(PDOMNode parent, IBinding binding) throws CoreException, DOMException { PDOMBinding createBinding(PDOMNode parent, IBinding binding) throws CoreException, DOMException {
PDOMBinding pdomBinding= null; PDOMBinding pdomBinding= null;
PDOMNode inheritFileLocal = parent;
// template parameters are created directly by their owners. // template parameters are created directly by their owners.
if (binding instanceof ICPPTemplateParameter) if (binding instanceof ICPPTemplateParameter)
@ -357,6 +358,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
PDOMBinding pdomEnumeration = adaptBinding((IEnumeration) enumeration); PDOMBinding pdomEnumeration = adaptBinding((IEnumeration) enumeration);
if (pdomEnumeration instanceof PDOMCPPEnumeration) { if (pdomEnumeration instanceof PDOMCPPEnumeration) {
pdomBinding = new PDOMCPPEnumerator(pdom, parent, etor, (PDOMCPPEnumeration)pdomEnumeration); pdomBinding = new PDOMCPPEnumerator(pdom, parent, etor, (PDOMCPPEnumeration)pdomEnumeration);
inheritFileLocal= pdomEnumeration;
} }
} }
} else if (binding instanceof ITypedef) { } else if (binding instanceof ITypedef) {
@ -364,7 +366,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
} }
if (pdomBinding != null) { if (pdomBinding != null) {
pdomBinding.setLocalToFileRec(getLocalToFileRec(parent, binding)); pdomBinding.setLocalToFileRec(getLocalToFileRec(inheritFileLocal, binding));
parent.addChild(pdomBinding); parent.addChild(pdomBinding);
afterAddBinding(pdomBinding); afterAddBinding(pdomBinding);
} }
@ -579,12 +581,24 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
if (parent == null) { if (parent == null) {
parent= adaptOrAddParent(false, binding); parent= adaptOrAddParent(false, binding);
} }
PDOMNode inheritFileLocal= parent;
if (binding instanceof IEnumerator) {
try {
IType enumeration= ((IEnumerator)binding).getType();
if (enumeration instanceof IEnumeration) {
inheritFileLocal= adaptBinding((IEnumeration) enumeration);
}
} catch (DOMException e) {
CCorePlugin.log(e);
}
}
if (parent == this) { if (parent == this) {
int localToFileRec= getLocalToFileRec(null, binding); int localToFileRec= getLocalToFileRec(inheritFileLocal, binding);
return CPPFindBinding.findBinding(getIndex(), this, binding, localToFileRec); return CPPFindBinding.findBinding(getIndex(), this, binding, localToFileRec);
} }
if (parent instanceof PDOMCPPNamespace) { if (parent instanceof PDOMCPPNamespace) {
int localToFileRec= getLocalToFileRec(parent, binding); int localToFileRec= getLocalToFileRec(inheritFileLocal, binding);
return CPPFindBinding.findBinding(((PDOMCPPNamespace) parent).getIndex(), this, binding, return CPPFindBinding.findBinding(((PDOMCPPNamespace) parent).getIndex(), this, binding,
localToFileRec); localToFileRec);
} }
@ -593,7 +607,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
(ICPPTemplateParameter) binding); (ICPPTemplateParameter) binding);
} }
if (parent instanceof IPDOMMemberOwner) { if (parent instanceof IPDOMMemberOwner) {
int localToFileRec= getLocalToFileRec(parent, binding); int localToFileRec= getLocalToFileRec(inheritFileLocal, binding);
return CPPFindBinding.findBinding(parent, this, binding, localToFileRec); return CPPFindBinding.findBinding(parent, this, binding, localToFileRec);
} }
return null; return null;

View file

@ -176,10 +176,6 @@ class PDOMCPPNamespace extends PDOMCPPBinding
return result; return result;
} }
public boolean isFullyCached() throws DOMException {
return true;
}
@Override @Override
public boolean mayHaveChildren() { public boolean mayHaveChildren() {
return true; return true;