diff options
Diffstat (limited to 'core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom')
3 files changed, 87 insertions, 19 deletions
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/IPDOMIterator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/IPDOMIterator.java new file mode 100644 index 00000000000..f9e5143a273 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/IPDOMIterator.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2013 QNX Software Systems 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 + */ +package org.eclipse.cdt.internal.core.pdom.dom; + +import java.util.NoSuchElementException; + +import org.eclipse.core.runtime.CoreException; + +/** + * A generic interface for iterating through lists that are stored in the PDOM. The + * difference between this interface and the standard one in java.util is that this + * one can throw a CoreException from either method. Also, this one does not provide + * a way to remove elements. + */ +public interface IPDOMIterator<T> { + + /** + * Return true if the next call to #next will yield a value and false otherwise. + * + * @see java.util.Iterator#hasNext() + */ + public boolean hasNext() throws CoreException; + + /** + * Return the next element in the iteration. Throws {@link NoSuchElementException} if + * there are no elements left in the iteration. + * + * @see java.util.Iterator#next + */ + public T next() throws CoreException; +} 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 22b81c33e48..cb5198df1dc 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 @@ -37,6 +37,7 @@ import org.eclipse.cdt.internal.core.index.IIndexScope; import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.cdt.internal.core.pdom.db.IString; +import org.eclipse.cdt.internal.core.pdom.db.PDOMExternalReferencesList; import org.eclipse.cdt.internal.core.pdom.tag.PDOMTaggable; import org.eclipse.core.runtime.CoreException; @@ -46,13 +47,14 @@ import org.eclipse.core.runtime.CoreException; public abstract class PDOMBinding extends PDOMNamedNode implements IPDOMBinding { public static final PDOMBinding[] EMPTY_PDOMBINDING_ARRAY = {}; - private static final int FIRST_DECL_OFFSET = PDOMNamedNode.RECORD_SIZE + 0; // size 4 + private static final int FIRST_DECL_OFFSET = PDOMNamedNode.RECORD_SIZE + 0; // size 4 private static final int FIRST_DEF_OFFSET = PDOMNamedNode.RECORD_SIZE + 4; // size 4 private static final int FIRST_REF_OFFSET = PDOMNamedNode.RECORD_SIZE + 8; // size 4 private static final int LOCAL_TO_FILE = PDOMNamedNode.RECORD_SIZE + 12; // size 4 + private static final int FIRST_EXTREF_OFFSET = PDOMNamedNode.RECORD_SIZE + 16; // size 4 @SuppressWarnings("hiding") - protected static final int RECORD_SIZE = PDOMNamedNode.RECORD_SIZE + 16; + protected static final int RECORD_SIZE = PDOMNamedNode.RECORD_SIZE + 20; private byte hasDeclaration= -1; protected PDOMBinding(PDOMLinkage linkage, PDOMNode parent, char[] name) throws CoreException { @@ -95,7 +97,8 @@ public abstract class PDOMBinding extends PDOMNamedNode implements IPDOMBinding Database db = pdom.getDB(); return db.getRecPtr(record + FIRST_DECL_OFFSET) == 0 && db.getRecPtr(record + FIRST_DEF_OFFSET) == 0 - && db.getRecPtr(record + FIRST_REF_OFFSET) == 0; + && db.getRecPtr(record + FIRST_REF_OFFSET) == 0 + && db.getRecPtr(record + FIRST_EXTREF_OFFSET) == 0; } @Override @@ -132,6 +135,14 @@ public abstract class PDOMBinding extends PDOMNamedNode implements IPDOMBinding } public final void addReference(PDOMName name) throws CoreException { + // This needs to filter between the local and external lists because it can be used in + // contexts that don't know which type of list they are iterating over. E.g., this is + // used when deleting names from a PDOMFile. + if (!getLinkage().equals(name.getLinkage())) { + new PDOMExternalReferencesList(getPDOM(), record + FIRST_EXTREF_OFFSET).add(name); + return; + } + PDOMName first = getFirstReference(); if (first != null) { first.setPrevInBinding(name); @@ -165,7 +176,25 @@ public abstract class PDOMBinding extends PDOMNamedNode implements IPDOMBinding return namerec != 0 ? new PDOMName(getLinkage(), namerec) : null; } + /** + * Returns an iterator over the names in other linkages that reference this binding. Does + * not return null. + */ + public IPDOMIterator<PDOMName> getExternalReferences() throws CoreException { + return new PDOMExternalReferencesList(getPDOM(), record + FIRST_EXTREF_OFFSET).getIterator(); + } + public void setFirstReference(PDOMName name) throws CoreException { + // This needs to filter between the local and external lists because it can be used in + // contexts that don't know which type of list they are iterating over. E.g., this is + // used when deleting names from a PDOMFile. + if (name != null + && !getLinkage().equals(name.getLinkage())) { + new PDOMExternalReferencesList(getPDOM(), record + FIRST_EXTREF_OFFSET).add(name); + return; + } + + // Otherwise put the reference into list of locals. long namerec = name != null ? name.getRecord() : 0; getDB().putRecPtr(record + FIRST_REF_OFFSET, namerec); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java index d222425d19c..d6da2296727 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java @@ -33,7 +33,7 @@ import org.eclipse.core.runtime.IPath; public final class PDOMName implements IIndexFragmentName, IASTFileLocation { private final PDOMLinkage linkage; private final long record; - + private static final int FILE_REC_OFFSET = 0; private static final int FILE_NEXT_OFFSET = 4; private static final int CALLER_REC_OFFSET = 8; @@ -42,7 +42,7 @@ public final class PDOMName implements IIndexFragmentName, IASTFileLocation { private static final int BINDING_NEXT_OFFSET = 20; private static final int NODE_OFFSET_OFFSET = 24; // 3-byte unsigned int (sufficient for files <= 16mb) private static final int NODE_LENGTH_OFFSET = 27; // short (sufficient for names <= 32k) - private static final int FLAGS = 29; + private static final int FLAGS = 29; private static final int RECORD_SIZE = 30; // 30 yields a 32-byte block. (31 would trigger a 40-byte block) @@ -58,7 +58,6 @@ public final class PDOMName implements IIndexFragmentName, IASTFileLocation { public static final int READ_ACCESS = 0x20; public static final int WRITE_ACCESS = 0x40; - public PDOMName(PDOMLinkage linkage, IASTName name, PDOMFile file, PDOMBinding binding, PDOMName caller) throws CoreException { this.linkage = linkage; @@ -67,7 +66,7 @@ public final class PDOMName implements IIndexFragmentName, IASTFileLocation { // What kind of name are we int flags= getRoleOfName(name); - + flags |= binding.getAdditionalNameFlags(flags, name); db.putByte(record + FLAGS, (byte) flags); @@ -85,7 +84,7 @@ public final class PDOMName implements IIndexFragmentName, IASTFileLocation { } db.putRecPtr(record + BINDING_REC_OFFSET, binding.getRecord()); - + db.putRecPtr(record + FILE_REC_OFFSET, file.getRecord()); if (caller != null) { db.putRecPtr(record + CALLER_REC_OFFSET, caller.getRecord()); @@ -100,18 +99,22 @@ public final class PDOMName implements IIndexFragmentName, IASTFileLocation { private int getRoleOfName(IASTName name) { if (name.isDefinition()) { return IS_DEFINITION; - } + } if (name.isDeclaration()) { return IS_DECLARATION; - } + } return IS_REFERENCE; } - + public PDOMName(PDOMLinkage linkage, long nameRecord) { this.linkage = linkage; this.record = nameRecord; } - + + public PDOMLinkage getLinkage() { + return linkage; + } + public long getRecord() { return record; } @@ -127,7 +130,7 @@ public final class PDOMName implements IIndexFragmentName, IASTFileLocation { public PDOM getPDOM() { return linkage.getPDOM(); } - + @Override public PDOMBinding getBinding() throws CoreException { long bindingrec = getRecField(BINDING_REC_OFFSET); @@ -160,11 +163,11 @@ public final class PDOMName implements IIndexFragmentName, IASTFileLocation { public PDOMName getNextInBinding() throws CoreException { return getNameField(BINDING_NEXT_OFFSET); } - + public void setNextInBinding(PDOMName name) throws CoreException { setNameField(BINDING_NEXT_OFFSET, name); } - + @Override public PDOMFile getFile() throws CoreException { long filerec = linkage.getDB().getRecPtr(record + FILE_REC_OFFSET); @@ -188,11 +191,11 @@ public final class PDOMName implements IIndexFragmentName, IASTFileLocation { long getEnclosingDefinitionRecord() throws CoreException { return linkage.getDB().getRecPtr(record + CALLER_REC_OFFSET); } - + public PDOMName getNextInFile() throws CoreException { return getNameField(FILE_NEXT_OFFSET); } - + public void setNextInFile(PDOMName name) throws CoreException { setNameField(FILE_NEXT_OFFSET, name); } @@ -223,7 +226,7 @@ public final class PDOMName implements IIndexFragmentName, IASTFileLocation { public String toString() { return new String(getSimpleID()); } - + private int getFlags(int mask) throws CoreException { return linkage.getDB().getByte(record + FLAGS) & mask; } @@ -254,7 +257,7 @@ public final class PDOMName implements IIndexFragmentName, IASTFileLocation { public boolean isBaseSpecifier() throws CoreException { return getFlags(INHERIT_FRIEND_INLINE_MASK) == IS_INHERITANCE_SPEC; } - + @Override public boolean isInlineNamespaceDefinition() throws CoreException { return getFlags(INHERIT_FRIEND_INLINE_MASK) == IS_INLINE_NAMESPACE; |