From a9fcf919bee2541a88a137ec5059514eb039457f Mon Sep 17 00:00:00 2001
From: Markus Schorn <markus.schorn@windriver.com>
Date: Mon, 12 Jan 2009 16:21:19 +0000
Subject: [PATCH] Correct usage of scopes in name-resolution, bug 259544.

---
 .../core/parser/tests/ast2/AST2CPPTests.java  |   2 +-
 .../cdt/core/dom/ast/cpp/ICPPClassScope.java  |  19 +-
 .../internal/core/dom/parser/ASTInternal.java |  10 +-
 .../core/dom/parser/IASTInternalScope.java    |  10 -
 .../core/dom/parser/ProblemBinding.java       |  13 -
 .../AbstractCPPClassSpecializationScope.java  |  38 ++-
 .../core/dom/parser/cpp/CPPClassScope.java    |  34 +--
 .../cpp/CPPClassSpecializationScope.java      |  30 +-
 .../core/dom/parser/cpp/CPPClassTemplate.java |   4 +-
 .../core/dom/parser/cpp/CPPClassType.java     |   6 +-
 .../dom/parser/cpp/CPPNamespaceScope.java     |   9 +-
 .../core/dom/parser/cpp/CPPScope.java         | 177 +++++------
 .../dom/parser/cpp/CPPUnknownConstructor.java |  55 ++++
 .../dom/parser/cpp/CPPUnknownFunction.java    |   4 +
 .../core/dom/parser/cpp/CPPUnknownScope.java  |  13 -
 .../core/dom/parser/cpp/ClassTypeHelper.java  |  74 +++--
 .../dom/parser/cpp/ICPPASTInternalScope.java  |  32 ++
 .../cpp/ICPPClassSpecializationScope.java     |   6 -
 .../cpp/ICPPInternalClassTypeMixinHost.java   |   7 +
 .../parser/cpp/semantics/CPPSemantics.java    | 275 ++++++++++--------
 .../parser/cpp/semantics/CPPTemplates.java    |  18 +-
 .../dom/parser/cpp/semantics/CPPVisitor.java  |   3 +
 .../dom/parser/cpp/semantics/LookupData.java  |  18 +-
 .../composite/cpp/CompositeCPPClassScope.java |  18 +-
 .../internal/core/pdom/dom/PDOMBinding.java   |   7 +-
 .../core/pdom/dom/c/PDOMCLinkage.java         |  23 +-
 .../core/pdom/dom/cpp/PDOMCPPClassScope.java  |  39 ++-
 .../core/pdom/dom/cpp/PDOMCPPLinkage.java     |  22 +-
 .../core/pdom/dom/cpp/PDOMCPPNamespace.java   |   4 -
 29 files changed, 541 insertions(+), 429 deletions(-)
 create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownConstructor.java
 create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPASTInternalScope.java

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<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);
-	        } 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<Object> os= (ObjectSet<Object>) 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<Object> set = (ObjectSet<Object>) 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<Object> set= (ObjectSet<Object>) 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<ICPPNamespaceScope> handled= new HashSet<ICPPNamespaceScope>();
 						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<IFunction>(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<IFunction>(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<IBinding> set = new ObjectSet<IBinding>(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<ICPPNamespaceScope, List<ICPPNamespaceScope>> 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<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 {
 		IBinding binding = ((ICPPClassType)rbinding).getCompositeScope().getBinding(name, resolve, fileSet);
 		return processUncertainBinding(binding);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java
index 8b410215ed4..7d0b6afc2d6 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java
@@ -6,7 +6,7 @@
  * http://www.eclipse.org/legal/epl-v10.html
  *
  * Contributors:
- *    QNX - Initial API and implementation
+ *    Doug Schaefer (QNX) - Initial API and implementation
  *    Markus Schorn (Wind River Systems)
  *    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.IBinding;
 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.parser.util.CharArrayUtils;
 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;
 
 /**
- * @author Doug Schaefer
+ * Base class for bindings in the pdom.
  */
 public abstract class PDOMBinding extends PDOMNamedNode implements IPDOMBinding {
 	public static final PDOMBinding[] EMPTY_PDOMBINDING_ARRAY = {};
@@ -289,7 +288,7 @@ public abstract class PDOMBinding extends PDOMNamedNode implements IPDOMBinding
 		try {
 			PDOMNode node = this;
 			while (node != null) {
-				if (node instanceof PDOMBinding && !(node instanceof ICPPTemplateInstance)) {							
+				if (node instanceof PDOMBinding) {							
 					result.add(0, ((PDOMBinding)node).getName());
 				}
 				node = node.getParentNode();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java
index c6bad422213..ee2c1fb972c 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java
@@ -11,7 +11,6 @@
  *     IBM Corporation
  *     Andrew Ferguson (Symbian)
  *******************************************************************************/
-
 package org.eclipse.cdt.internal.core.pdom.dom.c;
 
 import org.eclipse.cdt.core.CCorePlugin;
@@ -106,7 +105,8 @@ class PDOMCLinkage extends PDOMLinkage implements IIndexCBindingConstants {
 	
 	private PDOMBinding createBinding(PDOMNode parent, IBinding binding) throws CoreException {
 		PDOMBinding pdomBinding= null;
-		
+		PDOMNode inheritFileLocal= parent;
+
 		if (binding instanceof IField) { // must be before IVariable
 			if (parent instanceof IPDOMMemberOwner)
 				pdomBinding = new PDOMCField(pdom, (IPDOMMemberOwner)parent, (IField) binding);
@@ -125,6 +125,7 @@ class PDOMCLinkage extends PDOMLinkage implements IIndexCBindingConstants {
 				IType enumeration= ((IEnumerator)binding).getType();
 				if (enumeration instanceof IEnumeration) {
 					PDOMBinding pdomEnumeration = adaptBinding((IEnumeration) enumeration);
+					inheritFileLocal= pdomEnumeration;
 					if (pdomEnumeration instanceof PDOMCEnumeration)
 						pdomBinding = new PDOMCEnumerator(pdom, parent, (IEnumerator) binding, (PDOMCEnumeration)pdomEnumeration);
 				}
@@ -136,7 +137,7 @@ class PDOMCLinkage extends PDOMLinkage implements IIndexCBindingConstants {
 		}
 
 		if (pdomBinding != null) {
-			pdomBinding.setLocalToFileRec(getLocalToFileRec(parent, binding));
+			pdomBinding.setLocalToFileRec(getLocalToFileRec(inheritFileLocal, binding));
 			parent.addChild(pdomBinding);
 			afterAddBinding(pdomBinding);
 		}
@@ -260,12 +261,24 @@ class PDOMCLinkage extends PDOMLinkage implements IIndexCBindingConstants {
 		if (parent == null) {
 			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) {
-			int localToFileRec= getLocalToFileRec(null, binding);
+			int localToFileRec= getLocalToFileRec(inheritFileLocal, binding);
 			return FindBinding.findBinding(getIndex(), getPDOM(), binding.getNameCharArray(), new int[] {getBindingType(binding)}, localToFileRec);
 		} 
 		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 null;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassScope.java
index c17f112fe48..76862ec4f3a 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassScope.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassScope.java
@@ -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.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.ICPPMethod;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
 import org.eclipse.cdt.core.index.IIndexBinding;
@@ -80,11 +81,7 @@ class PDOMCPPClassScope implements ICPPClassScope, IIndexScope {
 		            return CPPSemantics.resolveAmbiguities(name, fBinding.getConstructors());
 		        }
 	            //9.2 ... The class-name is also inserted into the scope of the class itself
-		        if (fBinding instanceof ICPPClassTemplatePartialSpecialization)
-		        	return ((ICPPClassTemplatePartialSpecialization) fBinding).getPrimaryClassTemplate();
-		        if (fBinding instanceof ICPPSpecialization)
-		        	return ((ICPPSpecialization) fBinding).getSpecializedBinding();
-	            return fBinding;
+		        return getClassNameBinding();
 		    }
 			
 			final IBinding[] candidates = getBindingsViaCache(fBinding, nameChars, IndexFilter.CPP_DECLARED_OR_IMPLICIT_NO_INSTANCE);
@@ -94,25 +91,34 @@ class PDOMCPPClassScope implements ICPPClassScope, IIndexScope {
 		}
 		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 {
 		IBinding[] result = null;
 		try {
 			final char[] nameChars = name.getSimpleID();
 			if (!prefixLookup) {
-				return getBindingsViaCache(fBinding, nameChars, IndexFilter.CPP_DECLARED_OR_IMPLICIT_NO_INSTANCE);
+				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);
 			}
+			
+			// prefix lookup
 			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)) {
-				// 9.2 ... The class-name is also inserted into the scope of
-				// the class itself
-				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);
+				// add the class itself, constructors will be found during the visit
+		        visitor.visit((IPDOMNode) getClassNameBinding());
 			}
 			acceptViaCache(fBinding, visitor, true);
 			result= visitor.getBindings();
@@ -221,6 +227,9 @@ class PDOMCPPClassScope implements ICPPClassScope, IIndexScope {
 		}
 	}
 
+	public ICPPConstructor[] getConstructors() throws DOMException {
+		return fBinding.getConstructors();
+	}
 
 	public IIndexScope getParent() {
 		return fBinding.getScope();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
index fd8352b47d9..e9c36fd56f3 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
@@ -295,6 +295,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
 
 	PDOMBinding createBinding(PDOMNode parent, IBinding binding) throws CoreException, DOMException {
 		PDOMBinding pdomBinding= null;
+		PDOMNode inheritFileLocal = parent;
 
 		// template parameters are created directly by their owners.
 		if (binding instanceof ICPPTemplateParameter) 
@@ -357,6 +358,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
 				PDOMBinding pdomEnumeration = adaptBinding((IEnumeration) enumeration);
 				if (pdomEnumeration instanceof PDOMCPPEnumeration) {
 					pdomBinding = new PDOMCPPEnumerator(pdom, parent, etor,	(PDOMCPPEnumeration)pdomEnumeration);
+					inheritFileLocal= pdomEnumeration;
 				}
 			}
 		} else if (binding instanceof ITypedef) {
@@ -364,7 +366,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
 		}
 
 		if (pdomBinding != null) {
-			pdomBinding.setLocalToFileRec(getLocalToFileRec(parent, binding));
+			pdomBinding.setLocalToFileRec(getLocalToFileRec(inheritFileLocal, binding));
 			parent.addChild(pdomBinding);
 			afterAddBinding(pdomBinding);
 		}
@@ -579,12 +581,24 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
 		if (parent == null) {
 			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) {
-			int localToFileRec= getLocalToFileRec(null, binding);
+			int localToFileRec= getLocalToFileRec(inheritFileLocal, binding);
 			return CPPFindBinding.findBinding(getIndex(), this, binding, localToFileRec);
 		}
 		if (parent instanceof PDOMCPPNamespace) {
-			int localToFileRec= getLocalToFileRec(parent, binding);
+			int localToFileRec= getLocalToFileRec(inheritFileLocal, binding);
 			return CPPFindBinding.findBinding(((PDOMCPPNamespace) parent).getIndex(), this, binding,
 					localToFileRec);
 		}
@@ -593,7 +607,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
 					(ICPPTemplateParameter) binding);
 		}
 		if (parent instanceof IPDOMMemberOwner) {
-			int localToFileRec= getLocalToFileRec(parent, binding);
+			int localToFileRec= getLocalToFileRec(inheritFileLocal, binding);
 			return CPPFindBinding.findBinding(parent, this, binding, localToFileRec);
 		}
 		return null;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java
index 57ef2408d04..e204a97e62c 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java
@@ -176,10 +176,6 @@ class PDOMCPPNamespace extends PDOMCPPBinding
 		return result;
 	}
 
-	public boolean isFullyCached() throws DOMException {
-		return true;
-	}
-
 	@Override
 	public boolean mayHaveChildren() {
 		return true;