From 21b09a659cfd02c1780693e5e5187ca4070f9443 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Fri, 7 Dec 2007 10:33:34 +0000 Subject: [PATCH] Headers included from c- and c++-files (bug 191989). --- .../pdomdepgen/PDOMDependencyCalculator.java | 7 +- .../parser/tests/scanner/InclusionTests.java | 2 +- .../index/tests/EmptyIndexFragment.java | 7 +- .../internal/index/tests/IndexBugsTests.java | 12 +- .../index/tests/IndexIncludeTest.java | 38 +- .../cdt/internal/pdom/tests/DefDeclTests.java | 5 +- .../pdom/tests/FilesOnReindexTests.java | 3 +- .../internal/pdom/tests/IncludesTests.java | 5 +- .../testplugin/util/TestSourceReader.java | 7 +- .../org.eclipse.cdt.core/META-INF/MANIFEST.MF | 3 - .../cdt/core/model/AssemblyLanguage.java | 4 + .../org/eclipse/cdt/core/model/ILanguage.java | 41 +- .../cdt/core/model/LanguageManager.java | 3 +- .../internal/core/model/TranslationUnit.java | 88 +- .../org/eclipse/cdt/core/dom/ILinkage.java | 6 +- .../cdt/core/dom/IPDOMIndexerTask.java | 5 +- .../cdt/core/dom/ast/gnu/c/GCCLanguage.java | 13 +- .../cdt/core/dom/ast/gnu/cpp/GPPLanguage.java | 14 +- .../org/eclipse/cdt/core/index/IIndex.java | 14 +- .../eclipse/cdt/core/index/IIndexFile.java | 15 +- .../cdt/internal/core/index/CIndex.java | 42 +- .../cdt/internal/core/index/EmptyCIndex.java | 6 +- .../internal/core/index/IIndexFragment.java | 16 +- .../core/index/IIndexFragmentFile.java | 20 +- .../internal/core/index/IWritableIndex.java | 18 +- .../core/index/IWritableIndexFragment.java | 4 +- .../index/IndexBasedCodeReaderFactory.java | 299 ++----- .../core/index/IndexFileLocation.java | 9 +- .../internal/core/index/WritableCIndex.java | 22 +- .../indexer/StandaloneFastIndexerTask.java | 187 +---- .../indexer/StandaloneFullIndexerTask.java | 146 +--- ...StandaloneIndexBasedCodeReaderFactory.java | 96 --- .../core/indexer/StandaloneIndexer.java | 20 +- ...tandaloneIndexerFallbackReaderFactory.java | 63 ++ .../StandaloneIndexerInputAdapter.java | 129 +++ .../core/indexer/StandaloneIndexerTask.java | 410 +-------- .../core/parser/scanner/LocationCtxFile.java | 3 - .../core/pdom/ASTFilePathResolver.java | 38 + .../core/pdom/AbstractIndexerTask.java | 782 ++++++++++++++++++ .../core/pdom/IndexerInputAdapter.java | 73 ++ .../pdom/{indexer => }/IndexerStatistics.java | 2 +- .../cdt/internal/core/pdom/Messages.java | 3 + .../eclipse/cdt/internal/core/pdom/PDOM.java | 25 +- .../internal/core/pdom/PDOMIndexerJob.java | 3 + .../cdt/internal/core/pdom/PDOMManager.java | 2 +- .../cdt/internal/core/pdom/PDOMProxy.java | 11 +- .../cdt/internal/core/pdom/PDOMWriter.java | 375 ++++----- .../core/pdom/TeamPDOMExportOperation.java | 25 +- .../core/pdom/TeamPDOMImportOperation.java | 36 +- .../cdt/internal/core/pdom/WritablePDOM.java | 4 +- .../cdt/internal/core/pdom/dom/PDOMFile.java | 95 ++- .../pdom/indexer/AbstractPDOMIndexer.java | 3 + .../core/pdom/indexer/DeltaAnalyzer.java | 2 +- .../internal/core/pdom/indexer/Messages.java | 3 - .../indexer/{fast => }/PDOMFastIndexer.java | 13 +- .../pdom/indexer/PDOMFastIndexerTask.java | 30 + .../indexer/{full => }/PDOMFullIndexer.java | 7 +- .../pdom/indexer/PDOMFullIndexerTask.java | 32 + .../core/pdom/indexer/PDOMIndexerTask.java | 542 ++---------- .../indexer/{nulli => }/PDOMNullIndexer.java | 11 +- .../core/pdom/indexer/PDOMRebuildTask.java | 10 +- .../core/pdom/indexer/PDOMUpdateTask.java | 11 +- .../indexer/ProjectIndexerInputAdapter.java | 164 ++++ .../indexer/TranslationUnitCollector.java | 9 +- .../indexer/fast/PDOMFastIndexerTask.java | 215 ----- .../indexer/full/PDOMFullIndexerTask.java | 215 ----- .../core/pdom/indexer/messages.properties | 3 - .../internal/core/pdom/messages.properties | 3 + core/org.eclipse.cdt.core/plugin.xml | 6 +- .../src/org/eclipse/cdt/core/CCorePlugin.java | 3 +- .../eclipse/cdt/ui/tests/BaseUITestCase.java | 7 +- .../callhierarchy/BasicCallHierarchyTest.java | 6 +- .../CallHierarchyAcrossProjectsTest.java | 16 +- .../ui/includebrowser/IBContentProvider.java | 27 +- .../cdt/internal/ui/viewsupport/IndexUI.java | 18 +- 75 files changed, 2155 insertions(+), 2457 deletions(-) delete mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexBasedCodeReaderFactory.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerFallbackReaderFactory.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerInputAdapter.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/ASTFilePathResolver.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerInputAdapter.java rename core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/{indexer => }/IndexerStatistics.java (94%) rename core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/{fast => }/PDOMFastIndexer.java (71%) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFastIndexerTask.java rename core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/{full => }/PDOMFullIndexer.java (84%) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFullIndexerTask.java rename core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/{nulli => }/PDOMNullIndexer.java (79%) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java delete mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerTask.java delete mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerTask.java diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/pdomdepgen/PDOMDependencyCalculator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/pdomdepgen/PDOMDependencyCalculator.java index 26dadfca0e2..b12d8ea2789 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/pdomdepgen/PDOMDependencyCalculator.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/pdomdepgen/PDOMDependencyCalculator.java @@ -8,6 +8,7 @@ * Contributors: * QNX Software Systems - Initial API and implementation * Anton Leherbauer (Wind River Systems) + * Markus Schorn (Wind River Systems) **********************************************************************/ package org.eclipse.cdt.managedbuilder.pdomdepgen; @@ -63,9 +64,9 @@ public class PDOMDependencyCalculator implements IManagedDependencyCalculator { IIndex index = CCorePlugin.getIndexManager().getIndex(project, IIndexManager.ADD_DEPENDENCIES); index.acquireReadLock(); try { - IIndexFile file = index.getFile(IndexLocationFactory.getWorkspaceIFL((IFile)resource)); - if (file != null) { - IIndexInclude[] includes = index.findIncludes(file, IIndex.DEPTH_INFINITE); + IIndexFile[] files = index.getFiles(IndexLocationFactory.getWorkspaceIFL((IFile)resource)); + if (files.length > 0) { + IIndexInclude[] includes = index.findIncludes(files[0], IIndex.DEPTH_INFINITE); List/**/ list = new ArrayList/**/(); for (int i = 0; i < includes.length; ++i) { diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/InclusionTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/InclusionTests.java index b38c54857aa..6c3b2c3f5f3 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/InclusionTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/InclusionTests.java @@ -25,7 +25,7 @@ import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.ScannerInfo; import org.eclipse.cdt.core.testplugin.CProjectHelper; import org.eclipse.cdt.core.testplugin.util.TestSourceReader; -import org.eclipse.cdt.internal.core.pdom.indexer.nulli.PDOMNullIndexer; +import org.eclipse.cdt.internal.core.pdom.indexer.PDOMNullIndexer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.runtime.NullProgressMonitor; diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java index ba13a86fded..25613ef55d6 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java @@ -80,11 +80,16 @@ public class EmptyIndexFragment implements IIndexFragment { return 0; } - public IIndexFragmentFile getFile(IIndexFileLocation location) + public IIndexFragmentFile getFile(int linkageID, IIndexFileLocation location) throws CoreException { return null; } + + public IIndexFragmentFile[] getFiles(IIndexFileLocation location) throws CoreException { + return new IIndexFragmentFile[0]; + } + public long getLastWriteAccess() { return 0; } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java index 7a52e5dc6c0..b839174f036 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java @@ -304,7 +304,7 @@ public class IndexBugsTests extends BaseTestCase { fIndex.acquireReadLock(); try { - IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(file)); + IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file)); assertNotNull(ifile); IIndexInclude[] includes= ifile.getIncludes(); assertEquals(1, includes.length); @@ -329,7 +329,7 @@ public class IndexBugsTests extends BaseTestCase { fIndex.acquireReadLock(); try { - IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(file)); + IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file)); assertNotNull(ifile); IIndexInclude[] includes= ifile.getIncludes(); assertEquals(1, includes.length); @@ -355,7 +355,7 @@ public class IndexBugsTests extends BaseTestCase { fIndex.acquireReadLock(); try { - IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(file)); + IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file)); assertNotNull(ifile); IIndexInclude[] includes= ifile.getIncludes(); assertEquals(1, includes.length); @@ -381,7 +381,7 @@ public class IndexBugsTests extends BaseTestCase { fIndex.acquireReadLock(); try { - IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(file)); + IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file)); assertNotNull(ifile); IIndexInclude[] includes= ifile.getIncludes(); assertEquals(1, includes.length); @@ -412,7 +412,7 @@ public class IndexBugsTests extends BaseTestCase { fIndex.acquireReadLock(); try { - IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(file)); + IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file)); assertNotNull(ifile); IIndexMacro[] macros= ifile.getMacros(); assertEquals(2, macros.length); @@ -826,7 +826,7 @@ public class IndexBugsTests extends BaseTestCase { assertEquals(1, names.length); assertEquals(f4.getFullPath().toString(), names[0].getFile().getLocation().getFullPath()); - IIndexFile idxFile= index.getFile(IndexLocationFactory.getWorkspaceIFL(f5)); + IIndexFile idxFile= index.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(f5)); IIndexInclude[] includes= idxFile.getIncludes(); assertEquals(2, includes.length); assertTrue(includes[0].isActive()); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexIncludeTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexIncludeTest.java index 081239b8954..939d4ef65db 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexIncludeTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexIncludeTest.java @@ -17,6 +17,7 @@ import java.util.regex.Pattern; import junit.framework.TestSuite; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.IPDOMManager; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IVariable; @@ -134,7 +135,7 @@ public class IndexIncludeTest extends IndexTestBase { TestSourceReader.waitUntilFileIsIndexed(fIndex, file, 4000); fIndex.acquireReadLock(); try { - IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(file)); + IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file)); assertNotNull("Can't find " + file.getLocation(), ifile); assertTrue("timestamp not ok", ifile.getTimestamp() >= timestamp); @@ -163,7 +164,7 @@ public class IndexIncludeTest extends IndexTestBase { fIndex.acquireReadLock(); try { - IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(file)); + IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file)); assertNotNull(ifile); IIndexInclude[] includes= ifile.getIncludes(); assertEquals(2, includes.length); @@ -188,7 +189,7 @@ public class IndexIncludeTest extends IndexTestBase { fIndex.acquireReadLock(); try { - IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(file)); + IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file)); assertNotNull(ifile); IIndexInclude[] includes= ifile.getIncludes(); assertEquals(1, includes.length); @@ -209,7 +210,7 @@ public class IndexIncludeTest extends IndexTestBase { fIndex.acquireReadLock(); try { - IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(file)); + IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file)); assertNotNull(ifile); IIndexInclude[] includes= ifile.getIncludes(); assertEquals(1, includes.length); @@ -231,7 +232,7 @@ public class IndexIncludeTest extends IndexTestBase { fIndex.acquireReadLock(); try { - IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(file)); + IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file)); assertNotNull(ifile); IIndexInclude[] includes= ifile.getIncludes(); assertEquals(1, includes.length); @@ -311,16 +312,17 @@ public class IndexIncludeTest extends IndexTestBase { fIndex.acquireReadLock(); try { - IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(header)); + IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(header)); assertNotNull(ifile); IIndexInclude[] includes= fIndex.findIncludedBy(ifile); assertEquals(2, includes.length); - assertEquals(s1.getFullPath().toString(), includes[0].getIncludedByLocation().getFullPath()); - assertEquals(s2.getFullPath().toString(), includes[1].getIncludedByLocation().getFullPath()); IIndexInclude context= ifile.getParsedInContext(); assertNotNull(context); assertEquals(s1.getFullPath().toString(), context.getIncludedByLocation().getFullPath()); + + assertEquals(s1.getFullPath().toString(), includes[0].getIncludedByLocation().getFullPath()); + assertEquals(s2.getFullPath().toString(), includes[1].getIncludedByLocation().getFullPath()); } finally { fIndex.releaseReadLock(); @@ -331,7 +333,7 @@ public class IndexIncludeTest extends IndexTestBase { fIndex.acquireReadLock(); try { assertEquals(1, fIndex.findBindings("a20070426".toCharArray(), IndexFilter.ALL_DECLARED, NPM).length); - IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(header)); + IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(header)); assertNotNull(ifile); IIndexInclude[] includes= fIndex.findIncludedBy(ifile); assertEquals(2, includes.length); @@ -350,7 +352,7 @@ public class IndexIncludeTest extends IndexTestBase { fIndex.acquireReadLock(); try { assertEquals(1, fIndex.findBindings("b20070426".toCharArray(), IndexFilter.ALL_DECLARED, NPM).length); - IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(header)); + IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(header)); assertNotNull(ifile); IIndexInclude[] includes= fIndex.findIncludedBy(ifile); assertEquals(2, includes.length); @@ -435,8 +437,8 @@ public class IndexIncludeTest extends IndexTestBase { try { assertEquals(1, fIndex.findBindings(tag.toCharArray(), IndexFilter.ALL_DECLARED, NPM).length); - IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(header)); - IIndexFile sfile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(s1)); + IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(header)); + IIndexFile sfile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(s1)); assertNotNull(ifile); IIndexInclude[] includes= fIndex.findIncludedBy(ifile); assertEquals(1, includes.length); @@ -477,8 +479,8 @@ public class IndexIncludeTest extends IndexTestBase { try { assertEquals(1, fIndex.findBindings(tag.toCharArray(), IndexFilter.ALL_DECLARED, NPM).length); - IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(header)); - IIndexFile sfile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(s1)); + IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(header)); + IIndexFile sfile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(s1)); assertNotNull(ifile); IIndexInclude[] includes= fIndex.findIncludedBy(ifile); assertEquals(0, includes.length); @@ -509,8 +511,8 @@ public class IndexIncludeTest extends IndexTestBase { try { assertEquals(1, fIndex.findBindings(tag.toCharArray(), IndexFilter.ALL_DECLARED, NPM).length); - IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(header)); - IIndexFile sfile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(s1)); + IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(header)); + IIndexFile sfile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(s1)); assertNotNull(ifile); IIndexInclude[] includes= fIndex.findIncludedBy(ifile); assertEquals(1, includes.length); @@ -545,8 +547,8 @@ public class IndexIncludeTest extends IndexTestBase { try { assertEquals(1, fIndex.findBindings(tag.toCharArray(), IndexFilter.ALL_DECLARED, NPM).length); - IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(header)); - IIndexFile sfile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(s1)); + IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(header)); + IIndexFile sfile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(s1)); assertNotNull(ifile); IIndexInclude[] includes= fIndex.findIncludedBy(ifile); assertEquals(1, includes.length); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/DefDeclTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/DefDeclTests.java index 49653ab3402..51f7744354a 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/DefDeclTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/DefDeclTests.java @@ -17,6 +17,7 @@ import java.util.regex.Pattern; import junit.framework.AssertionFailedError; import junit.framework.Test; +import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IBinding; @@ -218,7 +219,7 @@ public class DefDeclTests extends PDOMTestBase { String elName = "foo" + "08"; IIndexFileLocation ifl= IndexLocationFactory.getIFL((ITranslationUnit) cproject.findElement(new Path("func.c"))); - IIndexFile file= pdom.getFile(ifl); + IIndexFile file= pdom.getFile(ILinkage.C_LINKAGE_ID, ifl); int offset= TestSourceReader.indexOfInFile("foo08();", new Path(ifl.getFullPath())); IIndexName[] names= file.findNames(offset, 5); assertEquals(1, names.length); @@ -230,7 +231,7 @@ public class DefDeclTests extends PDOMTestBase { // check the other file ifl= IndexLocationFactory.getIFL((ITranslationUnit) cproject.findElement(new Path("second.c"))); - file= pdom.getFile(ifl); + file= pdom.getFile(ILinkage.C_LINKAGE_ID, ifl); offset= TestSourceReader.indexOfInFile("foo08();", new Path(ifl.getFullPath())); names= file.findNames(offset, 5); assertEquals(1, names.length); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/FilesOnReindexTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/FilesOnReindexTests.java index edcbe635f7a..7cf506ad56a 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/FilesOnReindexTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/FilesOnReindexTests.java @@ -15,6 +15,7 @@ import java.util.regex.Pattern; import junit.framework.Test; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexBinding; @@ -69,7 +70,7 @@ public class FilesOnReindexTests extends PDOMTestBase { void performAssertions(IFile file) throws CoreException { IIndex index = CCorePlugin.getIndexManager().getIndex(project); - assertNotNull(index.getFile(IndexLocationFactory.getWorkspaceIFL(file))); + assertNotNull(index.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file))); IBinding[] bs = index.findBindings(Pattern.compile("C"), true, IndexFilter.ALL, new NullProgressMonitor()); assertEquals(1, bs.length); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/IncludesTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/IncludesTests.java index 5fc875ea8b0..817bbcb7821 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/IncludesTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/IncludesTests.java @@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.pdom.tests; import junit.framework.Test; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexFile; import org.eclipse.cdt.core.index.IIndexInclude; @@ -48,7 +49,7 @@ public class IncludesTests extends PDOMTestBase { public void testIncludedBy() throws Exception { IResource loc = project.getProject().findMember("I2.h"); - IIndexFile file = index.getFile(IndexLocationFactory.getWorkspaceIFL((IFile)loc)); + IIndexFile file = index.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL((IFile)loc)); assertNotNull(file); IIndexInclude[] allIncludedBy = index.findIncludedBy(file, -1); assertEquals(9, allIncludedBy.length); // i.e. all of them @@ -56,7 +57,7 @@ public class IncludesTests extends PDOMTestBase { public void testIncludes() throws Exception { IResource loc = project.getProject().findMember("I1.cpp"); - IIndexFile file = index.getFile(IndexLocationFactory.getWorkspaceIFL((IFile)loc)); + IIndexFile file = index.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL((IFile)loc)); assertNotNull(file); IIndexInclude[] allIncludesTo= index.findIncludes(file, -1); assertEquals(2, allIncludesTo.length); // i.e. I1.h, I2.h diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/TestSourceReader.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/TestSourceReader.java index a0ec54a8ee7..913fc570a16 100644 --- a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/TestSourceReader.java +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/TestSourceReader.java @@ -27,6 +27,7 @@ import junit.framework.Assert; import junit.framework.TestCase; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexFile; @@ -285,7 +286,11 @@ public class TestSourceReader { Assert.assertTrue(CCorePlugin.getIndexManager().joinIndexer(timeLeft, new NullProgressMonitor())); index.acquireReadLock(); try { - IIndexFile pfile= index.getFile(IndexLocationFactory.getWorkspaceIFL(file)); + IIndexFile pfile= index.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file)); + if (pfile != null && pfile.getTimestamp() >= file.getLocalTimeStamp()) { + return; + } + pfile= index.getFile(ILinkage.C_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file)); if (pfile != null && pfile.getTimestamp() >= file.getLocalTimeStamp()) { return; } diff --git a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF index 5a343694fd9..d4d49f138cd 100644 --- a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF +++ b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF @@ -64,9 +64,6 @@ Export-Package: org.eclipse.cdt.core, org.eclipse.cdt.internal.core.pdom.dom.cpp;x-internal:=true, org.eclipse.cdt.internal.core.pdom.export, org.eclipse.cdt.internal.core.pdom.indexer;x-friends:="org.eclipse.cdt.ui", - org.eclipse.cdt.internal.core.pdom.indexer.fast;x-internal:=true, - org.eclipse.cdt.internal.core.pdom.indexer.full;x-internal:=true, - org.eclipse.cdt.internal.core.pdom.indexer.nulli;x-internal:=true, org.eclipse.cdt.internal.core.util;x-internal:=true, org.eclipse.cdt.internal.errorparsers;x-internal:=true, org.eclipse.cdt.internal.formatter;x-internal:=true, diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/AssemblyLanguage.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/AssemblyLanguage.java index a413edb2123..d6a34663eed 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/AssemblyLanguage.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/AssemblyLanguage.java @@ -14,6 +14,7 @@ import java.util.Set; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ICodeReaderFactory; +import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.IASTCompletionNode; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; @@ -151,4 +152,7 @@ public class AssemblyLanguage extends AbstractLanguage implements IAsmLanguage, fId= CCorePlugin.PLUGIN_ID + '.' + config.getAttribute("id"); //$NON-NLS-1$ } + public int getLinkageID() { + return ILinkage.NO_LINKAGE_ID; + } } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ILanguage.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ILanguage.java index bd4f90f706a..811d8f00bac 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ILanguage.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ILanguage.java @@ -6,14 +6,15 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * QNX - Initial API and implementation - * Markus Schorn (Wind River Systems) - * IBM Corporation + * QNX - Initial API and implementation + * Markus Schorn (Wind River Systems) + * IBM Corporation *******************************************************************************/ package org.eclipse.cdt.core.model; import org.eclipse.cdt.core.dom.ICodeReaderFactory; +import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.IASTCompletionNode; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; @@ -25,7 +26,7 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; /** - * Models differences between languages. The interace is not supposed to be implemented directly. + * Models differences between languages. The interface is not supposed to be implemented directly. * Rather than that clients may subclass {@link AbstractLanguage}. * @author Doug Schaefer */ @@ -34,34 +35,20 @@ public interface ILanguage extends IAdaptable { //public static final QualifiedName KEY = new QualifiedName(CCorePlugin.PLUGIN_ID, "language"); //$NON-NLS-1$ public static final String KEY = "language"; //$NON-NLS-1$ - /** - * @deprecated has no effect. - */ - public static final int AST_USE_INDEX = 1; - - /** - * @deprecated use {@link ITranslationUnit#AST_SKIP_ALL_HEADERS} - */ - public static final int AST_SKIP_ALL_HEADERS = ITranslationUnit.AST_SKIP_ALL_HEADERS; - - /** - * @deprecated use {@link ITranslationUnit#AST_SKIP_INDEXED_HEADERS} - */ - public static final int AST_SKIP_INDEXED_HEADERS = ITranslationUnit.AST_SKIP_INDEXED_HEADERS; - - /** - * @deprecated use {@link ITranslationUnit#AST_SKIP_IF_NO_BUILD_INFO} - */ - public static final int AST_SKIP_IF_NO_BUILD_INFO = ITranslationUnit.AST_SKIP_IF_NO_BUILD_INFO; - /** * Return the language id for this language. - * This is to differentiate languages from eachother. - * - * @return language id + * This is to differentiate languages from each other. */ public String getId(); + /** + * Return the id of the linkage this language contributes to. This is especially important + * for languages that write to the index. + * @see ILinkage + * @since 5.0 + */ + public int getLinkageID(); + /** * @return the human readable name corresponding to this language, suitable for display. * @since 4.0 diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/LanguageManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/LanguageManager.java index 5a9f140b9a7..e7437257793 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/LanguageManager.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/LanguageManager.java @@ -24,6 +24,7 @@ import java.util.Map; import java.util.Set; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.language.ProjectLanguageConfiguration; import org.eclipse.cdt.core.language.WorkspaceLanguageConfiguration; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; @@ -195,7 +196,7 @@ public class LanguageManager { return getLanguageForContentTypeID(contentTypeID); } - private ILanguage getLanguageForContentTypeID(String contentTypeID) { + public ILanguage getLanguageForContentTypeID(String contentTypeID) { cacheAllLanguages(); ILanguage language = (ILanguage)fContentTypeToLanguageCache.get(contentTypeID); diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java index 5158443d028..716d3c60777 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java @@ -25,10 +25,12 @@ import java.util.Map; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ICodeReaderFactory; +import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.IASTCompletionNode; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexFile; +import org.eclipse.cdt.core.index.IIndexFileLocation; import org.eclipse.cdt.core.index.IIndexInclude; import org.eclipse.cdt.core.index.IndexLocationFactory; import org.eclipse.cdt.core.model.AbstractLanguage; @@ -60,6 +62,7 @@ import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.internal.core.dom.NullCodeReaderFactory; import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory; import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory; +import org.eclipse.cdt.internal.core.pdom.indexer.ProjectIndexerInputAdapter; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -742,16 +745,6 @@ public class TranslationUnit extends Openable implements ITranslationUnit { } public IASTTranslationUnit getAST(IIndex index, int style) throws CoreException { - ICodeReaderFactory codeReaderFactory; - if ((style & AST_SKIP_NONINDEXED_HEADERS) != 0) { - codeReaderFactory= NullCodeReaderFactory.getInstance(); - } else { - codeReaderFactory= SavedCodeReaderFactory.getInstance(); - } - if (index != null && (style & AST_SKIP_INDEXED_HEADERS) != 0) { - codeReaderFactory= new IndexBasedCodeReaderFactory(getCProject(), index, codeReaderFactory); - } - ITranslationUnit configureWith = getSourceContextTU(index, style); IScannerInfo scanInfo= configureWith.getScannerInfo( (style & AST_SKIP_IF_NO_BUILD_INFO) == 0); @@ -766,6 +759,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit { ILanguage language= configureWith.getLanguage(); fLanguageOfContext= language; if (language != null) { + ICodeReaderFactory crf= getCodeReaderFactory(style, index, language.getLinkageID()); IASTTranslationUnit ast= null; if (language instanceof AbstractLanguage) { int options= 0; @@ -775,10 +769,10 @@ public class TranslationUnit extends Openable implements ITranslationUnit { if ((style & AST_CREATE_COMMENT_NODES) != 0) { options |= AbstractLanguage.OPTION_ADD_COMMENTS; } - ast= ((AbstractLanguage)language).getASTTranslationUnit(reader, scanInfo, codeReaderFactory, index, options, ParserUtil.getParserLogService()); + ast= ((AbstractLanguage)language).getASTTranslationUnit(reader, scanInfo, crf, index, options, ParserUtil.getParserLogService()); } else { - ast= language.getASTTranslationUnit(reader, scanInfo, codeReaderFactory, index, ParserUtil.getParserLogService()); + ast= language.getASTTranslationUnit(reader, scanInfo, crf, index, ParserUtil.getParserLogService()); } if (ast != null) { ast.setIsHeaderUnit(isHeaderUnit()); @@ -789,27 +783,46 @@ public class TranslationUnit extends Openable implements ITranslationUnit { return null; } + private ICodeReaderFactory getCodeReaderFactory(int style, IIndex index, int linkageID) { + ICodeReaderFactory codeReaderFactory; + if ((style & AST_SKIP_NONINDEXED_HEADERS) != 0) { + codeReaderFactory= NullCodeReaderFactory.getInstance(); + } else { + codeReaderFactory= SavedCodeReaderFactory.getInstance(); + } + + if (index != null && (style & AST_SKIP_INDEXED_HEADERS) != 0) { + IndexBasedCodeReaderFactory ibcf= new IndexBasedCodeReaderFactory(index, new ProjectIndexerInputAdapter(getCProject()), linkageID, codeReaderFactory); + codeReaderFactory= ibcf; + } + + return codeReaderFactory; + } + + private static int[] CTX_LINKAGES= {ILinkage.CPP_LINKAGE_ID, ILinkage.C_LINKAGE_ID}; private ITranslationUnit getSourceContextTU(IIndex index, int style) { - ITranslationUnit configureWith= this; if (index != null && (style & AST_CONFIGURE_USING_SOURCE_CONTEXT) != 0) { try { fLanguageOfContext= null; - IIndexFile context= null; - IIndexFile indexFile= index.getFile(IndexLocationFactory.getIFL(this)); - if (indexFile != null) { - // bug 199412, when a source-file includes itself the context may recurse. - HashSet visited= new HashSet(); - visited.add(indexFile); - indexFile = getParsedInContext(indexFile); - while (indexFile != null && visited.add(indexFile)) { - context= indexFile; - indexFile= getParsedInContext(indexFile); + for (int i = 0; i < CTX_LINKAGES.length; i++) { + IIndexFile context= null; + final IIndexFileLocation ifl = IndexLocationFactory.getIFL(this); + IIndexFile indexFile= index.getFile(CTX_LINKAGES[i], ifl); + if (indexFile != null) { + // bug 199412, when a source-file includes itself the context may recurse. + HashSet visited= new HashSet(); + visited.add(indexFile); + indexFile = getParsedInContext(indexFile); + while (indexFile != null && visited.add(indexFile)) { + context= indexFile; + indexFile= getParsedInContext(indexFile); + } } - } - if (context != null) { - ITranslationUnit tu= CoreModelUtil.findTranslationUnitForLocation(context.getLocation(), getCProject()); - if (tu != null && tu.isSourceUnit()) { - configureWith= tu; + if (context != null) { + ITranslationUnit tu= CoreModelUtil.findTranslationUnitForLocation(context.getLocation(), getCProject()); + if (tu != null && tu.isSourceUnit()) { + return tu; + } } } } @@ -817,7 +830,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit { CCorePlugin.log(e); } } - return configureWith; + return this; } private IIndexFile getParsedInContext(IIndexFile indexFile) @@ -830,20 +843,6 @@ public class TranslationUnit extends Openable implements ITranslationUnit { } public IASTCompletionNode getCompletionNode(IIndex index, int style, int offset) throws CoreException { - ICodeReaderFactory codeReaderFactory; - if (index != null && (style & (ITranslationUnit.AST_SKIP_INDEXED_HEADERS | ITranslationUnit.AST_SKIP_ALL_HEADERS)) != 0) { - ICodeReaderFactory fallbackFactory; - if ((style & ITranslationUnit.AST_SKIP_ALL_HEADERS) != 0) { - fallbackFactory= NullCodeReaderFactory.getInstance(); - } else { - fallbackFactory= SavedCodeReaderFactory.getInstance(); - } - codeReaderFactory= new IndexBasedCodeReaderFactory(getCProject(), index, fallbackFactory); - } - else { - codeReaderFactory = SavedCodeReaderFactory.getInstance(); - } - ITranslationUnit configureWith= getSourceContextTU(index, style); IScannerInfo scanInfo = configureWith.getScannerInfo( (style & ITranslationUnit.AST_SKIP_IF_NO_BUILD_INFO) == 0); @@ -857,7 +856,8 @@ public class TranslationUnit extends Openable implements ITranslationUnit { ILanguage language= configureWith.getLanguage(); fLanguageOfContext= language; if (language != null) { - return language.getCompletionNode(reader, scanInfo, codeReaderFactory, index, ParserUtil.getParserLogService(), offset); + ICodeReaderFactory crf= getCodeReaderFactory(style, index, language.getLinkageID()); + return language.getCompletionNode(reader, scanInfo, crf, index, ParserUtil.getParserLogService(), offset); } return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ILinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ILinkage.java index 1343a83b6a1..fb36bf3901a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ILinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ILinkage.java @@ -28,9 +28,11 @@ public interface ILinkage { final static String FORTRAN_LINKAGE_NAME= "Fortran"; //$NON-NLS-1$ final static int NO_LINKAGE_ID= 0; - final static int C_LINKAGE_ID= 1; - final static int CPP_LINKAGE_ID= 2; + final static int CPP_LINKAGE_ID= 1; + final static int C_LINKAGE_ID= 2; final static int FORTRAN_LINKAGE_ID= 3; + + final static int MAX_LINKAGE_ID= FORTRAN_LINKAGE_ID; /** * Returns the name of the linkage. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOMIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOMIndexerTask.java index baab9c1b003..9523c760233 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOMIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOMIndexerTask.java @@ -9,9 +9,6 @@ * QNX Software Systems - initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ -/** - * - */ package org.eclipse.cdt.core.dom; import org.eclipse.cdt.core.CCorePlugin; @@ -31,7 +28,7 @@ public interface IPDOMIndexerTask { /** * Called by the framework to perform the task. */ - public void run(IProgressMonitor monitor); + public void run(IProgressMonitor monitor) throws InterruptedException; /** * Returns the indexer the task belongs to. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java index 48f4350e492..f1bf50b6337 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java @@ -6,15 +6,16 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * QNX - Initial API and implementation - * Markus Schorn (Wind River Systems) - * IBM Corporation - * Anton Leherbauer (Wind River Systems) + * QNX - Initial API and implementation + * Markus Schorn (Wind River Systems) + * IBM Corporation + * Anton Leherbauer (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.core.dom.ast.gnu.c; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.parser.IScannerExtensionConfiguration; import org.eclipse.cdt.core.dom.parser.c.AbstractCLanguage; import org.eclipse.cdt.core.dom.parser.c.GCCParserExtensionConfiguration; @@ -42,6 +43,10 @@ public class GCCLanguage extends AbstractCLanguage { return ID; } + public int getLinkageID() { + return ILinkage.C_LINKAGE_ID; + } + /* * @see org.eclipse.cdt.core.dom.parser.c.AbstractCLanguage#getScannerExtensionConfiguration() */ 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 291a52fcf2c..63bfe2193ff 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 @@ -6,14 +6,15 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * QNX - Initial API and implementation - * Markus Schorn (Wind River Systems) - * IBM Corporation - * Anton Leherbauer (Wind River Systems) + * QNX - Initial API and implementation + * Markus Schorn (Wind River Systems) + * IBM Corporation + * Anton Leherbauer (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.core.dom.ast.gnu.cpp; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.parser.IScannerExtensionConfiguration; import org.eclipse.cdt.core.dom.parser.cpp.AbstractCPPLanguage; import org.eclipse.cdt.core.dom.parser.cpp.AbstractCPPParserExtensionConfiguration; @@ -40,6 +41,11 @@ public class GPPLanguage extends AbstractCPPLanguage { return ID; } + + public int getLinkageID() { + return ILinkage.CPP_LINKAGE_ID; + } + /* * @see org.eclipse.cdt.core.dom.parser.cpp.AbstractCPPLanguage#getScannerExtensionConfiguration() */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java index 9b2be5a4914..d11be371cbe 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java @@ -132,13 +132,21 @@ public interface IIndex { public long getLastWriteAccess(); /** - * Looks for a file with the given location. Will return null if there - * is no entry in the index for the given location. + * Returns the file-object for the given location and linkage or returns + * null if the file was not indexed in this linkage. * @param location an IIndexFileLocation representing the location of the file * @return the file in the index or null * @throws CoreException */ - public IIndexFile getFile(IIndexFileLocation location) throws CoreException; + public IIndexFile getFile(int linkageID, IIndexFileLocation location) throws CoreException; + + /** + * Returns the file-objects for the given location in any linkage. + * @param location an IIndexFileLocation representing the location of the file + * @return an array of file-objects. + * @throws CoreException + */ + public IIndexFile[] getFiles(IIndexFileLocation location) throws CoreException; /** * Looks for include relations originated by the given file. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexFile.java index d6800c94e45..be6ace5dd32 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexFile.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexFile.java @@ -30,6 +30,8 @@ import org.eclipse.core.runtime.CoreException; * @since 4.0 */ public interface IIndexFile { + IIndexFile[] EMPTY_FILE_ARRAY = {}; + /** * Returns an IIndexFileLocation representing the location of this file * @return an IIndexFileLocation representing the location of this file @@ -59,9 +61,9 @@ public interface IIndexFile { long getTimestamp() throws CoreException; /** - * Returns the hashcode of the scanner configuration that was used to parse the file. - * 0 will be returned in case the hashcode is unknown. - * @return the hashcode of the scanner configuration or 0. + * Returns the hash-code of the scanner configuration that was used to parse the file. + * 0 will be returned in case the hash-code is unknown. + * @return the hash-code of the scanner configuration or 0. * @throws CoreException */ int getScannerConfigurationHashcode() throws CoreException; @@ -75,5 +77,10 @@ public interface IIndexFile { * Returns the include that was used to parse this file, may be null. */ IIndexInclude getParsedInContext() throws CoreException; - + + /** + * Returns the id of the linkage this file was parsed in. + * @since 5.0 + */ + int getLinkageID() throws CoreException; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java index 9b7b0cdd548..5be4a64fb59 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java @@ -16,6 +16,7 @@ package org.eclipse.cdt.internal.core.index; import java.util.ArrayList; import java.util.Arrays; +import java.util.BitSet; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -158,19 +159,34 @@ public class CIndex implements IIndex { return findNames(binding, FIND_REFERENCES); } - public IIndexFile getFile(IIndexFileLocation location) throws CoreException { - IIndexFile result= null, backup= null; - for (int i = 0; result==null && i < fPrimaryFragmentCount; i++) { - IIndexFragmentFile candidate= fFragments[i].getFile(location); - if(candidate!=null) { - if(candidate.hasNames()) { - result = candidate; - } - if(backup==null) - backup = candidate; + public IIndexFile getFile(int linkageID, IIndexFileLocation location) throws CoreException { + for (int i = 0; i < fPrimaryFragmentCount; i++) { + IIndexFragmentFile candidate= fFragments[i].getFile(linkageID, location); + if (candidate!=null && candidate.hasContent()) { + return candidate; } } - return result == null ? backup : result; + return null; + } + + public IIndexFile[] getFiles(IIndexFileLocation location) throws CoreException { + ArrayList result= new ArrayList(); + BitSet linkages= new BitSet(); + for (int i = 0; i < fPrimaryFragmentCount; i++) { + IIndexFragmentFile[] candidates= fFragments[i].getFiles(location); + for (int j = 0; j < candidates.length; j++) { + IIndexFragmentFile candidate= candidates[j]; + int linkage= candidate.getLinkageID(); + if (!linkages.get(linkage) && candidate.hasContent()) { + result.add(candidate); + linkages.set(linkage); + } + } + } + if (result.isEmpty()) { + return IIndexFile.EMPTY_FILE_ARRAY; + } + return (IIndexFile[]) result.toArray(new IIndexFile[result.size()]); } public IIndexFile resolveInclude(IIndexInclude include) throws CoreException { @@ -179,11 +195,11 @@ public class CIndex implements IIndex { } IIndexFragmentInclude fragmentInclude = (IIndexFragmentInclude) include; IIndexFragmentFile result= fragmentInclude.getIncludes(); - if (result != null && result.hasNames()) { + if (result != null && result.hasContent()) { return result; } - return getFile(include.getIncludesLocation()); + return getFile(include.getIncludedBy().getLinkageID(), include.getIncludesLocation()); } public IIndexInclude[] findIncludedBy(IIndexFile file) throws CoreException { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java index cc4d17df512..2618be1045b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java @@ -50,9 +50,13 @@ final public class EmptyCIndex implements IIndex { return IIndexFragmentName.EMPTY_NAME_ARRAY; } - public IIndexFile getFile(IIndexFileLocation location) { + public IIndexFile getFile(int linkageID, IIndexFileLocation location) { return null; } + + public IIndexFile[] getFiles(IIndexFileLocation location) { + return IIndexFile.EMPTY_FILE_ARRAY; + } public IIndexFile resolveInclude(IIndexInclude include) { return null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java index 18091a19250..29c0c164cab 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java @@ -80,13 +80,25 @@ public interface IIndexFragment { public static final String PROPERTY_FRAGMENT_FORMAT_VERSION= "org.eclipse.cdt.internal.core.index.fragment.format.version"; //$NON-NLS-1$ /** - * Returns the file for the given location. May return null, if no such file exists. + * Returns the file for the given location and linkage. + * May return null, if no such file exists. + * This method may only return files that are actually managed by this fragment. + * This method returns files without content, also. + * @param linkageID the id of the linkage in which the file has been parsed. + * @param location the IIndexFileLocation representing the location of the file + * @return the file for the location, or null if the file is not present in the index + * @throws CoreException + */ + IIndexFragmentFile getFile(int linkageID, IIndexFileLocation location) throws CoreException; + + /** + * Returns the files in all linkages for the given location. * This method may only return files that are actually managed by this fragment. * @param location the IIndexFileLocation representing the location of the file * @return the file for the location, or null if the file is not present in the index * @throws CoreException */ - IIndexFragmentFile getFile(IIndexFileLocation location) throws CoreException; + IIndexFragmentFile[] getFiles(IIndexFileLocation location) throws CoreException; /** * Returns all include directives that point to the given file. The input file may belong to diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java index a6f4f575c1a..b6979bd13a3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFile.java @@ -16,6 +16,7 @@ import org.eclipse.cdt.core.index.IIndexFile; import org.eclipse.core.runtime.CoreException; public interface IIndexFragmentFile extends IIndexFile { + IIndexFragmentFile[] EMPTY_ARRAY = {}; /** * Returns the fragment that owns this file. @@ -24,23 +25,24 @@ public interface IIndexFragmentFile extends IIndexFile { /** * Sets the timestamp of the file - * @throws CoreException */ void setTimestamp(long timestamp) throws CoreException; /** - * Sets the hashcode of the scanner configuration. - * @param hashcode a hashcode or 0 if it is unknown. + * Sets the hash-code of the scanner configuration. + * @param hashcode a hash-code or 0 if it is unknown. * @throws CoreException */ void setScannerConfigurationHashcode(int hashcode) throws CoreException; /** - * Returns whether any names are associated with this file object - * in this fragment - i.e. whether this file contains content in its - * associated fragment - * @return whether any names are associated with this file object - * in this fragment + * Returns whether this file contains content in its + * associated fragment. Files without content are inserted to track includes. */ - boolean hasNames() throws CoreException; + boolean hasContent() throws CoreException; + + /** + * Returns the id of the linkage this file belongs to. + */ + int getLinkageID() throws CoreException; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndex.java index adcd7f76c82..25e687427f6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndex.java @@ -18,6 +18,7 @@ import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; import org.eclipse.cdt.core.index.IIndex; +import org.eclipse.cdt.core.index.IIndexFile; import org.eclipse.cdt.core.index.IIndexFileLocation; import org.eclipse.core.runtime.CoreException; @@ -38,12 +39,19 @@ public interface IWritableIndex extends IIndex { /** * Checks whether the given file can be written to in this index. */ - boolean isWritableFile(IIndexFragmentFile file); + boolean isWritableFile(IIndexFile file); /** - * Returns a writable file for the given location, or null. + * Returns a writable file for the given location and linkage, or null. This method + * returns file-objects without content, also. */ - IIndexFragmentFile getWritableFile(IIndexFileLocation location) throws CoreException; + IIndexFragmentFile getWritableFile(int linkageID, IIndexFileLocation location) throws CoreException; + + /** + * Returns the writable files for the given location in any linkage. This method + * returns file-objects without content, also. + */ + IIndexFragmentFile[] getWritableFiles(IIndexFileLocation location) throws CoreException; /** * Clears the given file in the index. @@ -56,13 +64,13 @@ public interface IWritableIndex extends IIndex { /** * Creates a file object for the given location or returns an existing one. */ - IIndexFragmentFile addFile(IIndexFileLocation fileLocation) throws CoreException; + IIndexFragmentFile addFile(int linkageID, IIndexFileLocation fileLocation) throws CoreException; /** * Adds content to the given file. */ void setFileContent(IIndexFragmentFile sourceFile, - IncludeInformation[] includes, + int linkageID, IncludeInformation[] includes, IASTPreprocessorMacroDefinition[] macros, IASTName[][] names) throws CoreException; /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndexFragment.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndexFragment.java index 3df054c60d1..a64177930f3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndexFragment.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndexFragment.java @@ -39,12 +39,12 @@ public interface IWritableIndexFragment extends IIndexFragment { void clearFile(IIndexFragmentFile file, Collection contextsRemoved) throws CoreException; /** - * Creates a file object for the given location or returns an existing one. + * Creates a file object for the given location and linkage or returns an existing one. * @param fileLocation an IIndexFileLocation representing the location of the file * @return the existing IIndexFragmentFile for this location, or a newly created one * @throws CoreException */ - IIndexFragmentFile addFile(IIndexFileLocation fileLocation) throws CoreException; + IIndexFragmentFile addFile(int linkageID, IIndexFileLocation fileLocation) throws CoreException; /** * Adds an include to the given file. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java index 5abd73481e4..f7b36b2a841 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java @@ -6,22 +6,17 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * QNX - Initial API and implementation - * Markus Schorn (Wind River Systems) - * Andrew Ferguson (Symbian) - * Anton Leherbauer (Wind River Systems) - * IBM Corporation + * QNX - Initial API and implementation + * Markus Schorn (Wind River Systems) + * Andrew Ferguson (Symbian) + * Anton Leherbauer (Wind River Systems) + * IBM Corporation *******************************************************************************/ package org.eclipse.cdt.internal.core.index; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.List; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; @@ -33,93 +28,49 @@ import org.eclipse.cdt.core.index.IIndexFile; import org.eclipse.cdt.core.index.IIndexFileLocation; import org.eclipse.cdt.core.index.IIndexInclude; import org.eclipse.cdt.core.index.IIndexMacro; -import org.eclipse.cdt.core.index.IndexLocationFactory; -import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.ICodeReaderCache; import org.eclipse.cdt.core.parser.IMacro; import org.eclipse.cdt.core.parser.ParserUtil; import org.eclipse.cdt.internal.core.parser.scanner2.IIndexBasedCodeReaderFactory; -import org.eclipse.cdt.internal.core.parser.scanner2.ObjectStyleMacro; +import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver; +import org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask; import org.eclipse.cdt.internal.core.pdom.dom.PDOMMacro; import org.eclipse.core.runtime.CoreException; /** * Code reader factory, that fakes code readers for header files already stored in the * index. - * - *

- * This interface is not intended to be implemented by clients. - *

*/ -public class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderFactory { - public static interface CallbackHandler { - boolean needToUpdate(IndexFileInfo fileInfo) throws CoreException; - } - public static class IndexFileInfo { - public final static int NOT_REQUESTED= 0; - public final static int REQUESTED_IF_CONFIG_CHANGED= 1; - public final static int REQUESTED= 2; - - private IndexFileInfo() {} - private IMacro[] fMacros= null; - - public IIndexFile fFile= null; - public int fRequested= 0; - - public boolean hasCachedMacros() { - return fMacros != null; - } - } - private static class NeedToParseException extends Exception { - private static final long serialVersionUID = 1L; - } - - private final static boolean CASE_SENSITIVE_FILES= !new File("a").equals(new File("A")); //$NON-NLS-1$//$NON-NLS-2$ +public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderFactory { + private static final class NeedToParseException extends Exception {} private final static char[] EMPTY_CHARS = new char[0]; - private final IIndex index; - private Map/**/ fileInfoCache; - private Map/**/ iflCache; - private List usedMacros = new ArrayList(); - private Set/**/ fIncluded= new HashSet(); + private final IIndex fIndex; + private int fLinkage; + private Set fIncludedFiles= new HashSet(); /** The fall-back code reader factory used in case a header file is not indexed */ - private ICodeReaderFactory fFallBackFactory; - private CallbackHandler fCallbackHandler; - private final ICProject cproject; - private final String fProjectPathPrefix; + private final ICodeReaderFactory fFallBackFactory; + private final ASTFilePathResolver fPathResolver; + private final AbstractIndexerTask fRelatedIndexerTask; - public IndexBasedCodeReaderFactory(ICProject cproject, IIndex index) { - this(cproject, index, new HashMap/**/()); + public IndexBasedCodeReaderFactory(IIndex index, ASTFilePathResolver pathResolver, int linkage) { + this(index, pathResolver, linkage, null); } - public IndexBasedCodeReaderFactory(ICProject cproject, IIndex index, ICodeReaderFactory fallbackFactory) { - this(cproject, index, new HashMap/**/(), fallbackFactory); + public IndexBasedCodeReaderFactory(IIndex index, ASTFilePathResolver pathResolver, int linkage, ICodeReaderFactory fallbackFactory) { + this(index, pathResolver, linkage, fallbackFactory, null); } - public IndexBasedCodeReaderFactory(ICProject cproject, IIndex index, Map iflCache) { - this(cproject, index, iflCache, null); + public IndexBasedCodeReaderFactory(IIndex index, ASTFilePathResolver pathResolver, int linkage, + ICodeReaderFactory fallbackFactory, AbstractIndexerTask relatedIndexerTask) { + fIndex= index; + fFallBackFactory= fallbackFactory; + fPathResolver= pathResolver; + fRelatedIndexerTask= relatedIndexerTask; + fLinkage= linkage; } - /** - * @param cproject the ICProject to prefer when resolving external includes to workspace resources (may be null) - * @param index the IIndex that backs this code reader - * @param iflCache - * @param fallbackFactory - */ - public IndexBasedCodeReaderFactory(ICProject cproject, IIndex index, Map iflCache, ICodeReaderFactory fallbackFactory) { - this.cproject= cproject; - this.index = index; - this.fileInfoCache = new HashMap/**/(); - this.iflCache = iflCache; - this.fFallBackFactory= fallbackFactory; - this.fProjectPathPrefix= cproject == null ? null : '/' + cproject.getElementName() + '/'; - } - - final protected Map getIFLCache() { - return iflCache; - } - public int getUniqueIdentifier() { return 0; } @@ -129,185 +80,95 @@ public class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderFactory } public CodeReader createCodeReaderForInclusion(IMacroCollector scanner, String path) { - // if the file is in the index, we skip it - File location= new File(path); - String canonicalPath= path; - if (!location.exists()) { + IIndexFileLocation ifl= fPathResolver.resolveIncludeFile(path); + if (ifl == null) { return null; } - if (!CASE_SENSITIVE_FILES) { - try { - canonicalPath= location.getCanonicalPath(); - } - catch (IOException e) { - // just use the original - } + path= fPathResolver.getASTPath(ifl); + + // include files once, only. + if (!fIncludedFiles.add(ifl)) { + return new CodeReader(path, EMPTY_CHARS); } + try { - IIndexFileLocation incLocation = findLocation(canonicalPath); - IndexFileInfo info= createInfo(incLocation, null); - - if (isIncluded(info)) { - return new CodeReader(canonicalPath, EMPTY_CHARS); - } - - // try to build macro dictionary off index - if (info.fFile != null) { + IIndexFile file= fIndex.getFile(fLinkage, ifl); + if (file != null) { try { - LinkedHashSet infos= new LinkedHashSet(); - getInfosForMacroDictionary(info, infos); - for (Iterator iter = infos.iterator(); iter.hasNext();) { - IndexFileInfo fi = (IndexFileInfo) iter.next(); - if (fi.fMacros == null) { - assert fi.fFile != null; - IIndexMacro[] macros= fi.fFile.getMacros(); - IMacro[] converted= new IMacro[macros.length]; - for (int i = 0; i < macros.length; i++) { - IIndexMacro macro = macros[i]; - converted[i]= ((PDOMMacro)macro).getMacro(); - } - fi.fMacros= converted; + LinkedHashMap macroMap= new LinkedHashMap(); + collectMacros(file, macroMap, false); + for (Iterator iterator = macroMap.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = (Map.Entry) iterator.next(); + IIndexFileLocation includedIFL = (IIndexFileLocation) entry.getKey(); + IMacro[] macros = (IMacro[]) entry.getValue(); + for (int i = 0; i < macros.length; ++i) { + scanner.addDefinition(macros[i]); } - for (int i = 0; i < fi.fMacros.length; ++i) { - scanner.addDefinition(fi.fMacros[i]); - } - // record the macros we used. - usedMacros.add(fi.fMacros); - setIncluded(fi); + fIncludedFiles.add(includedIFL); } - return new CodeReader(canonicalPath, EMPTY_CHARS); - } catch (NeedToParseException e) { + return new CodeReader(path, EMPTY_CHARS); + } + catch (NeedToParseException e) { } } - setIncluded(info); } catch (CoreException e) { CCorePlugin.log(e); - // still try to parse the file. } if (fFallBackFactory != null) { - return fFallBackFactory.createCodeReaderForInclusion(scanner, canonicalPath); + return fFallBackFactory.createCodeReaderForInclusion(scanner, path); } - return ParserUtil.createReader(canonicalPath, null); + return ParserUtil.createReader(path, null); } public boolean hasFileBeenIncludedInCurrentTranslationUnit(String path) { - String canonicalPath= path; - if (!CASE_SENSITIVE_FILES) { - try { - File location= new File(path); - canonicalPath= location.getCanonicalPath(); - } - catch (IOException e) { - // just use the original - } - } - IIndexFileLocation loc= findLocation(canonicalPath); - IndexFileInfo info= (IndexFileInfo) fileInfoCache.get(loc); - if (info != null && isIncluded(info)) { - return true; - } - return false; - } - - /** - * Mark the given inclusion as included. - * @param info - */ - private void setIncluded(IndexFileInfo info) { - fIncluded.add(info); - } - - /** - * Test whether the given inclusion is already included. - * @param info - * @return true if the inclusion is already included. - */ - private boolean isIncluded(IndexFileInfo info) { - return fIncluded.contains(info); - } - - private IndexFileInfo createInfo(IIndexFileLocation location, IIndexFile file) throws CoreException { - IndexFileInfo info= (IndexFileInfo) fileInfoCache.get(location); - if (info == null) { - info= new IndexFileInfo(); - if (file != null) { - info.fFile= file; - } - else { - // bug 205555, in case a file of the project is also part of a read-only pdom, - // we prefer the writable pdom. - final String path= location.getFullPath(); - if (path != null && fProjectPathPrefix != null && - path.startsWith(fProjectPathPrefix) && index instanceof IWritableIndex) { - info.fFile= ((IWritableIndex) index).getWritableFile(location); - } - else { - info.fFile= index.getFile(location); - } - } - fileInfoCache.put(location, info); - } - return info; + IIndexFileLocation ifl= fPathResolver.resolveASTPath(path); + return fIncludedFiles.contains(ifl); } - private void getInfosForMacroDictionary(IndexFileInfo fileInfo, LinkedHashSet/**/ target) throws CoreException, NeedToParseException { - // in case the file is already included, don't load the macros again. - if (isIncluded(fileInfo)) { + private void collectMacros(IIndexFile file, LinkedHashMap macroMap, boolean checkIncluded) throws CoreException, NeedToParseException { + IIndexFileLocation ifl= file.getLocation(); + if (macroMap.containsKey(ifl) || (checkIncluded && fIncludedFiles.contains(ifl))) { return; } - if (!target.add(fileInfo)) { - return; + IMacro[] converted; + if (fRelatedIndexerTask != null) { + converted= fRelatedIndexerTask.getConvertedMacros(fLinkage, ifl); + if (converted == null) { + throw new NeedToParseException(); + } } - final IIndexFile file= fileInfo.fFile; - if (file == null || - (fCallbackHandler != null && fCallbackHandler.needToUpdate(fileInfo))) { - throw new NeedToParseException(); + else { + IIndexMacro[] macros= file.getMacros(); + converted= new IMacro[macros.length]; + for (int i = 0; i < macros.length; i++) { + IIndexMacro macro = macros[i]; + converted[i]= ((PDOMMacro)macro).getMacro(); + } } - - // Follow the includes + macroMap.put(ifl, converted); // prevent recursion + + // follow the includes IIndexInclude[] includeDirectives= file.getIncludes(); for (int i = 0; i < includeDirectives.length; i++) { - IIndexFile includedFile= index.resolveInclude(includeDirectives[i]); + final IIndexInclude indexInclude = includeDirectives[i]; + IIndexFile includedFile= fIndex.resolveInclude(indexInclude); if (includedFile != null) { - IndexFileInfo nextInfo= createInfo(includedFile.getLocation(), includedFile); - getInfosForMacroDictionary(nextInfo, target); + collectMacros(includedFile, macroMap, true); } } } - - public void clearMacroAttachements() { - Iterator i = usedMacros.iterator(); - while (i.hasNext()) { - IMacro[] macros = (IMacro[])i.next(); - for (int j = 0; j < macros.length; ++j) { - if (macros[j] instanceof ObjectStyleMacro) { - ((ObjectStyleMacro)macros[j]).attachment = null; - } - } - } - usedMacros.clear(); - fIncluded.clear(); + + public void cleanupAfterTranslationUnit() { + fIncludedFiles.clear(); } public ICodeReaderCache getCodeReaderCache() { - // No need for cache here return null; } - public IndexFileInfo createFileInfo(IIndexFileLocation location) throws CoreException { - return createInfo(location, null); - } - - public IIndexFileLocation findLocation(String absolutePath) { - if(!iflCache.containsKey(absolutePath)) { - iflCache.put(absolutePath, IndexLocationFactory.getIFLExpensive(cproject, absolutePath)); - } - return (IIndexFileLocation) iflCache.get(absolutePath); - } - - public void setCallbackHandler(CallbackHandler callbackHandler) { - fCallbackHandler= callbackHandler; + public void setLinkage(int linkageID) { + fLinkage= linkageID; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFileLocation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFileLocation.java index 6c249285abc..d2b4df21bfe 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFileLocation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFileLocation.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006 Symbian Software Ltd. and others. + * Copyright (c) 2006, 2007 Symbian Software Ltd. 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 @@ -62,4 +62,11 @@ public class IndexFileLocation implements IIndexFileLocation { public int hashCode() { return uri.hashCode(); } + + public String toString() { + if (fullPath == null) { + return uri.toString(); + } + return fullPath.toString() + " (" + uri.toString() + ')'; //$NON-NLS-1$ + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/WritableCIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/WritableCIndex.java index 7961948b1ef..94d007584ae 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/WritableCIndex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/WritableCIndex.java @@ -16,6 +16,7 @@ import java.util.Collection; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; +import org.eclipse.cdt.core.index.IIndexFile; import org.eclipse.cdt.core.index.IIndexFileLocation; import org.eclipse.core.runtime.CoreException; @@ -40,19 +41,23 @@ public class WritableCIndex extends CIndex implements IWritableIndex { return fWritableFragment; } - public IIndexFragmentFile getWritableFile(IIndexFileLocation location) throws CoreException { - return fWritableFragment.getFile(location); + public IIndexFragmentFile getWritableFile(int linkageID, IIndexFileLocation location) throws CoreException { + return fWritableFragment.getFile(linkageID, location); } - public IIndexFragmentFile addFile(IIndexFileLocation fileLocation) throws CoreException { - return fWritableFragment.addFile(fileLocation); + public IIndexFragmentFile[] getWritableFiles(IIndexFileLocation location) throws CoreException { + return fWritableFragment.getFiles(location); + } + + public IIndexFragmentFile addFile(int linkageID, IIndexFileLocation fileLocation) throws CoreException { + return fWritableFragment.addFile(linkageID, fileLocation); } private boolean isWritableFragment(IIndexFragment frag) { return frag == fWritableFragment; } - public void setFileContent(IIndexFragmentFile file, + public void setFileContent(IIndexFragmentFile file, int linkageID, IncludeInformation[] includes, IASTPreprocessorMacroDefinition[] macros, IASTName[][] names) throws CoreException { @@ -64,7 +69,7 @@ public class WritableCIndex extends CIndex implements IWritableIndex { for (int i = 0; i < includes.length; i++) { IncludeInformation ii= includes[i]; if (ii.fLocation != null) { - ii.fTargetFile= addFile(ii.fLocation); + ii.fTargetFile= addFile(linkageID, ii.fLocation); } } ((IWritableIndexFragment) indexFragment).addFileContent(file, includes, macros, names); @@ -75,8 +80,9 @@ public class WritableCIndex extends CIndex implements IWritableIndex { fWritableFragment.clear(); } - public boolean isWritableFile(IIndexFragmentFile file) { - return isWritableFragment(file.getIndexFragment()); + public boolean isWritableFile(IIndexFile file) { + return file instanceof IIndexFragmentFile && + isWritableFragment(((IIndexFragmentFile)file).getIndexFragment()); } public void clearFile(IIndexFragmentFile file, Collection clearedContexts) throws CoreException { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFastIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFastIndexerTask.java index 248fe1047b1..a99ce96f782 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFastIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFastIndexerTask.java @@ -6,35 +6,16 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * QNX - Initial API and implementation - * Markus Schorn (Wind River Systems) - * IBM Corporation + * QNX - Initial API and implementation + * Markus Schorn (Wind River Systems) + * IBM Corporation *******************************************************************************/ package org.eclipse.cdt.internal.core.indexer; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; import java.util.List; -import java.util.Map; -import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; -import org.eclipse.cdt.core.index.IIndexFile; -import org.eclipse.cdt.core.index.IIndexFileLocation; -import org.eclipse.cdt.core.model.AbstractLanguage; -import org.eclipse.cdt.core.parser.CodeReader; -import org.eclipse.cdt.core.parser.IScannerInfo; -import org.eclipse.cdt.internal.core.index.IWritableIndex; -import org.eclipse.cdt.internal.core.index.IndexFileLocation; -import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory.CallbackHandler; -import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory.IndexFileInfo; -import org.eclipse.core.filesystem.URIUtil; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.cdt.core.dom.ICodeReaderFactory; /** * A task for index updates. @@ -48,162 +29,12 @@ import org.eclipse.core.runtime.IProgressMonitor; * * @since 4.0 */ -public class StandaloneFastIndexerTask extends StandaloneIndexerTask implements CallbackHandler { - private List fChanged = new ArrayList(); - private List fRemoved = new ArrayList(); - private IWritableIndex fIndex; - private StandaloneIndexBasedCodeReaderFactory fCodeReaderFactory; - private Map fIflCache; - private int fCurrentConfigHash= 0; - - public StandaloneFastIndexerTask(StandaloneFastIndexer indexer, List added, - List changed, List removed) { - super(indexer); - fChanged.addAll(added); - fChanged.addAll(changed); - fRemoved.addAll(removed); - updateInfo(0, 0, fChanged.size() + fRemoved.size()); +public class StandaloneFastIndexerTask extends StandaloneIndexerTask { + public StandaloneFastIndexerTask(StandaloneFastIndexer indexer, List added, List changed, List removed) { + super(indexer, added, changed, removed, true); } - public void run(IProgressMonitor monitor) throws IOException{ - long start = System.currentTimeMillis(); - try { - setupIndexAndReaderFactory(); - fIndex.acquireReadLock(); - try { - registerTUsInReaderFactory(fChanged); - - Iterator i= fRemoved.iterator(); - while (i.hasNext()) { - if (monitor.isCanceled()) - return; - String tu = (String) i.next(); - removeTU(fIndex, getIndexFileLocation(tu), 1); - if (isValidSourceUnitName(tu)) { - updateInfo(1, 0, 0); - } - else { - updateInfo(0, 1, -1); - } - } - - // separate headers - List headers= new ArrayList(); - List sources= fChanged; - for (Iterator iter = fChanged.iterator(); iter.hasNext();) { - String tu = (String) iter.next(); - if (!isValidSourceUnitName(tu)) { - headers.add(tu); - iter.remove(); - } - } - - parseTUs(fIndex, 1, sources, headers, monitor); - if (monitor.isCanceled()) { - return; - } - } - finally { - fIndex.releaseReadLock(); - } - } catch (CoreException e) { - e.printStackTrace(); - } catch (InterruptedException e) { - } - traceEnd(start); - } - - private void setupIndexAndReaderFactory() throws CoreException { - fIndex= fIndexer.getIndex(); - fIndex.resetCacheCounters(); - fIflCache = new HashMap/**/(); - fCodeReaderFactory = new StandaloneIndexBasedCodeReaderFactory(fIndex, fIflCache); - fCodeReaderFactory.setCallbackHandler(this); - } - - private void registerTUsInReaderFactory(Collection files) throws IOException, CoreException { - int removed= 0; - for (Iterator iter = files.iterator(); iter.hasNext();) { - String sourcePath = (String) iter.next(); - String path = new File(sourcePath).getCanonicalPath(); - IIndexFileLocation location = getIndexFileLocation(path); - IndexFileInfo info= fCodeReaderFactory.createFileInfo(location); - if (updateAll()) { - info.fRequested= IndexFileInfo.REQUESTED; - } - else if (updateChangedTimestamps() && isOutdated(location, info.fFile)) { - info.fRequested= IndexFileInfo.REQUESTED; - } - else { - iter.remove(); - removed++; - } - } - updateInfo(0, 0, -removed); - - } - - protected IIndexFileLocation findLocation(String absolutePath) { - IIndexFileLocation result = (IIndexFileLocation) fIflCache.get(absolutePath); - if(result==null) { - //Standalone indexing stores the absolute paths of files being indexed - result = new IndexFileLocation(URIUtil.toURI(absolutePath),absolutePath); - fIflCache.put(absolutePath, result); - } - return result; - } - - protected IASTTranslationUnit createAST(AbstractLanguage lang, CodeReader codeReader, IScannerInfo scanInfo, int options, IProgressMonitor pm) throws CoreException { - - // get the AST in a "Fast" way - IASTTranslationUnit ast= lang.getASTTranslationUnit(codeReader, scanInfo, fCodeReaderFactory, fIndex, options, fIndexer.getParserLog()); - if (pm.isCanceled()) { - return null; - } - // Clear the macros - fCodeReaderFactory.clearMacroAttachements(); - return ast; - } - - protected boolean needToUpdate(IIndexFileLocation location, int confighash) throws CoreException { - if (super.needToUpdate(location, confighash)) { - // file is requested or is not yet indexed. - IndexFileInfo info= fCodeReaderFactory.createFileInfo(location); - return needToUpdate(info, confighash); - } - return false; - } - - public boolean needToUpdate(IndexFileInfo info) throws CoreException { - return needToUpdate(info, fCurrentConfigHash); - } - - private boolean needToUpdate(IndexFileInfo info, int confighash) throws CoreException { - if (info.fFile == null) { - return true; - } - if (confighash != 0 && info.fRequested == IndexFileInfo.REQUESTED_IF_CONFIG_CHANGED) { - int oldhash= info.fFile.getScannerConfigurationHashcode(); - if (oldhash == 0 || oldhash==confighash) { - info.fRequested= IndexFileInfo.NOT_REQUESTED; - updateInfo(0, 0, -1); - } - else { - info.fRequested= IndexFileInfo.REQUESTED; - } - } - return info.fRequested != IndexFileInfo.NOT_REQUESTED; - } - - - protected boolean postAddToIndex(IIndexFileLocation path, IIndexFile file) - throws CoreException { - IndexFileInfo info= fCodeReaderFactory.createFileInfo(path); - info.fFile= file; - if (info.fRequested != IndexFileInfo.NOT_REQUESTED) { - info.fRequested= IndexFileInfo.NOT_REQUESTED; - return true; - } - return false; + protected ICodeReaderFactory createReaderFactory() { + return new StandaloneIndexerFallbackReaderFactory(); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFullIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFullIndexerTask.java index 7f34773363b..691cb4c01ad 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFullIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFullIndexerTask.java @@ -13,26 +13,9 @@ package org.eclipse.cdt.internal.core.indexer; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; import java.util.List; -import java.util.Map; -import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; -import org.eclipse.cdt.core.index.IIndexFile; -import org.eclipse.cdt.core.index.IIndexFileLocation; -import org.eclipse.cdt.core.model.AbstractLanguage; -import org.eclipse.cdt.core.parser.CodeReader; -import org.eclipse.cdt.core.parser.IScannerInfo; -import org.eclipse.cdt.internal.core.index.IWritableIndex; -import org.eclipse.cdt.internal.core.index.IndexFileLocation; -import org.eclipse.core.filesystem.URIUtil; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.cdt.core.dom.ICodeReaderFactory; /** * A task for index updates. @@ -47,133 +30,12 @@ import org.eclipse.core.runtime.IProgressMonitor; * @since 4.0 */ public class StandaloneFullIndexerTask extends StandaloneIndexerTask { - private final static Object REQUIRED= new Object(); - private final static Object MISSING = new Object(); - private final static Object SKIP= new Object(); - - private List fChanged = new ArrayList(); - private List fRemoved = new ArrayList(); - private IWritableIndex fIndex = null; - private Map filePathsToParse = new HashMap/**/(); - private Map fIflCache = new HashMap/**/(); - public StandaloneFullIndexerTask(StandaloneFullIndexer indexer, List added, List changed, List removed) { - super(indexer); - fChanged.addAll(added); - fChanged.addAll(changed); - fRemoved.addAll(removed); - updateInfo(0, 0, fChanged.size() + fRemoved.size()); + super(indexer, added, changed, removed, false); } - public void run(IProgressMonitor monitor) throws IOException { - long start = System.currentTimeMillis(); - try { - setupIndex(); - registerTUsInReaderFactory(fChanged); - - // separate headers - List headers= new ArrayList(); - List sources= fChanged; - for (Iterator iter = fChanged.iterator(); iter.hasNext();) { - String tu = (String) iter.next(); - if (!isValidSourceUnitName(tu)) { - headers.add(tu); - iter.remove(); - } - } - - Iterator i= fRemoved.iterator(); - while (i.hasNext()) { - if (monitor.isCanceled()) - return; - String tu = (String) i.next(); - removeTU(fIndex, getIndexFileLocation(tu), 0); - if (isValidSourceUnitName(tu)) { - updateInfo(1, 0, 0); - } - else { - updateInfo(0, 1, -1); - } - } - - fIndex.acquireReadLock(); - try { - parseTUs(fIndex, 1, sources, headers, monitor); - } - finally { - fIndex.releaseReadLock(); - } - } catch (CoreException e) { - e.printStackTrace(); - } catch (InterruptedException e) { - } - traceEnd(start); - } - - private void setupIndex() throws CoreException { - fIndex = fIndexer.getIndex(); - fIndex.resetCacheCounters(); - } - - private void registerTUsInReaderFactory(Collection/**/ sources) - throws IOException, CoreException { - int removed= 0; - filePathsToParse= new HashMap/**/(); - for (Iterator iter = sources.iterator(); iter.hasNext();) { - String sourcePath = (String) iter.next(); - String path = new File(sourcePath).getCanonicalPath(); - IIndexFileLocation location = getIndexFileLocation(path); - if (updateAll()) { - filePathsToParse.put(location, REQUIRED); - } - else if (updateChangedTimestamps() && isOutdated(location, fIndex.getFile(location))) { - filePathsToParse.put(location, REQUIRED); - } - else { - iter.remove(); - removed++; - continue; - } - updateInfo(0, 0, -removed); - } - } - - protected IIndexFileLocation findLocation(String absolutePath) { - IIndexFileLocation result = (IIndexFileLocation) fIflCache.get(absolutePath); - if(result==null) { - //Standalone indexing stores the absolute paths of files being indexed - result = new IndexFileLocation(URIUtil.toURI(absolutePath),absolutePath); - fIflCache.put(absolutePath, result); - } - return result; - } - - protected IASTTranslationUnit createAST(AbstractLanguage lang, CodeReader codeReader, IScannerInfo scanInfo, int options, IProgressMonitor pm) throws CoreException { - // get the AST in a "Fast" way - IASTTranslationUnit ast= lang.getASTTranslationUnit(codeReader, scanInfo, ((StandaloneFullIndexer)fIndexer).getCodeReaderFactory(), null, options, fIndexer.getParserLog()); - if (pm.isCanceled()) { - return null; - } - return ast; - } - - protected boolean needToUpdate(IIndexFileLocation location, int confighash) throws CoreException { - if (super.needToUpdate(location, confighash)) { - Object required= filePathsToParse.get(location); - if (required == null) { - required= MISSING; - filePathsToParse.put(location, required); - } - return required != SKIP; - } - return false; - } - - protected boolean postAddToIndex(IIndexFileLocation location, IIndexFile file) - throws CoreException { - Object required= filePathsToParse.get(location); - filePathsToParse.put(location, SKIP); - return required == REQUIRED; + protected ICodeReaderFactory createReaderFactory() { + return ((StandaloneFullIndexer)fIndexer).getCodeReaderFactory(); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexBasedCodeReaderFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexBasedCodeReaderFactory.java deleted file mode 100644 index 8ec8b5e4b33..00000000000 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexBasedCodeReaderFactory.java +++ /dev/null @@ -1,96 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 IBM Corporation 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: - * IBM - Initial API and implementation - *******************************************************************************/ - -package org.eclipse.cdt.internal.core.indexer; - -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.cdt.core.dom.ICodeReaderFactory; -import org.eclipse.cdt.core.dom.IMacroCollector; -import org.eclipse.cdt.core.index.IIndex; -import org.eclipse.cdt.core.index.IIndexFileLocation; -import org.eclipse.cdt.core.parser.CodeReader; -import org.eclipse.cdt.core.parser.ICodeReaderCache; -import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory; -import org.eclipse.cdt.internal.core.index.IndexFileLocation; -import org.eclipse.core.filesystem.URIUtil; - -/** - * A factory for CodeReaders construction. - * - *

- * EXPERIMENTAL. This class or interface has been added as - * part of a work in progress. There is no guarantee that this API will work or - * that it will remain the same. Please do not use this API without consulting - * with the CDT team. - *

- * - * @since 4.0 - */ -public class StandaloneIndexBasedCodeReaderFactory extends IndexBasedCodeReaderFactory { - - public static class DefaultFallBackFactory implements ICodeReaderFactory { - - public CodeReader createCodeReaderForInclusion(IMacroCollector callback, String path) { - try { - if (!new File(path).exists()) - return null; - return new CodeReader(path); - } catch (IOException e) { - return null; - } - } - - public CodeReader createCodeReaderForTranslationUnit(String path) { - try { - if (!new File(path).exists()) - return null; - return new CodeReader(path); - } catch (IOException e) { - return null; - } - } - - public ICodeReaderCache getCodeReaderCache() { - return null; - } - - public int getUniqueIdentifier() { - return 0; - } - - } - - public StandaloneIndexBasedCodeReaderFactory(IIndex index) { - super(null, index); - } - - public StandaloneIndexBasedCodeReaderFactory(IIndex index, ICodeReaderFactory fallbackFactory) { - super(null, index, new HashMap/**/(), fallbackFactory); - } - - public StandaloneIndexBasedCodeReaderFactory(IIndex index, Map iflCache) { - super(null, index, iflCache, new DefaultFallBackFactory()); - } - - public IIndexFileLocation findLocation(String absolutePath) { - IIndexFileLocation result = (IIndexFileLocation) getIFLCache().get(absolutePath); - if(result==null) { - //Standalone indexing stores the absolute paths of files being indexed - result = new IndexFileLocation(URIUtil.toURI(absolutePath),absolutePath); - getIFLCache().put(absolutePath, result); - } - return result; - } -} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexer.java index 2e12e2048e6..ea66d8309a8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexer.java @@ -306,15 +306,13 @@ public abstract class StandaloneIndexer { fDelegate= createTask(getFilesAdded(tus), NO_TUS, NO_TUS); fDelegate.setUpdateFlags(fUpdateOptions); + if (fDelegate != null) { + fDelegate.run(monitor); + } } catch (CoreException e) { e.printStackTrace(); } catch (InterruptedException e) { } - - if (fDelegate != null) { - fDelegate.run(monitor); - } - } /** @@ -329,12 +327,12 @@ public abstract class StandaloneIndexer { fProgress= new IndexerProgress(); fDelegate= createTask(getFilesAdded(added), changed, removed); - if (fDelegate instanceof StandaloneIndexerTask) { - fDelegate.setUpdateFlags(fUpdateOptions); - } - if (fDelegate != null) { - fDelegate.run(monitor); + try { + fDelegate.setUpdateFlags(fUpdateOptions); + fDelegate.run(monitor); + } catch (InterruptedException e) { + } } } @@ -360,7 +358,7 @@ public abstract class StandaloneIndexer { if (file.isDirectory()) { String[] files = file.list(filter); for (int i = 0; i < files.length; i++) { - added.add((String)files[i]); + added.add(files[i]); } } else { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerFallbackReaderFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerFallbackReaderFactory.java new file mode 100644 index 00000000000..e3875d588e7 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerFallbackReaderFactory.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2007 IBM Corporation 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: + * IBM - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.core.indexer; + +import java.io.File; +import java.io.IOException; + +import org.eclipse.cdt.core.dom.ICodeReaderFactory; +import org.eclipse.cdt.core.dom.IMacroCollector; +import org.eclipse.cdt.core.parser.CodeReader; +import org.eclipse.cdt.core.parser.ICodeReaderCache; + +/** + * A factory for CodeReaders construction. + * + *

+ * EXPERIMENTAL. This class or interface has been added as + * part of a work in progress. There is no guarantee that this API will work or + * that it will remain the same. Please do not use this API without consulting + * with the CDT team. + *

+ * + * @since 4.0 + */ +public class StandaloneIndexerFallbackReaderFactory implements ICodeReaderFactory { + + public CodeReader createCodeReaderForInclusion(IMacroCollector callback, String path) { + try { + if (!new File(path).exists()) + return null; + return new CodeReader(path); + } catch (IOException e) { + return null; + } + } + + public CodeReader createCodeReaderForTranslationUnit(String path) { + try { + if (!new File(path).exists()) + return null; + return new CodeReader(path); + } catch (IOException e) { + return null; + } + } + + public ICodeReaderCache getCodeReaderCache() { + return null; + } + + public int getUniqueIdentifier() { + return 0; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerInputAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerInputAdapter.java new file mode 100644 index 00000000000..393383aebcc --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerInputAdapter.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) 2007 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.indexer; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; + +import org.eclipse.cdt.core.index.IIndexFileLocation; +import org.eclipse.cdt.core.model.AbstractLanguage; +import org.eclipse.cdt.core.model.ILanguage; +import org.eclipse.cdt.core.parser.CodeReader; +import org.eclipse.cdt.core.parser.IScannerInfo; +import org.eclipse.cdt.internal.core.index.IndexFileLocation; +import org.eclipse.cdt.internal.core.pdom.IndexerInputAdapter; +import org.eclipse.core.filesystem.URIUtil; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +/** + * Provides information about the file paths represented as strings. + * @since 5.0 + */ +public class StandaloneIndexerInputAdapter extends IndexerInputAdapter { + private HashMap fIflCache= new HashMap(); + + private final StandaloneIndexer fIndexer; + + public StandaloneIndexerInputAdapter(StandaloneIndexer indexer) { + fIndexer= indexer; + } + + public IScannerInfo getBuildConfiguration(int linkageID, Object tu) { + return fIndexer.getScannerInfo(); + } + + public long getLastModified(IIndexFileLocation location) { + return new File(location.getFullPath()).lastModified(); + } + + public boolean isSourceUnit(Object tu) { + return isValidSourceUnitName((String) tu); + } + + public IIndexFileLocation resolveFile(Object tu) { + return resolveASTPath((String) tu); + } + + public String getASTPath(IIndexFileLocation ifl) { + return ifl.getFullPath(); + } + + public IIndexFileLocation resolveASTPath(String astPath) { + IIndexFileLocation result= (IIndexFileLocation) fIflCache.get(astPath); + if (result == null) { + try { + astPath = new File(astPath).getCanonicalPath(); + } catch (IOException e) { + // use the original + } + //Standalone indexing stores the absolute paths of files being indexed + result = new IndexFileLocation(URIUtil.toURI(astPath),astPath); + fIflCache.put(astPath, result); + } + return result; + } + + public IIndexFileLocation resolveIncludeFile(String includePath) { + IIndexFileLocation result= (IIndexFileLocation) fIflCache.get(includePath); + if (result == null) { + File file= new File(includePath); + if (!file.exists()) { + return null; + } + try { + includePath = file.getCanonicalPath(); + } catch (IOException e) { + // use the original + } + //Standalone indexing stores the absolute paths of files being indexed + result = new IndexFileLocation(URIUtil.toURI(includePath),includePath); + fIflCache.put(includePath, result); + } + return result; + } + + public boolean isFileBuildConfigured(Object tu) { + return isValidSourceUnitName((String) tu); + } + + public boolean canBePartOfSDK(IIndexFileLocation ifl) { + return false; + } + + public CodeReader getCodeReader(Object tu) { + try { + return new CodeReader((String) tu); + } catch (IOException e) { + } + return null; + } + + public Object getInputFile(IIndexFileLocation location) { + return location.getFullPath(); + } + + public AbstractLanguage[] getLanguages(Object tu) { + ILanguage language = fIndexer.getLanguageMapper().getLanguage((String) tu); + if (language instanceof AbstractLanguage) { + return new AbstractLanguage[] {(AbstractLanguage) language}; + } + return new AbstractLanguage[0]; + } + + private boolean isValidSourceUnitName(String file) { + IPath path = new Path(file); + if (fIndexer.getValidSourceUnitNames() == null || fIndexer.getValidSourceUnitNames().size() == 0) + return true; + return fIndexer.getValidSourceUnitNames().contains(path.getFileExtension()); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerTask.java index d5c92ff089c..cc3b307208f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneIndexerTask.java @@ -12,38 +12,16 @@ package org.eclipse.cdt.internal.core.indexer; -import java.io.File; -import java.io.IOException; -import java.net.URI; import java.text.NumberFormat; -import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; import java.util.Iterator; -import java.util.List; -import java.util.Map; -import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; -import org.eclipse.cdt.core.index.IIndex; -import org.eclipse.cdt.core.index.IIndexFile; -import org.eclipse.cdt.core.index.IIndexFileLocation; -import org.eclipse.cdt.core.index.IIndexInclude; import org.eclipse.cdt.core.model.AbstractLanguage; import org.eclipse.cdt.core.model.ILanguage; -import org.eclipse.cdt.core.parser.CodeReader; -import org.eclipse.cdt.core.parser.IExtendedScannerInfo; -import org.eclipse.cdt.core.parser.IScannerInfo; -import org.eclipse.cdt.internal.core.index.IIndexFragmentFile; import org.eclipse.cdt.internal.core.index.IWritableIndex; -import org.eclipse.cdt.internal.core.index.IndexFileLocation; +import org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask; import org.eclipse.cdt.internal.core.pdom.IndexerProgress; -import org.eclipse.cdt.internal.core.pdom.PDOMWriter; -import org.eclipse.core.filesystem.URIUtil; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Path; /** * A task for index updates. @@ -57,23 +35,39 @@ import org.eclipse.core.runtime.Path; * * @since 4.0 */ -public abstract class StandaloneIndexerTask extends PDOMWriter{ - private static final Object NO_CONTEXT = new Object(); +public abstract class StandaloneIndexerTask extends AbstractIndexerTask { protected StandaloneIndexer fIndexer; - protected Map/**/ fContextMap = new HashMap/**/(); - private List fFilesUpFront= new ArrayList(); - private String fDummyFileName; - private URI fDummyFileURI; - private int fUpdateFlags= StandaloneIndexer.UPDATE_ALL; - protected StandaloneIndexerTask(StandaloneIndexer indexer) { + protected StandaloneIndexerTask(StandaloneIndexer indexer, Collection added, Collection changed, Collection removed, boolean isFast) { + super(concat(added, changed), removed.toArray(), new StandaloneIndexerInputAdapter(indexer), isFast); fIndexer= indexer; setShowActivity(fIndexer.getShowActivity()); setShowProblems(fIndexer.getShowProblems()); setSkipReferences(fIndexer.getSkipReferences()); + + if (getIndexAllFiles()) { + setIndexFilesWithoutBuildConfiguration(true); + setIndexHeadersWithoutContext(true); + } + else { + setIndexFilesWithoutBuildConfiguration(false); + setIndexHeadersWithoutContext(false); + } } + private static Object[] concat(Collection added, Collection changed) { + Object[] result= new Object[added.size() + changed.size()]; + int i=0; + for (Iterator iterator = added.iterator(); iterator.hasNext();) { + result[i++]= iterator.next(); + } + for (Iterator iterator = changed.iterator(); iterator.hasNext();) { + result[i++]= iterator.next(); + } + return result; + } + /** * Return the indexer. * @return @@ -88,294 +82,41 @@ public abstract class StandaloneIndexerTask extends PDOMWriter{ final public IndexerProgress getProgressInformation() { return super.getProgressInformation(); } - - public void setUpdateFlags(int flags) { - fUpdateFlags= flags; - } - - final public boolean updateAll() { - return (fUpdateFlags & StandaloneIndexer.UPDATE_ALL) != 0; - } - - final public boolean updateChangedTimestamps() { - return (fUpdateFlags & StandaloneIndexer.UPDATE_CHECK_TIMESTAMPS) != 0; - } + /** * Tells the parser which files to parse first */ final public void setParseUpFront() { - String[] files = fIndexer.getFilesToParseUpFront(); - for (int i = 0; i < files.length; i++) { - fFilesUpFront.add((String) files[i]); - } + setParseUpFront(fIndexer.getFilesToParseUpFront()); } /** - * Figurues out whether all files (sources without config, headers not included) + * Figures out whether all files (sources without config, headers not included) * should be parsed. * @since 4.0 */ final protected boolean getIndexAllFiles() { return getIndexer().getIndexAllFiles(); } - - private IASTTranslationUnit createAST(IIndexFileLocation location, IScannerInfo scannerInfo, int options, IProgressMonitor pm) throws IOException, CoreException { - String path = location.getFullPath(); - if (path == null) { - return null; - } - ILanguage language = fIndexer.getLanguageMapper().getLanguage(path); - if (language == null) - return null; - - CodeReader codeReader = new CodeReader(path); - if (codeReader == null) { - return null; - } - - return createAST((AbstractLanguage)language, codeReader, scannerInfo, options, pm); - } - - /** - * Called to create the ast for a translation unit or a pre-parsed file. - * May return null. - * @see #parseTUs(IWritableIndex, int, Collection, Collection, IProgressMonitor) - * @since 4.0 - */ - abstract protected IASTTranslationUnit createAST(AbstractLanguage lang, CodeReader codeReader, IScannerInfo scanInfo, int options, IProgressMonitor pm) throws CoreException; - - /** - * Convenience method for subclasses, parses the files calling out to the methods - * {@link #createAST(IIndexFileLocation, IProgressMonitor)}, - * {@link #needToUpdate(IIndexFileLocation)}, - * {@link #addSymbols(IASTTranslationUnit, IWritableIndex, int, IProgressMonitor)} - * {@link #postAddToIndex(IIndexFileLocation, IIndexFile)} and - * {@link #findLocation(String)} - * @since 4.0 - */ - protected void parseTUs(IWritableIndex index, int readlockCount, Collection sources, Collection headers, IProgressMonitor monitor) throws IOException, CoreException, InterruptedException { - int options= 0; - if (fIndexer.getSkipReferences() == StandaloneIndexer.SKIP_ALL_REFERENCES) { - options |= AbstractLanguage.OPTION_SKIP_FUNCTION_BODIES; - } - for (Iterator iter = fFilesUpFront.iterator(); iter.hasNext();) { - String upfront= (String) iter.next(); - parseUpFront(upfront, options, index, readlockCount, monitor); - } - - // sources first - for (Iterator iter = sources.iterator(); iter.hasNext();) { - if (monitor.isCanceled()) - return; - String sourcePath = (String) iter.next(); - String path = new File(sourcePath).getCanonicalPath(); - final IIndexFileLocation ifl = getIndexFileLocation(path); - - if (needToUpdate(ifl, 0)) { - parseTU(ifl, options, index, readlockCount, monitor); - } - } - - // headers with context - for (Iterator iter = headers.iterator(); iter.hasNext();) { - if (monitor.isCanceled()) - return; - String sourcePath = (String) iter.next(); - String path = new File(sourcePath).getCanonicalPath(); - final IIndexFileLocation location = getIndexFileLocation(path); - - if (!needToUpdate(location, 0)) { - iter.remove(); - } - else { - IIndexFileLocation context= findContext(index, location); - if (context != null) { - parseTU(context, options, index, readlockCount, monitor); - } - } - } - - // headers without context - if (getIndexAllFiles()) { - for (Iterator iter = headers.iterator(); iter.hasNext();) { - if (monitor.isCanceled()) - return; - - String sourcePath = (String) iter.next(); - String path = new File(sourcePath).getCanonicalPath(); - final IIndexFileLocation ifl = getIndexFileLocation(path); - - if (!needToUpdate(ifl, 0)) { - iter.remove(); - } - else { - parseTU(ifl, options, index, readlockCount, monitor); - } - } + + final protected AbstractLanguage[] getLanguages(String filename) { + ILanguage l = fIndexer.getLanguageMapper().getLanguage(filename); + if (l instanceof AbstractLanguage) { + return new AbstractLanguage[] {(AbstractLanguage) l}; } + return new AbstractLanguage[0]; } - final protected boolean isOutdated(IIndexFileLocation ifl, IIndexFile indexFile) throws CoreException { - if (indexFile == null) { - return true; - } - File res = new File(ifl.getFullPath()); - if (res != null) { - if (indexFile != null) { - if (res.lastModified() == indexFile.getTimestamp()) { - return false; - } - } - return true; - } - return false; + protected final IWritableIndex createIndex() { + return fIndexer.getIndex(); } - - private void parseTU(IIndexFileLocation location, int options, IWritableIndex index, int readlockCount, IProgressMonitor pm) throws IOException, CoreException, InterruptedException { - String path = location.getFullPath(); - - try { - // skip if no scanner info - IScannerInfo scanner= fIndexer.getScannerInfo(); - if (scanner == null) { - updateInfo(0, 0, -1); - } - else { - final int configHash = computeHashCode(scanner); - if (needToUpdate(location, configHash)) { - if (fShowActivity) { - System.out.println("Indexer: parsing " + path); //$NON-NLS-1$ - } - long start= System.currentTimeMillis(); - IASTTranslationUnit ast= createAST(location, scanner, options, pm); - fStatistics.fParsingTime += System.currentTimeMillis()-start; - if (ast != null) { - addSymbols(ast, index, readlockCount, configHash, pm); - } - } - } - } - catch (CoreException e) { - e.printStackTrace(); - } - catch (RuntimeException e) { - e.printStackTrace(); - } - catch (Error e) { - e.printStackTrace(); - } - } - private void parseUpFront(String file, int options, IWritableIndex index, int readlockCount, IProgressMonitor pm) throws CoreException, InterruptedException { - file= file.trim(); - if (file.length() == 0) { - return; - } - try { - if (fShowActivity) { - System.out.println("Indexer: parsing " + file + " up front"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - long start= System.currentTimeMillis(); - - IASTTranslationUnit ast= null; - ILanguage l = fIndexer.getLanguageMapper().getLanguage(file); - if (l instanceof AbstractLanguage) { - AbstractLanguage lang= (AbstractLanguage) l; - IScannerInfo scanInfo = fIndexer.getScannerInfo(); - String code= "#include \"" + file + "\"\n"; //$NON-NLS-1$ //$NON-NLS-2$ - if (fDummyFileName == null) { - fDummyFileName= file + "___"; //$NON-NLS-1$ - fDummyFileURI= findLocation(fDummyFileName).getURI(); - } - CodeReader codeReader= new CodeReader(fDummyFileName, code.toCharArray()); - ast= createAST(lang, codeReader, scanInfo, options, pm); - } - fStatistics.fParsingTime += System.currentTimeMillis()-start; - if (ast != null) { - addSymbols(ast, index, readlockCount, 0, pm); - updateInfo(-1, +1, 0); - } - } - catch (CoreException e) { - e.printStackTrace(); - } - catch (RuntimeException e) { - e.printStackTrace(); - } - catch (Error e) { - e.printStackTrace(); - } - } - - /** - * Overriders must call super.needToUpdate(). If false is returned - * this must be passed on to their caller: - *
-	 *   if (super.needToUpdate()) {
-	 *      // your code
-	 *   }
-	 *   return false;
-	 */
-	protected boolean needToUpdate(IIndexFileLocation fileLoc, int configHash) throws CoreException {
-		return fDummyFileURI==null || !fDummyFileURI.equals(fileLoc.getURI());
-	}
-
-	private IIndexFileLocation findContext(IIndex index, IIndexFileLocation location) {
-		Object cachedContext= fContextMap.get(location);
-		if (cachedContext != null) {
-			return cachedContext == NO_CONTEXT ? null : (IIndexFileLocation) cachedContext;
-		}
-		IIndexFileLocation context= null;
-		fContextMap.put(location, NO_CONTEXT); // prevent recursion
-		IIndexFile pdomFile;
-		try {
-			pdomFile = index.getFile(location);
-			if (pdomFile != null) {
-				IIndexInclude[] includedBy = index.findIncludedBy(pdomFile, IIndex.DEPTH_ZERO);
-				ArrayList/**/ paths= new ArrayList/**/(includedBy.length);
-				for (int i = 0; i < includedBy.length; i++) {
-					IIndexInclude include = includedBy[i];
-					IIndexFileLocation incLocation = include.getIncludedByLocation();
-					if (isValidSourceUnitName(incLocation.getFullPath())) {
-						context = incLocation;
-						if (context != null) {
-							fContextMap.put(location, context);
-							return context;
-						}
-					}
-					paths.add(incLocation);
-				}
-				for (Iterator/**/ iter = paths.iterator(); iter.hasNext();) {
-					IIndexFileLocation nextLevel = (IIndexFileLocation) iter.next();
-					context = findContext(index, nextLevel);
-					if (context != null) {
-						fContextMap.put(location, context);
-						return context;
-					}
-				}
-			}
-		} catch (CoreException e) {
-			CCorePlugin.log(e);
-		}
-		return null;
-	}
-
-	/**
-	 * Conveninence method for subclasses, removes a translation unit from the index.
-	 * @since 4.0
-	 */
-	protected void removeTU(IWritableIndex index, IIndexFileLocation ifl, int readlocks) throws CoreException, InterruptedException {
-		index.acquireWriteLock(readlocks);
-		try {
-			IIndexFragmentFile file = (IIndexFragmentFile) index.getFile(ifl);
-			if (file != null)
-				index.clearFile(file, null);
-		} finally {
-			index.releaseWriteLock(readlocks);
-		}
+	public final void run(IProgressMonitor monitor) throws InterruptedException {
+		long start = System.currentTimeMillis();
+		runTask(monitor);
+		traceEnd(start);
 	}
 
 	protected void traceEnd(long start) {
@@ -425,75 +166,4 @@ public abstract class StandaloneIndexerTask extends PDOMWriter{
 			}
 		}
 	}
-	
-	public abstract void run(IProgressMonitor monitor) throws IOException;
-	
-	protected IIndexFileLocation getIndexFileLocation(String path) {
-		String absolutePath = new File(path).getAbsolutePath();
-		//Standalone indexing stores the absolute paths of files being indexed
-		return new IndexFileLocation(URIUtil.toURI(absolutePath),absolutePath); 
-	}
-	
-	protected boolean isValidSourceUnitName(String filename) {
-		IPath path = new Path(filename);
-		if (fIndexer.getValidSourceUnitNames() == null || fIndexer.getValidSourceUnitNames().size() == 0)
-			return true;
-		return fIndexer.getValidSourceUnitNames().contains(path.getFileExtension());
-	}
-	
-	protected long getLastModified(IIndexFileLocation location) {
-		return new File(location.getFullPath()).lastModified();
-	}
-	
-	protected static int computeHashCode(IScannerInfo scannerInfo) {
-		int result= 0;
-		Map macros= scannerInfo.getDefinedSymbols();
-		if (macros != null) {
-			for (Iterator i = macros.entrySet().iterator(); i.hasNext();) {
-				Map.Entry entry = (Map.Entry) i.next();
-				String key = (String) entry.getKey();
-				String value = (String) entry.getValue();
-				result= addToHashcode(result, key);
-				if (value != null && value.length() > 0) {
-					result= addToHashcode(result, value);
-				}
-			}
-		}
-		String[] a= scannerInfo.getIncludePaths();
-		if (a != null) {
-			for (int i = 0; i < a.length; i++) {
-				result= addToHashcode(result, a[i]);
-
-			}
-		}
-		if (scannerInfo instanceof IExtendedScannerInfo) {
-			IExtendedScannerInfo esi= (IExtendedScannerInfo) scannerInfo;
-			a= esi.getIncludeFiles();
-			if (a != null) {
-				for (int i = 0; i < a.length; i++) {
-					result= addToHashcode(result, a[i]);
-
-				}
-			}			
-			a= esi.getLocalIncludePath();
-			if (a != null) {
-				for (int i = 0; i < a.length; i++) {
-					result= addToHashcode(result, a[i]);
-
-				}
-			}		
-			a= esi.getMacroFiles();
-			if (a != null) {
-				for (int i = 0; i < a.length; i++) {
-					result= addToHashcode(result, a[i]);
-
-				}
-			}		
-		}
-		return result;
-	}
-
-	private static int addToHashcode(int result, String key) {
-		return result*31 + key.hashCode();
-	}
 }
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxFile.java
index 0c3ea46b7e8..2ea099d04a4 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxFile.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxFile.java
@@ -28,9 +28,6 @@ class LocationCtxFile extends LocationCtxContainer {
 	
 	public final void addChildSequenceLength(int childLength) {
 		super.addChildSequenceLength(childLength);
-		if (fASTInclude != null) {
-			fASTInclude.setLength(fASTInclude.getLength()+childLength);
-		}
 	}
 
 	public final String getFilePath() {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/ASTFilePathResolver.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/ASTFilePathResolver.java
new file mode 100644
index 00000000000..93e15900345
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/ASTFilePathResolver.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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.pdom;
+
+import org.eclipse.cdt.core.index.IIndexFileLocation;
+
+/**
+ * Abstract class for resolving paths as computed by the parser.
+ * @since 5.0
+ */
+public abstract class ASTFilePathResolver {
+
+	/**
+	 * Resolve a path as stored in the AST.
+	 * @return an index file location.
+	 */
+	public abstract IIndexFileLocation resolveASTPath(String astFilePath);
+
+	/**
+	 * Resolve a path for an inclusion as computed by the preprocessor. Check for existance
+	 * and return null if the file does not exist. 
+	 * @return an index file location or null if the file does not exist.
+	 */
+	public abstract IIndexFileLocation resolveIncludeFile(String includePath);
+	
+	/**
+	 * Convert an index file location to the path as it will be stored in the AST.
+	 */
+	public abstract String getASTPath(IIndexFileLocation ifl);
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java
new file mode 100644
index 00000000000..cca21f57972
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java
@@ -0,0 +1,782 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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.pdom;
+
+import java.net.URI;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.dom.ICodeReaderFactory;
+import org.eclipse.cdt.core.dom.ILinkage;
+import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
+import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree;
+import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree.IASTInclusionNode;
+import org.eclipse.cdt.core.index.IIndexFile;
+import org.eclipse.cdt.core.index.IIndexFileLocation;
+import org.eclipse.cdt.core.index.IIndexInclude;
+import org.eclipse.cdt.core.index.IIndexMacro;
+import org.eclipse.cdt.core.index.IIndexManager;
+import org.eclipse.cdt.core.index.IndexLocationFactory;
+import org.eclipse.cdt.core.model.AbstractLanguage;
+import org.eclipse.cdt.core.parser.CodeReader;
+import org.eclipse.cdt.core.parser.IExtendedScannerInfo;
+import org.eclipse.cdt.core.parser.IMacro;
+import org.eclipse.cdt.core.parser.IScannerInfo;
+import org.eclipse.cdt.core.parser.ParserUtil;
+import org.eclipse.cdt.core.parser.ScannerInfo;
+import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
+import org.eclipse.cdt.internal.core.index.IWritableIndex;
+import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory;
+import org.eclipse.cdt.internal.core.pdom.dom.PDOMMacro;
+import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+
+/**
+ * Task for the actual indexing. Various indexers need to implement the abstract methods.
+ * @since 5.0
+ */
+public abstract class AbstractIndexerTask extends PDOMWriter {
+	private static final int MAX_ERRORS = 500;
+	
+	private static class FileKey {
+		final URI fUri;
+		final int fLinkageID;
+		
+		public FileKey(int linkageID, URI uri) {
+			fUri= uri;
+			fLinkageID= linkageID;
+		}
+		public int hashCode() {
+			return fUri.hashCode() * 31 + fLinkageID;
+		}
+		public boolean equals(Object obj) {
+			FileKey other = (FileKey) obj;
+			return fLinkageID == other.fLinkageID && fUri.equals(other.fUri);
+		}
+	}
+
+	private static class FileInfo {
+		IIndexFile fIndexFile= null;
+		boolean fRequestUpdate= false;
+		boolean fIsUpdated= false;
+		public IMacro[] fMacros;
+	}
+	
+	private int fUpdateFlags= IIndexManager.UPDATE_ALL;
+	private boolean fIndexHeadersWithoutContext= true;
+	private boolean fIndexFilesWithoutConfiguration= true;
+	private HashMap fFileInfos= new HashMap();
+
+	private Object[] fFilesToUpdate;
+	private List fFilesToRemove = new ArrayList();
+	private List fFilesUpFront= new ArrayList();
+	private int fASTOptions;
+	
+	protected IWritableIndex fIndex;
+	private ITodoTaskUpdater fTodoTaskUpdater;
+	private final boolean fIsFastIndexer;
+	private ICodeReaderFactory fCodeReaderFactory;
+
+	public AbstractIndexerTask(Object[] filesToUpdate, Object[] filesToRemove, IndexerInputAdapter resolver, boolean fastIndexer) {
+		super(resolver);
+		fIsFastIndexer= fastIndexer;
+		fFilesToUpdate= filesToUpdate;
+		fFilesToRemove.addAll(Arrays.asList(filesToRemove));
+		updateInfo(0, 0, fFilesToUpdate.length + fFilesToRemove.size());
+	}
+	
+	public final void setIndexHeadersWithoutContext(boolean val) {
+		fIndexHeadersWithoutContext= val;
+	}
+	public final void setIndexFilesWithoutBuildConfiguration(boolean val) {
+		fIndexFilesWithoutConfiguration= val;
+	}
+	public final void setUpdateFlags(int flags) {
+		fUpdateFlags= flags;
+	}
+	public final void setParseUpFront(String[] astFilePaths) {
+		fFilesUpFront.addAll(Arrays.asList(astFilePaths));
+	}
+
+	protected abstract IWritableIndex createIndex();
+	protected abstract ICodeReaderFactory createReaderFactory();
+	protected abstract AbstractLanguage[] getLanguages(String fileName);
+
+	protected ITodoTaskUpdater createTodoTaskUpdater() {
+		return null;
+	}
+	
+	protected IScannerInfo createDefaultScannerConfig(int linkageID) {
+		return new ScannerInfo();
+	}
+	
+	protected String getASTPathForParsingUpFront() {
+		return "______"; //$NON-NLS-1$
+	}
+
+
+	
+	private final IASTTranslationUnit createAST(String code, AbstractLanguage lang, IScannerInfo scanInfo, 
+			int options, IProgressMonitor monitor) throws CoreException {
+		String dummyName= getASTPathForParsingUpFront();
+		if (dummyName != null) {
+			IIndexFileLocation dummyLoc= fResolver.resolveASTPath(dummyName);
+			setIndexed(lang.getLinkageID(), dummyLoc);
+			CodeReader codeReader= new CodeReader(dummyName, code.toCharArray());
+			return createAST(lang, codeReader, scanInfo, options, monitor);
+		}
+		return null;
+	}
+	
+
+	private final IASTTranslationUnit createAST(Object tu, AbstractLanguage language, IScannerInfo scanInfo, int options, IProgressMonitor pm)
+			throws CoreException {
+		final CodeReader codeReader= fResolver.getCodeReader(tu);
+		if (codeReader == null) {
+			return null;
+		}
+		
+		IASTTranslationUnit ast= createAST(language, codeReader, scanInfo, options, pm);
+		if (ast != null && !fResolver.isSourceUnit(tu)) {
+			ast.setIsHeaderUnit(true);
+		}
+		return ast;
+	}
+
+	private final IASTTranslationUnit createAST(AbstractLanguage language, CodeReader codeReader,
+			IScannerInfo scanInfo, int options, IProgressMonitor pm) throws CoreException {
+		if (fCodeReaderFactory == null) {
+			if (fIsFastIndexer) {
+				fCodeReaderFactory= new IndexBasedCodeReaderFactory(fIndex, fResolver, language.getLinkageID(), createReaderFactory(), this);
+			}
+			else {
+				fCodeReaderFactory= createReaderFactory();
+			}
+		}
+		else if (fIsFastIndexer) {
+			((IndexBasedCodeReaderFactory) fCodeReaderFactory).setLinkage(language.getLinkageID());
+		}
+		
+		try {
+			IASTTranslationUnit ast= language.getASTTranslationUnit(codeReader, scanInfo, fCodeReaderFactory, fIndex, options, ParserUtil.getParserLogService());
+			if (pm.isCanceled()) {
+				return null;
+			}
+			return ast;
+		}
+		finally {
+			if (fIsFastIndexer) {
+				((IndexBasedCodeReaderFactory) fCodeReaderFactory).cleanupAfterTranslationUnit();
+			}
+		}
+	}
+
+	public final void runTask(IProgressMonitor monitor) throws InterruptedException {
+		if (!fIndexFilesWithoutConfiguration) {
+			fIndexHeadersWithoutContext= false;
+		}
+		
+		fIndex= createIndex();
+		if (fIndex == null) {
+			return;
+		}
+		fTodoTaskUpdater= createTodoTaskUpdater();
+		
+		fASTOptions= AbstractLanguage.OPTION_ADD_COMMENTS | AbstractLanguage.OPTION_NO_IMAGE_LOCATIONS;
+		if (getSkipReferences() == SKIP_ALL_REFERENCES) {
+			fASTOptions |= AbstractLanguage.OPTION_SKIP_FUNCTION_BODIES;
+		}
+
+		fIndex.resetCacheCounters();
+		fIndex.acquireReadLock();
+
+		try { 
+			try {
+				// split into sources and headers, remove excluded sources.
+				final HashMap files= new HashMap();
+				final ArrayList ifilesToRemove= new ArrayList();
+				extractFiles(files, ifilesToRemove, monitor);
+
+				// remove files from index
+				removeFilesInIndex(fFilesToRemove, ifilesToRemove, monitor);
+
+				parseFilesUpFront(monitor);
+				parseLinkage(ILinkage.CPP_LINKAGE_ID, files, monitor);
+				parseLinkage(ILinkage.C_LINKAGE_ID, files, monitor);
+			}
+			finally {
+				fIndex.flush();
+			}
+		}
+		catch (CoreException e) {
+			CCorePlugin.log(e);
+		}
+		finally {
+			fIndex.releaseReadLock();
+		}
+	}
+
+	private void extractFiles(Map files, List iFilesToRemove, IProgressMonitor monitor) throws CoreException {
+		final boolean force= (fUpdateFlags & IIndexManager.UPDATE_ALL) != 0;
+		final boolean checkTimestamps= (fUpdateFlags & IIndexManager.UPDATE_CHECK_TIMESTAMPS) != 0;
+		final boolean checkConfig= (fUpdateFlags & IIndexManager.UPDATE_CHECK_CONFIGURATION) != 0;
+
+		int count= 0;
+		for (int i = 0; i < fFilesToUpdate.length; i++) {
+			if (monitor.isCanceled())
+				return;
+
+			final Object tu= fFilesToUpdate[i];
+			final IIndexFileLocation ifl= fResolver.resolveFile(tu);
+			final boolean isSourceUnit= fResolver.isSourceUnit(tu);
+			final boolean isExcludedSource= isSourceUnit && !fIndexFilesWithoutConfiguration && !fResolver.isFileBuildConfigured(tu);
+			final IIndexFragmentFile[] indexFiles= fIndex.getWritableFiles(ifl);
+			
+			if ((isSourceUnit && !isExcludedSource) || fIndexHeadersWithoutContext) {
+				// headers or sources required with a specific linkage
+				AbstractLanguage[] langs= fResolver.getLanguages(tu);
+				for (int j = 0; j < langs.length; j++) {
+					int linkageID = langs[j].getLinkageID();
+					IIndexFragmentFile ifile= getFile(linkageID, indexFiles);
+					if (ifile == null || !ifile.hasContent()) {
+						store(tu, linkageID, isSourceUnit, files);
+						requestUpdate(linkageID, ifl, null);
+						count++;
+					}
+					else {
+						takeFile(ifile, indexFiles);
+						boolean update= false;
+						if (checkConfig) {
+							update= isSourceUnit ? isSourceUnitConfigChange(tu, ifile) : isHeaderConfigChange(tu, ifile);
+						}
+						update= update || force || (checkTimestamps && fResolver.getLastModified(ifl) != ifile.getTimestamp());
+						if (update) {
+							requestUpdate(linkageID, ifl, ifile);
+							store(tu, linkageID, isSourceUnit, files);
+							count++;
+						}
+					}
+				}
+			}
+			
+			// handle other files present in index
+			for (int j = 0; j < indexFiles.length; j++) {
+				IIndexFragmentFile ifile = indexFiles[j];
+				if (ifile != null && ifile.hasContent()) {
+					IIndexInclude ctx= ifile.getParsedInContext();
+					if (ctx == null) {
+						iFilesToRemove.add(ifile);
+						count++;
+					}
+					else {
+						boolean update= false;
+						if (checkConfig && ifile.getParsedInContext() != null) {
+							update= isHeaderConfigChange(tu, ifile);
+						}
+						update= update || force || (checkTimestamps && fResolver.getLastModified(ifl) != ifile.getTimestamp());
+						if (update) {
+							final int linkageID = ifile.getLinkageID();
+							requestUpdate(linkageID, ifl, ifile);
+							store(tu, linkageID, false, files);
+							count++;
+						}
+					}
+				}
+			}
+		}
+		updateInfo(0, 0, count-fFilesToUpdate.length);
+		fFilesToUpdate= null;
+	}
+	
+	private void requestUpdate(int linkageID, IIndexFileLocation ifl, IIndexFragmentFile ifile) {
+		FileKey key= new FileKey(linkageID, ifl.getURI());
+		FileInfo info= (FileInfo) fFileInfos.get(key);
+		if (info == null) {
+			info= createFileInfo(key, null);
+		}
+		info.fIndexFile= ifile;
+		info.fRequestUpdate= true;
+	}
+	
+	private void setIndexed(int linkageID, IIndexFileLocation ifl) {
+		FileKey key= new FileKey(linkageID, ifl.getURI());
+		FileInfo info= (FileInfo) fFileInfos.get(key);
+		if (info == null) {
+			info= createFileInfo(key, null);
+		}
+		info.fIsUpdated= true;
+		info.fMacros= null;
+	}
+
+	private FileInfo createFileInfo(FileKey key, IIndexFile ifile) {
+		FileInfo info = new FileInfo();
+		fFileInfos.put(key, info);
+		info.fIndexFile= ifile;
+		return info;
+	}
+
+	private FileInfo getFileInfo(int linkageID, IIndexFileLocation ifl) {
+		FileKey key= new FileKey(linkageID, ifl.getURI());
+		return (FileInfo) fFileInfos.get(key);
+	}
+
+	private boolean isSourceUnitConfigChange(Object tu, IIndexFragmentFile ifile) {
+		return false;
+	}
+
+	private boolean isHeaderConfigChange(Object tu, IIndexFragmentFile ifile) {
+		return false;
+	}
+	
+	private IIndexFragmentFile getFile(int linkageID, IIndexFragmentFile[] indexFiles) throws CoreException {
+		for (int i = 0; i < indexFiles.length; i++) {
+			IIndexFragmentFile ifile = indexFiles[i];
+			if (ifile != null && ifile.getLinkageID() == linkageID) {
+				return ifile;
+			}
+		}
+		return null;
+	}
+
+	private void takeFile(IIndexFragmentFile ifile, IIndexFragmentFile[] indexFiles) {
+		for (int i = 0; i < indexFiles.length; i++) {
+			if (indexFiles[i] == ifile) {
+				indexFiles[i]= null;
+				return;
+			}
+		}
+	}
+
+	private void store(Object tu, int linkageID, boolean isSourceUnit, Map files) {
+		Integer key = getFileListKey(linkageID, isSourceUnit);
+		List list= (List) files.get(key);
+		if (list == null) {
+			list= new LinkedList();
+			files.put(key, list);
+		}
+		list.add(tu);
+	}
+
+	private Integer getFileListKey(int linkageID, boolean isSourceUnit) {
+		Integer key= new Integer(linkageID*2 + (isSourceUnit ? 0 : 1));
+		return key;
+	}
+
+	private void removeFilesInIndex(List filesToRemove, List ifilesToRemove, IProgressMonitor monitor) throws InterruptedException, CoreException {
+		if (!filesToRemove.isEmpty() || !ifilesToRemove.isEmpty()) {
+			fIndex.acquireWriteLock(1);
+			try {
+				for (Iterator iterator = fFilesToRemove.iterator(); iterator.hasNext();) {
+					if (monitor.isCanceled()) {
+						return;
+					}
+					final Object tu = iterator.next();
+					IIndexFileLocation ifl= fResolver.resolveFile(tu);
+					IIndexFragmentFile[] ifiles= fIndex.getWritableFiles(ifl);
+					for (int i = 0; i < ifiles.length; i++) {
+						IIndexFragmentFile ifile = ifiles[i];
+						fIndex.clearFile(ifile, null);
+					}
+					updateInfo(0, 0, -1);
+				}
+				for (Iterator iterator = ifilesToRemove.iterator(); iterator.hasNext();) {
+					if (monitor.isCanceled()) {
+						return;
+					}
+					IIndexFragmentFile ifile= (IIndexFragmentFile) iterator.next();
+					fIndex.clearFile(ifile, null);
+					updateInfo(0, 0, -1);
+				}
+			} finally {
+				fIndex.releaseWriteLock(1);
+			}
+		}
+		fFilesToRemove.clear();
+	}
+	
+	private void parseFilesUpFront(IProgressMonitor monitor) throws CoreException {
+		for (Iterator iter = fFilesUpFront.iterator(); iter.hasNext();) {
+			if (monitor.isCanceled()) {
+				return;
+			}
+			String upfront= (String) iter.next();
+			String filePath = upfront;
+			filePath= filePath.trim();
+			if (filePath.length() == 0) {
+				continue;
+			}
+			final IPath path= new Path(filePath);
+			final String fileName = path.lastSegment();
+			try {
+				if (fShowActivity) {
+					System.out.println("Indexer: parsing " + filePath + " up front");  //$NON-NLS-1$ //$NON-NLS-2$
+				}
+				monitor.subTask(MessageFormat.format(Messages.AbstractIndexerTask_parsingFileTask,
+						new Object[]{fileName, path.removeLastSegments(1).toString()}));
+				
+				AbstractLanguage[] langs= getLanguages(fileName);
+				for (int i = 0; i < langs.length; i++) {
+					AbstractLanguage lang= langs[i];
+					int linkageID= lang.getLinkageID();
+					String code= "#include \"" + filePath + "\"\n";  //$NON-NLS-1$ //$NON-NLS-2$
+					
+					IScannerInfo scanInfo= createDefaultScannerConfig(linkageID);
+					if (scanInfo != null) {
+						long start= System.currentTimeMillis();
+						IASTTranslationUnit ast= createAST(code, lang, scanInfo, fASTOptions, monitor);
+						fStatistics.fParsingTime += System.currentTimeMillis()-start;
+						
+						if (ast != null) {
+							writeToIndex(linkageID, ast, computeHashCode(scanInfo), monitor);
+							updateInfo(0, 1, 0);
+						}
+					}
+				}
+			}
+			catch (OutOfMemoryError e) {
+				throw e;
+			}
+			catch (Throwable e) {
+				swallowError(path, e); 
+			}
+		}
+		fFilesUpFront.clear();
+	}
+	
+	private void parseLinkage(int linkageID, Map fileListMap, IProgressMonitor monitor) throws CoreException, InterruptedException {
+		// sources
+		List files= (List) fileListMap.get(getFileListKey(linkageID, true));
+		if (files != null) {
+			for (Iterator iter = files.iterator(); iter.hasNext();) {
+				if (monitor.isCanceled()) 
+					return;
+				final Object tu= iter.next();
+				final IIndexFileLocation ifl = fResolver.resolveFile(tu);
+				final FileInfo info= getFileInfo(linkageID, ifl);
+				if (info != null && info.fRequestUpdate && !info.fIsUpdated) {
+					final IScannerInfo scannerInfo= fResolver.getBuildConfiguration(linkageID, tu);
+					parseFile(tu, linkageID, ifl, scannerInfo, monitor);
+					if (info.fIsUpdated) {
+						updateInfo(1, 0, 0);	// a source file was parsed
+					}
+				}
+			}
+			files.clear();
+		}
+		
+		// headers with context
+		HashMap contextMap= new HashMap();
+		files= (List) fileListMap.get(getFileListKey(linkageID, false));
+		if (files != null) {
+			for (Iterator iter = files.iterator(); iter.hasNext();) {
+				if (monitor.isCanceled()) 
+					return;
+				final Object header= iter.next();
+				final IIndexFileLocation ifl = fResolver.resolveFile(header);
+				final FileInfo info= getFileInfo(linkageID, ifl);
+				if (info != null && info.fRequestUpdate && !info.fIsUpdated) {
+					if (info.fIndexFile != null && fIndex.isWritableFile(info.fIndexFile)) {
+						Object tu= findContext((IIndexFragmentFile) info.fIndexFile, contextMap);
+						if (tu != null) {
+							final IScannerInfo scannerInfo= fResolver.getBuildConfiguration(linkageID, tu);
+							parseFile(tu, linkageID, fResolver.resolveFile(tu), scannerInfo, monitor);
+							if (info.fIsUpdated) {
+								updateInfo(0, 1, 0);	// a header was parsed in context
+								iter.remove();
+							}
+						}
+					}
+				}
+				else {
+					// file was already parsed.
+					iter.remove();
+				}
+			}
+
+			// headers without context
+			contextMap= null;
+			for (Iterator iter = files.iterator(); iter.hasNext();) {
+				if (monitor.isCanceled()) 
+					return;
+				final Object header= iter.next();
+				final IIndexFileLocation ifl = fResolver.resolveFile(header);
+				final FileInfo info= getFileInfo(linkageID, ifl);
+				if (info != null && info.fRequestUpdate && !info.fIsUpdated) {
+					final IScannerInfo scannerInfo= fResolver.getBuildConfiguration(linkageID, header);
+					parseFile(header, linkageID, ifl, scannerInfo, monitor);
+					if (info.fIsUpdated) {
+						updateInfo(-1, 1, 0);	// a header was parsed without context
+						iter.remove();
+					}
+				}
+			}
+		}
+	}
+
+	private static Object NO_CONTEXT= new Object();
+	private Object findContext(IIndexFragmentFile ifile, HashMap contextMap) {
+		Object cachedContext= contextMap.get(ifile);
+		if (cachedContext != null) {
+			return cachedContext == NO_CONTEXT ? null : cachedContext;
+		}
+		try {
+			Object context= fResolver.getInputFile(ifile.getLocation());
+			if (context != null) {
+				contextMap.put(ifile, context); 
+				return context;
+			}
+
+			contextMap.put(ifile, NO_CONTEXT); // prevent recursion
+			final IIndexInclude contextInclude= ifile.getParsedInContext();
+			if (contextInclude != null) {
+				final IIndexFragmentFile contextIFile= (IIndexFragmentFile) contextInclude.getIncludedBy();
+				context= findContext(contextIFile, contextMap);
+				if (context != null) {
+					contextMap.put(ifile, context);
+					return context;
+				}
+			}
+		} catch (CoreException e) {
+			CCorePlugin.log(e);
+		}
+		return null;
+	}
+
+	private void parseFile(Object tu, int linkageID, IIndexFileLocation ifl, IScannerInfo scanInfo, IProgressMonitor pm) throws CoreException, InterruptedException {
+		IPath path= getPathForLabel(ifl);
+		AbstractLanguage[] langs= fResolver.getLanguages(tu);
+		AbstractLanguage lang= null;
+		for (int i = 0; i < langs.length; i++) {
+			if (langs[i].getLinkageID() == linkageID) {
+				lang= langs[i];
+				break;
+			}
+		}
+		if (lang==null) {
+			return;
+		}
+		
+		try {
+			if (fShowActivity) {
+				System.out.println("Indexer: parsing " + path.toOSString()); //$NON-NLS-1$
+			}
+			pm.subTask(MessageFormat.format(Messages.AbstractIndexerTask_parsingFileTask,
+					new Object[]{path.lastSegment(), path.removeLastSegments(1).toString()}));
+			long start= System.currentTimeMillis();
+			IASTTranslationUnit ast= createAST(tu, lang, scanInfo, fASTOptions, pm);
+			fStatistics.fParsingTime += System.currentTimeMillis()-start;
+			if (ast != null) {
+				writeToIndex(linkageID, ast, computeHashCode(scanInfo), pm);
+			}
+		}
+		catch (CoreException e) {
+			swallowError(path, e); 
+		}
+		catch (RuntimeException e) {
+			swallowError(path, e); 
+		}
+		catch (PDOMNotImplementedError e) {
+			swallowError(path, e); 
+		}
+	}
+	
+	private void writeToIndex(final int linkageID, IASTTranslationUnit ast, int configHash, IProgressMonitor pm) throws CoreException, InterruptedException {
+		HashSet enteredASTFilePaths= new HashSet();
+		ArrayList orderedIFLs= new ArrayList();
+		final String astPath = ast.getFilePath();
+		enteredASTFilePaths.add(astPath);
+		
+		IDependencyTree tree= ast.getDependencyTree();
+		IASTInclusionNode[] inclusions= tree.getInclusions();
+		for (int i=0; i < inclusions.length; i++) {
+			collectOrderedIFLs(linkageID, inclusions[i], enteredASTFilePaths, orderedIFLs);
+		}
+		
+		IIndexFileLocation ifl= fResolver.resolveASTPath(astPath);
+		FileInfo info= getFileInfo(linkageID, ifl);
+		if (info != null && info.fRequestUpdate && !info.fIsUpdated) {
+			orderedIFLs.add(fResolver.resolveASTPath(astPath));
+		}
+		
+		IIndexFileLocation[] ifls= (IIndexFileLocation[]) orderedIFLs.toArray(new IIndexFileLocation[orderedIFLs.size()]);
+		addSymbols(ast, ifls, fIndex, 1, false, configHash, fTodoTaskUpdater, pm);
+		for (int i = 0; i < ifls.length; i++) {
+			ifl= ifls[i];
+			info= getFileInfo(linkageID, ifl);
+			assert info != null;
+			if (info != null) {
+				info.fIsUpdated= true;
+			}
+		}
+	}
+
+	private void collectOrderedIFLs(final int linkageID, IASTInclusionNode inclusion, HashSet enteredASTFilePaths, ArrayList orderedIFLs) throws CoreException {
+		final IASTPreprocessorIncludeStatement id= inclusion.getIncludeDirective();
+		if (id.isActive() && id.isResolved()) {
+			final String path= id.getPath();
+			final boolean isFirst= enteredASTFilePaths.add(path);
+			IASTInclusionNode[] nested= inclusion.getNestedInclusions();
+			for (int i = 0; i < nested.length; i++) {
+				collectOrderedIFLs(linkageID, nested[i], enteredASTFilePaths, orderedIFLs);
+			}
+			if (isFirst) {
+				final IIndexFileLocation ifl= fResolver.resolveASTPath(path);
+				if (needToUpdateHeader(linkageID, ifl)) {
+					orderedIFLs.add(ifl);
+				}
+			}
+		}
+	}
+
+	public final boolean needToUpdateHeader(int linkageID, IIndexFileLocation ifl) throws CoreException {
+		FileInfo info= getFileInfo(linkageID, ifl);
+		if (info == null) {
+			IIndexFile ifile= null;
+			if (fResolver.canBePartOfSDK(ifl)) {
+				ifile= fIndex.getFile(linkageID, ifl);
+			}
+			else {
+				IIndexFragmentFile fragFile= fIndex.getWritableFile(linkageID, ifl);
+				if (fragFile != null && fragFile.hasContent()) {
+					ifile= fragFile;
+				}
+			}
+			info= createFileInfo(new FileKey(linkageID, ifl.getURI()), ifile);
+			if (ifile == null) {
+				if (info.fRequestUpdate && !info.fIsUpdated) {
+					updateInfo(0,0,-1);	// header found implicitly
+				}
+				info.fRequestUpdate= true;
+			}
+		} 
+		return !info.fIsUpdated && info.fRequestUpdate;
+	}
+
+	private IPath getPathForLabel(IIndexFileLocation ifl) {
+		String fullPath= ifl.getFullPath();
+		if (fullPath != null) {
+			return new Path(fullPath);
+		}
+		IPath path= IndexLocationFactory.getAbsolutePath(ifl);
+		if (path != null) {
+			return path;
+		}
+		URI uri= ifl.getURI();
+		return new Path(uri.getPath());
+	}
+
+	private void swallowError(IPath file, Throwable e) throws CoreException {
+		if (e instanceof CoreException) {
+			CCorePlugin.log(((CoreException) e).getStatus());
+		}
+		else {
+			IStatus status= CCorePlugin.createStatus(
+					MessageFormat.format(Messages.AbstractIndexerTask_errorWhileParsing, new Object[]{file}), e);
+			CCorePlugin.log(status);
+		}
+		if (++fStatistics.fErrorCount > MAX_ERRORS) {
+			throw new CoreException(CCorePlugin.createStatus(Messages.AbstractIndexerTask_tooManyIndexProblems));
+		}
+	}
+
+	private static int computeHashCode(IScannerInfo scannerInfo) {
+		int result= 0;
+		Map macros= scannerInfo.getDefinedSymbols();
+		if (macros != null) {
+			for (Iterator i = macros.entrySet().iterator(); i.hasNext();) {
+				Map.Entry entry = (Map.Entry) i.next();
+				String key = (String) entry.getKey();
+				String value = (String) entry.getValue();
+				result= addToHashcode(result, key);
+				if (value != null && value.length() > 0) {
+					result= addToHashcode(result, value);
+				}
+			}
+		}
+		String[] a= scannerInfo.getIncludePaths();
+		if (a != null) {
+			for (int i = 0; i < a.length; i++) {
+				result= addToHashcode(result, a[i]);
+
+			}
+		}
+		if (scannerInfo instanceof IExtendedScannerInfo) {
+			IExtendedScannerInfo esi= (IExtendedScannerInfo) scannerInfo;
+			a= esi.getIncludeFiles();
+			if (a != null) {
+				for (int i = 0; i < a.length; i++) {
+					result= addToHashcode(result, a[i]);
+
+				}
+			}			
+			a= esi.getLocalIncludePath();
+			if (a != null) {
+				for (int i = 0; i < a.length; i++) {
+					result= addToHashcode(result, a[i]);
+
+				}
+			}		
+			a= esi.getMacroFiles();
+			if (a != null) {
+				for (int i = 0; i < a.length; i++) {
+					result= addToHashcode(result, a[i]);
+
+				}
+			}		
+		}
+		return result;
+	}
+
+	private static int addToHashcode(int result, String key) {
+		return result*31 + key.hashCode();
+	}
+
+	public final IMacro[] getConvertedMacros(int linkageID, IIndexFileLocation ifl) throws CoreException {
+		if (!needToUpdateHeader(linkageID, ifl)) {
+			FileInfo info= getFileInfo(linkageID, ifl);
+			assert info != null;
+			if (info != null) {
+				if (info.fIndexFile == null) {
+					info.fIndexFile= fIndex.getFile(linkageID, ifl);
+					if (info.fIndexFile == null) {
+						return null;
+					}
+				}
+				IMacro[] result= info.fMacros;
+				if (result == null) {
+					IIndexMacro[] macros= info.fIndexFile.getMacros();
+					result= new IMacro[macros.length];
+					for (int i = 0; i < macros.length; i++) {
+						IIndexMacro macro = macros[i];
+						result[i]= ((PDOMMacro)macro).getMacro();
+					}
+					info.fMacros= result;
+				}
+				return result;
+			}
+		}
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerInputAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerInputAdapter.java
new file mode 100644
index 00000000000..47180905fa8
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerInputAdapter.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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.pdom;
+
+import org.eclipse.cdt.core.index.IIndexFileLocation;
+import org.eclipse.cdt.core.model.AbstractLanguage;
+import org.eclipse.cdt.core.parser.CodeReader;
+import org.eclipse.cdt.core.parser.IScannerInfo;
+
+/**
+ * Abstract class to obtain information about the input to the indexer. For the 
+ * project based indexers the input are translation units, for the stand-alone
+ * indexer they are file-paths represented as strings.
+ * @since 5.0
+ */
+public abstract class IndexerInputAdapter extends ASTFilePathResolver {
+
+	/**
+	 * Returns an object representing an input file for the given index location,
+	 * or null, if it does not exist.
+	 */
+	public abstract Object getInputFile(IIndexFileLocation location);
+
+	/**
+	 * Return the last modification date for the file denoted by the index location.
+	 */
+	public abstract long getLastModified(IIndexFileLocation location);
+
+	/**
+	 * Create an index location for the given input file.
+	 */
+	public abstract IIndexFileLocation resolveFile(Object tu);
+
+	/**
+	 * Tests whether the input file is a source unit.
+	 */
+	public abstract boolean isSourceUnit(Object tu);
+
+	/**
+	 * Tests whether the input file is part of the build.
+	 */
+	public abstract boolean isFileBuildConfigured(Object tu);
+
+	/**
+	 * Tests whether the file in the index is allowed to be part of an SDK. If not
+	 * it will be indexed.
+	 */
+	public abstract boolean canBePartOfSDK(IIndexFileLocation ifl);
+
+	/**
+	 * Obtains the languages the input file should be parsed with.
+	 */
+	public abstract AbstractLanguage[] getLanguages(Object tu);
+
+	/**
+	 * Obtains the scanner configuration for the input file.
+	 */
+	public abstract IScannerInfo getBuildConfiguration(int linkageID, Object tu);
+
+	/**
+	 * Returns a code reader for the given input file.
+	 */
+	public abstract CodeReader getCodeReader(Object tu);
+
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerStatistics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerStatistics.java
similarity index 94%
rename from core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerStatistics.java
rename to core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerStatistics.java
index 7b45dd45354..48e1cc0430e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerStatistics.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerStatistics.java
@@ -9,7 +9,7 @@
  *    Markus Schorn - initial API and implementation
  *******************************************************************************/ 
 
-package org.eclipse.cdt.internal.core.pdom.indexer;
+package org.eclipse.cdt.internal.core.pdom;
 
 public class IndexerStatistics {
 	public int fResolutionTime;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/Messages.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/Messages.java
index 272a37a9ef0..4558752d4ed 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/Messages.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/Messages.java
@@ -32,6 +32,9 @@ public class Messages extends NLS {
 	public static String TeamPDOMExportOperation_subtaskCreateDatabase;
 	public static String TeamPDOMExportOperation_taskExportIndex;
 	public static String WritablePDOM_error_unknownLinkage;
+	public static String AbstractIndexerTask_parsingFileTask;
+	public static String AbstractIndexerTask_errorWhileParsing;
+	public static String AbstractIndexerTask_tooManyIndexProblems;
 	static {
 		// initialize resource bundle
 		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
index aded3430b6c..eae61ce4a6a 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
@@ -90,7 +90,7 @@ public class PDOM extends PlatformObject implements IPDOM {
 	 */
 	public static final String FRAGMENT_PROPERTY_VALUE_FORMAT_ID= "org.eclipse.cdt.internal.core.pdom.PDOM"; //$NON-NLS-1$
 	
-	public static final int CURRENT_VERSION = 51;
+	public static final int CURRENT_VERSION = 52;
 	public static final int MIN_SUPPORTED_VERSION= CURRENT_VERSION;
 	
 	/**
@@ -151,6 +151,7 @@ public class PDOM extends PlatformObject implements IPDOM {
 	 *  
 	 *  50 - support for complex, imaginary and long long (bug 209049).
 	 *  51 - modeling extern "C" (bug 191989)
+	 *  52 - files per linkage (bug 191989)
 	 */
 	
 	public static final int LINKAGES = Database.DATA_AREA;
@@ -261,11 +262,15 @@ public class PDOM extends PlatformObject implements IPDOM {
 		return fileIndex;
 	}
 
-	public IIndexFragmentFile getFile(IIndexFileLocation location) throws CoreException {
-		return PDOMFile.findFile(this, getFileIndex(), location, locationConverter);
+	public IIndexFragmentFile getFile(int linkageID, IIndexFileLocation location) throws CoreException {
+		return PDOMFile.findFile(this, getFileIndex(), location, linkageID, locationConverter);
 	}
 
-	public List/**/ getAllFileLocations() throws CoreException {
+	public IIndexFragmentFile[] getFiles(IIndexFileLocation location) throws CoreException {
+		return PDOMFile.findFiles(this, getFileIndex(), location, locationConverter);
+	}
+
+	public IIndexFragmentFile[] getAllFiles() throws CoreException {
 		final List locations = new ArrayList();
 		getFileIndex().accept(new IBTreeVisitor(){
 			public int compare(int record) throws CoreException {
@@ -273,17 +278,17 @@ public class PDOM extends PlatformObject implements IPDOM {
 			}
 			public boolean visit(int record) throws CoreException {
 				PDOMFile file = new PDOMFile(PDOM.this, record);
-				locations.add(file.getLocation());
+				locations.add(file);
 				return true;
 			}
 		});
-		return locations;
+		return (IIndexFragmentFile[]) locations.toArray(new IIndexFragmentFile[locations.size()]);
 	}
 	
-	protected IIndexFragmentFile addFile(IIndexFileLocation location) throws CoreException {
-		IIndexFragmentFile file = getFile(location);
+	protected IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location) throws CoreException {
+		IIndexFragmentFile file = getFile(linkageID, location);
 		if (file == null) {
-			PDOMFile pdomFile = new PDOMFile(this, location);
+			PDOMFile pdomFile = new PDOMFile(this, location, linkageID);
 			getFileIndex().insert(pdomFile.getRecord());
 			file= pdomFile;
 		}
@@ -758,7 +763,7 @@ public class PDOM extends PlatformObject implements IPDOM {
 			return (PDOMFile) file;
 		}
 
-		return (PDOMFile) getFile(file.getLocation());
+		return (PDOMFile) getFile(file.getLinkageID(), file.getLocation());
 	}
 
 	public File getPath() {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMIndexerJob.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMIndexerJob.java
index 00d4e5bfb6d..2a5142c676a 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMIndexerJob.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMIndexerJob.java
@@ -93,6 +93,9 @@ public class PDOMIndexerJob extends Job {
 							System.out.println("Indexer: completed " + name + "[" + time + "ms]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 						}
 					}
+					catch (InterruptedException e) {
+						Thread.currentThread().interrupt();
+					}
 					catch (OperationCanceledException e) {
 					}
 				}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java
index f40d73101bd..73ccbfac686 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java
@@ -64,10 +64,10 @@ import org.eclipse.cdt.internal.core.pdom.PDOM.IListener;
 import org.eclipse.cdt.internal.core.pdom.db.ChunkCache;
 import org.eclipse.cdt.internal.core.pdom.dom.PDOMProjectIndexLocationConverter;
 import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
+import org.eclipse.cdt.internal.core.pdom.indexer.PDOMNullIndexer;
 import org.eclipse.cdt.internal.core.pdom.indexer.PDOMRebuildTask;
 import org.eclipse.cdt.internal.core.pdom.indexer.PDOMUpdateTask;
 import org.eclipse.cdt.internal.core.pdom.indexer.TriggerNotificationTask;
-import org.eclipse.cdt.internal.core.pdom.indexer.nulli.PDOMNullIndexer;
 import org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager;
 import org.eclipse.core.resources.IFolder;
 import org.eclipse.core.resources.IProject;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java
index de108946e10..1794f15cf08 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java
@@ -120,13 +120,20 @@ public class PDOMProxy implements IPDOM {
 		return 0;
 	}
 
-	public synchronized IIndexFragmentFile getFile(IIndexFileLocation location) throws CoreException {
+	public synchronized IIndexFragmentFile getFile(int linkageID, IIndexFileLocation location) throws CoreException {
 		if (fDelegate != null)
-			return fDelegate.getFile(location);
+			return fDelegate.getFile(linkageID, location);
 
 		return null;
 	}
 
+	public synchronized IIndexFragmentFile[] getFiles(IIndexFileLocation location) throws CoreException {
+		if (fDelegate != null)
+			return fDelegate.getFiles(location);
+
+		return IIndexFragmentFile.EMPTY_ARRAY;
+	}
+
 	public synchronized long getLastWriteAccess() {
 		if (fDelegate != null)
 			return fDelegate.getLastWriteAccess();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java
index 0b298409d1b..cbf5c3881a1 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java
@@ -17,7 +17,6 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
-import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -44,13 +43,10 @@ import org.eclipse.cdt.core.index.IIndexFileLocation;
 import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
 import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
 import org.eclipse.cdt.internal.core.index.IWritableIndex;
-import org.eclipse.cdt.internal.core.index.IndexFileLocation;
 import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
 import org.eclipse.cdt.internal.core.pdom.dom.PDOMASTAdapter;
 import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError;
 import org.eclipse.cdt.internal.core.pdom.indexer.IndexerASTVisitor;
-import org.eclipse.cdt.internal.core.pdom.indexer.IndexerStatistics;
-import org.eclipse.core.filesystem.EFS;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
@@ -68,13 +64,15 @@ abstract public class PDOMWriter {
 	
 	protected boolean fShowActivity;
 	protected boolean fShowProblems;
-	protected IndexerStatistics fStatistics;
+	protected final IndexerStatistics fStatistics;
+	protected final IndexerInputAdapter fResolver;
 	
 	private IndexerProgress fInfo= new IndexerProgress();
 	private int fSkipReferences= SKIP_NO_REFERENCES;
 	
-	public PDOMWriter() {
+	public PDOMWriter(IndexerInputAdapter resolver) {
 		fStatistics= new IndexerStatistics();
+		fResolver= resolver;
 	}
 	
 	public void setShowActivity(boolean val) {
@@ -93,38 +91,10 @@ abstract public class PDOMWriter {
 		fSkipReferences= options;
 	}
 	
-	/**
-	 * Called to check whether a translation unit still needs to be updated.
-	 * @see #addSymbols(IASTTranslationUnit, IWritableIndex, int, IProgressMonitor)
-	 * @since 4.0
-	 */
-	protected abstract boolean needToUpdate(IIndexFileLocation location, int confighash) throws CoreException;
-
-	/**
-	 * Called after a file was added to the index. 
-	 * @return whether the file was actually requested by the indexer.
-	 * @see #addSymbols(IASTTranslationUnit, IWritableIndex, int, IProgressMonitor)
-	 * @since 4.0
-	 */
-	protected abstract boolean postAddToIndex(IIndexFileLocation location, IIndexFile file) throws CoreException;
-
-	/**
-	 * Called to resolve an absolute path to an index file location. 
-	 * @since 4.0
-	 */
-	protected abstract IIndexFileLocation findLocation(String absolutePath);
-		
-	/**
-	 * Fully equivalent to 
-	 * addSymbols(IASTTranslationUnit, IWritableIndex, int, true, int, null, IProgressMonitor).
-	 * @since 4.0
-	 */
-	public void addSymbols(IASTTranslationUnit ast, 
-			IWritableIndex index, int readlockCount,
-			int configHash, IProgressMonitor pm) throws InterruptedException, CoreException {
-		addSymbols(ast, index, readlockCount, true, configHash, null, pm);
+	public int getSkipReferences() {
+		return fSkipReferences;
 	}
-
+			
 	/**
 	 * Extracts symbols from the given ast and adds them to the index. It will
 	 * make calls to 	  
@@ -137,124 +107,31 @@ abstract public class PDOMWriter {
 	 * index after your last write operation.
 	 * @since 4.0
 	 */
-	public void addSymbols(IASTTranslationUnit ast, 
-			IWritableIndex index, int readlockCount, boolean flushIndex,
-			int configHash, ITodoTaskUpdater taskUpdater, IProgressMonitor pm) throws InterruptedException, CoreException {
+	public void addSymbols(IASTTranslationUnit ast, IIndexFileLocation[] ifls, IWritableIndex index, 
+			int readlockCount, boolean flushIndex, int configHash, ITodoTaskUpdater taskUpdater, IProgressMonitor pm) 
+			throws InterruptedException, CoreException {
 		final Map symbolMap= new HashMap();
-		ArrayList stati= new ArrayList();
-		IIndexFileLocation[] orderedPaths= null;
-		try {
-			HashSet contextIncludes= new HashSet();
-			orderedPaths= extractSymbols(ast, symbolMap, configHash, contextIncludes);
-			for (int i=0; i 0) {
-				path= orderedPaths[orderedPaths.length-1].getURI().getPath();
+			if (ifls != null && ifls.length > 0) {
+				path= ifls[ifls.length-1].getURI().getPath();
 			}
 			else {
 				path= ast.getFilePath().toString();
@@ -271,74 +148,120 @@ abstract public class PDOMWriter {
 		}
 	}
 
-	private IIndexFileLocation[] extractSymbols(IASTTranslationUnit ast, 
-			final Map symbolMap, int confighash, Collection contextIncludes) throws CoreException {
-		LinkedHashSet/**/ orderedIFLs= new LinkedHashSet/**/();
-		ArrayList/**/ iflStack= new ArrayList/**/();
-		HashMap firstIncludePerTarget= new HashMap();
-		
-		final IIndexFileLocation astLocation = findLocation(ast.getFilePath());
-		IIndexFileLocation aboveStackIFL = astLocation;
+	private void storeSymbolsInIndex(final Map symbolMap, IIndexFileLocation[] ifls, int linkageID, int configHash,
+			HashSet contextIncludes, IWritableIndex index, int readlockCount, boolean flushIndex,
+			ArrayList stati, IProgressMonitor pm) throws InterruptedException, CoreException {
+		index.acquireWriteLock(readlockCount);
+		long start= System.currentTimeMillis();
+		try {
+			for (int i=0; i= 0) {
+				cmp= db.getInt(record + PDOMFile.LINKAGE_ID) - linkageID;
+			}
+			return cmp;
 		}
 
 		public boolean visit(int record) throws CoreException {
-			this.record = record;
-			return false;
+			if (linkageID >= 0) {
+				this.record = record;
+				return false;
+			}
+			if (this.record == 0) {
+				this.record= record;
+			}
+			else if (this.records == null) {
+				this.records= new int[] {this.record, record};
+			}
+			else {
+				int[] cpy= new int[this.records.length+1];
+				System.arraycopy(this.records, 0, cpy, 0, this.records.length);
+				cpy[cpy.length-1]= record;
+				this.records= cpy;
+			}
+			return linkageID < 0;
 		}
 
 		public int getRecord() {
@@ -422,8 +485,8 @@ public class PDOMFile implements IIndexFragmentFile {
 		return result;
 	}
 	
-	public boolean hasNames() throws CoreException {
-		return getFirstName()!=null || getFirstMacro() != null || getFirstInclude() != null;
+	public boolean hasContent() throws CoreException {
+		return getTimestamp() != -1;
 	}
 
 	public void convertIncludersToUnresolved() throws CoreException {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/AbstractPDOMIndexer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/AbstractPDOMIndexer.java
index d58745b98ae..289d7bfe057 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/AbstractPDOMIndexer.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/AbstractPDOMIndexer.java
@@ -18,6 +18,9 @@ import java.util.Properties;
 import org.eclipse.cdt.core.dom.IPDOMIndexer;
 import org.eclipse.cdt.core.model.ICProject;
 
+/**
+ * Abstract base class for all indexers.
+ */
 public abstract class AbstractPDOMIndexer implements IPDOMIndexer {
 	
 	protected ICProject project;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/DeltaAnalyzer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/DeltaAnalyzer.java
index 812f23fd43d..3f5b22d96ff 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/DeltaAnalyzer.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/DeltaAnalyzer.java
@@ -74,7 +74,7 @@ public class DeltaAnalyzer {
 	}
 
 	private void collectSources(ICContainer container, Collection sources) throws CoreException {
-		container.accept(new TranslationUnitCollector(sources, sources, true, new NullProgressMonitor()));
+		container.accept(new TranslationUnitCollector(sources, sources, new NullProgressMonitor()));
 	}
 
 	public ITranslationUnit[] getAddedTUs() {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/Messages.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/Messages.java
index 72488747abc..637e7df38ba 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/Messages.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/Messages.java
@@ -18,9 +18,6 @@ public class Messages extends NLS {
 	public static String PDOMImportTask_errorInvalidArchive;
 	public static String PDOMImportTask_errorInvalidPDOMVersion;
 	public static String PDOMIndexerTask_collectingFilesTask;
-	public static String PDOMIndexerTask_errorWhileParsing;
-	public static String PDOMIndexerTask_parsingFileTask;
-	public static String PDOMIndexerTask_tooManyIndexProblems;
 	public static String TodoTaskUpdater_DeleteJob;
 	public static String TodoTaskUpdater_taskFormat;
 	public static String TodoTaskUpdater_UpdateJob;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFastIndexer.java
similarity index 71%
rename from core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexer.java
rename to core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFastIndexer.java
index 12913b85837..381625b9c6a 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexer.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFastIndexer.java
@@ -6,21 +6,19 @@
  * http://www.eclipse.org/legal/epl-v10.html
  *
  * Contributors:
- * QNX - Initial API and implementation
- * Markus Schorn (Wind River Systems)
+ *    QNX - Initial API and implementation
+ *    Markus Schorn (Wind River Systems)
  *******************************************************************************/
 
-package org.eclipse.cdt.internal.core.pdom.indexer.fast;
+package org.eclipse.cdt.internal.core.pdom.indexer;
 
 
 import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
 import org.eclipse.cdt.core.dom.IPDOMManager;
 import org.eclipse.cdt.core.model.ITranslationUnit;
-import org.eclipse.cdt.internal.core.pdom.indexer.AbstractPDOMIndexer;
 
 /**
- * @author Doug Schaefer
- *
+ * Configures the abstract indexer to return tasks suitable for fast indexing.
  */
 public class PDOMFastIndexer extends AbstractPDOMIndexer {
 	// Must match extension id
@@ -30,8 +28,7 @@ public class PDOMFastIndexer extends AbstractPDOMIndexer {
 		return ID;
 	}
 
-	public IPDOMIndexerTask createTask(ITranslationUnit[] added,
-			ITranslationUnit[] changed, ITranslationUnit[] removed) {
+	public IPDOMIndexerTask createTask(ITranslationUnit[] added, ITranslationUnit[] changed, ITranslationUnit[] removed) {
 		return new PDOMFastIndexerTask(this, added, changed, removed);
 	}
 }
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFastIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFastIndexerTask.java
new file mode 100644
index 00000000000..0ae5aae3547
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFastIndexerTask.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 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
+ *
+ * Contributors:
+ *    QNX - Initial API and implementation
+ *    Markus Schorn (Wind River Systems)
+ *******************************************************************************/
+
+package org.eclipse.cdt.internal.core.pdom.indexer;
+
+import org.eclipse.cdt.core.dom.ICodeReaderFactory;
+import org.eclipse.cdt.core.model.ITranslationUnit;
+
+/**
+ * Configures the abstract indexer to return tasks suitable for fast indexing.
+ */
+class PDOMFastIndexerTask extends PDOMIndexerTask {
+	public PDOMFastIndexerTask(PDOMFastIndexer indexer, ITranslationUnit[] added, 
+			ITranslationUnit[] changed, ITranslationUnit[] removed) {
+		super(added, changed, removed, indexer, true);
+	}
+
+	protected ICodeReaderFactory createReaderFactory() {
+		return null;
+	}
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFullIndexer.java
similarity index 84%
rename from core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexer.java
rename to core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFullIndexer.java
index 1ac78548d78..040d93706cf 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexer.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFullIndexer.java
@@ -6,16 +6,15 @@
  * http://www.eclipse.org/legal/epl-v10.html
  *
  * Contributors:
- * QNX - Initial API and implementation
- * Markus Schorn (Wind River Systems)
+ *    QNX - Initial API and implementation
+ *    Markus Schorn (Wind River Systems)
  *******************************************************************************/
 
-package org.eclipse.cdt.internal.core.pdom.indexer.full;
+package org.eclipse.cdt.internal.core.pdom.indexer;
 
 import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
 import org.eclipse.cdt.core.dom.IPDOMManager;
 import org.eclipse.cdt.core.model.ITranslationUnit;
-import org.eclipse.cdt.internal.core.pdom.indexer.AbstractPDOMIndexer;
 
 /**
  * The Full indexer does full parsing in order to gather index information.
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFullIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFullIndexerTask.java
new file mode 100644
index 00000000000..b9f97b4203c
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMFullIndexerTask.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 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
+ *
+ * Contributors:
+ *    QNX - Initial API and implementation
+ *    Markus Schorn (Wind River Systems)
+ *******************************************************************************/
+
+package org.eclipse.cdt.internal.core.pdom.indexer;
+
+import org.eclipse.cdt.core.dom.ICodeReaderFactory;
+import org.eclipse.cdt.core.model.ITranslationUnit;
+import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory;
+
+
+/**
+ * Configures the indexer task as a fast indexer task.
+ */
+class PDOMFullIndexerTask extends PDOMIndexerTask {
+	public PDOMFullIndexerTask(PDOMFullIndexer indexer, ITranslationUnit[] added, 
+			ITranslationUnit[] changed, ITranslationUnit[] removed) {
+		super(added, changed, removed, indexer, false);
+	}
+
+	protected ICodeReaderFactory createReaderFactory() {
+		return SavedCodeReaderFactory.getInstance();
+	}
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java
index 00e5e3f04fd..0a3b70763ab 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java
@@ -12,70 +12,44 @@
 
 package org.eclipse.cdt.internal.core.pdom.indexer;
 
-import java.net.URI;
-import java.text.MessageFormat;
 import java.text.NumberFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
 
 import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.dom.ILinkage;
 import org.eclipse.cdt.core.dom.IPDOMIndexer;
 import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
-import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
-import org.eclipse.cdt.core.index.IIndex;
-import org.eclipse.cdt.core.index.IIndexFile;
-import org.eclipse.cdt.core.index.IIndexFileLocation;
-import org.eclipse.cdt.core.index.IIndexInclude;
-import org.eclipse.cdt.core.index.IIndexManager;
-import org.eclipse.cdt.core.index.IndexLocationFactory;
 import org.eclipse.cdt.core.model.AbstractLanguage;
-import org.eclipse.cdt.core.model.CoreModelUtil;
 import org.eclipse.cdt.core.model.ICProject;
 import org.eclipse.cdt.core.model.ILanguage;
 import org.eclipse.cdt.core.model.ITranslationUnit;
 import org.eclipse.cdt.core.model.LanguageManager;
-import org.eclipse.cdt.core.parser.CodeReader;
-import org.eclipse.cdt.core.parser.IExtendedScannerInfo;
 import org.eclipse.cdt.core.parser.IScannerInfo;
 import org.eclipse.cdt.core.parser.IScannerInfoProvider;
 import org.eclipse.cdt.core.parser.ScannerInfo;
-import org.eclipse.cdt.internal.core.CContentTypes;
-import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
 import org.eclipse.cdt.internal.core.index.IWritableIndex;
+import org.eclipse.cdt.internal.core.index.IWritableIndexManager;
+import org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask;
 import org.eclipse.cdt.internal.core.pdom.ITodoTaskUpdater;
 import org.eclipse.cdt.internal.core.pdom.IndexerProgress;
-import org.eclipse.cdt.internal.core.pdom.PDOMWriter;
 import org.eclipse.cdt.internal.core.pdom.db.ChunkCache;
 import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.content.IContentType;
 
-public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexerTask {
-	private static final Object NO_CONTEXT = new Object();
-	private static final int MAX_ERRORS = 500;
+/**
+ * Configures the abstract indexer task suitable for indexing projects.
+ */
+public abstract class PDOMIndexerTask extends AbstractIndexerTask implements IPDOMIndexerTask {
 	private static final String TRUE = "true"; //$NON-NLS-1$
 	
 	private AbstractPDOMIndexer fIndexer;
-	protected Map/**/ fContextMap = new HashMap/**/();
-	private List fFilesUpFront= new ArrayList();
-	private String fDummyFileName;
-	private URI fDummyFileURI;
-	private int fUpdateFlags= IIndexManager.UPDATE_ALL;
-	private boolean fAllFilesProvided= true;
-
-	protected PDOMIndexerTask(AbstractPDOMIndexer indexer) {
+	
+	protected PDOMIndexerTask(ITranslationUnit[] addFiles, ITranslationUnit[] updateFiles, ITranslationUnit[] removeFiles, 
+			AbstractPDOMIndexer indexer, boolean isFastIndexer) {
+		super(concat(addFiles, updateFiles), removeFiles, new ProjectIndexerInputAdapter(indexer.getProject()), isFastIndexer);
 		fIndexer= indexer;
 		setShowActivity(checkDebugOption(TRACE_ACTIVITY, TRUE));
 		setShowProblems(checkDebugOption(TRACE_PROBLEMS, TRUE));
@@ -85,47 +59,42 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer
 		else if (checkProperty(IndexerPreferences.KEY_SKIP_TYPE_REFERENCES)) {
 			setSkipReferences(SKIP_TYPE_REFERENCES);
 		}
+		if (getIndexAllFiles()) {
+			setIndexFilesWithoutBuildConfiguration(true);
+			setIndexHeadersWithoutContext(true);
+		}
+		else {
+			setIndexFilesWithoutBuildConfiguration(false);
+			setIndexHeadersWithoutContext(false);
+		}
+	}
+	
+	private static ITranslationUnit[] concat(ITranslationUnit[] added, ITranslationUnit[] changed) {
+		ITranslationUnit[] result= new ITranslationUnit[added.length+changed.length];
+		System.arraycopy(added, 0, result, 0, added.length);
+		System.arraycopy(changed, 0, result, added.length, changed.length);
+		return result;
+	}
+	
+	public final void setParseUpFront() {
+		setParseUpFront(fIndexer.getFilesToParseUpFront());
 	}
 
-	final public IPDOMIndexer getIndexer() {
+
+	public final IPDOMIndexer getIndexer() {
 		return fIndexer;
 	}
 	
-	final public ICProject getProject() {
-		return fIndexer.getProject();
+	public final void run(IProgressMonitor monitor) throws InterruptedException {
+		long start = System.currentTimeMillis();
+		runTask(monitor);
+		traceEnd(start, fIndex);
 	}
 	
-	final public IndexerProgress getProgressInformation() {
+	
+	public IndexerProgress getProgressInformation() {
 		return super.getProgressInformation();
 	}
-	
-	public void setUpateFlags(int flags) {
-		fUpdateFlags= flags;
-	}
-	
-	final public boolean updateAll() {
-		return (fUpdateFlags & IIndexManager.UPDATE_ALL) != 0;
-	}
-	
-	final public boolean updateChangedTimestamps() {
-		return (fUpdateFlags & IIndexManager.UPDATE_CHECK_TIMESTAMPS) != 0;
-	}
-
-	final public boolean updateChangedConfiguration() {
-		return (fUpdateFlags & IIndexManager.UPDATE_CHECK_CONFIGURATION) != 0;
-	}
-		
-	final public void setParseUpFront() {
-		fFilesUpFront.addAll(Arrays.asList(fIndexer.getFilesToParseUpFront()));
-	}
-	
-	final public void setAllFilesProvided(boolean allFiles) {
-		fAllFilesProvided= allFiles;
-	}
-	
-	final public boolean getAllFilesProvided() {
-		return fAllFilesProvided;
-	}
 
 	/**
 	 * Checks whether a given debug option is enabled. See {@link IPDOMIndexerTask}
@@ -138,12 +107,7 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer
 		return internallyActivated || (trace != null && trace.equalsIgnoreCase(value));
 	}
 
-	/**
-	 * Figures out whether all files (sources without configuration, headers not included)
-	 * should be parsed.
-	 * @since 4.0
-	 */
-	final protected boolean getIndexAllFiles() {
+	private boolean getIndexAllFiles() {
 		return checkProperty(IndexerPreferences.KEY_INDEX_ALL_FILES);
 	}
 
@@ -151,362 +115,63 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer
 		return TRUE.equals(getIndexer().getProperty(key));
 	}
 
-	private IASTTranslationUnit createAST(ITranslationUnit tu, IScannerInfo scannerInfo, int options, IProgressMonitor pm) throws CoreException {
-		IPath path = tu.getLocation();
-		if (path == null) {
+	
+	protected String getASTPathForParsingUpFront() {
+		final IProject project = getProject().getProject();
+		final IPath prjLocation= project.getLocation();
+		if (prjLocation == null) {
 			return null;
 		}
-		ILanguage language = tu.getLanguage();
-		if (!(language instanceof AbstractLanguage))
-			return null;
-
-		CodeReader codeReader = tu.getCodeReader();
-		if (codeReader == null) {
-			return null;
-		}
-		
-		IASTTranslationUnit ast= createAST((AbstractLanguage) language, codeReader, scannerInfo, options, pm);
-		if (ast != null) {
-			ast.setIsHeaderUnit(tu.isHeaderUnit());
-		}
-		return ast;
+		return prjLocation.append(super.getASTPathForParsingUpFront()).toString(); 
 	}
 
-	/**
-	 * Called to create the ast for a translation unit or a pre-parsed file. 
-	 * May return null.
-	 * @see #parseTUs(IWritableIndex, int, Collection, Collection, IProgressMonitor)
-	 * @since 4.0
-	 */
-	abstract protected IASTTranslationUnit createAST(AbstractLanguage lang, CodeReader codeReader,
-			IScannerInfo scanInfo, int options, IProgressMonitor pm) throws CoreException;
-
-	/**
-	 * Convenience method for subclasses, parses the files calling out to the methods 
-	 * {@link #createAST(AbstractLanguage, CodeReader, IScannerInfo, int, IProgressMonitor)}, 
-	 * {@link #needToUpdate(IIndexFileLocation,int)}, 
-	 * {@link #addSymbols(IASTTranslationUnit, IWritableIndex, int, IProgressMonitor)}
-	 * {@link #postAddToIndex(IIndexFileLocation, IIndexFile)},
-	 * {@link #getLastModified(IIndexFileLocation)} and
-	 * {@link #findLocation(String)}
-	 * @since 4.0
-	 */
-	protected void parseTUs(IWritableIndex index, int readlockCount, Collection sources, Collection headers, IProgressMonitor monitor) throws CoreException, InterruptedException {
-		try {
-			internalParseTUs(index, readlockCount, sources, headers, monitor);
-		}
-		finally {
-			index.flush();
-		}
-	}
-	
-	private void internalParseTUs(IWritableIndex index, int readlockCount, Collection sources, Collection headers, IProgressMonitor monitor) throws CoreException, InterruptedException {
-		TodoTaskUpdater taskUpdater = new TodoTaskUpdater();
-
-		int options= AbstractLanguage.OPTION_ADD_COMMENTS | AbstractLanguage.OPTION_NO_IMAGE_LOCATIONS;
-		if (checkProperty(IndexerPreferences.KEY_SKIP_ALL_REFERENCES)) {
-			options |= AbstractLanguage.OPTION_SKIP_FUNCTION_BODIES;
-		}
-		for (Iterator iter = fFilesUpFront.iterator(); iter.hasNext();) {
-			String upfront= (String) iter.next();
-			parseUpFront(upfront, options, index, readlockCount, taskUpdater, monitor);
-		}
-
-		// sources first
-		sources= sortByContentType(sources);
-		for (Iterator iter = sources.iterator(); iter.hasNext();) {
-			if (monitor.isCanceled()) 
-				return;
-			ITranslationUnit tu = (ITranslationUnit) iter.next();
-			final IIndexFileLocation ifl = IndexLocationFactory.getIFL(tu);
-			if (needToUpdate(ifl, 0)) {
-				parseTU(ifl, tu, options, index, readlockCount, taskUpdater, monitor);
-			}
-		}
-
-		// headers with context
-		headers= sortByContentType(headers);
-		for (Iterator iter = headers.iterator(); iter.hasNext();) {
-			if (monitor.isCanceled()) 
-				return;
-			ITranslationUnit tu = (ITranslationUnit) iter.next();
-			final IIndexFileLocation ifl = IndexLocationFactory.getIFL(tu);
-			if (!needToUpdate(ifl, 0)) {
-				iter.remove();
-			} 
-			else {
-				ITranslationUnit context= findContext(index, ifl);
-				if (context != null) {
-					parseTU(ifl, context, options, index, readlockCount, taskUpdater, monitor);
-				}
-			}
-		}
-
-		// headers without context
-		if (getIndexAllFiles()) {
-			for (Iterator iter = headers.iterator(); iter.hasNext();) {
-				if (monitor.isCanceled()) 
-					return;
-				ITranslationUnit tu = (ITranslationUnit) iter.next();
-				final IIndexFileLocation ifl = IndexLocationFactory.getIFL(tu);
-				if (!needToUpdate(ifl, 0)) {
-					iter.remove();
-				}
-				else {
-					parseTU(ifl, tu, options, index, readlockCount, taskUpdater, monitor);
-				}
-			}
-		}
-	}
-	
-	private Collection sortByContentType(Collection sources) {
-		HashMap ctToLists= new HashMap();
-		for (Iterator iterator = sources.iterator(); iterator.hasNext();) {
-			final ITranslationUnit tu = (ITranslationUnit) iterator.next();
-			final String ct= tu.getContentTypeId();
-			List list= (List) ctToLists.get(ct);
-			if (list == null) {
-				list= new ArrayList();
-				ctToLists.put(ct, list);
-			}
-			list.add(tu);
-		}
-		if (ctToLists.size() <= 1) {
-			return sources;
-		}
-		Collection result= new ArrayList(sources.size());
-		// do C++ first
-		List list= (List) ctToLists.remove(CCorePlugin.CONTENT_TYPE_CXXSOURCE);
-		if (list != null) {
-			result.addAll(list);
-		}
-		list= (List) ctToLists.remove(CCorePlugin.CONTENT_TYPE_CXXHEADER);
-		if (list != null) {
-			result.addAll(list);
-		}
-		for (Iterator iterator = ctToLists.values().iterator(); iterator.hasNext();) {
-			list = (List) iterator.next();
-			result.addAll(list);
-		}
-		return result;
-	}
-
-	/**
-	 * Convenience method to check whether a translation unit in the index is outdated
-	 * with respect to its timestamp.
-	 * @throws CoreException
-	 * @since 4.0
-	 */
-	final protected boolean isOutdated(ITranslationUnit tu, IIndexFile indexFile) throws CoreException {
-		if (indexFile == null) {
-			return true;
-		}
-		IResource res= tu.getResource();
-		if (res != null) {
-			if (indexFile != null) {
-				if (res.getLocalTimeStamp() == indexFile.getTimestamp()) {
-					return false;
-				}
-			}
-			return true;
-		}
-		return false;
-	}
-
-
-	private void parseTU(IIndexFileLocation originator, ITranslationUnit tu, int options, IWritableIndex index,
-			int readlockCount, ITodoTaskUpdater taskUpdater, IProgressMonitor pm) throws CoreException, InterruptedException {
-		IPath path= tu.getPath();
-		try {
-			// skip if no scanner info
-			IScannerInfo scanner= tu.getScannerInfo(getIndexAllFiles());
-			if (scanner == null) {
-				updateInfo(0, 0, -1);
-			}
-			else {
-				final int configHash = computeHashCode(scanner);
-				if (needToUpdate(originator, configHash)) {
-					if (fShowActivity) {
-						System.out.println("Indexer: parsing " + path.toOSString()); //$NON-NLS-1$
-					}
-					pm.subTask(MessageFormat.format(Messages.PDOMIndexerTask_parsingFileTask,
-							new Object[]{path.lastSegment(), path.removeLastSegments(1).toString()}));
-					long start= System.currentTimeMillis();
-					IASTTranslationUnit ast= createAST(tu, scanner, options, pm);
-					fStatistics.fParsingTime += System.currentTimeMillis()-start;
-					if (ast != null) {
-						addSymbols(ast, index, readlockCount, false, configHash, taskUpdater, pm);
+	protected AbstractLanguage[] getLanguages(String filename) {
+		IContentType ct= CCorePlugin.getContentType(filename);
+		if (ct != null) {
+			ILanguage l = LanguageManager.getInstance().getLanguage(ct);
+			if (l instanceof AbstractLanguage) {
+				if (ct.getId().equals(CCorePlugin.CONTENT_TYPE_CXXHEADER) && l.getLinkageID() == ILinkage.CPP_LINKAGE_ID) {
+					ILanguage l2= LanguageManager.getInstance().getLanguageForContentTypeID(CCorePlugin.CONTENT_TYPE_CHEADER);
+					if (l2 instanceof AbstractLanguage) {
+						return new AbstractLanguage[] {(AbstractLanguage) l, (AbstractLanguage) l2};
 					}
 				}
+				return new AbstractLanguage[] {(AbstractLanguage) l};
 			}
 		}
-		catch (CoreException e) {
-			swallowError(path, e); 
-		}
-		catch (RuntimeException e) {
-			swallowError(path, e); 
-		}
-		catch (Error e) {
-			swallowError(path, e); 
-		}
+		return new AbstractLanguage[0];
 	}
 
-	private void parseUpFront(String file, int options, IWritableIndex index, int readlockCount,
-			ITodoTaskUpdater taskUpdater, IProgressMonitor pm) throws CoreException, InterruptedException {
-		file= file.trim();
-		if (file.length() == 0) {
-			return;
-		}
-		IPath path= new Path(file);
-		try {
-			if (fShowActivity) {
-				System.out.println("Indexer: parsing " + file + " up front"); //$NON-NLS-1$ //$NON-NLS-2$
-			}
-			pm.subTask(MessageFormat.format(Messages.PDOMIndexerTask_parsingFileTask,
-					new Object[]{path.lastSegment(), path.removeLastSegments(1).toString()}));
-			long start= System.currentTimeMillis();
-
-			IASTTranslationUnit ast= null;
-			final IProject project = getProject().getProject();
-			IContentType ct= CContentTypes.getContentType(project, file);
-			if (ct != null) {
-				ILanguage l = LanguageManager.getInstance().getLanguage(ct);
-				if (l instanceof AbstractLanguage) {
-					AbstractLanguage lang= (AbstractLanguage) l;
-					IScannerInfoProvider provider= CCorePlugin.getDefault().getScannerInfoProvider(project);
-					IScannerInfo scanInfo;
-					if (provider != null) { 
-						scanInfo= provider.getScannerInformation(project);
-					}
-					else {
-						scanInfo= new ScannerInfo();
-					}
-					String code= "#include \"" + file + "\"\n"; //$NON-NLS-1$ //$NON-NLS-2$
-					if (fDummyFileName == null) {
-						fDummyFileName= project.getLocation().append("___").toString(); //$NON-NLS-1$
-						fDummyFileURI= findLocation(fDummyFileName).getURI();
-					}
-					CodeReader codeReader= new CodeReader(fDummyFileName, code.toCharArray());
-					ast= createAST(lang, codeReader, scanInfo, options, pm);
-				}
-			}
-				
-			fStatistics.fParsingTime += System.currentTimeMillis()-start;
-			if (ast != null) {
-				addSymbols(ast, index, readlockCount, false, 0, taskUpdater, pm);
-				updateInfo(-1, +1, 0);
-			}
-		}
-		catch (CoreException e) {
-			swallowError(path, e); 
-		}
-		catch (RuntimeException e) {
-			swallowError(path, e); 
-		}
-		catch (Error e) {
-			swallowError(path, e); 
-		}
-	}
-
-	/**
-	 * Overrides must call super.needToUpdate(). If false is returned
-	 * this must be passed on to their caller:
-	 * 
-	 *   if (super.needToUpdate()) {
-	 *      // your code
-	 *   }
-	 *   return false;
-	 */
-	protected boolean needToUpdate(IIndexFileLocation fileLoc, int configHash) throws CoreException {
-		return fDummyFileURI==null || !fDummyFileURI.equals(fileLoc.getURI());
-	}
-	
-	private void swallowError(IPath file, Throwable e) throws CoreException {
-		if (e instanceof CoreException) {
-			CCorePlugin.log(((CoreException) e).getStatus());
+	protected IScannerInfo createDefaultScannerConfig(int linkageID) {
+		IProject project= getProject().getProject();
+		IScannerInfoProvider provider= CCorePlugin.getDefault().getScannerInfoProvider(project);
+		IScannerInfo scanInfo;
+		if (provider != null) { 
+			scanInfo= provider.getScannerInformation(project);
 		}
 		else {
-			IStatus status= CCorePlugin.createStatus(
-					MessageFormat.format(Messages.PDOMIndexerTask_errorWhileParsing, new Object[]{file}), e);
-			CCorePlugin.log(status);
-		}
-		if (++fStatistics.fErrorCount > MAX_ERRORS) {
-			throw new CoreException(CCorePlugin.createStatus(
-					MessageFormat.format(Messages.PDOMIndexerTask_tooManyIndexProblems, new Object[]{getIndexer().getProject().getElementName()})));
+			scanInfo= new ScannerInfo();
 		}
+		return scanInfo;
 	}
 
-	private ITranslationUnit findContext(IIndex index, final IIndexFileLocation location) {
-		Object cachedContext= fContextMap.get(location);
-		if (cachedContext != null) {
-			return cachedContext == NO_CONTEXT ? null : (ITranslationUnit) cachedContext;
-		}
+	private ICProject getProject() {
+		return getIndexer().getProject();
+	}
 
-		fContextMap.put(location, NO_CONTEXT); // prevent recursion
-		IIndexFile pdomFile;
+	protected final IWritableIndex createIndex() {
 		try {
-			final ICProject project= getIndexer().getProject();
-			pdomFile = index.getFile(location);
-			if (pdomFile != null) {
-				final IIndexInclude contextInclude= pdomFile.getParsedInContext();
-				if (contextInclude != null) {
-					final IIndexFileLocation loc= contextInclude.getIncludedByLocation();
-					ITranslationUnit context= getSourceUnit(project, loc);
-					if (context == null) {
-						context= findContext(index, loc);
-					}
-					if (context != null) {
-						fContextMap.put(location, context);
-						return context;
-					}
-				}
-				
-				// fallback to other includes
-				IIndexInclude[] includedBy = index.findIncludedBy(pdomFile, IIndex.DEPTH_ZERO);
-				for (int i = includedBy.length-1; i >=0; i--) {
-					final IIndexFileLocation loc= includedBy[i].getIncludedByLocation();
-					ITranslationUnit context= getSourceUnit(project, loc);
-					if (context == null) {
-						context= findContext(index, loc);
-					}
-					if (context != null) {
-						fContextMap.put(location, context);
-						return context;
-					}
-				}
-			}
+			return ((IWritableIndexManager) CCorePlugin.getIndexManager()).getWritableIndex(getProject());
 		} catch (CoreException e) {
 			CCorePlugin.log(e);
 		}
 		return null;
 	}
 
-	private ITranslationUnit getSourceUnit(final ICProject project, final IIndexFileLocation location)
-			throws CoreException {
-		ITranslationUnit tu= CoreModelUtil.findTranslationUnitForLocation(location, getIndexer().getProject());
-		if (tu != null) {
-			if (tu.isSourceUnit()) {
-				return tu;
-			}
-		}
-		return null;
+	protected final ITodoTaskUpdater createTodoTaskUpdater() {
+		return new TodoTaskUpdater();
 	}
-
-	/**
-	 * Conveninence method for subclasses, removes a translation unit from the index.
-	 * @since 4.0
-	 */
-	protected void removeTU(IWritableIndex index, ITranslationUnit tu, int readlocks) throws CoreException, InterruptedException {
-		index.acquireWriteLock(readlocks);
-		try {
-			IIndexFragmentFile file = (IIndexFragmentFile) index.getFile(IndexLocationFactory.getIFL(tu));
-			if (file != null)
-				index.clearFile(file, null);
-		} finally {
-			index.releaseWriteLock(readlocks);
-		}
-	}
-
+	
 	protected void traceEnd(long start, IWritableIndex index) {
 		if (checkDebugOption(IPDOMIndexerTask.TRACE_STATISTICS, TRUE)) {
 			IndexerProgress info= getProgressInformation();
@@ -558,69 +223,6 @@ public abstract class PDOMIndexerTask extends PDOMWriter implements IPDOMIndexer
 		}
 	}
 
-	protected long getLastModified(IIndexFileLocation location)	throws CoreException {
-		String fullPath= location.getFullPath();
-		if (fullPath != null) {
-			IResource res= ResourcesPlugin.getWorkspace().getRoot().findMember(fullPath);
-			if (res != null) {
-				return res.getLocalTimeStamp();
-			}
-		}
-		return super.getLastModified(location);
-	}
-
-	protected static int computeHashCode(IScannerInfo scannerInfo) {
-		int result= 0;
-		Map macros= scannerInfo.getDefinedSymbols();
-		if (macros != null) {
-			for (Iterator i = macros.entrySet().iterator(); i.hasNext();) {
-				Map.Entry entry = (Map.Entry) i.next();
-				String key = (String) entry.getKey();
-				String value = (String) entry.getValue();
-				result= addToHashcode(result, key);
-				if (value != null && value.length() > 0) {
-					result= addToHashcode(result, value);
-				}
-			}
-		}
-		String[] a= scannerInfo.getIncludePaths();
-		if (a != null) {
-			for (int i = 0; i < a.length; i++) {
-				result= addToHashcode(result, a[i]);
-
-			}
-		}
-		if (scannerInfo instanceof IExtendedScannerInfo) {
-			IExtendedScannerInfo esi= (IExtendedScannerInfo) scannerInfo;
-			a= esi.getIncludeFiles();
-			if (a != null) {
-				for (int i = 0; i < a.length; i++) {
-					result= addToHashcode(result, a[i]);
-
-				}
-			}			
-			a= esi.getLocalIncludePath();
-			if (a != null) {
-				for (int i = 0; i < a.length; i++) {
-					result= addToHashcode(result, a[i]);
-
-				}
-			}		
-			a= esi.getMacroFiles();
-			if (a != null) {
-				for (int i = 0; i < a.length; i++) {
-					result= addToHashcode(result, a[i]);
-
-				}
-			}		
-		}
-		return result;
-	}
-
-	private static int addToHashcode(int result, String key) {
-		return result*31 + key.hashCode();
-	}
-	
 	protected ICProject getCProject() {
 		return fIndexer.project;
 	}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/nulli/PDOMNullIndexer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMNullIndexer.java
similarity index 79%
rename from core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/nulli/PDOMNullIndexer.java
rename to core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMNullIndexer.java
index 782fb01f3fe..7203bf83bab 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/nulli/PDOMNullIndexer.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMNullIndexer.java
@@ -6,21 +6,18 @@
  * http://www.eclipse.org/legal/epl-v10.html
  *
  * Contributors:
- * QNX - Initial API and implementation
- * Markus Schorn (Wind River Systems)
+ *    QNX - Initial API and implementation
+ *    Markus Schorn (Wind River Systems)
  *******************************************************************************/
 
-package org.eclipse.cdt.internal.core.pdom.indexer.nulli;
+package org.eclipse.cdt.internal.core.pdom.indexer;
 
 import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
 import org.eclipse.cdt.core.dom.IPDOMManager;
 import org.eclipse.cdt.core.model.ITranslationUnit;
-import org.eclipse.cdt.internal.core.pdom.indexer.AbstractPDOMIndexer;
 
 /**
- * @author Doug Schaefer
- *
- * The Null Indexer which does nothing.
+ * Configures the abstract indexer to do nothing.
  */
 public class PDOMNullIndexer extends AbstractPDOMIndexer {
 
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMRebuildTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMRebuildTask.java
index aa8ba589a44..377f4741c5b 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMRebuildTask.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMRebuildTask.java
@@ -32,6 +32,9 @@ import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.osgi.util.NLS;
 
+/**
+ * A task for rebuilding an index, works for all indexers.
+ */
 public class PDOMRebuildTask implements IPDOMIndexerTask {
 	protected static final String TRUE= String.valueOf(true);
 	protected static final ITranslationUnit[] NO_TUS = new ITranslationUnit[0];
@@ -55,7 +58,7 @@ public class PDOMRebuildTask implements IPDOMIndexerTask {
 		return fIndexer;
 	}
 
-	public void run(IProgressMonitor monitor) {
+	public void run(IProgressMonitor monitor) throws InterruptedException {
 		monitor.subTask(NLS.bind(Messages.PDOMIndexerTask_collectingFilesTask, 
 				fIndexer.getProject().getElementName()));
 
@@ -102,15 +105,14 @@ public class PDOMRebuildTask implements IPDOMIndexerTask {
 		boolean allFiles= TRUE.equals(fIndexer.getProperty(IndexerPreferences.KEY_INDEX_ALL_FILES));
 		List sources= new ArrayList();
 		List headers= allFiles ? sources : null;
-		TranslationUnitCollector collector= new TranslationUnitCollector(sources, headers, allFiles, monitor);
+		TranslationUnitCollector collector= new TranslationUnitCollector(sources, headers, monitor);
 		project.accept(collector);
 		ITranslationUnit[] tus= (ITranslationUnit[]) sources.toArray(new ITranslationUnit[sources.size()]);
 		fDelegate= fIndexer.createTask(tus, NO_TUS, NO_TUS);
 		if (fDelegate instanceof PDOMIndexerTask) {
 			final PDOMIndexerTask delegate = (PDOMIndexerTask) fDelegate;
-			delegate.setUpateFlags(IIndexManager.UPDATE_ALL);
+			delegate.setUpdateFlags(IIndexManager.UPDATE_ALL);
 			delegate.setParseUpFront();
-			delegate.setAllFilesProvided(allFiles);
 		}
 	}
 
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMUpdateTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMUpdateTask.java
index bec431a6c0c..8a51c72227e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMUpdateTask.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMUpdateTask.java
@@ -28,6 +28,9 @@ import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.osgi.util.NLS;
 
+/**
+ * A task for updating an index, suitable for all indexers.
+ */
 public class PDOMUpdateTask implements IPDOMIndexerTask {
 	protected static final String TRUE= String.valueOf(true);
 	protected static final ITranslationUnit[] NO_TUS = new ITranslationUnit[0];
@@ -54,7 +57,7 @@ public class PDOMUpdateTask implements IPDOMIndexerTask {
 		return fIndexer;
 	}
 
-	public void run(IProgressMonitor monitor) {
+	public void run(IProgressMonitor monitor) throws InterruptedException {
 		monitor.subTask(NLS.bind(Messages.PDOMIndexerTask_collectingFilesTask, 
 				fIndexer.getProject().getElementName()));
 
@@ -75,9 +78,8 @@ public class PDOMUpdateTask implements IPDOMIndexerTask {
 	}
 	
 	private synchronized void createDelegate(ICProject project, IProgressMonitor monitor) throws CoreException {
-		boolean allFiles= TRUE.equals(fIndexer.getProperty(IndexerPreferences.KEY_INDEX_ALL_FILES));
 		HashSet set= new HashSet();
-		TranslationUnitCollector collector= new TranslationUnitCollector(set, set, allFiles, monitor);
+		TranslationUnitCollector collector= new TranslationUnitCollector(set, set, monitor);
 		if (fFilesAndFolders == null) {
 			project.accept(collector);
 		}
@@ -91,8 +93,7 @@ public class PDOMUpdateTask implements IPDOMIndexerTask {
 		fDelegate= fIndexer.createTask(tus, NO_TUS, NO_TUS);
 		if (fDelegate instanceof PDOMIndexerTask) {
 			final PDOMIndexerTask task = (PDOMIndexerTask) fDelegate;
-			task.setUpateFlags(fUpdateOptions);
-			task.setAllFilesProvided(allFiles);
+			task.setUpdateFlags(fUpdateOptions);
 		}
 	}
 
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java
new file mode 100644
index 00000000000..3d52c17c7a0
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ProjectIndexerInputAdapter.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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.pdom.indexer;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.index.IIndexFileLocation;
+import org.eclipse.cdt.core.index.IndexLocationFactory;
+import org.eclipse.cdt.core.model.AbstractLanguage;
+import org.eclipse.cdt.core.model.CModelException;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.CoreModelUtil;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.model.ILanguage;
+import org.eclipse.cdt.core.model.ITranslationUnit;
+import org.eclipse.cdt.core.parser.CodeReader;
+import org.eclipse.cdt.core.parser.IScannerInfo;
+import org.eclipse.cdt.core.parser.ScannerInfo;
+import org.eclipse.cdt.internal.core.pdom.IndexerInputAdapter;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+
+/**
+ * Provides information about translation-units.
+ * @since 5.0
+ */
+public class ProjectIndexerInputAdapter extends IndexerInputAdapter {
+	private final static boolean CASE_SENSITIVE_FILES= !new File("a").equals(new File("A"));  //$NON-NLS-1$//$NON-NLS-2$
+
+	private final ICProject fCProject;
+	private HashMap fIflCache= new HashMap();
+
+	public ProjectIndexerInputAdapter(ICProject cproject) {
+		fCProject= cproject;
+	}
+
+	public IIndexFileLocation resolveASTPath(String astPath) {
+		IIndexFileLocation result= (IIndexFileLocation) fIflCache.get(astPath);
+		if (result == null) {
+			result= IndexLocationFactory.getIFLExpensive(fCProject, astPath);
+			fIflCache.put(astPath, result);
+		}
+		return result;
+	}
+
+	public IIndexFileLocation resolveIncludeFile(String includePath) {
+		IIndexFileLocation result= (IIndexFileLocation) fIflCache.get(includePath);
+		if (result == null) {
+			File location= new File(includePath);
+			if (!location.exists()) {
+				return null;
+			}
+			result= IndexLocationFactory.getIFLExpensive(fCProject, includePath);
+			if (result.getFullPath() == null && !CASE_SENSITIVE_FILES) {
+				try {
+					String canonicalPath= location.getCanonicalPath();
+					if (!includePath.equals(canonicalPath)) {
+						result= IndexLocationFactory.getExternalIFL(canonicalPath);
+						fIflCache.put(canonicalPath, result);
+					}
+				}
+				catch (IOException e) {
+					// just use the original
+				}
+			}
+			fIflCache.put(includePath, result);
+		}
+		return result;
+	}
+
+	public String getASTPath(IIndexFileLocation ifl) {
+		IPath path= IndexLocationFactory.getAbsolutePath(ifl);
+		if (path != null) {
+			return path.toString();
+		}
+		return ifl.getURI().getPath();
+	}
+
+	public IScannerInfo getBuildConfiguration(int linkageID, Object tu) {
+		IScannerInfo info= ((ITranslationUnit) tu).getScannerInfo(true);
+		if (info == null) {
+			info= new ScannerInfo();
+		}
+		return info;
+	}
+
+	public long getLastModified(IIndexFileLocation ifl) {
+		String fullPath= ifl.getFullPath();
+		if (fullPath != null) {
+			IResource res= ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(fullPath));
+			if (res != null) {
+				return res.getLocalTimeStamp();
+			}
+			return 0;
+		}
+		IPath location= IndexLocationFactory.getAbsolutePath(ifl);
+		if (location != null) {
+			return location.toFile().lastModified();
+		}
+		return 0;
+	}
+
+	
+	public AbstractLanguage[] getLanguages(Object tuo) {
+		ITranslationUnit tu= (ITranslationUnit) tuo;
+		try {
+			ILanguage lang= tu.getLanguage();
+			if (lang instanceof AbstractLanguage) {
+				return new AbstractLanguage[] {(AbstractLanguage) lang};
+			}
+		}
+		catch (CoreException e) {
+			CCorePlugin.log(e);
+		}
+		return new AbstractLanguage[0];
+	}
+
+	public boolean isFileBuildConfigured(Object tuo) {
+		ITranslationUnit tu= (ITranslationUnit) tuo;
+		return !CoreModel.isScannerInformationEmpty(tu.getResource());
+	}
+
+	public boolean isSourceUnit(Object tuo) {
+		ITranslationUnit tu= (ITranslationUnit) tuo;
+		return tu.isSourceUnit();
+	}
+
+	public IIndexFileLocation resolveFile(Object tuo) {
+		ITranslationUnit tu= (ITranslationUnit) tuo;
+		return IndexLocationFactory.getIFL(tu);
+	}
+	
+	public boolean canBePartOfSDK(IIndexFileLocation ifl) {
+		return ifl.getFullPath() == null;
+	}
+
+	public Object getInputFile(IIndexFileLocation location) {
+		try {
+			return CoreModelUtil.findTranslationUnitForLocation(location, fCProject);
+		} catch (CModelException e) {
+			CCorePlugin.log(e);
+		}
+		return null;
+	}
+
+	public CodeReader getCodeReader(Object tuo) {
+		ITranslationUnit tu= (ITranslationUnit) tuo;
+		return tu.getCodeReader();
+	}
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/TranslationUnitCollector.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/TranslationUnitCollector.java
index fa680b2e47c..6fc2f314206 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/TranslationUnitCollector.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/TranslationUnitCollector.java
@@ -13,7 +13,6 @@ package org.eclipse.cdt.internal.core.pdom.indexer;
 
 import java.util.Collection;
 
-import org.eclipse.cdt.core.model.CoreModel;
 import org.eclipse.cdt.core.model.ICElement;
 import org.eclipse.cdt.core.model.ICElementVisitor;
 import org.eclipse.cdt.core.model.ITranslationUnit;
@@ -23,13 +22,11 @@ import org.eclipse.core.runtime.IProgressMonitor;
 final class TranslationUnitCollector implements ICElementVisitor {
 	private final Collection fSources;
 	private final Collection fHeaders;
-	private final boolean fAllFiles;
 	private final IProgressMonitor fProgressMonitor;
 
-	public TranslationUnitCollector(Collection sources, Collection headers, boolean allFiles, IProgressMonitor pm) {
+	public TranslationUnitCollector(Collection sources, Collection headers, IProgressMonitor pm) {
 		fSources= sources;
 		fHeaders= headers;
-		fAllFiles = allFiles;
 		fProgressMonitor= pm;
 	}
 
@@ -41,9 +38,7 @@ final class TranslationUnitCollector implements ICElementVisitor {
 		case ICElement.C_UNIT:
 			ITranslationUnit tu = (ITranslationUnit)element;
 			if (tu.isSourceUnit()) {
-				if (fAllFiles || !CoreModel.isScannerInformationEmpty(tu.getResource())) {
-					fSources.add(tu);
-				}
+				fSources.add(tu);
 			}
 			else if (fHeaders != null && tu.isHeaderUnit()) {
 				fHeaders.add(tu);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerTask.java
deleted file mode 100644
index ffb1ee84885..00000000000
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerTask.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 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
- *
- * Contributors:
- *    QNX - Initial API and implementation
- *    Markus Schorn (Wind River Systems)
- *******************************************************************************/
-
-package org.eclipse.cdt.internal.core.pdom.indexer.fast;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-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;
-import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
-import org.eclipse.cdt.core.index.IIndexFile;
-import org.eclipse.cdt.core.index.IIndexFileLocation;
-import org.eclipse.cdt.core.index.IndexLocationFactory;
-import org.eclipse.cdt.core.model.AbstractLanguage;
-import org.eclipse.cdt.core.model.CoreModel;
-import org.eclipse.cdt.core.model.ITranslationUnit;
-import org.eclipse.cdt.core.parser.CodeReader;
-import org.eclipse.cdt.core.parser.IScannerInfo;
-import org.eclipse.cdt.core.parser.ParserUtil;
-import org.eclipse.cdt.internal.core.index.IWritableIndex;
-import org.eclipse.cdt.internal.core.index.IWritableIndexManager;
-import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory;
-import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory.CallbackHandler;
-import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory.IndexFileInfo;
-import org.eclipse.cdt.internal.core.pdom.indexer.PDOMIndexerTask;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-
-class PDOMFastIndexerTask extends PDOMIndexerTask implements CallbackHandler {
-	private List fChanged = new LinkedList();
-	private List fRemoved = new ArrayList();
-	private IWritableIndex fIndex;
-	private IndexBasedCodeReaderFactory fCodeReaderFactory;
-	private Map fIflCache;
-	private int fCurrentConfigHash= 0;
-
-	public PDOMFastIndexerTask(PDOMFastIndexer indexer, ITranslationUnit[] added,
-			ITranslationUnit[] changed, ITranslationUnit[] removed) {
-		super(indexer);
-		fChanged.addAll(Arrays.asList(added));
-		fChanged.addAll(Arrays.asList(changed));
-		fRemoved.addAll(Arrays.asList(removed));
-		updateInfo(0, 0, fChanged.size() + fRemoved.size());
-	}
-
-	public void run(IProgressMonitor monitor) {
-		long start = System.currentTimeMillis();
-		try {
-			// separate headers remove files that have no scanner configuration
-			final boolean filterFiles= !getIndexAllFiles() && getAllFilesProvided();
-			List headers= new ArrayList();
-			List sources= fChanged;
-			for (Iterator iter = fChanged.iterator(); iter.hasNext();) {
-				ITranslationUnit tu = (ITranslationUnit) iter.next();
-				if (tu.isSourceUnit()) {
-					if (filterFiles && CoreModel.isScannerInformationEmpty(tu.getResource())) {
-						iter.remove();
-						updateInfo(0, 0, -1);
-					}
-				}
-				else {
-					headers.add(tu);
-					iter.remove();
-				}
-			}
-
-			if (!setupIndexAndReaderFactory()) {
-				return;
-			}
-			fIndex.acquireReadLock();
-			try {
-				registerTUsInReaderFactory(sources);
-				registerTUsInReaderFactory(headers);
-
-				Iterator i= fRemoved.iterator();
-				while (i.hasNext()) {
-					if (monitor.isCanceled())
-						return;
-					ITranslationUnit tu = (ITranslationUnit)i.next();
-					removeTU(fIndex, tu, 1);
-					if (tu.isSourceUnit()) {
-						updateInfo(1, 0, 0);
-					}
-					else {
-						updateInfo(0, 1, -1);
-					}
-				}
-
-				parseTUs(fIndex, 1, sources, headers, monitor);
-				if (monitor.isCanceled()) {
-					return;
-				}	
-			}
-			finally {
-				fIndex.releaseReadLock();
-			}
-		} catch (CoreException e) {
-			CCorePlugin.log(e);
-		} catch (InterruptedException e) {
-		}
-		traceEnd(start, fIndex);
-	}
-
-	private boolean setupIndexAndReaderFactory() throws CoreException {
-		fIndex= ((IWritableIndexManager) CCorePlugin.getIndexManager()).getWritableIndex(getProject());
-		if (fIndex == null) {
-			return false;
-		}
-		fIndex.resetCacheCounters();
-		fIflCache = new HashMap/**/();
-		fCodeReaderFactory = new IndexBasedCodeReaderFactory(getCProject(), fIndex, fIflCache);
-		fCodeReaderFactory.setCallbackHandler(this);
-		return true;
-	}
-
-	private void registerTUsInReaderFactory(Collection tus) throws CoreException {
-		int removed= 0;
-		for (Iterator iter = tus.iterator(); iter.hasNext();) {
-			ITranslationUnit tu = (ITranslationUnit) iter.next();
-			IIndexFileLocation ifl = IndexLocationFactory.getIFL(tu);
-			IndexFileInfo info= fCodeReaderFactory.createFileInfo(ifl);
-			if (updateAll()) {
-				info.fRequested= IndexFileInfo.REQUESTED;
-			}
-			else if (updateChangedTimestamps() && isOutdated(tu, info.fFile)) {
-				info.fRequested= IndexFileInfo.REQUESTED;
-			}
-			else if (updateChangedConfiguration()) {
-				info.fRequested= IndexFileInfo.REQUESTED_IF_CONFIG_CHANGED;
-			}
-			else {
-				iter.remove();
-				removed++;
-			}
-		}
-		updateInfo(0, 0, -removed);
-	}
-
-	protected IIndexFileLocation findLocation(String absolutePath) {
-		IIndexFileLocation result = (IIndexFileLocation) fIflCache.get(absolutePath); 
-		if(result==null) {
-			result = IndexLocationFactory.getIFLExpensive(getCProject(), absolutePath);
-			fIflCache.put(absolutePath, result);
-		}
-		return result;
-	}
-
-	protected IASTTranslationUnit createAST(AbstractLanguage lang, CodeReader codeReader, IScannerInfo scanInfo, int options, IProgressMonitor pm) throws CoreException {
-		// get the AST in a "Fast" way
-		IASTTranslationUnit ast= lang.getASTTranslationUnit(codeReader, scanInfo, fCodeReaderFactory, fIndex, options, ParserUtil.getParserLogService());
-		if (pm.isCanceled()) {
-			return null;
-		}
-		// Clear the macros
-		fCodeReaderFactory.clearMacroAttachements();
-		return ast;
-	}
-
-	protected boolean needToUpdate(IIndexFileLocation location, int confighash) throws CoreException {
-		if (super.needToUpdate(location, confighash)) {
-			// file is requested or is not yet indexed.
-			IndexFileInfo info= fCodeReaderFactory.createFileInfo(location);
-			return needToUpdate(info, confighash);
-		}
-		return false;
-	}
-	
-	public boolean needToUpdate(IndexFileInfo info) throws CoreException {
-		return needToUpdate(info, fCurrentConfigHash);
-	}
-	
-	private boolean needToUpdate(IndexFileInfo info, int confighash) throws CoreException {
-		if (info.fFile == null) {
-			return true;
-		}
-		if (confighash != 0 && info.fRequested == IndexFileInfo.REQUESTED_IF_CONFIG_CHANGED) {
-			int oldhash= info.fFile.getScannerConfigurationHashcode();
-			if (oldhash == 0 || oldhash==confighash) {
-				info.fRequested= IndexFileInfo.NOT_REQUESTED;
-				updateInfo(0, 0, -1);
-			}
-			else {
-				info.fRequested= IndexFileInfo.REQUESTED;
-			}
-		}
-		return info.fRequested != IndexFileInfo.NOT_REQUESTED;
-	}
-
-	protected boolean postAddToIndex(IIndexFileLocation path, IIndexFile file)
-			throws CoreException {
-		IndexFileInfo info= fCodeReaderFactory.createFileInfo(path);
-		info.fFile= file;
-		assert !info.hasCachedMacros();
-		if (info.fRequested != IndexFileInfo.NOT_REQUESTED) {
-			info.fRequested= IndexFileInfo.NOT_REQUESTED;
-			return true;
-		}
-		return false;
-	}
-}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerTask.java
deleted file mode 100644
index e794cc181ac..00000000000
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerTask.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 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
- *
- * Contributors:
- *    QNX - Initial API and implementation
- *    Markus Schorn (Wind River Systems)
- *******************************************************************************/
-
-package org.eclipse.cdt.internal.core.pdom.indexer.full;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-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;
-import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
-import org.eclipse.cdt.core.index.IIndexFile;
-import org.eclipse.cdt.core.index.IIndexFileLocation;
-import org.eclipse.cdt.core.index.IndexLocationFactory;
-import org.eclipse.cdt.core.model.AbstractLanguage;
-import org.eclipse.cdt.core.model.CoreModel;
-import org.eclipse.cdt.core.model.ITranslationUnit;
-import org.eclipse.cdt.core.parser.CodeReader;
-import org.eclipse.cdt.core.parser.IScannerInfo;
-import org.eclipse.cdt.core.parser.ParserUtil;
-import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory;
-import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
-import org.eclipse.cdt.internal.core.index.IWritableIndex;
-import org.eclipse.cdt.internal.core.index.IWritableIndexManager;
-import org.eclipse.cdt.internal.core.pdom.indexer.PDOMIndexerTask;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-
-/**
- * @author Doug Schaefer
- *
- */
-class PDOMFullIndexerTask extends PDOMIndexerTask {
-	private final static Object REQUIRED= new Object();
-	private final static Object MISSING = new Object();
-	private final static Object SKIP=     new Object();
-	private final static Object REQUIRED_IF_CONFIG_CHANGED= new Object();
-	
-	private List fChanged = new LinkedList();
-	private List fRemoved = new ArrayList();
-	private IWritableIndex fIndex = null;
-	private Map filePathsToParse = new HashMap/**/();
-	private Map fIflCache = new HashMap/**/();
-
-	public PDOMFullIndexerTask(PDOMFullIndexer indexer, ITranslationUnit[] added,
-			ITranslationUnit[] changed, ITranslationUnit[] removed) {
-		super(indexer);
-		fChanged.addAll(Arrays.asList(added));
-		fChanged.addAll(Arrays.asList(changed));
-		fRemoved.addAll(Arrays.asList(removed));
-		updateInfo(0, 0, fChanged.size() + fRemoved.size());
-	}
-
-	public void run(IProgressMonitor monitor) {
-		long start = System.currentTimeMillis();
-		try {
-			// separate headers remove files that have no scanner configuration
-			final boolean filterFiles= !getIndexAllFiles() && getAllFilesProvided();
-			List headers= new ArrayList();
-			List sources= fChanged;
-			for (Iterator iter = fChanged.iterator(); iter.hasNext();) {
-				ITranslationUnit tu = (ITranslationUnit) iter.next();
-				if (tu.isSourceUnit()) {
-					if (filterFiles && CoreModel.isScannerInformationEmpty(tu.getResource())) {
-						iter.remove();
-						updateInfo(0, 0, -1);
-					}
-				}
-				else {
-					headers.add(tu);
-					iter.remove();
-				}
-			}
-
-			if (!setupIndex()) {
-				return;
-			}
-			registerTUsInReaderFactory(sources);
-			registerTUsInReaderFactory(headers);
-
-			Iterator i= fRemoved.iterator();
-			while (i.hasNext()) {
-				if (monitor.isCanceled())
-					return;
-				ITranslationUnit tu = (ITranslationUnit)i.next();
-				removeTU(fIndex, tu, 0);
-				if (tu.isSourceUnit()) {
-					updateInfo(1, 0, 0);
-				}
-				else {
-					updateInfo(0, 1, -1);
-				}
-			}
-
-			fIndex.acquireReadLock();
-			try {
-				parseTUs(fIndex, 1, sources, headers, monitor);
-			}
-			finally {
-				fIndex.releaseReadLock();
-			}
-		} catch (CoreException e) {
-			CCorePlugin.log(e);
-		} catch (InterruptedException e) {
-		}
-		traceEnd(start, fIndex);
-	}
-
-	private boolean setupIndex() throws CoreException {
-		// there is no mechanism to clear dirty files from the cache, so flush it.
-		SavedCodeReaderFactory.getInstance().getCodeReaderCache().flush();	
-
-		fIndex = ((IWritableIndexManager) CCorePlugin.getIndexManager()).getWritableIndex(getProject());
-		if (fIndex == null) {
-			return false;
-		}
-		fIndex.resetCacheCounters();
-		return true;
-	}
-
-	private void registerTUsInReaderFactory(Collection/**/ sources)
-			throws CoreException {
-		int removed= 0;
-		filePathsToParse= new HashMap/**/();
-		for (Iterator iter = sources.iterator(); iter.hasNext();) {
-			ITranslationUnit tu = (ITranslationUnit) iter.next();
-			IIndexFileLocation ifl= IndexLocationFactory.getIFL(tu);
-			if (updateAll()) {
-				filePathsToParse.put(ifl, REQUIRED);
-			}
-			else if (updateChangedTimestamps() && isOutdated(tu, fIndex.getFile(ifl))) {
-				filePathsToParse.put(ifl, REQUIRED);
-			}
-			else if (updateChangedConfiguration()) {
-				filePathsToParse.put(ifl, REQUIRED_IF_CONFIG_CHANGED);
-			}
-			else {
-				iter.remove();
-				removed++;
-				continue;
-			}
-			updateInfo(0, 0, -removed);
-		}
-	}
-
-	protected IIndexFileLocation findLocation(String absolutePath) {
-		IIndexFileLocation result = (IIndexFileLocation) fIflCache.get(absolutePath);
-		if(result==null) {
-			result = IndexLocationFactory.getIFLExpensive(getCProject(), absolutePath);
-			fIflCache.put(absolutePath, result);
-		}
-		return result;
-	}
-
-	protected IASTTranslationUnit createAST(AbstractLanguage lang, CodeReader codeReader, IScannerInfo scanInfo, int options, IProgressMonitor pm) throws CoreException {
-		SavedCodeReaderFactory codeReaderFactory= SavedCodeReaderFactory.getInstance();
-		IASTTranslationUnit ast= lang.getASTTranslationUnit(codeReader, scanInfo, codeReaderFactory, null, options, ParserUtil.getParserLogService());
-		if (pm.isCanceled()) {
-			return null;
-		}
-		return ast;
-	}
-	
-	public boolean needToUpdate(IIndexFileLocation location, int confighash) throws CoreException {
-		if (super.needToUpdate(location, confighash)) {
-			Object required= filePathsToParse.get(location);
-			if (required == null) {
-				required= MISSING;
-				// bug 197311, don't attempt to update files in fragments of other projects.
-				IIndexFragmentFile file= (IIndexFragmentFile) fIndex.getFile(location);
-				if (file != null && !fIndex.isWritableFile(file)) {
-					required= SKIP;
-				}
-				filePathsToParse.put(location, required);
-			}
-			else if (confighash != 0 && required == REQUIRED_IF_CONFIG_CHANGED) {
-				IIndexFile file= fIndex.getFile(location);
-				if (file != null) {
-					int oldConfig= file.getScannerConfigurationHashcode();
-					if (oldConfig == 0 || oldConfig == confighash) {
-						required= SKIP;
-						updateInfo(0, 0, -1);
-					}
-					else {
-						required= REQUIRED;
-					}
-					filePathsToParse.put(location, required);
-				}
-			}
-			return required != SKIP;
-		}
-		return false;
-	}
-
-	protected boolean postAddToIndex(IIndexFileLocation location, IIndexFile file)
-			throws CoreException {
-		Object required= filePathsToParse.get(location);
-		filePathsToParse.put(location, SKIP);
-		return required == REQUIRED;
-	}
-}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/messages.properties b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/messages.properties
index e80338b707f..1ff19e7e27a 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/messages.properties
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/messages.properties
@@ -9,10 +9,7 @@
 #     Markus Schorn (Wind River Systems)
 ###############################################################################
 PDOMIndexerTask_collectingFilesTask=Collecting files (project ''{0}'')
-PDOMIndexerTask_tooManyIndexProblems=Too many problems while indexing project ''{0}'', stopping indexer.
 PDOMImportTask_errorInvalidPDOMVersion=The version of the cdt-index to import for project {0} does not match
-PDOMIndexerTask_parsingFileTask=parsing {0} ({1})
-PDOMIndexerTask_errorWhileParsing=Error while parsing {0}.
 PDOMImportTask_errorInvalidArchive=Invalid Archive: {0}
 
 # {0} - task tag, {1} - task message.
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/messages.properties b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/messages.properties
index 81410d3fbfa..db91077ef8c 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/messages.properties
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/messages.properties
@@ -25,3 +25,6 @@ TeamPDOMExportOperation_taskExportIndex=Export team shared index
 TeamPDOMExportOperation_subtaskCreateDatabase=Creating database
 TeamPDOMExportOperation_errorWriteTempFile=Cannot write to temporary file
 TeamPDOMExportOperation_errorCreateArchive=Error creating archive
+AbstractIndexerTask_parsingFileTask=parsing {0} ({1})
+AbstractIndexerTask_errorWhileParsing=Error while parsing {0}.
+AbstractIndexerTask_tooManyIndexProblems=Too many errors while indexing, stopping indexer.
diff --git a/core/org.eclipse.cdt.core/plugin.xml b/core/org.eclipse.cdt.core/plugin.xml
index 214bbefa1cc..49d76de7e10 100644
--- a/core/org.eclipse.cdt.core/plugin.xml
+++ b/core/org.eclipse.cdt.core/plugin.xml
@@ -531,19 +531,19 @@
    		 id="nullindexer"
          name="%CDTIndexer.nullindexer"
          point="org.eclipse.cdt.core.CIndexer">
-      
+      
    
    
-      
+      
    
    
-      
+      
    
    
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java
index 8ef6c81e0b2..2a89a59fc9e 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java
@@ -53,7 +53,6 @@ import org.eclipse.cdt.internal.core.model.DeltaProcessor;
 import org.eclipse.cdt.internal.core.model.IBufferFactory;
 import org.eclipse.cdt.internal.core.model.Util;
 import org.eclipse.cdt.internal.core.pdom.PDOMManager;
-import org.eclipse.cdt.internal.core.pdom.indexer.fast.PDOMFastIndexer;
 import org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IProjectDescription;
@@ -103,7 +102,7 @@ public class CCorePlugin extends Plugin {
 	public static final String INDEXER_SIMPLE_ID = "CIndexer"; //$NON-NLS-1$
 	public static final String INDEXER_UNIQ_ID = PLUGIN_ID + "." + INDEXER_SIMPLE_ID; //$NON-NLS-1$
 	public static final String PREF_INDEXER = "indexer"; //$NON-NLS-1$
-	public static final String DEFAULT_INDEXER = PDOMFastIndexer.ID;
+	public static final String DEFAULT_INDEXER = IPDOMManager.ID_FAST_INDEXER;
 	
 	public final static String ERROR_PARSER_SIMPLE_ID = "ErrorParser"; //$NON-NLS-1$
 	public final static String ERROR_PARSER_UNIQ_ID = PLUGIN_ID + "." + ERROR_PARSER_SIMPLE_ID; //$NON-NLS-1$
diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/BaseUITestCase.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/BaseUITestCase.java
index acb466f54bf..90204d8d058 100644
--- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/BaseUITestCase.java
+++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/BaseUITestCase.java
@@ -43,6 +43,7 @@ import org.eclipse.ui.WorkbenchException;
 import org.eclipse.ui.handlers.IHandlerService;
 
 import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.dom.ILinkage;
 import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
 import org.eclipse.cdt.core.index.IIndex;
 import org.eclipse.cdt.core.index.IIndexFile;
@@ -98,7 +99,11 @@ public class BaseUITestCase extends BaseTestCase {
 			
 			index.acquireReadLock();
 			try {
-				IIndexFile pfile= index.getFile(IndexLocationFactory.getWorkspaceIFL(file));
+				IIndexFile pfile= index.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file));
+				if (pfile != null && pfile.getTimestamp() >= file.getLocalTimeStamp()) {
+					return;
+				}
+				pfile= index.getFile(ILinkage.C_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file));
 				if (pfile != null && pfile.getTimestamp() >= file.getLocalTimeStamp()) {
 					return;
 				}
diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/BasicCallHierarchyTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/BasicCallHierarchyTest.java
index f202b122969..3cd2fe29016 100644
--- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/BasicCallHierarchyTest.java
+++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/BasicCallHierarchyTest.java
@@ -615,11 +615,11 @@ public class BasicCallHierarchyTest extends CallHierarchyBaseTest {
 		editor.selectAndReveal(content1.indexOf("sf"), 0);
 		openCallHierarchy(editor);
 		tree = getCHTreeViewer().getTree();
-		i0= checkTreeNode(tree, 0, "sf()");
+		checkTreeNode(tree, 0, "sf()");
 		assertEquals(1, tree.getItemCount());
 
-		i1= checkTreeNode(i0, 0, "sf()");	// sf()[f2] <- sf()[f2]
-		checkTreeNode(i0, 1, null);			// not called by gf()
+		i1= checkTreeNode(tree, 0, 0, "sf()");	// sf()[f2] <- sf()[f2]
+		checkTreeNode(tree, 0, 1, null);			// not called by gf()
 
 		expandTreeItem(i1);
 		checkTreeNode(i1, 0, null);
diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CallHierarchyAcrossProjectsTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CallHierarchyAcrossProjectsTest.java
index 76cb447f1f2..78764976098 100644
--- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CallHierarchyAcrossProjectsTest.java
+++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CallHierarchyAcrossProjectsTest.java
@@ -170,11 +170,11 @@ public class CallHierarchyAcrossProjectsTest extends CallHierarchyBaseTest {
 		openCallHierarchy(editor);
 		TreeViewer tv = getCHTreeViewer();
 
-		TreeItem item= checkTreeNode(tv.getTree(), 0, "MyClass::method3()");
-		TreeItem nextItem= checkTreeNode(item, 0, "MyClass::method2()");
-		checkTreeNode(item, 1, null); item= nextItem;
+		checkTreeNode(tv.getTree(), 0, "MyClass::method3()");
+		TreeItem item= checkTreeNode(tv.getTree(), 0, 0, "MyClass::method2()");
+		checkTreeNode(tv.getTree(), 0, 1, null); 
 		tv.setExpandedState(item.getData(), true); 
-		nextItem= checkTreeNode(item, 0, "MyClass::method1()");
+		TreeItem nextItem= checkTreeNode(item, 0, "MyClass::method1()");
 		checkTreeNode(item, 1, null); item= nextItem;
 		tv.setExpandedState(item.getData(), true); 
 		checkTreeNode(item, 0, null);
@@ -220,10 +220,10 @@ public class CallHierarchyAcrossProjectsTest extends CallHierarchyBaseTest {
 		openCallHierarchy(editor);
 		TreeViewer tv = getCHTreeViewer();
 
-		TreeItem item= checkTreeNode(tv.getTree(), 0, "MyClass::method3()");
-		TreeItem item0= checkTreeNode(item, 0, "MyClass::method1()");
-		TreeItem item1= checkTreeNode(item, 1, "MyClass::method2()");
-		checkTreeNode(item, 2, null); item= null;
+		checkTreeNode(tv.getTree(), 0, "MyClass::method3()");
+		TreeItem item0= checkTreeNode(tv.getTree(), 0, 0, "MyClass::method1()");
+		TreeItem item1= checkTreeNode(tv.getTree(), 0, 1, "MyClass::method2()");
+		checkTreeNode(tv.getTree(), 0, 2, null); 
 		
 		// method 1
 		tv.setExpandedState(item0.getData(), true); 
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBContentProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBContentProvider.java
index dd6731e3674..138a7a8f1ad 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBContentProvider.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBContentProvider.java
@@ -12,6 +12,7 @@
 package org.eclipse.cdt.internal.ui.includebrowser;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
@@ -154,9 +155,16 @@ public class IBContentProvider extends AsyncTreeContentProvider {
 	private IIndexInclude[] findIncludedBy(IIndex index, IIndexFileLocation ifl, IProgressMonitor pm) {
 		try {
 			if (ifl != null) {
-				IIndexFile file= index.getFile(ifl);
-				if (file != null) {
-					return index.findIncludedBy(file);
+				IIndexFile[] files= index.getFiles(ifl);
+				if (files.length == 1) {
+					return index.findIncludedBy(files[0]);
+				}
+				if (files.length > 0) {
+					ArrayList list= new ArrayList();
+					for (int i = 0; i < files.length; i++) {
+						list.addAll(Arrays.asList(index.findIncludedBy(files[i])));
+					}
+					return (IIndexInclude[]) list.toArray(new IIndexInclude[list.size()]);
 				}
 			}
 		}
@@ -169,9 +177,16 @@ public class IBContentProvider extends AsyncTreeContentProvider {
 	public IIndexInclude[] findIncludesTo(IIndex index, IIndexFileLocation ifl, IProgressMonitor pm) {
 		try {
 			if (ifl != null) {
-				IIndexFile file= index.getFile(ifl);
-				if (file != null) {
-					return index.findIncludes(file);
+				IIndexFile[] files= index.getFiles(ifl);
+				if (files.length == 1) {
+					return index.findIncludes(files[0]);
+				}
+				if (files.length > 0) {
+					ArrayList list= new ArrayList();
+					for (int i = 0; i < files.length; i++) {
+						list.addAll(Arrays.asList(index.findIncludes(files[i])));
+					}
+					return (IIndexInclude[]) list.toArray(new IIndexInclude[list.size()]);
 				}
 			}
 		}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java
index 27b76008b76..15783e619bb 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java
@@ -168,15 +168,16 @@ public class IndexUI {
 			if (tu != null) {
 				IIndexFileLocation location= IndexLocationFactory.getIFL(tu);
 				if (location != null) {
-					IIndexFile file= index.getFile(location);
-					if (file != null) {
+					IIndexFile[] files= index.getFiles(location);
+					for (int i = 0; i < files.length; i++) {
+						IIndexFile file = files[i];
 						String elementName= element.getElementName();
 						int idx= elementName.lastIndexOf(":")+1; //$NON-NLS-1$
 						ISourceRange pos= sf.getSourceRange();
 						IRegion region = getConvertedRegion(tu, file, pos.getIdStartPos()+idx, pos.getIdLength()-idx);
 						IIndexName[] names= file.findNames(region.getOffset(), region.getLength());
-						for (int i = 0; i < names.length; i++) {
-							IIndexName name = names[i];
+						for (int j = 0; j < names.length; j++) {
+							IIndexName name = names[j];
 							if (!name.isReference() && elementName.endsWith(new String(name.toCharArray()))) {
 								return name;
 							}
@@ -195,8 +196,8 @@ public class IndexUI {
 			if (tu != null) {
 				IIndexFileLocation location= IndexLocationFactory.getIFL(tu);
 				if (location != null) {
-					IIndexFile file= index.getFile(location);
-					return file != null;
+					IIndexFile[] files= index.getFiles(location);
+					return files.length > 0;
 				}
 			}
 		}
@@ -218,8 +219,9 @@ public class IndexUI {
 			if (tu != null) {
 				IIndexFileLocation location= IndexLocationFactory.getIFL(tu);
 				if (location != null) {
-					IIndexFile file= index.getFile(location);
-					if (file != null) {
+					IIndexFile[] files= index.getFiles(location);
+					for (int j=0; j