diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java index 4fc518cc2a9..f02ca5524ea 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java @@ -42,6 +42,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPParserExtensionConfigurat import org.eclipse.cdt.internal.core.parser.scanner2.DOMScanner; import org.eclipse.cdt.internal.core.parser.scanner2.GPPScannerExtensionConfiguration; import org.eclipse.cdt.internal.core.parser.scanner2.IScannerExtensionConfiguration; +import org.eclipse.cdt.internal.core.pdom.PDOMCodeReaderFactory; import org.eclipse.cdt.internal.core.pdom.PDOMDatabase; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; import org.eclipse.cdt.internal.core.pdom.dom.cpp.PDOMCPPFunction; @@ -77,7 +78,12 @@ public class GPPLanguage implements ILanguage { // TODO - use different factories if we are working copy, or style // is skip headers. - ICodeReaderFactory fileCreator = SavedCodeReaderFactory.getInstance(); + ICodeReaderFactory fileCreator; + if ((style & ILanguage.AST_SKIP_INDEXED_HEADERS) != 0) + fileCreator = new PDOMCodeReaderFactory((PDOMDatabase)tu.getCProject().getIndex()); + else + fileCreator = SavedCodeReaderFactory.getInstance(); + CodeReader reader = fileCreator.createCodeReaderForTranslationUnit(tu); if( reader == null ) return null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMCodeReaderFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMCodeReaderFactory.java index 473e85b6b70..269d3ff38f8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMCodeReaderFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMCodeReaderFactory.java @@ -56,7 +56,7 @@ public class PDOMCodeReaderFactory implements ICodeReaderFactory { } public CodeReader createCodeReaderForTranslationUnit(ITranslationUnit tu) { - return new CodeReader(tu.getPath().toOSString(), tu.getContents()); + return new CodeReader(tu.getResource().getLocation().toOSString(), tu.getContents()); } public CodeReader createCodeReaderForInclusion(String path) { @@ -67,7 +67,9 @@ public class PDOMCodeReaderFactory implements ICodeReaderFactory { } catch (IOException e) { // ignore and use the path we were passed in } - if (PDOMFile.find(pdom, path) != null) + PDOMFile file = PDOMFile.find(pdom, path); + if (file != null && file.getFirstName() != null) + // Already got things from here return null; } catch (CoreException e) { CCorePlugin.log(new CoreException(new Status(IStatus.ERROR, diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMDatabase.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMDatabase.java index 005721caecd..bcc2edf3fe3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMDatabase.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMDatabase.java @@ -12,6 +12,8 @@ package org.eclipse.cdt.internal.core.pdom; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; import java.util.Map; import org.eclipse.cdt.core.CCorePlugin; @@ -28,7 +30,9 @@ import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.internal.core.pdom.db.BTree; import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile; import org.eclipse.cdt.internal.core.pdom.dom.PDOMName; +import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; @@ -71,6 +75,32 @@ public class PDOMDatabase implements IPDOM { db = new Database(dbPath.toOSString(), VERSION); } + public static interface IListener { + public void handleChange(PDOMDatabase pdom); + } + + private List listeners; + + public void addListener(IListener listener) { + if (listeners == null) + listeners = new LinkedList(); + listeners.add(listener); + } + + public void removeListener(IListener listener) { + if (listeners == null) + return; + listeners.remove(listener); + } + + private void fireChange() { + if (listeners == null) + return; + Iterator i = listeners.iterator(); + while (i.hasNext()) + ((IListener)i.next()).handleChange(this); + } + public Database getDB() throws CoreException { if (db == null) db = new Database(dbPath.toOSString(), VERSION); @@ -120,16 +150,24 @@ public class PDOMDatabase implements IPDOM { } }; });; + + fireChange(); } - public void removeSymbols(ITranslationUnit ast) { - + public void removeSymbols(ITranslationUnit tu) throws CoreException { + String filename = ((IFile)tu.getResource()).getLocation().toOSString(); + PDOMFile file = PDOMFile.find(this, filename); + if (file == null) + return; + file.clear(); } public void delete() throws CoreException { getDB().clear(); bindingIndex = null; fileIndex = null; + languageCache = null; + languages = null; } public ICodeReaderFactory getCodeReaderFactory() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMUpdator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMUpdator.java index 1e1647b49be..ea99fa11fed 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMUpdator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMUpdator.java @@ -22,7 +22,6 @@ import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElementDelta; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ITranslationUnit; -import org.eclipse.cdt.internal.core.model.Util; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -198,7 +197,7 @@ public class PDOMUpdator extends Job { mypdom.addSymbols(tu); } - private void processRemovedTU(ITranslationUnit tu) { + private void processRemovedTU(ITranslationUnit tu) throws CoreException { IProject project = tu.getCProject().getProject(); IPDOM pdom = PDOM.getPDOM(project); if (pdom == null || !(pdom instanceof PDOMDatabase)) @@ -206,6 +205,8 @@ public class PDOMUpdator extends Job { PDOMDatabase mypdom = (PDOMDatabase)pdom; mypdom.removeSymbols(tu); + // TODO delete the file itself from the database + // the removeSymbols only removes the names in the file } private void processChangedTU(ITranslationUnit tu) throws CoreException { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java index 25e7d6f85e1..1fb56ac5f9d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java @@ -105,6 +105,11 @@ public class Chunk { this.prevChunk = prevChunk; } + void clear(int offset, int length) { + buffer.position(offset % Database.CHUNK_SIZE); + buffer.put(new byte[length]); + } + void free() { // nextChunk should be null db.toc[index] = null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java index 7f91d87196b..f4207bd4fa7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java @@ -13,7 +13,10 @@ package org.eclipse.cdt.internal.core.pdom.db; import java.io.IOException; import java.io.RandomAccessFile; +import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; /** * @author Doug Schaefer @@ -223,9 +226,13 @@ public class Database { */ public void free(int offset) throws CoreException { // TODO - look for opportunities to merge blocks - int block = offset - INT_SIZE; + int block = offset - 4; Chunk chunk = getChunk(block); int blocksize = - chunk.getInt(block); + if (blocksize < 0) + // already freed + throw new CoreException(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, 0, "Already Freed", new Exception())); + chunk.clear(offset, blocksize - 4); addBlock(chunk, blocksize, block); } 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 6570914df81..01f0178169a 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 @@ -10,8 +10,6 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom; -import java.io.IOException; - import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ILanguage; import org.eclipse.cdt.core.dom.ast.DOMException; @@ -25,8 +23,6 @@ import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator; import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; /** * @author Doug Schaefer @@ -145,6 +141,12 @@ public class PDOMBinding implements IBinding { return pdom.getDB().getChar(record + TYPE_OFFSET); } + public boolean hasDeclarations() throws CoreException { + Database db = pdom.getDB(); + return db.getInt(record + FIRST_DECL_OFFSET) != 0 + || db.getInt(record + FIRST_DEF_OFFSET) != 0; + } + public void addDeclaration(PDOMName name) throws CoreException { PDOMName firstDeclaration = getFirstDeclaration(); if (firstDeclaration != null) { @@ -155,13 +157,13 @@ public class PDOMBinding implements IBinding { } public PDOMName getFirstDeclaration() throws CoreException { - try { - int firstDeclRec = pdom.getDB().getInt(record + FIRST_DECL_OFFSET); - return firstDeclRec != 0 ? new PDOMName(pdom, firstDeclRec) : null; - } catch (IOException e) { - throw new CoreException(new Status(IStatus.ERROR, - CCorePlugin.PLUGIN_ID, 0, "PDOM", e)); - } + int firstDeclRec = pdom.getDB().getInt(record + FIRST_DECL_OFFSET); + return firstDeclRec != 0 ? new PDOMName(pdom, firstDeclRec) : null; + } + + public void setFirstDeclaration(PDOMName name) throws CoreException { + int namerec = name != null ? name.getRecord() : 0; + pdom.getDB().putInt(record + FIRST_DECL_OFFSET, namerec); } public String getName() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java index 5b53cf74fb4..05643f80cb2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java @@ -98,16 +98,26 @@ public class PDOMFile { return pdom.getDB().getString(record + FILE_NAME_OFFSET); } - public int getFirstName() throws CoreException { - return pdom.getDB().getInt(record + FIRST_NAME_OFFSET); + public PDOMName getFirstName() throws CoreException { + int namerec = pdom.getDB().getInt(record + FIRST_NAME_OFFSET); + return namerec != 0 ? new PDOMName(pdom, namerec) : null; } - public void setFirstName(int firstName) throws CoreException { - pdom.getDB().putInt(record + FIRST_NAME_OFFSET, firstName); + public void setFirstName(PDOMName firstName) throws CoreException { + int namerec = firstName != null ? firstName.getRecord() : 0; + pdom.getDB().putInt(record + FIRST_NAME_OFFSET, namerec); } - public void free() throws CoreException { - pdom.getDB().free(record); + public void clear() throws CoreException { + // Delete all the names in this file + PDOMName name = getFirstName(); + while (name != null) { + PDOMName nextName = name.getNextInFile(); + name.delete(); + name = nextName; + } + + setFirstName(null); } } 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 17211e48f1c..8274b9abc37 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 @@ -10,8 +10,6 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom; -import java.io.IOException; - import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.ASTVisitor; @@ -38,7 +36,7 @@ public class PDOMName implements IASTName, IASTFileLocation { private static final int FILE_REC_OFFSET = 0 * Database.INT_SIZE; private static final int FILE_PREV_OFFSET = 1 * Database.INT_SIZE; private static final int FILE_NEXT_OFFSET = 2 * Database.INT_SIZE; - private static final int BINDING_REC_OFFET = 3 * Database.INT_SIZE; + private static final int BINDING_REC_OFFSET = 3 * Database.INT_SIZE; private static final int BINDING_PREV_OFFSET = 4 * Database.INT_SIZE; private static final int BINDING_NEXT_OFFSET = 5 * Database.INT_SIZE; private static final int NODE_OFFSET_OFFSET = 6 * Database.INT_SIZE; @@ -53,7 +51,7 @@ public class PDOMName implements IASTName, IASTFileLocation { // Hook us up to the binding if (binding != null) { - db.putInt(record + BINDING_REC_OFFET, binding.getRecord()); + db.putInt(record + BINDING_REC_OFFSET, binding.getRecord()); if (name.isDeclaration()) binding.addDeclaration(this); } @@ -63,18 +61,18 @@ public class PDOMName implements IASTName, IASTFileLocation { String filename = fileloc.getFileName(); PDOMFile pdomFile = PDOMFile.insert(pdom, filename); db.putInt(record + FILE_REC_OFFSET, pdomFile.getRecord()); - int firstName = pdomFile.getFirstName(); - if (firstName != 0) { - db.putInt(record + FILE_NEXT_OFFSET, firstName); - db.putInt(firstName + FILE_PREV_OFFSET, record); + PDOMName firstName = pdomFile.getFirstName(); + if (firstName != null) { + db.putInt(record + FILE_NEXT_OFFSET, firstName.getRecord()); + firstName.setPrevInFile(this); } - pdomFile.setFirstName(record); - + pdomFile.setFirstName(this); + db.putInt(record + NODE_OFFSET_OFFSET, fileloc.getNodeOffset()); db.putInt(record + NODE_LENGTH_OFFSET, fileloc.getNodeLength()); } - public PDOMName(PDOMDatabase pdom, int nameRecord) throws IOException { + public PDOMName(PDOMDatabase pdom, int nameRecord) { this.pdom = pdom; this.record = nameRecord; } @@ -82,22 +80,75 @@ public class PDOMName implements IASTName, IASTFileLocation { public int getRecord() { return record; } + + private int getRecField(int offset) throws CoreException { + return pdom.getDB().getInt(record + offset); + } + + private void setRecField(int offset, int fieldrec) throws CoreException { + pdom.getDB().putInt(record + offset, fieldrec); + } + + public PDOMBinding getPDOMBinding() throws CoreException { + int bindingrec = getRecField(BINDING_REC_OFFSET); + return bindingrec != 0 ? new PDOMBinding(pdom, bindingrec) : null; + } public void setBinding(PDOMBinding binding) throws CoreException { - pdom.getDB().putInt(record + BINDING_REC_OFFET, binding.getRecord()); + int bindingrec = binding != null ? binding.getRecord() : 0; + setRecField(BINDING_REC_OFFSET, bindingrec); } - public void setPrevInBinding(PDOMName prevName) throws CoreException { - pdom.getDB().putInt(record + BINDING_PREV_OFFSET, prevName.getRecord()); + private PDOMName getNameField(int offset) throws CoreException { + int namerec = getRecField(offset); + return namerec != 0 ? new PDOMName(pdom, namerec) : null; } - public void setNextInBinding(PDOMName nextName) throws CoreException { - pdom.getDB().putInt(record + BINDING_NEXT_OFFSET, nextName.getRecord()); + private void setNameField(int offset, PDOMName name) throws CoreException { + int namerec = name != null ? name.getRecord() : 0; + setRecField(offset, namerec); + } + + public PDOMName getPrevInBinding() throws CoreException { + return getNameField(BINDING_PREV_OFFSET); + } + + public void setPrevInBinding(PDOMName name) throws CoreException { + setNameField(BINDING_PREV_OFFSET, name); + } + + public PDOMName getNextInBinding() throws CoreException { + return getNameField(BINDING_NEXT_OFFSET); + } + + public void setNextInBinding(PDOMName name) throws CoreException { + setNameField(BINDING_NEXT_OFFSET, name); + } + + public PDOMFile getFile() throws CoreException { + int filerec = pdom.getDB().getInt(record + FILE_REC_OFFSET); + return filerec != 0 ? new PDOMFile(pdom, filerec) : null; + } + + public PDOMName getNextInFile() throws CoreException { + return getNameField(FILE_NEXT_OFFSET); + } + + public void setNextInFile(PDOMName name) throws CoreException { + setNameField(FILE_NEXT_OFFSET, name); + } + + public PDOMName getPrevInFile() throws CoreException { + return getNameField(FILE_PREV_OFFSET); + } + + public void setPrevInFile(PDOMName name) throws CoreException { + setNameField(FILE_PREV_OFFSET, name); } public IBinding resolveBinding() { try { - int bindingRecord = pdom.getDB().getInt(record + BINDING_REC_OFFET); + int bindingRecord = pdom.getDB().getInt(record + BINDING_REC_OFFSET); return new PDOMBinding(pdom, bindingRecord); } catch (CoreException e) { CCorePlugin.log(e); @@ -120,7 +171,7 @@ public class PDOMName implements IASTName, IASTFileLocation { public char[] toCharArray() { try { Database db = pdom.getDB(); - int bindingRec = db.getInt(record + BINDING_REC_OFFET); + int bindingRec = db.getInt(record + BINDING_REC_OFFSET); if (bindingRec == 0) return null; @@ -190,7 +241,8 @@ public class PDOMName implements IASTName, IASTFileLocation { public String getFileName() { try { - return new PDOMFile(pdom, pdom.getDB().getInt(record + FILE_REC_OFFSET)).getFileName(); + PDOMFile file = getFile(); + return file != null ? file.getFileName() : null; } catch (CoreException e) { CCorePlugin.log(e); return null; @@ -228,4 +280,20 @@ public class PDOMName implements IASTName, IASTFileLocation { return null; } + public void delete() throws CoreException { + // Delete from the binding chain + PDOMName prevName = getPrevInBinding(); + PDOMName nextName = getNextInBinding(); + if (prevName != null) + prevName.setNextInBinding(nextName); + else + getPDOMBinding().setFirstDeclaration(nextName); + + if (nextName != null) + nextName.setPrevInBinding(prevName); + + // Delete our record + pdom.getDB().free(record); + } + }