diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 58dffcfb95a..d3f059bef2c 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -2311,7 +2311,7 @@ public class AST2CPPTests extends AST2BaseTest { assertTrue(result.contains("a3")); assertTrue(result.contains("a4")); assertTrue(result.contains("A")); - assertEquals(5, bs.length); + assertEquals(7, bs.length); // the bindings above + 2 constructors } // static void f(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassScope.java index f5653a78457..3a6b9f9338f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassScope.java @@ -6,15 +6,18 @@ * http://www.eclipse.org/legal/epl-v10.html * * 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; +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 { /** @@ -31,4 +34,10 @@ public interface ICPPClassScope extends ICPPScope { * */ public ICPPMethod[] getImplicitMethods(); + + /** + * Returns the array of constructors, including implicit ones. + * @since 5.1 + */ + public ICPPConstructor[] getConstructors() throws DOMException; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTInternal.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTInternal.java index 1c9dbf15fce..775c0ecf01a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTInternal.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTInternal.java @@ -8,7 +8,6 @@ * Contributors: * Markus Schorn - initial API and implementation *******************************************************************************/ - package org.eclipse.cdt.internal.core.dom.parser; 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.IFunction; 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.ICInternalFunction; 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 { - if (scope instanceof IASTInternalScope) { - return ((IASTInternalScope) scope).isFullyCached(); + if (scope instanceof CScope) { + return ((CScope) scope).isFullyCached(); } return true; } public static void setFullyCached(IScope scope, boolean val) throws DOMException { - if (scope instanceof IASTInternalScope) { - ((IASTInternalScope) scope).setFullyCached(val); + if (scope instanceof CScope) { + ((CScope) scope).setFullyCached(val); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTInternalScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTInternalScope.java index a2a7d862da7..47916afda5e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTInternalScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTInternalScope.java @@ -25,16 +25,6 @@ public interface IASTInternalScope extends IScope { * Return the physical IASTNode that this scope was created for */ 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 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java index 280a64fdda1..e9cdde2477d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java @@ -193,19 +193,6 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I 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) * @see org.eclipse.cdt.core.dom.ast.IType#isSameType(org.eclipse.cdt.core.dom.ast.IType) */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPClassSpecializationScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPClassSpecializationScope.java index 34752a82f08..8b4ed373158 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPClassSpecializationScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPClassSpecializationScope.java @@ -81,27 +81,45 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat 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 { + 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(); - IBinding[] result = null; if ((!prefixLookup && CharArrayUtils.equals(c, specialClass.getNameCharArray())) || (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(); IScope classScope = specialized.getCompositeScope(); - IBinding[] bindings = classScope != null ? - classScope.getBindings(name, forceResolve, prefixLookup, fileSet) : null; + if (classScope == null) + return IBinding.EMPTY_BINDING_ARRAY; - if (bindings != null) { - for (IBinding binding : bindings) { - result = (IBinding[]) ArrayUtil.append(IBinding.class, result, specialClass.specializeMember(binding)); - } + 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) { + binding= specialClass.specializeMember(binding); + result = (IBinding[]) ArrayUtil.append(IBinding.class, result, binding); } - return (IBinding[]) ArrayUtil.trim(IBinding.class, result); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java index 08366a1515e..a32dc79e01d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java @@ -220,7 +220,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { } if (CharArrayUtils.equals(c, compName.getLookupKey())) { 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 return compName.resolveBinding(); @@ -229,7 +229,8 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { } @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(); ICPPASTCompositeTypeSpecifier compType = (ICPPASTCompositeTypeSpecifier) getPhysicalNode(); @@ -241,7 +242,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { if ((!prefixLookup && CharArrayUtils.equals(c, compName.getLookupKey())) || (prefixLookup && CharArrayUtils.equals(compName.getLookupKey(), 0, c.length, c, true))) { 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 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); } 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); } @@ -263,23 +264,22 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { return true; } - protected ICPPConstructor[] getConstructors(boolean forceResolve) { - return getConstructors(bindings, forceResolve, null); - } - static protected ICPPConstructor[] getConstructors(CharArrayObjectMap bindings, boolean forceResolve) { - return getConstructors(bindings, forceResolve, null); + public ICPPConstructor[] getConstructors() { + return getConstructors(null, true); } - @SuppressWarnings("unchecked") - static protected ICPPConstructor[] getConstructors(CharArrayObjectMap bindings, boolean forceResolve, IASTName forName) { - if (bindings == null) + private ICPPConstructor[] getConstructors(IASTName forName, boolean forceResolve) { + populateCache(); + + final CharArrayObjectMap nameMap = bindings; + if (nameMap == null) return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY; - Object o = bindings.get(CONSTRUCTOR_KEY); + Object o = nameMap.get(CONSTRUCTOR_KEY); if (o != null) { IBinding binding = null; - if (o instanceof ObjectSet) { - ObjectSet set = (ObjectSet) o; + if (o instanceof ObjectSet) { + ObjectSet set = (ObjectSet) o; IBinding[] bs = null; for (int i = 0; i < set.size(); i++) { Object obj = set.keyAt(i); @@ -297,7 +297,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { } else if (o instanceof IASTName) { 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. - bindings.put(CONSTRUCTOR_KEY, o); + nameMap.put(CONSTRUCTOR_KEY, o); binding = ((IASTName)o).resolveBinding(); } } 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; IASTNode node = name.getParent(); if (node instanceof ICPPASTTemplateId) - node = node.getParent(); + return false; if (node instanceof ICPPASTQualifiedName) { if (((ICPPASTQualifiedName) node).getLastName() == name) node = node.getParent(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecializationScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecializationScope.java index 65691d9bfab..2512a421969 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecializationScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecializationScope.java @@ -6,46 +6,28 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM - Initial API and implementation - * Markus Schorn (Wind River Systems) - * Bryan Wilkinson (QNX) - * Andrew Ferguson (Symbian) + * Andrew Niefer (IBM) - Initial API and implementation + * Markus Schorn (Wind River Systems) + * Bryan Wilkinson (QNX) + * Andrew Ferguson (Symbian) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; -import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.cpp.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) { 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 - public void setFullyCached(boolean b) {} public void flushCache() {} public void addName(IASTName name) {} public IASTNode getPhysicalNode() { return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java index a4c558bc200..4df8c4e5308 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java @@ -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.ICPPASTTemplateId; 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.ICPPClassTemplatePartialSpecialization; 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.ICPPMethod; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArrayUtils; @@ -141,7 +141,7 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements return null; } - public ICPPScope getCompositeScope() { + public ICPPClassScope getCompositeScope() { if (definition == null) { checkForDefinition(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java index b313c775013..f99cae09fc5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java @@ -281,7 +281,7 @@ public class CPPClassType extends PlatformObject implements ICPPInternalClassTyp return scope; } - public IScope getCompositeScope() { + public ICPPClassScope getCompositeScope() { if (definition == null) { checkForDefinition(); } @@ -291,7 +291,9 @@ public class CPPClassType extends PlatformObject implements ICPPInternalClassTyp // fwd-declarations must be backed up from the index if (typeInIndex != null) { try { - return typeInIndex.getCompositeScope(); + IScope scope = typeInIndex.getCompositeScope(); + if (scope instanceof ICPPClassScope) + return (ICPPClassScope) scope; } catch (DOMException e) { // index bindings don't throw DOMExeptions. } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java index 0924189d4f2..51f750ec10d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java @@ -6,7 +6,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM Corporation - initial API and implementation + * Andrew Niefer (IBM Corporation) - initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ 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.ICPPUsingDirective; 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; /** - * @author aniefer + * Implementation of namespace scopes, including global scope. */ public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{ ICPPUsingDirective[] usings = null; @@ -48,9 +47,7 @@ public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{ * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope#getUsingDirectives() */ public ICPPUsingDirective[] getUsingDirectives() throws DOMException { - if (!isFullyCached()) { - CPPSemantics.lookupInScope(null, this, null); - } + populateCache(); return (ICPPUsingDirective[]) ArrayUtil.trim( ICPPUsingDirective.class, usings, true ); } /* (non-Javadoc) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java index 7c1e5203bd1..8138ad8ef5f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java @@ -6,7 +6,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM Corporation - initial API and implementation + * Andrew Niefer (IBM Corporation) - initial API and implementation * Markus Schorn (Wind River Systems) * Bryan Wilkinson (QNX) * 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.ICPPASTNamespaceDefinition; 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.ICPPNamespaceScope; 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.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.ProblemBinding; 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.LookupData; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; 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 IASTNode physicalNode; - private boolean isfull = false; + private boolean isCached = false; protected CharArrayObjectMap bindings = null; public static class CPPScopeProblem extends ProblemBinding implements ICPPScope { @@ -106,7 +107,7 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope { IScope scope= this; IASTName[] na= name.getNames(); try { - for (int i= na.length - 2; i >= 0; i++) { + for (int i= na.length - 2; i >= 0; i--) { if (scope == null) return false; IName scopeName = scope.getScopeName(); @@ -156,15 +157,7 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope { if (nsbinding instanceof ICPPNamespace) { ICPPNamespace nsbindingAdapted = (ICPPNamespace) index.adaptBinding(nsbinding); if (nsbindingAdapted!=null) { - IBinding[] bindings = nsbindingAdapted.getNamespaceScope().find(new String(nchars)); - if (fileSet != null) { - bindings= fileSet.filterFileLocalBindings(bindings); - } - binding= CPPSemantics.resolveAmbiguities(name, bindings); - if (binding instanceof ICPPUsingDeclaration) { - binding= CPPSemantics.resolveAmbiguities(name, - ((ICPPUsingDeclaration)binding).getDelegates()); - } + return nsbindingAdapted.getNamespaceScope().getBinding(name, forceResolve, fileSet); } } } @@ -174,59 +167,17 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope { } public IBinding getBindingInAST(IASTName name, boolean forceResolve) throws DOMException { - char[] c = name.getLookupKey(); - //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 os = (ObjectSet) 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); - } 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; + IBinding[] bs= getBindingsInAST(name, forceResolve, false, false, false); + return CPPSemantics.resolveAmbiguities(name, bs); } - public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) - throws DOMException { - IBinding[] result = getBindingsInAST(name, resolve, prefixLookup); - + public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) throws DOMException { + return getBindings(name, resolve, prefixLookup, fileSet, true); + } + + 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(); if (tu != null) { IIndex index = tu.getIndex(); @@ -267,16 +218,17 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope { return (IBinding[]) ArrayUtil.trim(IBinding.class, result); } - public IBinding[] getBindingsInAST(IASTName name, boolean forceResolve, boolean prefixLookup) - throws DOMException { - char[] c = name.getLookupKey(); + public IBinding[] getBindingsInAST(IASTName name, boolean forceResolve, boolean prefixLookup, + boolean checkPointOfDecl, boolean expandUsingDirectives) throws DOMException { + populateCache(); + final char[] c = name.getLookupKey(); IBinding[] result = null; Object[] obj = null; if (prefixLookup) { Object[] keys = bindings != null ? bindings.keyArray() : new Object[0]; - for (Object key2 : keys) { - char[] key = (char[]) key2; + for (int i = 0; i < keys.length; i++) { + final char[] key = (char[]) keys[i]; if (CharArrayUtils.equals(key, 0, c.length, c, true)) { obj = ArrayUtil.append(obj, bindings.get(key)); } @@ -287,45 +239,58 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope { obj = ArrayUtil.trim(Object.class, obj); for (Object element : obj) { - if (element instanceof ObjectSet) { - @SuppressWarnings("unchecked") - ObjectSet os= (ObjectSet) element; + if (element instanceof ObjectSet) { + ObjectSet os= (ObjectSet) element; for (int j = 0; j < os.size(); j++) { - Object o = os.keyAt(j); - 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 { - result = (IBinding[]) ArrayUtil.append(IBinding.class, result, o); - } + result= addCandidate(os.keyAt(j), 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); + result = addCandidate(element, name, forceResolve, checkPointOfDecl, expandUsingDirectives, result); } } return (IBinding[]) ArrayUtil.trim(IBinding.class, result); } - public void setFullyCached(boolean full) { - isfull = full; - } + private IBinding[] addCandidate(Object candidate, IASTName name, boolean forceResolve, + 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() { - return isfull; + IBinding binding; + 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) @@ -341,7 +306,7 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope { return; Object obj = bindings.get(key); - if (obj instanceof ObjectSet) { + if (obj instanceof ObjectSet) { @SuppressWarnings("unchecked") ObjectSet set = (ObjectSet) obj; 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)) { bindings.remove(key, 0, key.length); } - isfull = false; + isCached = false; } /* (non-Javadoc) @@ -381,7 +346,7 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope { allBuiltins= new CharArrayObjectMap(1); } allBuiltins.put(map.keyAt(i), o); - } else if (o instanceof ObjectSet) { + } else if (o instanceof ObjectSet) { @SuppressWarnings("unchecked") final ObjectSet set= (ObjectSet) map.getAt(i); if (set != null) { @@ -408,7 +373,7 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope { } bindings= allBuiltins; } - isfull = false; + isCached = false; } @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 { - return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY); + return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY, true); } public IName getScopeName() throws DOMException { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownConstructor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownConstructor.java new file mode 100644 index 00000000000..d4e27c8cae1 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownConstructor.java @@ -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; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownFunction.java index 98b8a954fed..ce7a264d79e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownFunction.java @@ -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.IScope; 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.ICPPFunctionType; @@ -27,6 +28,9 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; public class CPPUnknownFunction extends CPPUnknownBinding implements ICPPFunction { 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()); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java index 5d7f96c59f5..16e78fda6fa 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java @@ -176,19 +176,6 @@ public class CPPUnknownScope implements ICPPScope, ICPPInternalUnknownScope { 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) * @see org.eclipse.cdt.core.dom.ast.IScope#flushCache() */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java index 134b9056b72..096f48fcf71 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java @@ -77,6 +77,11 @@ public class ClassTypeHelper { if (host.getDefinition() == null) { host.checkForDefinition(); if (host.getDefinition() == null) { + try { + ICPPClassType backup= getBackupDefinition(host); + if (backup != null) + return backup.getFriends(); + } catch (DOMException e) {} IASTNode[] declarations= host.getDeclarations(); IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; 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); } + /** + * 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) { if (host.getDefinition() == null) { host.checkForDefinition(); if (host.getDefinition() == null) { + try { + ICPPClassType backup= getBackupDefinition(host); + if (backup != null) + return backup.getBases(); + } catch (DOMException e) {} + IASTNode[] declarations= host.getDeclarations(); IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; 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) { host.checkForDefinition(); if (host.getDefinition() == null) { + try { + ICPPClassType backup= getBackupDefinition(host); + if (backup != null) + return backup.getDeclaredFields(); + } catch (DOMException e) {} + IASTNode[] declarations= host.getDeclarations(); IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; 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() */ public static ICPPConstructor[] getConstructors(ICPPInternalClassTypeMixinHost host) throws DOMException { - if (host.getDefinition() == null) { - host.checkForDefinition(); - if (host.getDefinition() == null) { - IASTNode[] declarations= host.getDeclarations(); - IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; - return new ICPPConstructor[] { new CPPConstructor.CPPConstructorProblem(node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, host.getNameCharArray()) }; - } + ICPPClassScope scope = host.getCompositeScope(); + if (scope == null) { + IASTNode[] declarations= host.getDeclarations(); + IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; + return new ICPPConstructor[] { new CPPConstructor.CPPConstructorProblem(node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, host.getNameCharArray()) }; } - - 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); + return scope.getConstructors(); } public static ICPPClassType[] getNestedClasses(ICPPInternalClassTypeMixinHost host) { if (host.getDefinition() == null) { host.checkForDefinition(); if (host.getDefinition() == null) { + try { + ICPPClassType backup= getBackupDefinition(host); + if (backup != null) + return backup.getNestedClasses(); + } catch (DOMException e) {} + IASTNode[] declarations= host.getDeclarations(); IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; return new ICPPClassType[] { new CPPClassTypeProblem(node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, host.getNameCharArray()) }; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPASTInternalScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPASTInternalScope.java new file mode 100644 index 00000000000..a887752c696 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPASTInternalScope.java @@ -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; + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPClassSpecializationScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPClassSpecializationScope.java index 654c9dca3cd..abb3a50bb39 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPClassSpecializationScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPClassSpecializationScope.java @@ -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.ICPPClassSpecialization; 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.ICPPMethod; @@ -42,11 +41,6 @@ public interface ICPPClassSpecializationScope extends ICPPClassScope { */ ICPPBase[] getBases() throws DOMException; - /** - * Computes the constructors via the original class. - */ - ICPPConstructor[] getConstructors() throws DOMException; - /** * Computes the methods via the original class. */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalClassTypeMixinHost.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalClassTypeMixinHost.java index c4c7c4e8a7f..bf4c59bbec0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalClassTypeMixinHost.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalClassTypeMixinHost.java @@ -10,7 +10,9 @@ *******************************************************************************/ 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.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; /** @@ -22,6 +24,11 @@ interface ICPPInternalClassTypeMixinHost extends ICPPClassType, ICPPInternalBind */ ICPPASTCompositeTypeSpecifier getCompositeTypeSpecifier(); + /** + * {@inheritDoc} + */ + ICPPClassScope getCompositeScope() throws DOMException; + /** * Ensures the ICPPInternalBinding definition is set, if this is possible. * @see ICPPInternalBinding#getDefinition() diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index 00db31e1b56..e5c64da6a68 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -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.CPPUnknownBinding; 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.CPPUsingDeclaration; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDirective; @@ -240,7 +241,9 @@ public class CPPSemantics { data.ignoreUsingDirectives = true; data.forceQualified = true; 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); } @@ -314,19 +317,21 @@ public class CPPSemantics { ICPPASTTemplateId id = (ICPPASTTemplateId) data.astName; ICPPTemplateArgument[] args = CPPTemplates.createTemplateArgumentArray(id); IBinding inst= CPPTemplates.instantiate((ICPPClassTemplate) cls, args); - cls = inst instanceof ICPPClassType && !(inst instanceof ICPPDeferredClassInstance) ? - (ICPPClassType) inst : cls; + if (inst instanceof ICPPClassType) { + cls= (ICPPClassType) inst; + } } } - if (cls != null) { + if (cls instanceof ICPPDeferredClassInstance) { + binding= new CPPUnknownConstructor(cls, data.astName); + } else { // Force resolution of constructor bindings - IBinding[] ctors = cls.getConstructors(); - if (ctors.length > 0 && !(ctors[0] instanceof IProblemBinding)) { - // then use the class scope to resolve which one. - binding = ((ICPPClassScope) cls.getCompositeScope()).getBinding(data.astName, true); + final ICPPConstructor[] constructors = cls.getConstructors(); + if (constructors.length > 0) { + binding= CPPSemantics.resolveAmbiguities(data.astName, constructors); } } - } catch (DOMException e) { + } catch (DOMException e) { binding = e.getProblem(); } } @@ -355,7 +360,11 @@ public class CPPSemantics { if (data.functionParameters != null) { binding= new CPPUnknownFunction(data.skippedScope, name.getLastName()); } else { - binding= new CPPUnknownBinding(data.skippedScope, name.getLastName()); + if (name.getPropertyInParent() == IASTNamedTypeSpecifier.NAME) { + binding= new CPPUnknownClass(data.skippedScope, name.getLastName()); + } else { + binding= new CPPUnknownBinding(data.skippedScope, name.getLastName()); + } } } @@ -570,7 +579,7 @@ public class CPPSemantics { * @param scoped * @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; 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{ final IIndexFileSet fileSet= getIndexFileSet(data); - final boolean isIndexBased= fileSet != IIndexFileSet.EMPTY; - IASTNode blockItem= data.astName; if (blockItem == null) return; @@ -695,33 +702,11 @@ public class CPPSemantics { blockItem = CPPVisitor.getContainingBlockItem(blockItem); if (!data.usingDirectivesOnly) { - if (data.contentAssist) { - if (!ASTInternal.isFullyCached(scope)) { - lookupInScope(data, scope, blockItem); - } - // now scope is fully cached. - final IBinding[] bindings = scope.getBindings(data.astName, true, data.prefixLookup, fileSet); - 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); - } - } + IBinding[] bindings= scope.getBindings(data.astName, true, data.prefixLookup, fileSet); + if (data.typesOnly) { + removeObjects(bindings); } + mergeResults(data, bindings, true); // store using-directives found in this block or namespace for later use. if ((!data.hasResults() || !data.qualified() || data.contentAssist) && scope instanceof ICPPNamespaceScope) { @@ -736,7 +721,7 @@ public class CPPSemantics { if (uds != null && uds.length > 0) { HashSet handled= new HashSet(); for (final ICPPUsingDirective ud : uds) { - if (CPPSemantics.declaredBefore(ud, data.astName, false)) { + if (declaredBefore(ud, data.astName, false)) { 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) { IASTNode parent= node.getParent(); if (parent instanceof IASTName) { @@ -880,26 +885,24 @@ public class CPPSemantics { // is circular inheritance if (!data.inheritanceChain.containsKey(classScope)) { //is this name define in this scope? - if (ASTInternal.isFullyCached(classScope)) { - if (data.astName != null && !data.contentAssist) { - inherited = classScope.getBinding(data.astName, true); - } else if (data.astName != null) { - inherited = classScope.getBindings(data.astName, true, data.prefixLookup); - } - } else { - inherited = lookupInScope(data, classScope, null); + IBinding[] inCurrentScope= classScope.getBindings(data.astName, true, data.prefixLookup); + if (data.typesOnly) { + removeObjects(inCurrentScope); } - - if (inherited == null || data.contentAssist) { + final boolean isEmpty= inCurrentScope.length == 0 || inCurrentScope[0] == null; + if (data.contentAssist) { Object temp = lookupInParents(data, classScope, overallScope); - if (inherited != null) { - inherited = mergePrefixResults(null, inherited, true); + if (!isEmpty) { + inherited = mergePrefixResults(null, inCurrentScope, true); inherited = mergePrefixResults((CharArrayObjectMap)inherited, (CharArrayObjectMap)temp, true); } else { - inherited = temp; + inherited= temp; } + } else if (isEmpty) { + inherited= lookupInParents(data, classScope, overallScope); } else { - visitVirtualBaseClasses(data, cls); + inherited= inCurrentScope; + visitVirtualBaseClasses(data, cls); } } else { data.problem = new ProblemBinding(null, IProblemBinding.SEMANTIC_CIRCULAR_INHERITANCE, cls.getNameCharArray()); @@ -1116,13 +1119,7 @@ public class CPPSemantics { IASTName[] namespaceDefs = null; 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) { IASTNode p = parent.getParent(); if (p instanceof IASTFunctionDefinition) { @@ -1276,10 +1273,7 @@ public class CPPSemantics { } } } - - ASTInternal.setFullyCached(scope, true); - return found; } @@ -1298,16 +1292,13 @@ public class CPPSemantics { data.visited.put(nominated); boolean found = false; - if (ASTInternal.isFullyCached(nominated)) { - IBinding[] bindings= nominated.getBindings(data.astName, true, data.prefixLookup); - if (bindings != null && bindings.length > 0) { - mergeResults(data, bindings, true); - found = true; + IBinding[] bindings= nominated.getBindings(data.astName, true, data.prefixLookup); + if (bindings != null && bindings.length > 0) { + if (data.typesOnly) { + removeObjects(bindings); } - } else { - IASTName[] f = lookupInScope(data, nominated, null); - if (f != null) { - mergeResults(data, f, true); + if (bindings[0] != null) { + mergeResults(data, bindings, true); found = true; } } @@ -1611,10 +1602,14 @@ public class CPPSemantics { } static public boolean declaredBefore(Object obj, IASTNode node, boolean indexBased) { - if (node == null) return true; - if (node.getPropertyInParent() == STRING_LOOKUP_PROPERTY) return true; - final int pointOfRef= ((ASTNode) node).getOffset(); + if (node == null) + return true; + final int pointOfRef= ((ASTNode) node).getOffset(); + if (node.getPropertyInParent() == STRING_LOOKUP_PROPERTY && pointOfRef <= 0) { + return true; + } + ASTNode nd = null; if (obj instanceof ICPPSpecialization) { obj = ((ICPPSpecialization)obj).getSpecializedBinding(); @@ -1627,24 +1622,8 @@ public class CPPSemantics { // 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 // in one of the headers. - if (indexBased) { - 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) { - } + if (indexBased && acceptDeclaredAfter(cpp)) { + return true; } IASTNode[] n = cpp.getDeclarations(); if (n != null && n.length > 0) { @@ -1657,10 +1636,19 @@ public class CPPSemantics { } if (nd == null) return true; - } else if (obj instanceof ASTNode) { - nd = (ASTNode) obj; - } else if (obj instanceof ICPPUsingDirective) { - pointOfDecl= ((ICPPUsingDirective) obj).getPointOfDeclaration(); + } 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; + } else if (obj instanceof ICPPUsingDirective) { + pointOfDecl= ((ICPPUsingDirective) obj).getPointOfDeclaration(); + } } if (pointOfDecl < 0 && nd != null) { @@ -1696,6 +1684,27 @@ public class CPPSemantics { } 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 { if (!data.hasResults() || data.contentAssist) @@ -1710,6 +1719,7 @@ public class CPPSemantics { IBinding obj = null; IBinding temp = null; boolean fnsFromAST= false; + boolean fnTmplsFromAST= false; Object[] items = (Object[]) data.foundItems; for (int i = 0; i < items.length && items[i] != null; i++) { @@ -1768,7 +1778,18 @@ public class CPPSemantics { if (function instanceof ICPPFunctionTemplate) { if (templateFns == ObjectSet.EMPTY_SET) templateFns = new ObjectSet(2); - templateFns.put(function); + if (isFromIndex(function)) { + // accept bindings from index only, in case we have none in the AST + if (!fnTmplsFromAST) { + templateFns.put(function); + } + } else { + if (!fnTmplsFromAST) { + templateFns.clear(); + fnTmplsFromAST= true; + } + templateFns.put(function); + } } else { if (fns == ObjectSet.EMPTY_SET) fns = new ObjectSet(2); @@ -1798,7 +1819,14 @@ public class CPPSemantics { if (type == null) { type = temp; } else if (type != temp && !((IType)type).isSameType((IType) temp)) { - return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.getNameCharArray()); + 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()); + } } } else { if (obj == null) { @@ -2611,10 +2639,13 @@ public class CPPSemantics { astName.setName(name); astName.setParent(ASTInternal.getPhysicalNodeOfScope(scope)); astName.setPropertyInParent(STRING_LOOKUP_PROPERTY); + if (beforeNode instanceof ASTNode) { + astName.setOffsetAndLength((ASTNode) beforeNode); + } LookupData data = new LookupData(astName); data.forceQualified = qualified; - return standardLookup(data, scope, beforeNode); + return standardLookup(data, scope); } public static IBinding[] findBindingsForContentAssist(IASTName name, boolean prefixLookup) { @@ -2665,7 +2696,7 @@ public class CPPSemantics { 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 { lookup(data, start); } catch (DOMException e) { @@ -2676,34 +2707,26 @@ public class CPPSemantics { if (items == null) return new IBinding[0]; - boolean indexBased= false; - if (beforeNode != null) { - IASTTranslationUnit tu= beforeNode.getTranslationUnit(); - if (tu != null && tu.getIndex() != null) - indexBased= true; - } ObjectSet set = new ObjectSet(items.length); IBinding binding = null; for (Object item : items) { - if (beforeNode == null || declaredBefore(item, beforeNode, indexBased)) { - if (item instanceof IASTName) { - binding = ((IASTName) item).resolveBinding(); - } else if (item instanceof IBinding) { - binding = (IBinding) item; - } else { - binding = null; - } + if (item instanceof IASTName) { + binding = ((IASTName) item).resolveBinding(); + } else if (item instanceof IBinding) { + binding = (IBinding) item; + } else { + binding = null; + } - if (binding != null) { - if (binding instanceof ICPPUsingDeclaration) { - set.addAll(((ICPPUsingDeclaration) binding).getDelegates()); - } else if (binding instanceof CPPCompositeBinding) { - set.addAll(((CPPCompositeBinding) binding).getBindings()); - } else { - set.put(binding); - } - } - } + if (binding != null) { + if (binding instanceof ICPPUsingDeclaration) { + set.addAll(((ICPPUsingDeclaration) binding).getDelegates()); + } else if (binding instanceof CPPCompositeBinding) { + set.addAll(((CPPCompositeBinding) binding).getBindings()); + } else { + set.put(binding); + } + } } return set.keyArray(IBinding.class); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index e6cb0d91ffa..91299f2d339 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -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.ObjectMap; 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.ITypeContainer; 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.CPPUnknownClassInstance; 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.ICPPClassSpecializationScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; @@ -2043,20 +2043,16 @@ public class CPPTemplates { } } else if (t instanceof ICPPClassType) { IScope s = ((ICPPClassType) t).getCompositeScope(); - if (s != null && ASTInternal.isFullyCached(s)) { - // 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. + if (s != null) { IASTName name= unknown.getUnknownName(); if (name != null) { - if (name.getParent() != null) { - result = s.getBinding(name, true); + IBinding[] candidates; + if (s instanceof ICPPASTInternalScope) { + candidates= ((ICPPASTInternalScope) s).getBindings(name, true, false, null, false); } else { - IBinding[] bindings = s.find(name.toString()); - if (bindings != null && bindings.length > 0) { - result = bindings[0]; - } + candidates= s.getBindings(name, true, false, null); } + result= CPPSemantics.resolveAmbiguities(name, candidates); if (unknown instanceof ICPPUnknownClassInstance && result instanceof ICPPTemplateDefinition) { ICPPTemplateArgument[] newArgs = CPPTemplates.instantiateArguments(((ICPPUnknownClassInstance) unknown).getArguments(), tpMap, within); if (result instanceof ICPPClassTemplate) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index 26aa90d0de1..88f794bef86 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -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.ICPPInternalFunction; 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; /** @@ -1991,6 +1992,8 @@ public class CPPVisitor extends ASTQueries { } } else if (type instanceof IPointerType || type instanceof IArrayType) { return ((ITypeContainer) type).getType(); + } else if (type instanceof ICPPUnknownType) { + return CPPUnknownClass.createUnnamedInstance(); } return new ProblemBinding(expression, IProblemBinding.SEMANTIC_INVALID_TYPE, expression.getRawSignature().toCharArray()); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java index e0dec2e33c9..c33b707febc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java @@ -50,7 +50,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit; /** * Context data for IASTName lookup */ -class LookupData { +public class LookupData { protected IASTName astName; protected CPPASTTranslationUnit tu; public Map> usingDirectives= Collections.emptyMap(); @@ -90,7 +90,7 @@ class LookupData { tu= (CPPASTTranslationUnit) astName.getTranslationUnit(); typesOnly = typesOnly(astName); considerConstructors = considerConstructors(); - checkWholeClassScope = checkWholeClassScope(); + checkWholeClassScope = checkWholeClassScope(n); } public LookupData() { @@ -233,6 +233,8 @@ class LookupData { if (p1 instanceof ICPPASTNamedTypeSpecifier && p2 instanceof IASTTypeId) { return p2.getParent() instanceof ICPPASTNewExpression; } else if (p1 instanceof ICPPASTQualifiedName) { + if (((ICPPASTQualifiedName) p1).getLastName() != astName) + return false; if (p2 instanceof ICPPASTFunctionDeclarator) { IASTName[] names = ((ICPPASTQualifiedName)p1).getNames(); if (names.length >= 2 && names[names.length - 1] == astName) @@ -270,11 +272,11 @@ class LookupData { return (p1 instanceof IASTIdExpression && p1.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME); } - private boolean checkWholeClassScope() { - if (astName == null) return false; - if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return true; + public static boolean checkWholeClassScope(IASTName name) { + if (name == null) return false; + if (name.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return true; - IASTNode parent = astName.getParent(); + IASTNode parent = name.getParent(); while (parent != null && !(parent instanceof IASTFunctionDefinition)) { ASTNodeProperty prop = parent.getPropertyInParent(); if (prop == IASTParameterDeclaration.DECL_SPECIFIER || @@ -289,9 +291,9 @@ class LookupData { if (parent.getPropertyInParent() != IASTCompositeTypeSpecifier.MEMBER_DECLARATION) return false; - ASTNodeProperty prop = astName.getPropertyInParent(); + ASTNodeProperty prop = name.getPropertyInParent(); if (prop == ICPPASTQualifiedName.SEGMENT_NAME) - prop = astName.getParent().getPropertyInParent(); + prop = name.getParent().getPropertyInParent(); if (prop == IASTIdExpression.ID_NAME || prop == IASTFieldReference.FIELD_NAME || prop == ICASTFieldDesignator.FIELD_NAME || diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassScope.java index 9af27c82449..285df426dd7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassScope.java @@ -6,7 +6,8 @@ * http://www.eclipse.org/legal/epl-v10.html * * 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; @@ -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.cpp.ICPPClassScope; 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.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexFileSet; @@ -51,6 +53,20 @@ class CompositeCPPClassScope extends CompositeScope implements ICPPClassScope { return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; } + public ICPPConstructor[] getConstructors() { + try { + ICPPClassScope rscope = (ICPPClassScope) ((ICPPClassType)rbinding).getCompositeScope(); + ICPPConstructor[] result = rscope.getConstructors(); + for(int i=0; i