Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] Type Cache patch for 63980 [ allow zip file ]

This patch should address some of the excessive memory usage by the type cache. There are also some further optimizations I can do - I'll provide another patch for this.

Interested parties, please give this a try and let me know if it helps.

Thanks
-Chris

Index: browser/org/eclipse/cdt/core/browser/ITypeInfo.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/ITypeInfo.java,v
retrieving revision 1.3
diff -u -r1.3 ITypeInfo.java
--- browser/org/eclipse/cdt/core/browser/ITypeInfo.java	26 May 2004 14:49:00 -0000	1.3
+++ browser/org/eclipse/cdt/core/browser/ITypeInfo.java	17 Jun 2004 18:53:42 -0000
@@ -36,6 +36,11 @@
 	public int getCElementType();
 
 	/**
+	 * Sets the CElement type.
+	 */
+	public void setCElementType(int type);
+
+	/**
 	 * Gets the type name.
 	 */
 	public String getName();
Index: browser/org/eclipse/cdt/core/browser/QualifiedTypeName.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/QualifiedTypeName.java,v
retrieving revision 1.1
diff -u -r1.1 QualifiedTypeName.java
--- browser/org/eclipse/cdt/core/browser/QualifiedTypeName.java	17 May 2004 15:48:48 -0000	1.1
+++ browser/org/eclipse/cdt/core/browser/QualifiedTypeName.java	17 Jun 2004 18:53:42 -0000
@@ -97,7 +97,6 @@
 		return null;
 	}
 
-//	TODO extra methods eg matchingFirstSegments() etc
 	public boolean isEmpty() {
 		return fSegments.length == 0;
 	}
@@ -179,7 +178,7 @@
 	
 	public IQualifiedTypeName removeFirstSegments(int count) {
 		if (count == 0) {
-			return new QualifiedTypeName(this);
+			return this;
 		} else if (count >= fSegments.length || count < 0) {
 			return new QualifiedTypeName(new String[0]);
 		} else {
@@ -192,7 +191,7 @@
 
 	public IQualifiedTypeName removeLastSegments(int count) {
 		if (count == 0) {
-			return new QualifiedTypeName(this);
+			return this;
 		} else if (count >= fSegments.length || count < 0) {
 			return new QualifiedTypeName(new String[0]);
 		} else {
Index: browser/org/eclipse/cdt/core/browser/TypeInfo.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/TypeInfo.java,v
retrieving revision 1.4
diff -u -r1.4 TypeInfo.java
--- browser/org/eclipse/cdt/core/browser/TypeInfo.java	26 May 2004 14:49:00 -0000	1.4
+++ browser/org/eclipse/cdt/core/browser/TypeInfo.java	17 Jun 2004 18:53:42 -0000
@@ -10,10 +10,6 @@
  *******************************************************************************/
 package org.eclipse.cdt.core.browser;
 
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
 import org.eclipse.cdt.core.model.ICElement;
 import org.eclipse.cdt.internal.core.browser.cache.ITypeCache;
 import org.eclipse.cdt.internal.core.browser.util.ArrayUtil;
@@ -23,26 +19,44 @@
 {
 	protected ITypeCache fTypeCache;
 	protected int fElementType;
-	protected QualifiedTypeName fQualifiedName;
-	protected Set fSourceRefs = new HashSet();
+	protected IQualifiedTypeName fQualifiedName;
+	protected ITypeReference[] fSourceRefs = null;
+	protected int fSourceRefsCount = 0;
+
+	protected final static int INITIAL_REFS_SIZE = 1;
+	protected final static int REFS_GROW_BY = 10;
 	protected final static ITypeInfo[] EMPTY_TYPES = new ITypeInfo[0];
 
 	public TypeInfo(int elementType, IQualifiedTypeName typeName) {
 		fElementType = elementType;
-		fQualifiedName = new QualifiedTypeName(typeName);
+		fQualifiedName = typeName;
 	}
 
 	public void addReference(ITypeReference location) {
-		fSourceRefs.add(location);
+		if (fSourceRefs == null) {
+			fSourceRefs = new ITypeReference[INITIAL_REFS_SIZE];
+			fSourceRefsCount = 0;
+		} else if (fSourceRefsCount == fSourceRefs.length) {
+			ITypeReference[] refs = new ITypeReference[fSourceRefs.length + REFS_GROW_BY];
+			System.arraycopy(fSourceRefs, 0, refs, 0, fSourceRefsCount);
+			fSourceRefs = refs;
+		}
+		fSourceRefs[fSourceRefsCount] = location;
+		++fSourceRefsCount;
 	}
 	
 	public ITypeReference[] getReferences() {
-		return (ITypeReference[]) fSourceRefs.toArray(new ITypeReference[fSourceRefs.size()]);
+		if (fSourceRefs != null) {
+			ITypeReference[] refs = new ITypeReference[fSourceRefsCount];
+			System.arraycopy(fSourceRefs, 0, refs, 0, fSourceRefsCount);
+			return refs;
+		}
+		return null;
 	}
 
 	public ITypeReference getResolvedReference() {
-		for (Iterator i = fSourceRefs.iterator(); i.hasNext(); ) {
-			ITypeReference location = (ITypeReference) i.next();
+		for (int i = 0; i < fSourceRefsCount; ++i) {
+			ITypeReference location = fSourceRefs[i];
 			if (location.getLength() != 0) {
 				return location;
 			}
@@ -51,7 +65,7 @@
 	}
 
 	public boolean isReferenced() {
-		return !fSourceRefs.isEmpty();
+		return (fSourceRefs != null);
 	}
 	
 	public boolean isUndefinedType() {
@@ -171,12 +185,12 @@
 			return true;
 
 		// check if path is in scope
-		for (Iterator i = fSourceRefs.iterator(); i.hasNext(); ) {
-			ITypeReference location = (ITypeReference) i.next();
+		for (int i = 0; i < fSourceRefsCount; ++i) {
+			ITypeReference location = fSourceRefs[i];
 			if (scope.encloses(location.getPath()))
 				return true;
 		}
-		
+
 		return false;
 	}
 	
Index: browser/org/eclipse/cdt/internal/core/browser/cache/IndexerTypesJob.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/IndexerTypesJob.java,v
retrieving revision 1.2
diff -u -r1.2 IndexerTypesJob.java
--- browser/org/eclipse/cdt/internal/core/browser/cache/IndexerTypesJob.java	26 May 2004 14:49:00 -0000	1.2
+++ browser/org/eclipse/cdt/internal/core/browser/cache/IndexerTypesJob.java	17 Jun 2004 18:53:42 -0000
@@ -149,18 +149,28 @@
 			int[] references = entry.getFileReferences();
 			if (references != null && references.length > 0) {
 				// add new type to cache
-				info = new TypeInfo(type, qualifiedName);
-				fTypeCache.insert(info);
+				if (info != null) {
+					info.setCElementType(type);
+				} else {
+					info = new TypeInfo(type, qualifiedName);
+					fTypeCache.insert(info);
+				}
 
-				for (int i = 0; i < references.length; ++i) {
-					if (monitor.isCanceled())
-						throw new InterruptedException();
-
-					IndexedFile file = input.getIndexedFile(references[i]);
-					if (file != null && file.getPath() != null) {
-						IPath path = PathUtil.getWorkspaceRelativePath(file.getPath());
-						info.addReference(new TypeReference(path, project));
-					}
+//				for (int i = 0; i < references.length; ++i) {
+//					if (monitor.isCanceled())
+//						throw new InterruptedException();
+//
+//					IndexedFile file = input.getIndexedFile(references[i]);
+//					if (file != null && file.getPath() != null) {
+//						IPath path = PathUtil.getWorkspaceRelativePath(file.getPath());
+//						info.addReference(new TypeReference(path, project));
+//					}
+//				}
+				// just grab the first reference
+				IndexedFile file = input.getIndexedFile(references[0]);
+				if (file != null && file.getPath() != null) {
+					IPath path = PathUtil.getWorkspaceRelativePath(file.getPath());
+					info.addReference(new TypeReference(path, project));
 				}
 			}
 		}
Index: browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java,v
retrieving revision 1.3
diff -u -r1.3 TypeCache.java
--- browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java	26 May 2004 14:48:59 -0000	1.3
+++ browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java	17 Jun 2004 18:53:43 -0000
@@ -44,12 +44,14 @@
 public class TypeCache implements ITypeCache {
 
 	private static final int INITIAL_TYPE_COUNT = 100;
-	private final Map fTypeNameMap = new HashMap(INITIAL_TYPE_COUNT);
+	private final Map fTypeKeyMap = new HashMap(INITIAL_TYPE_COUNT);
 	private final IProject fProject;
 	private final IWorkingCopyProvider fWorkingCopyProvider;
 	private final Collection fDeltas = new ArrayList();
 	private final ITypeInfo fGlobalNamespace;
 	
+	private static final int[] ENCLOSING_TYPES = {ICElement.C_NAMESPACE, ICElement.C_CLASS, ICElement.C_STRUCT, 0};
+	
 	private IJobChangeListener fJobChangeListener = new IJobChangeListener() {
 		public void aboutToRun(IJobChangeEvent event) {
 		}
@@ -94,7 +96,8 @@
 	private static class GlobalNamespace implements IQualifiedTypeName {
 		
 		private static final String GLOBAL_NAMESPACE = TypeCacheMessages.getString("TypeCache.globalNamespace"); //$NON-NLS-1$
-		
+		private static final String[] segments = new String[] { GLOBAL_NAMESPACE };
+
 		public GlobalNamespace() {
 		}
 		
@@ -127,7 +130,7 @@
 		}
 		
 		public String[] segments() {
-			return new String[] { GLOBAL_NAMESPACE };
+			return segments;
 		}
 		
 		public String segment(int index) {
@@ -161,11 +164,11 @@
 		}
 		
 		public IQualifiedTypeName removeFirstSegments(int count) {
-			return new QualifiedTypeName(this);
+			return this;
 		}
 		
 		public IQualifiedTypeName removeLastSegments(int count) {
-			return new QualifiedTypeName(this);
+			return this;
 		}
 		
 		public boolean isLowLevel() {
@@ -207,6 +210,28 @@
 		}
 	}
 	
+	private static class HashKey {
+		private IQualifiedTypeName name;
+		private int type;
+		public HashKey(IQualifiedTypeName name, int type) {
+			this.name = name;
+			this.type = type;
+		}
+		public int hashCode() {
+			return (this.name.hashCode() + this.type);
+		}
+		public boolean equals(Object obj) {
+			if (obj == this) {
+				return true;
+			}
+			if (!(obj instanceof HashKey)) {
+				return false;
+			}
+			HashKey otherKey = (HashKey)obj;
+			return (this.type == otherKey.type && this.name.equals(otherKey.name));
+		}
+	}
+	
 	public TypeCache(IProject project, IWorkingCopyProvider workingCopyProvider) {
 		fProject = project;
 		fWorkingCopyProvider = workingCopyProvider;
@@ -240,89 +265,49 @@
 	}
 	
 	public synchronized boolean isEmpty() {
-		return fTypeNameMap.isEmpty();
+		return fTypeKeyMap.isEmpty();
 	}
-
-	public synchronized void insert(ITypeInfo newType) {
-		// check if type already exists
-		Collection typeCollection = (Collection) fTypeNameMap.get(newType.getName());
-		if (typeCollection != null) {
-			for (Iterator typeIter = typeCollection.iterator(); typeIter.hasNext(); ) {
-				ITypeInfo currType = (ITypeInfo) typeIter.next();
-				if (currType.canSubstituteFor(newType)) {
-					// merge references into new type
-					ITypeReference[] refs = currType.getReferences();
-					for (int i = 0; i < refs.length; ++i) {
-						newType.addReference(refs[i]);
-					}
-					// remove the old type
-					currType.setCache(null);
-					typeIter.remove();
-				}
-			}
-		}
 	
+	public synchronized void insert(ITypeInfo newType) {
 		// check if enclosing types are already in cache
 		IQualifiedTypeName enclosingName = newType.getQualifiedTypeName().getEnclosingTypeName();
 		if (enclosingName != null) {
 			while (!enclosingName.isEmpty()) {
 				boolean foundType = false;
-				Collection enclosingCollection = (Collection) fTypeNameMap.get(enclosingName.getName());
-				if (enclosingCollection == null) {
-					enclosingCollection = new HashSet();
-					fTypeNameMap.put(enclosingName.getName(), enclosingCollection);
-				} else {
-					for (Iterator typeIter = enclosingCollection.iterator(); typeIter.hasNext(); ) {
-						ITypeInfo curr = (ITypeInfo) typeIter.next();
-						if (curr.getQualifiedTypeName().equals(enclosingName)) {
-							foundType = true;
-							break;
-						}
-					}
+				// try namespace, class, struct, then undefined
+				ITypeInfo enclosingType = null;
+				for (int i = 0; enclosingType == null && i < ENCLOSING_TYPES.length; ++i) {
+					enclosingType = (ITypeInfo) fTypeKeyMap.get(new HashKey(enclosingName, ENCLOSING_TYPES[i]));
 				}
-				if (!foundType) {
+				if (enclosingType == null) {
 					// create a dummy type to take this place (type 0 == unknown)
 					ITypeInfo dummyType = new TypeInfo(0, enclosingName);
-					enclosingCollection.add(dummyType);
 					dummyType.setCache(this);
+					fTypeKeyMap.put(new HashKey(enclosingName, 0), dummyType);
 				}
 				enclosingName = enclosingName.removeLastSegments(1);
 			}
 		}
 		
-		typeCollection = (Collection) fTypeNameMap.get(newType.getName());
-		if (typeCollection == null) {
-			typeCollection = new HashSet();
-			fTypeNameMap.put(newType.getName(), typeCollection);
-		}
-		typeCollection.add(newType);
+		fTypeKeyMap.put(new HashKey(newType.getQualifiedTypeName(), newType.getCElementType()), newType);
 		newType.setCache(this);
 	}
 	
 	public synchronized void remove(ITypeInfo info) {
-		Collection typeCollection = (Collection) fTypeNameMap.get(info.getName());
-		if (typeCollection != null) {
-			info.setCache(null);
-			typeCollection.remove(info);
-		}
+		fTypeKeyMap.remove(new HashKey(info.getQualifiedTypeName(), info.getCElementType()));
+		info.setCache(null);
 	}
 
 	public synchronized void flush(ITypeSearchScope scope) {
 		if (scope.encloses(fProject)) {
 			flushAll();
 		} else {
-			for (Iterator mapIter = fTypeNameMap.entrySet().iterator(); mapIter.hasNext(); ) {
+			for (Iterator mapIter = fTypeKeyMap.entrySet().iterator(); mapIter.hasNext(); ) {
 				Map.Entry entry = (Map.Entry) mapIter.next();
-				Collection typeCollection = (Collection) entry.getValue();
-				for (Iterator typeIter = typeCollection.iterator(); typeIter.hasNext(); ) {
-					ITypeInfo info = (ITypeInfo) typeIter.next();
-					if (info.isEnclosed(scope)) {
-						info.setCache(null);
-						typeIter.remove();
-					}
-				}
-				if (typeCollection.isEmpty())
+				ITypeInfo info = (ITypeInfo) entry.getValue();
+				if (info.isEnclosed(scope)) {
 					mapIter.remove();
+				}
 			}
 		}
 	}
@@ -342,19 +327,16 @@
 			}
 			public boolean shouldContinue() { return true; }
 		});
-		fTypeNameMap.clear();
+		fTypeKeyMap.clear();
 	}
 
 	public synchronized void accept(ITypeInfoVisitor visitor) {
-		for (Iterator mapIter = fTypeNameMap.entrySet().iterator(); mapIter.hasNext(); ) {
+		for (Iterator mapIter = fTypeKeyMap.entrySet().iterator(); mapIter.hasNext(); ) {
 			Map.Entry entry = (Map.Entry) mapIter.next();
-			Collection typeCollection = (Collection) entry.getValue();
-			for (Iterator typeIter = typeCollection.iterator(); typeIter.hasNext(); ) {
-				ITypeInfo info = (ITypeInfo) typeIter.next();
-				if (!visitor.shouldContinue())
-					return; // stop visiting
-				visitor.visit(info);
-			}
+			ITypeInfo info = (ITypeInfo) entry.getValue();
+			if (!visitor.shouldContinue())
+				return; // stop visiting
+			visitor.visit(info);
 		}
 	}
 
@@ -364,10 +346,12 @@
 			public boolean visit(ITypeInfo info) {
 				if (scope == null || info.isEnclosed(scope)) {
 					ITypeReference[] refs = info.getReferences();
-					for (int i = 0; i < refs.length; ++i) {
-						IPath path = refs[i].getPath();
-						if (scope == null || scope.encloses(path))
-							pathSet.add(path);
+					if (refs != null) {
+						for (int i = 0; i < refs.length; ++i) {
+							IPath path = refs[i].getPath();
+							if (scope == null || scope.encloses(path))
+								pathSet.add(path);
+						}
 					}
 				}
 				return true;
@@ -393,51 +377,38 @@
 	
 	public synchronized ITypeInfo[] getTypes(IQualifiedTypeName qualifiedName) {
 		Collection results = new ArrayList();
-		Collection typeCollection = (Collection) fTypeNameMap.get(qualifiedName.getName());
-		if (typeCollection != null) {
-			for (Iterator typeIter = typeCollection.iterator(); typeIter.hasNext(); ) {
-				ITypeInfo info = (ITypeInfo) typeIter.next();
-				if (info.getQualifiedTypeName().equals(qualifiedName)) {
-					results.add(info);
-				}
+		for (int i = 0; i < ITypeInfo.KNOWN_TYPES.length; ++i) {
+			ITypeInfo info = (ITypeInfo) fTypeKeyMap.get(new HashKey(qualifiedName, ITypeInfo.KNOWN_TYPES[i]));
+			if (info != null) {
+				results.add(info);
 			}
 		}
+		ITypeInfo info = (ITypeInfo) fTypeKeyMap.get(new HashKey(qualifiedName, 0));
+		if (info != null) {
+			results.add(info);
+		}
 		return (ITypeInfo[]) results.toArray(new ITypeInfo[results.size()]);
 	}
 	
 	public synchronized ITypeInfo getType(int type, IQualifiedTypeName qualifiedName) {
-		Collection typeCollection = (Collection) fTypeNameMap.get(qualifiedName.getName());
-		if (typeCollection != null) {
-			for (Iterator typeIter = typeCollection.iterator(); typeIter.hasNext(); ) {
-				ITypeInfo info = (ITypeInfo) typeIter.next();
-				if ((info.getCElementType() == type || info.getCElementType() == 0)
-						&& info.getQualifiedTypeName().equals(qualifiedName)) {
-					return info;
-				}
-			}
+		ITypeInfo info = (ITypeInfo) fTypeKeyMap.get(new HashKey(qualifiedName, type));
+		if (info == null && type != 0) {
+			info = (ITypeInfo) fTypeKeyMap.get(new HashKey(qualifiedName, 0));			
 		}
-		return null;
+		return info;
 	}
 	
 	public synchronized ITypeInfo getEnclosingType(ITypeInfo info, final int[] kinds) {
 		IQualifiedTypeName enclosingName = info.getQualifiedTypeName().getEnclosingTypeName();
 		if (enclosingName != null) {
-			Collection typeCollection = (Collection) fTypeNameMap.get(enclosingName.getName());
-			if (typeCollection != null) {
-				// try namespace, class, struct, then undefined
-				final int[] validKinds = {ICElement.C_NAMESPACE, ICElement.C_CLASS, ICElement.C_STRUCT, 0};
-				for (int i = 0; i < validKinds.length; ++i) {
-					if (ArrayUtil.contains(kinds, validKinds[i])) {
-						for (Iterator typeIter = typeCollection.iterator(); typeIter.hasNext(); ) {
-							ITypeInfo type = (ITypeInfo) typeIter.next();
-							if (type.getCElementType() == validKinds[i]
-								&& type.getQualifiedTypeName().equals(enclosingName)) {
-								return type;
-							}
-						}
-					}
+			// try namespace, class, struct, then undefined
+			ITypeInfo enclosingType = null;
+			for (int i = 0; enclosingType == null && i < ENCLOSING_TYPES.length; ++i) {
+				if (ArrayUtil.contains(kinds, ENCLOSING_TYPES[i])) {
+					enclosingType = (ITypeInfo) fTypeKeyMap.get(new HashKey(enclosingName, ENCLOSING_TYPES[i]));
 				}
 			}
+			return enclosingType;
 		}
 		return null;
 	}
@@ -451,23 +422,12 @@
 				return fGlobalNamespace;
 			return null;
 		}
-		String[] segments = qualifiedName.segments();
-		String namespace = segments[0];
-		Collection typeCollection = (Collection) fTypeNameMap.get(namespace);
-		if (typeCollection != null) {
-			// try namespace, then undefined
-			final int[] kinds = {ICElement.C_NAMESPACE, 0};
-			for (int i = 0; i < kinds.length; ++i) {
-				for (Iterator typeIter = typeCollection.iterator(); typeIter.hasNext(); ) {
-					ITypeInfo type = (ITypeInfo) typeIter.next();
-					if (type.getCElementType() == kinds[i]
-						&& type.getQualifiedTypeName().isGlobal()) {
-						return type;
-					}
-				}
-			}
-		}
-		return null;
+		IQualifiedTypeName namespace = qualifiedName.removeLastSegments(qualifiedName.segmentCount()-1);
+		// try namespace, then undefined
+		ITypeInfo namespaceType = (ITypeInfo) fTypeKeyMap.get(new HashKey(namespace, ICElement.C_NAMESPACE));
+		if (namespaceType == null)
+			namespaceType = (ITypeInfo) fTypeKeyMap.get(new HashKey(namespace, 0));
+		return namespaceType;
 	}
 
 	public synchronized boolean hasEnclosedTypes(final ITypeInfo info) {
Index: browser/org/eclipse/cdt/internal/core/browser/cache/TypeParser.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeParser.java,v
retrieving revision 1.4
diff -u -r1.4 TypeParser.java
--- browser/org/eclipse/cdt/internal/core/browser/cache/TypeParser.java	4 Jun 2004 21:01:47 -0000	1.4
+++ browser/org/eclipse/cdt/internal/core/browser/cache/TypeParser.java	17 Jun 2004 18:53:43 -0000
@@ -110,8 +110,8 @@
 	private IWorkingCopyProvider fWorkingCopyProvider;
 	private IProgressMonitor fProgressMonitor;
 	private ISourceElementCallbackDelegate fLastDeclaration;
-	private SimpleStack fScopeStack = new SimpleStack();
-	private SimpleStack fResourceStack = new SimpleStack();
+	private final SimpleStack fScopeStack = new SimpleStack();
+	private final SimpleStack fResourceStack = new SimpleStack();
 	private ITypeInfo fTypeToFind;
 	private boolean fFoundType;
 
@@ -311,6 +311,8 @@
 			}
 
 			if (reader != null) {
+				fResourceStack.clear();
+				fScopeStack.clear();
 				fResourceStack.push(stackObject);
 				parseContents(path, project, reader, language, progressMonitor);
 				fResourceStack.pop();
@@ -419,7 +421,8 @@
 		} catch (ParserFactoryError e) {
 			CCorePlugin.log(e);
 		} catch (ParseError e) {
-			CCorePlugin.log(e);
+			// no need to log
+			// CCorePlugin.log(e);
 		} catch (OperationCanceledException e) {
 			throw new InterruptedException();
 		} catch (Exception e) {
@@ -622,19 +625,35 @@
 			return;
 		}
 		
-		// collect enclosing names
+		if (fTypeToFind != null) {
+			if ((fTypeToFind.getCElementType() == type || fTypeToFind.isUndefinedType()) && name.equals(fTypeToFind.getName())) {
+				String[] enclosingNames = getEnclosingNames(offsetable);
+				QualifiedTypeName qualifiedName = new QualifiedTypeName(name, enclosingNames);
+				if (qualifiedName.equals(fTypeToFind.getQualifiedTypeName())) {
+					fFoundType = true;
+
+					// add types to cache
+					addType(type, name, enclosingNames, fResourceStack.bottom(), fResourceStack.top(), offset, end - offset);
+					fProgressMonitor.worked(1);
+				}
+			}
+		} else {
+			// add types to cache
+			addType(type, name, getEnclosingNames(offsetable), fResourceStack.bottom(), fResourceStack.top(), offset, end - offset);
+			fProgressMonitor.worked(1);
+		}
+	}
+	
+	private String[] getEnclosingNames(IASTOffsetableNamedElement elem) {
 		String[] enclosingNames = null;
-		if (offsetable instanceof IASTQualifiedNameElement) {
-			String[] names = ((IASTQualifiedNameElement) offsetable).getFullyQualifiedName();
+		if (elem instanceof IASTQualifiedNameElement) {
+			String[] names = ((IASTQualifiedNameElement) elem).getFullyQualifiedName();
 			if (names != null && names.length > 1) {
 				enclosingNames = new String[names.length - 1];
 				System.arraycopy(names, 0, enclosingNames, 0, names.length - 1);
 			}
 		}
-		
-		// add types to cache
-		addType(type, name, enclosingNames, fResourceStack.bottom(), fResourceStack.top(), offset, end - offset);
-		fProgressMonitor.worked(1);
+		return enclosingNames;
 	}
 
 	private int getElementType(IASTOffsetableNamedElement offsetable) {
@@ -667,8 +686,12 @@
 		ITypeInfo info = fTypeCache.getType(type, qualifiedName);
 		if (info == null || info.isUndefinedType()) {
 			// add new type to cache
-			info = new TypeInfo(type, qualifiedName);
-			fTypeCache.insert(info);
+			if (info != null) {
+				info.setCElementType(type);
+			} else {
+				info = new TypeInfo(type, qualifiedName);
+				fTypeCache.insert(info);
+			}
 			
 			TypeReference location;
 			if (originalRef instanceof IWorkingCopy) {
@@ -696,10 +719,6 @@
 			location = new TypeReference(path, fProject, offset, length);
 		}
 		info.addReference(location);
-		
-		if (fTypeToFind != null && fTypeToFind.equals(info)) {
-			fFoundType = true;
-		}
 	}
 
 	/* (non-Javadoc)
Index: browser/org/eclipse/cdt/internal/core/browser/util/PathUtil.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/util/PathUtil.java,v
retrieving revision 1.2
diff -u -r1.2 PathUtil.java
--- browser/org/eclipse/cdt/internal/core/browser/util/PathUtil.java	17 May 2004 15:48:48 -0000	1.2
+++ browser/org/eclipse/cdt/internal/core/browser/util/PathUtil.java	17 Jun 2004 18:53:43 -0000
@@ -13,6 +13,7 @@
 import java.io.File;
 import java.io.IOException;
 
+import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IWorkspace;
 import org.eclipse.core.resources.IWorkspaceRoot;
 import org.eclipse.core.resources.ResourcesPlugin;
@@ -70,8 +71,24 @@
 		return fullPath;
 	}
 	
+	public static IPath getProjectRelativePath(IPath fullPath, IProject project) {
+		IPath projectPath = project.getFullPath();
+		if (projectPath.isPrefixOf(fullPath)) {
+			return fullPath.removeFirstSegments(projectPath.segmentCount());
+		}
+		projectPath = project.getLocation();
+		if (projectPath.isPrefixOf(fullPath)) {
+			return fullPath.removeFirstSegments(projectPath.segmentCount());
+		}
+		return getWorkspaceRelativePath(fullPath);
+	}
+
 	public static IPath getWorkspaceRelativePath(String fullPath) {
 		return getWorkspaceRelativePath(new Path(fullPath));
+	}
+
+	public static IPath getProjectRelativePath(String fullPath, IProject project) {
+		return getProjectRelativePath(new Path(fullPath), project);
 	}
 
 	public static IPath getRawLocation(IPath wsRelativePath) {
Index: browser/org/eclipse/cdt/internal/core/browser/util/SimpleStack.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/util/SimpleStack.java,v
retrieving revision 1.2
diff -u -r1.2 SimpleStack.java
--- browser/org/eclipse/cdt/internal/core/browser/util/SimpleStack.java	17 May 2004 15:48:48 -0000	1.2
+++ browser/org/eclipse/cdt/internal/core/browser/util/SimpleStack.java	17 Jun 2004 18:53:43 -0000
@@ -31,6 +31,10 @@
     	items = new ArrayList(initialSize);
     }
     
+    public void clear() {
+    	items.clear();
+    }
+    
     public Object push(Object item) {
     	items.add(item);
     	if (VERBOSE)

Back to the top