1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-09-10 12:03:16 +02:00

Indexing of headers and index updates.

This commit is contained in:
Markus Schorn 2011-09-27 15:55:20 +02:00
parent 4e1d937050
commit 574406dc21
21 changed files with 818 additions and 776 deletions

View file

@ -769,7 +769,10 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
}
public IASTTranslationUnit getAST(IIndex index, int style, IProgressMonitor monitor) throws CoreException {
ITranslationUnit configureWith = getSourceContextTU(index, style);
IIndexFile[] contextToHeader = getContextToHeader(index, style);
ITranslationUnit configureWith = getConfigureWith(contextToHeader);
if (configureWith == this)
contextToHeader= null;
IScannerInfo scanInfo= configureWith.getScannerInfo((style & AST_SKIP_IF_NO_BUILD_INFO) == 0);
if (scanInfo == null) {
@ -786,7 +789,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
return null;
}
IncludeFileContentProvider crf= getIncludeFileContentProvider(style, index, language.getLinkageID());
IncludeFileContentProvider crf= getIncludeFileContentProvider(style, index, language.getLinkageID(), contextToHeader);
int options= 0;
if ((style & AST_SKIP_FUNCTION_BODIES) != 0) {
options |= ILanguage.OPTION_SKIP_FUNCTION_BODIES;
@ -812,7 +815,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
return ast;
}
private IncludeFileContentProvider getIncludeFileContentProvider(int style, IIndex index, int linkageID) {
private IncludeFileContentProvider getIncludeFileContentProvider(int style, IIndex index, int linkageID, IIndexFile[] contextToHeader) {
final ICProject cprj= getCProject();
final ProjectIndexerInputAdapter pathResolver = new ProjectIndexerInputAdapter(cprj);
IncludeFileContentProvider fileContentsProvider;
@ -825,9 +828,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
if (index != null && (style & AST_SKIP_INDEXED_HEADERS) != 0) {
IndexBasedFileContentProvider ibcf= new IndexBasedFileContentProvider(index, pathResolver, linkageID,
fileContentsProvider);
if ((style & AST_CONFIGURE_USING_SOURCE_CONTEXT) != 0) {
ibcf.setSupportFillGapFromContextToHeader(true);
}
ibcf.setContextToHeaderGap(contextToHeader);
fileContentsProvider= ibcf;
}
@ -840,39 +841,44 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
}
private static final int[] CTX_LINKAGES= { ILinkage.CPP_LINKAGE_ID, ILinkage.C_LINKAGE_ID };
public ITranslationUnit getSourceContextTU(IIndex index, int style) {
public IIndexFile[] getContextToHeader(IIndex index, int style) {
if (index != null && (style & AST_CONFIGURE_USING_SOURCE_CONTEXT) != 0) {
try {
fLanguageOfContext= null;
for (int linkageID : CTX_LINKAGES) {
IIndexFile context= null;
final IIndexFileLocation ifl = IndexLocationFactory.getIFL(this);
if (ifl != null) {
final IIndexFileLocation ifl = IndexLocationFactory.getIFL(this);
if (ifl != null) {
IIndexFile best= null;
int mostContent= -1;
for (int linkageID : CTX_LINKAGES) {
for (IIndexFile indexFile : index.getFiles(linkageID, ifl)) {
if (indexFile != null) {
// Bug 199412, when a source-file includes itself the context may recurse.
HashSet<IIndexFile> visited= new HashSet<IIndexFile>();
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()) {
return tu;
}
int count= indexFile.getMacros().length;
if (count > mostContent) {
mostContent= count;
best= indexFile;
}
}
}
if (best != null) {
IIndexFile context= best;
HashSet<IIndexFile> visited= new HashSet<IIndexFile>();
// Bug 199412, may recurse.
while (visited.add(context)) {
IIndexFile next= getParsedInContext(context);
if (next == null)
break;
context= next;
}
if (context != best) {
return new IIndexFile[] {context, best};
}
}
}
} catch (CoreException e) {
CCorePlugin.log(e);
}
}
return this;
return null;
}
private IIndexFile getParsedInContext(IIndexFile indexFile)
@ -883,9 +889,21 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
}
return null;
}
private ITranslationUnit getConfigureWith(IIndexFile[] contextToHeader) throws CoreException {
if (contextToHeader != null) {
ITranslationUnit configureWith = CoreModelUtil.findTranslationUnitForLocation(contextToHeader[0].getLocation(), getCProject());
if (configureWith != null)
return configureWith;
}
return this;
}
public IASTCompletionNode getCompletionNode(IIndex index, int style, int offset) throws CoreException {
ITranslationUnit configureWith= getSourceContextTU(index, style);
IIndexFile[] contextToHeader = getContextToHeader(index, style);
ITranslationUnit configureWith = getConfigureWith(contextToHeader);
if (configureWith == this)
contextToHeader= null;
IScannerInfo scanInfo = configureWith.getScannerInfo((style & ITranslationUnit.AST_SKIP_IF_NO_BUILD_INFO) == 0);
if (scanInfo == null) {
@ -897,7 +915,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
ILanguage language= configureWith.getLanguage();
fLanguageOfContext= language;
if (language != null) {
IncludeFileContentProvider crf= getIncludeFileContentProvider(style, index, language.getLinkageID());
IncludeFileContentProvider crf= getIncludeFileContentProvider(style, index, language.getLinkageID(), contextToHeader);
IASTCompletionNode result = language.getCompletionNode(fileContent, scanInfo, crf, index,
ParserUtil.getParserLogService(), offset);
if (result != null) {

View file

@ -11,6 +11,7 @@
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.parser.ISignificantMacros;
@ -73,4 +74,25 @@ public interface IASTPreprocessorIncludeStatement extends IASTPreprocessorStatem
* @noreference This method is not intended to be referenced by clients.
*/
public ISignificantMacros[] getLoadedVersions();
/**
* Returns a hash-code for the contents of the file included, or <code>0</code>
* if the content has not been parsed.
* @since 5.4
*/
public long getContentsHash();
/**
* Returns true, if an attempt will be or has been made to create AST for the target
* of this inclusion.
* @since 5.4
*/
public boolean createsAST();
/**
* Returns the file from the index that this include statement has pulled in, or <code>null</code>
* if the include creates AST or is unresolved or skipped.
* @since 5.4
*/
public IIndexFile getImportedIndexFile();
}

View file

@ -55,4 +55,10 @@ public interface IIndexFragmentFile extends IIndexFile {
* Returns the id of the linkage this file belongs to.
*/
int getLinkageID() throws CoreException;
/**
* Changes the inclusions pointing to 'source' to point to this file, instead.
* The file 'source' must belong to the same fragment as this file.
*/
void transferIncluders(IIndexFragmentFile source) throws CoreException;
}

View file

@ -12,8 +12,6 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.index;
import java.util.Collection;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
@ -73,7 +71,7 @@ public interface IWritableIndex extends IIndex {
* @param a collection that receives IndexFileLocation objects for files that
* had the cleared file as a context. May be <code>null</code>.
*/
void clearFile(IIndexFragmentFile file, Collection<IIndexFileLocation> clearedContexts) throws CoreException;
void clearFile(IIndexFragmentFile file) throws CoreException;
/**
* Creates a file object for the given location or returns an existing one.
@ -124,20 +122,20 @@ public interface IWritableIndex extends IIndex {
/**
* Acquires a write lock, while giving up a certain amount of read locks.
*/
void acquireWriteLock(int giveupReadLockCount) throws InterruptedException;
void acquireWriteLock() throws InterruptedException;
/**
* Releases a write lock, reestablishing a certain amount of read locks.
* Fully equivalent to <code>releaseWriteLock(int, true)</code>.
*/
void releaseWriteLock(int establishReadLockCount);
void releaseWriteLock();
/**
* Releases a write lock, reestablishing a certain amount of read locks.
* @param establishReadLockCount amount of read-locks to establish.
* @param flushDatabase when true the changes are flushed to disk.
*/
void releaseWriteLock(int establishReadLockCount, boolean flushDatabase);
void releaseWriteLock(boolean flushDatabase);
/**
* Resets the counters for cache-hits
@ -174,4 +172,10 @@ public interface IWritableIndex extends IIndex {
* Clears the result cache, caller needs to hold a write-lock.
*/
void clearResultCache();
/**
* Changes the inclusions pointing to 'source' to point to 'target', instead.
* Both files must belong to the writable fragment.
*/
void transferIncluders(IIndexFragmentFile source, IIndexFragmentFile target) throws CoreException;
}

View file

@ -13,8 +13,6 @@
package org.eclipse.cdt.internal.core.index;
import java.util.Collection;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.index.IIndexFileLocation;
@ -40,7 +38,7 @@ public interface IWritableIndexFragment extends IIndexFragment {
* @param a collection that receives IndexFileLocation objects for files that
* had the cleared file as a context.
*/
void clearFile(IIndexFragmentFile file, Collection<IIndexFileLocation> contextsRemoved) throws CoreException;
void clearFile(IIndexFragmentFile file) throws CoreException;
/**
* Creates a file object for the given location and linkage or returns an existing one.

View file

@ -56,9 +56,8 @@ public final class IndexBasedFileContentProvider extends InternalFileContentProv
private final InternalFileContentProvider fFallBackFactory;
private final ASTFilePathResolver fPathResolver;
private final AbstractIndexerTask fRelatedIndexerTask;
private boolean fSupportFillGapFromContextToHeader;
private long fFileSizeLimit= 0;
private IIndexFile[] fContextToHeaderGap;
private final Map<IIndexFileLocation, IFileNomination> fPragmaOnce= new HashMap<IIndexFileLocation, IFileNomination>();
public IndexBasedFileContentProvider(IIndex index,
@ -75,8 +74,8 @@ public final class IndexBasedFileContentProvider extends InternalFileContentProv
fLinkage= linkage;
}
public void setSupportFillGapFromContextToHeader(boolean val) {
fSupportFillGapFromContextToHeader= val;
public void setContextToHeaderGap(IIndexFile[] ctxToHeader) {
fContextToHeaderGap= ctxToHeader;
}
public void setFileSizeLimit(long limit) {
@ -254,29 +253,16 @@ public final class IndexBasedFileContentProvider extends InternalFileContentProv
@Override
public InternalFileContent getContentForContextToHeaderGap(String path,
IMacroDictionary macroDictionary) {
if (!fSupportFillGapFromContextToHeader) {
if (fContextToHeaderGap == null) {
return null;
}
IIndexFileLocation ifl= fPathResolver.resolveASTPath(path);
if (ifl == null) {
return null;
}
try {
// TODO(197989) This is wrong, the dictionary at this point does not relate to the target
// file. We'll have to provide the target file from the outside (i.e. from the indexer
// task.
IIndexFile targetFile = selectIndexFile(macroDictionary, ifl);
if (targetFile == null) {
IIndexFile contextFile= fContextToHeaderGap[0];
IIndexFile targetFile = fContextToHeaderGap[1];
if (contextFile == null || targetFile == null || contextFile == targetFile)
return null;
}
IIndexFile contextFile= findContext(targetFile);
if (contextFile == targetFile || contextFile == null) {
return null;
}
Map<IIndexFileLocation, IFileNomination> newPragmaOnce= new HashMap<IIndexFileLocation, IFileNomination>();
List<IIndexFile> filesIncluded= new ArrayList<IIndexFile>();
ArrayList<IIndexMacro> macros= new ArrayList<IIndexMacro>();
@ -309,22 +295,6 @@ public final class IndexBasedFileContentProvider extends InternalFileContentProv
return result;
}
private IIndexFile findContext(IIndexFile file) throws CoreException {
final HashSet<IIndexFile> ifiles= new HashSet<IIndexFile>();
ifiles.add(file);
IIndexInclude include= file.getParsedInContext();
while (include != null) {
final IIndexFile context= include.getIncludedBy();
if (!ifiles.add(context)) {
return file;
}
file= context;
include= context.getParsedInContext();
}
return file;
}
public IIndexFile[] findIndexFiles(InternalFileContent fc) throws CoreException {
IIndexFileLocation ifl = fPathResolver.resolveASTPath(fc.getFileLocation());
if (ifl != null) {

View file

@ -12,8 +12,6 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.index;
import java.util.Collection;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.index.IIndexFile;
@ -101,12 +99,12 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
isWritableFragment(((IIndexFragmentFile)file).getIndexFragment());
}
public void clearFile(IIndexFragmentFile file, Collection<IIndexFileLocation> clearedContexts) throws CoreException {
public void clearFile(IIndexFragmentFile file) throws CoreException {
IIndexFragment indexFragment = file.getIndexFragment();
if (!isWritableFragment(indexFragment)) {
assert false : "Attempt to clear file of read-only fragment"; //$NON-NLS-1$
} else {
((IWritableIndexFragment) indexFragment).clearFile(file, clearedContexts);
((IWritableIndexFragment) indexFragment).clearFile(file);
}
}
@ -126,25 +124,25 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
fThread= null;
}
public void acquireWriteLock(int giveupReadlockCount) throws InterruptedException {
public void acquireWriteLock() throws InterruptedException {
checkThread();
assert !fIsWriteLocked: "Multiple write locks is not allowed"; //$NON-NLS-1$
assert giveupReadlockCount == getReadLockCount(): "Unexpected read lock is not allowed"; //$NON-NLS-1$
fWritableFragment.acquireWriteLock(giveupReadlockCount);
fWritableFragment.acquireWriteLock(getReadLockCount());
fIsWriteLocked= true;
}
public void releaseWriteLock(int establishReadlockCount) {
releaseWriteLock(establishReadlockCount, true);
public void releaseWriteLock() {
releaseWriteLock(true);
}
public void releaseWriteLock(int establishReadlockCount, boolean flush) {
public void releaseWriteLock(boolean flush) {
checkThread();
assert fIsWriteLocked: "No write lock to be released"; //$NON-NLS-1$
assert establishReadlockCount == getReadLockCount(): "Unexpected read lock is not allowed"; //$NON-NLS-1$
// Bug 297641: Result cache of read only providers needs to be cleared.
int establishReadlockCount = getReadLockCount();
if (establishReadlockCount == 0) {
clearResultCache();
}
@ -176,10 +174,15 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
fWritableFragment.flush();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.index.IWritableIndex#getDatabaseSizeBytes()
*/
public long getDatabaseSizeBytes() {
return fWritableFragment.getDatabaseSizeBytes();
}
public void transferIncluders(IIndexFragmentFile source, IIndexFragmentFile target) throws CoreException {
if (source == null || target == null || !isWritableFile(source) || !isWritableFile(target))
throw new IllegalArgumentException();
if (source.equals(target))
return;
target.transferIncluders(source);
}
}

View file

@ -358,12 +358,12 @@ public abstract class StandaloneIndexer {
private void clearIndex() throws CoreException, InterruptedException {
IWritableIndex index= getIndex();
// First clear the pdom
index.acquireWriteLock(0);
index.acquireWriteLock();
try {
index.clear();
}
finally {
index.releaseWriteLock(0);
index.releaseWriteLock();
}
}

View file

@ -15,13 +15,8 @@ import java.text.NumberFormat;
import java.util.Collection;
import java.util.Iterator;
import com.ibm.icu.text.MessageFormat;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.model.AbstractLanguage;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.internal.core.index.IWritableIndex;
import org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask;
import org.eclipse.cdt.internal.core.pdom.IndexerProgress;
@ -29,6 +24,8 @@ import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import com.ibm.icu.text.MessageFormat;
/**
* A task for index updates.
*
@ -111,15 +108,6 @@ public abstract class StandaloneIndexerTask extends AbstractIndexerTask {
return getIndexer().getIndexAllFiles();
}
@Override
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];
}
@Override
protected final IWritableIndex createIndex() {
return fIndexer.getIndex();
@ -249,20 +237,6 @@ public abstract class StandaloneIndexerTask extends AbstractIndexerTask {
protected void logException(Throwable e) {
trace(e.getMessage());
}
@SuppressWarnings("deprecation")
@Override
protected IScannerInfo createDefaultScannerConfig(int linkageID) {
IStandaloneScannerInfoProvider provider = fIndexer.getScannerInfoProvider();
if(provider != null)
return provider.getDefaultScannerInformation(linkageID);
IScannerInfo scannerInfo = fIndexer.getScannerInfo();
if(scannerInfo != null)
return scannerInfo;
return super.createDefaultScannerConfig(linkageID);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask#getLinkagesToParse()

View file

@ -42,6 +42,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree.IASTIncl
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IFileNomination;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.parser.ISignificantMacros;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
@ -265,8 +266,10 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
private final boolean fFoundByHeuristics;
private final IFileNomination fNominationDelegate;
private boolean fPragmaOnce;
private boolean fCreatesAST;
private ISignificantMacros fSignificantMacros;
private ISignificantMacros[] fLoadedVersions = NO_VERSIONS;
private long fContentsHash;
public ASTInclusionStatement(IASTTranslationUnit parent,
int startNumber, int nameStartNumber, int nameEndNumber, int endNumber,
@ -350,6 +353,30 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
public ISignificantMacros[] getLoadedVersions() {
return fLoadedVersions;
}
public long getContentsHash() {
if (fNominationDelegate != null) {
return 0;
}
return fContentsHash;
}
public void setContentsHash(long hash) {
assert fNominationDelegate == null;
fCreatesAST= true;
fContentsHash= hash;
}
public boolean createsAST() {
return fCreatesAST;
}
public IIndexFile getImportedIndexFile() {
if (fNominationDelegate instanceof IIndexFile)
return (IIndexFile) fNominationDelegate;
return null;
}
}
class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessorObjectStyleMacroDefinition {

View file

@ -1407,7 +1407,6 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
final char[] nameChars= new char[len];
name.getChars(0, len, nameChars, 0);
handleProblem(IProblem.PREPROCESSOR_INCLUSION_NOT_FOUND, nameChars, poundOffset, condEndOffset);
// Inactive, found in index, skipped, or unresolved.
fLocationMap.encounterPoundInclude(poundOffset, nameOffsets[0], nameOffsets[1],
condEndOffset, headerName, null, userInclude, active, false, null);
return;
@ -1448,6 +1447,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
fCurrentContext= fctx;
fLocationMap.parsingFile(fFileContentProvider, fi);
stmt= ctx.getInclusionStatement();
stmt.setContentsHash(source.getContentsHash());
if (!fCurrentContext.isPragmaOnce()) {
// Track the loaded version count, even in a non-pragma-once context.
loadedVerisons= fFileContentProvider.getLoadedVersions(path);
@ -1462,7 +1462,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
break;
}
if (stmt == null) {
// Inactive, found in index, skipped, or unresolved.
// Found in index or skipped.
stmt= fLocationMap.encounterPoundInclude(poundOffset, nameOffsets[0], nameOffsets[1],
condEndOffset, headerName, path, userInclude, active, isHeuristic, nominationDelegate);
}

View file

@ -13,7 +13,6 @@
package org.eclipse.cdt.internal.core.pdom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@ -46,6 +45,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
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.parser.IProblem;
@ -72,12 +72,15 @@ import org.eclipse.osgi.util.NLS;
*/
abstract public class PDOMWriter {
public static class FileInAST {
public FileInAST(IASTPreprocessorIncludeStatement includeStmt, FileContentKey key) {
fIncludeStatement= includeStmt;
fFileContentKey= key;
}
final IASTPreprocessorIncludeStatement fIncludeStatement;
final FileContentKey fFileContentKey;
final long fContentsHash;
public FileInAST(IASTPreprocessorIncludeStatement includeStmt, FileContentKey key, long contentsHash) {
fIncludeStatement= includeStmt;
fFileContentKey= key;
fContentsHash= contentsHash;
}
@Override
public String toString() {
@ -170,29 +173,30 @@ abstract public class PDOMWriter {
* When flushIndex is set to <code>false</code>, you must make sure to flush
* the index after your last write operation.
*/
public void addSymbols(IASTTranslationUnit ast, FileInAST[] selectedFiles, IWritableIndex index,
int readlockCount, boolean flushIndex, long fileContentsHash,
ITodoTaskUpdater taskUpdater, IProgressMonitor pm) throws InterruptedException, CoreException {
final protected void addSymbols(IASTTranslationUnit ast, FileInAST[] selectedFiles,
IWritableIndex index, boolean flushIndex, IIndexFragmentFile replaceFile,
ITodoTaskUpdater taskUpdater, IProgressMonitor pm) throws InterruptedException,
CoreException {
if (fShowProblems) {
fShowInclusionProblems= true;
fShowScannerProblems= true;
fShowSyntaxProblems= true;
}
Data info= new Data(ast, selectedFiles, index);
Data data= new Data(ast, selectedFiles, index);
for (FileInAST file : selectedFiles) {
info.fSymbolMap.put(file.fIncludeStatement, new Symbols());
data.fSymbolMap.put(file.fIncludeStatement, new Symbols());
}
// Extract symbols from AST
extractSymbols(info);
extractSymbols(data);
// Name resolution
resolveNames(info, pm);
resolveNames(data, pm);
// Index update
storeSymbolsInIndex(info, fileContentsHash, readlockCount, flushIndex, pm);
storeSymbolsInIndex(data, replaceFile, flushIndex, pm);
// Tasks update
if (taskUpdater != null) {
@ -202,8 +206,8 @@ abstract public class PDOMWriter {
}
taskUpdater.updateTasks(ast.getComments(), locations.toArray(new IIndexFileLocation[locations.size()]));
}
if (!info.fStati.isEmpty()) {
List<IStatus> stati = info.fStati;
if (!data.fStati.isEmpty()) {
List<IStatus> stati = data.fStati;
String path= null;
if (selectedFiles.length > 0) {
path= selectedFiles[selectedFiles.length - 1].fFileContentKey.getLocation().getURI().getPath();
@ -224,24 +228,29 @@ abstract public class PDOMWriter {
}
}
private void storeSymbolsInIndex(final Data data, long fileContentsHash, int readlockCount,
boolean flushIndex, IProgressMonitor pm) throws InterruptedException, CoreException {
private void storeSymbolsInIndex(final Data data, IIndexFragmentFile replaceFile, boolean flushIndex, IProgressMonitor pm)
throws InterruptedException, CoreException {
final int linkageID= data.fAST.getLinkage().getLinkageID();
for (int i= 0; i < data.fSelectedFiles.length; i++) {
if (pm.isCanceled())
return;
final FileInAST file= data.fSelectedFiles[i];
if (file != null) {
final FileInAST fileInAST= data.fSelectedFiles[i];
if (fileInAST != null) {
if (fShowActivity) {
trace("Indexer: adding " + file.fFileContentKey.getLocation().getURI()); //$NON-NLS-1$
trace("Indexer: adding " + fileInAST.fFileContentKey.getLocation().getURI()); //$NON-NLS-1$
}
Throwable th= null;
YieldableIndexLock lock = new YieldableIndexLock(data.fIndex, readlockCount, flushIndex);
YieldableIndexLock lock = new YieldableIndexLock(data.fIndex, flushIndex);
lock.acquire();
try {
IIndexFragmentFile ifile= storeFileInIndex(data, file, linkageID, fileContentsHash, lock);
reportFileWrittenToIndex(file, ifile);
IIndexFragmentFile ifile= storeFileInIndex(data, fileInAST, linkageID, lock);
if (fileInAST.fIncludeStatement == null && replaceFile != null && !replaceFile.equals(ifile)) {
data.fIndex.transferIncluders(replaceFile, ifile);
reportFileWrittenToIndex(fileInAST, ifile, replaceFile);
} else {
reportFileWrittenToIndex(fileInAST, ifile, null);
}
} catch (RuntimeException e) {
th= e;
} catch (StackOverflowError e) {
@ -249,16 +258,16 @@ abstract public class PDOMWriter {
} catch (AssertionError e) {
th= e;
} finally {
// When the caller holds a read-lock, the result cache of the index is never cleared.
// Because the caller holds a read-lock, the result cache of the index is never cleared.
// ==> Before releasing the lock for the last time in this ast, we clear the result cache.
if (readlockCount > 0 && i == data.fSelectedFiles.length-1) {
if (i == data.fSelectedFiles.length-1) {
data.fIndex.clearResultCache();
}
lock.release();
}
if (th != null) {
data.fStati.add(createStatus(NLS.bind(Messages.PDOMWriter_errorWhileParsing,
file.fFileContentKey.getLocation().getURI().getPath()), th));
fileInAST.fFileContentKey.getLocation().getURI().getPath()), th));
}
fStatistics.fAddToIndexTime += lock.getCumulativeLockTime();
}
@ -473,10 +482,8 @@ abstract public class PDOMWriter {
}
private IIndexFragmentFile storeFileInIndex(Data data, FileInAST astFile, int linkageID,
long fileContentsHash, YieldableIndexLock lock) throws CoreException,
InterruptedException {
YieldableIndexLock lock) throws CoreException, InterruptedException {
final IWritableIndex index = data.fIndex;
Set<IIndexFileLocation> clearedContexts= Collections.emptySet();
IIndexFragmentFile file;
// We create a temporary PDOMFile with zero timestamp, add names to it, then replace
// contents of the old file from the temporary one, then delete the temporary file.
@ -488,16 +495,6 @@ abstract public class PDOMWriter {
IIndexFileLocation location = fileKey.getLocation();
ISignificantMacros significantMacros = fileKey.getSignificantMacros();
IIndexFragmentFile oldFile = index.getWritableFile(linkageID, location, significantMacros);
// mstodo this is wrong, see correct implementation in PDOMFile.clear().
if (oldFile != null) {
IIndexInclude[] includedBy = index.findIncludedBy(oldFile);
if (includedBy.length > 0) {
clearedContexts= new HashSet<IIndexFileLocation>();
for (IIndexInclude include : includedBy) {
clearedContexts.add(include.getIncludedByLocation());
}
}
}
file= index.addUncommittedFile(linkageID, location, significantMacros);
try {
boolean pragmaOnce= owner != null ? owner.hasPragmaOnceSemantics() : data.fAST.hasPragmaOnceSemantics();
@ -527,8 +524,8 @@ abstract public class PDOMWriter {
includeInfos.add(new IncludeInformation(stmt, targetLoc, sig, false));
}
}
final boolean isContext = stmt.isActive() &&
(data.fContextIncludes.contains(stmt) || clearedContexts.contains(targetLoc));
final boolean isContext = stmt.isActive() && stmt.isResolved() &&
(data.fContextIncludes.contains(stmt) || isContextFor(oldFile, stmt));
includeInfos.add(new IncludeInformation(stmt, targetLoc, mainSig, isContext));
}
}
@ -537,7 +534,7 @@ abstract public class PDOMWriter {
}
file.setTimestamp(fResolver.getLastModified(location));
file.setEncodingHashcode(fResolver.getEncoding(location).hashCode());
file.setContentsHash(fileContentsHash);
file.setContentsHash(astFile.fContentsHash);
file = index.commitUncommittedFile();
} finally {
index.clearUncommittedFile();
@ -545,10 +542,22 @@ abstract public class PDOMWriter {
return file;
}
private boolean isContextFor(IIndexFragmentFile oldFile, IASTPreprocessorIncludeStatement stmt)
throws CoreException {
IIndexFile target= stmt.getImportedIndexFile();
if (oldFile != null && target != null) {
IIndexInclude ctxInclude = target.getParsedInContext();
if (ctxInclude != null && oldFile.equals(ctxInclude.getIncludedBy()))
return true;
}
return false;
}
/**
* Informs the subclass that a file has been stored in the index.
*/
protected abstract void reportFileWrittenToIndex(FileInAST file, IIndexFragmentFile ifile);
protected abstract void reportFileWrittenToIndex(FileInAST file, IIndexFragmentFile iFile,
IIndexFragmentFile replacesFile) throws CoreException;
private String getLocationInfo(String filename, int lineNumber) {
return " at " + filename + "(" + lineNumber + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

View file

@ -264,7 +264,7 @@ public class TeamPDOMImportOperation implements IWorkspaceRunnable {
for (IIndexFragmentFile ifile : filesToDelete) {
if (ifile != null) {
checkMonitor(monitor);
pdom.clearFile(ifile, null);
pdom.clearFile(ifile);
}
}
for (FileAndChecksum fc : updateTimestamps) {

View file

@ -14,7 +14,6 @@ package org.eclipse.cdt.internal.core.pdom;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@ -32,7 +31,6 @@ import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
import org.eclipse.cdt.internal.core.pdom.db.BTree;
import org.eclipse.cdt.internal.core.pdom.db.ChunkCache;
import org.eclipse.cdt.internal.core.pdom.db.DBProperties;
import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
@ -88,20 +86,16 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
if (uncommittedFile == null)
return null;
PDOMFile file;
BTree fileIndex = getFileIndex();
if (fileBeingUpdated == null) {
// New file.
// New file, insert it into the index.
file = uncommittedFile;
getFileIndex().insert(file.getRecord());
} else {
// Existing file.
// Remove the file from the index before replacing its contents since position of
// the file in the index is content-dependent.
fileIndex.delete(fileBeingUpdated.getRecord());
fileBeingUpdated.replaceContentsFrom(uncommittedFile);
file = fileBeingUpdated;
fileBeingUpdated = null;
}
fileIndex.insert(file.getRecord()); // Insert the file to the file index.
fEvent.fFilesWritten.add(uncommittedKey.getLocation());
uncommittedFile = null;
uncommittedKey = null;
@ -111,7 +105,7 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
public void clearUncommittedFile() throws CoreException {
if (uncommittedFile != null) {
try {
uncommittedFile.clear(null);
uncommittedFile.clear();
uncommittedFile.delete();
} finally {
uncommittedFile = null;
@ -127,7 +121,6 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
assert sourceFile.getIndexFragment() == this;
PDOMFile pdomFile = (PDOMFile) sourceFile;
pdomFile.addIncludesTo(includes);
pdomFile.addMacros(macros);
final ASTFilePathResolver origResolver= fPathResolver;
fPathResolver= pathResolver;
@ -136,6 +129,8 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
} finally {
fPathResolver= origResolver;
}
// Includes expose the temporary file in the index, we must not yield the lock beyond this point.
pdomFile.addIncludesTo(includes);
final IIndexFileLocation location = pdomFile.getLocation();
if (location != null) {
@ -144,12 +139,11 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
}
}
public void clearFile(IIndexFragmentFile file, Collection<IIndexFileLocation> contextsRemoved)
throws CoreException {
public void clearFile(IIndexFragmentFile file) throws CoreException {
assert file.getIndexFragment() == this;
IIndexFileLocation location = file.getLocation();
PDOMFile pdomFile = (PDOMFile) file;
pdomFile.clear(contextsRemoved);
pdomFile.clear();
fEvent.fClearedFiles.add(location);
}
@ -214,7 +208,7 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
// remove content where converter returns null
for (PDOMFile file : notConverted) {
file.convertIncludersToUnresolved();
file.clear(null);
file.clear();
}
}

View file

@ -19,14 +19,12 @@ import org.eclipse.cdt.internal.core.index.IWritableIndex;
*/
public class YieldableIndexLock {
private final IWritableIndex index;
private final int readlockCount;
private final boolean flushIndex;
private long lastLockTime;
private long cumulativeLockTime;
public YieldableIndexLock(IWritableIndex index, int readlockCount, boolean flushIndex) {
public YieldableIndexLock(IWritableIndex index, boolean flushIndex) {
this.index = index;
this.readlockCount = readlockCount;
this.flushIndex = flushIndex;
}
@ -36,7 +34,7 @@ public class YieldableIndexLock {
* @throws InterruptedException
*/
public void acquire() throws InterruptedException {
index.acquireWriteLock(readlockCount);
index.acquireWriteLock();
lastLockTime = System.currentTimeMillis();
}
@ -45,7 +43,7 @@ public class YieldableIndexLock {
*/
public void release() {
if (lastLockTime != 0) {
index.releaseWriteLock(readlockCount, flushIndex);
index.releaseWriteLock(flushIndex);
cumulativeLockTime += System.currentTimeMillis() - lastLockTime;
lastLockTime = 0;
}
@ -58,7 +56,7 @@ public class YieldableIndexLock {
*/
public void yield() throws InterruptedException {
if (index.hasWaitingReaders()) {
index.releaseWriteLock(readlockCount, false);
index.releaseWriteLock(false);
cumulativeLockTime += System.currentTimeMillis() - lastLockTime;
lastLockTime = 0;
acquire();

View file

@ -16,7 +16,6 @@ package org.eclipse.cdt.internal.core.pdom.dom;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@ -31,7 +30,6 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
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.IIndexLocationConverter;
@ -168,79 +166,38 @@ public class PDOMFile implements IIndexFragmentFile {
* @throws CoreException
*/
public void replaceContentsFrom(PDOMFile sourceFile) throws CoreException {
ICPPUsingDirective[] directives= getUsingDirectives();
for (ICPPUsingDirective ud : directives) {
if (ud instanceof IPDOMNode) {
((IPDOMNode) ud).delete(null);
}
}
setFirstUsingDirectiveRec(sourceFile.getLastUsingDirectiveRec());
// Delete current content
clear();
// Replace the includes
PDOMInclude include = getFirstInclude();
while (include != null) {
PDOMInclude nextInclude = include.getNextInIncludes();
IIndexFile includedBy = include.getIncludedBy();
if (this.equals(includedBy)) {
include.delete();
}
include = nextInclude;
}
include = sourceFile.getFirstInclude();
// Link in the using directives
setLastUsingDirective(sourceFile.getLastUsingDirectiveRec());
// Link in the includes, replace the owner.
PDOMInclude include = sourceFile.getFirstInclude();
setFirstInclude(include);
while (include != null) {
IIndexFile includedBy = include.getIncludedBy();
if (sourceFile.equals(includedBy)) {
include.setIncludedBy(this);
if (sourceFile.equals(include.getIncludes())) {
include.setIncludes(this);
}
}
include = include.getNextInIncludes();
for (; include != null; include= include.getNextInIncludes()) {
include.setIncludedBy(this);
}
// Replace all the macros in this file.
PDOMLinkage linkage= getLinkage();
PDOMMacro macro = getFirstMacro();
while (macro != null) {
PDOMMacro nextMacro = macro.getNextMacro();
macro.delete(linkage);
macro = nextMacro;
}
macro = sourceFile.getFirstMacro();
// In the unexpected case that there is an included by relation, append it.
transferIncluders(sourceFile);
// Link in the macros.
PDOMMacro macro = sourceFile.getFirstMacro();
setFirstMacro(macro);
for (; macro != null; macro = macro.getNextMacro()) {
macro.setFile(this);
}
// Replace all macro references
ArrayList<PDOMMacroReferenceName> mrefs= new ArrayList<PDOMMacroReferenceName>();
PDOMMacroReferenceName mref = getFirstMacroReference();
while (mref != null) {
mrefs.add(mref);
mref= mref.getNextInFile();
}
for (PDOMMacroReferenceName m : mrefs) {
m.delete();
}
mref = sourceFile.getFirstMacroReference();
// Link in macro references
PDOMMacroReferenceName mref = sourceFile.getFirstMacroReference();
setFirstMacroReference(mref);
for (; mref != null; mref = mref.getNextInFile()) {
mref.setFile(this);
}
// Replace all the names in this file
ArrayList<PDOMName> names= new ArrayList<PDOMName>();
PDOMName name = getFirstName();
for (; name != null; name= name.getNextInFile()) {
names.add(name);
linkage.onDeleteName(name);
}
for (Iterator<PDOMName> iterator = names.iterator(); iterator.hasNext();) {
name = iterator.next();
name.delete();
}
name = sourceFile.getFirstName();
PDOMName name = sourceFile.getFirstName();
setFirstName(name);
for (; name != null; name= name.getNextInFile()) {
name.setFile(this);
@ -250,13 +207,35 @@ public class PDOMFile implements IIndexFragmentFile {
setEncodingHashcode(sourceFile.getEncodingHashcode());
setContentsHash(sourceFile.getContentsHash());
// Transfer the flags.
Database db= fLinkage.getDB();
// Transfer the flags.
db.putByte(record + FLAGS, db.getByte(sourceFile.record + FLAGS));
// Delete the source file
sourceFile.delete();
}
public void transferIncluders(IIndexFragmentFile sourceFile) throws CoreException {
PDOMFile source= (PDOMFile) sourceFile;
PDOMInclude include = source.getFirstIncludedBy();
if (include != null) {
for (PDOMInclude i=include; i != null; i= i.getNextInIncludedBy()) {
i.setIncludes(this);
}
PDOMInclude last= getFirstIncludedBy();
if (last == null) {
setFirstInclude(include);
} else {
for (PDOMInclude i=include; i != null; i= i.getNextInIncludedBy()) {
last= i;
}
last.setNextInIncludedBy(include);
include.setPrevInIncludedBy(last);
}
}
source.setFirstIncludedBy(null);
}
/**
* This method should not be called on PDOMFile objects that are referenced by the file index.
* @param location a new location
@ -494,22 +473,22 @@ public class PDOMFile implements IIndexFragmentFile {
return new PDOMMacroReferenceName(fLinkage, name, this, cont);
}
public void clear(Collection<IIndexFileLocation> contextsRemoved) throws CoreException {
public void clear() throws CoreException {
ICPPUsingDirective[] directives= getUsingDirectives();
for (ICPPUsingDirective ud : directives) {
if (ud instanceof IPDOMNode) {
((IPDOMNode) ud).delete(null);
}
}
setFirstUsingDirectiveRec(0);
setLastUsingDirective(0);
// Remove the includes
PDOMInclude include = getFirstInclude();
while (include != null) {
PDOMInclude nextInclude = include.getNextInIncludes();
if (contextsRemoved != null && include.getPrevInIncludedByRecord() == 0) {
contextsRemoved.add(include.getIncludesLocation());
}
// if (contextsRemoved != null && include.getPrevInIncludedByRecord() == 0) {
// contextsRemoved.add(include.getIncludesLocation());
// }
include.delete();
include = nextInclude;
}
@ -886,7 +865,7 @@ public class PDOMFile implements IIndexFragmentFile {
return fLinkage.getDB().getRecPtr(record + LAST_USING_DIRECTIVE);
}
public void setFirstUsingDirectiveRec(long rec) throws CoreException {
public void setLastUsingDirective(long rec) throws CoreException {
fLinkage.getDB().putRecPtr(record + LAST_USING_DIRECTIVE, rec);
}

View file

@ -876,7 +876,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
long rec= file.getLastUsingDirectiveRec();
PDOMCPPUsingDirective ud= new PDOMCPPUsingDirective(this, rec, containerNS,
pdomName.getBinding(), pdomName.getFileLocation().getNodeOffset());
file.setFirstUsingDirectiveRec(ud.getRecord());
file.setLastUsingDirective(ud.getRecord());
}
} else if (parentNode instanceof ICPPASTElaboratedTypeSpecifier) {
ICPPASTElaboratedTypeSpecifier elaboratedSpecifier = (ICPPASTElaboratedTypeSpecifier)parentNode;

View file

@ -15,36 +15,25 @@ import java.util.Arrays;
import java.util.Calendar;
import java.util.Comparator;
import java.util.HashSet;
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.index.IIndexManager;
import org.eclipse.cdt.core.model.AbstractLanguage;
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.IScannerInfo;
import org.eclipse.cdt.core.parser.IScannerInfoProvider;
import org.eclipse.cdt.core.parser.ScannerInfo;
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.db.ChunkCache;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.osgi.util.NLS;
import com.ibm.icu.text.NumberFormat;
@ -176,49 +165,6 @@ public abstract class PDOMIndexerTask extends AbstractIndexerTask implements IPD
return defaultValue;
}
@Override
protected AbstractLanguage[] getLanguages(String filename) {
IProject project = getProject().getProject();
IContentType ct= CCorePlugin.getContentType(project, filename);
if (ct != null) {
ILanguage l = LanguageManager.getInstance().getLanguage(ct, project);
if (l instanceof AbstractLanguage) {
if (filename.indexOf('.') >= 0 && 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};
}
}
return new AbstractLanguage[0];
}
@Override
protected IScannerInfo createDefaultScannerConfig(int linkageID) {
IProject project= getProject().getProject();
IScannerInfoProvider provider= CCorePlugin.getDefault().getScannerInfoProvider(project);
IScannerInfo scanInfo;
if (provider != null) {
String filename= linkageID == ILinkage.C_LINKAGE_ID ? "__cdt__.c" : "__cdt__.cpp"; //$NON-NLS-1$//$NON-NLS-2$
IFile file= project.getFile(filename);
scanInfo= provider.getScannerInformation(file);
if (scanInfo == null || scanInfo.getDefinedSymbols().isEmpty()) {
scanInfo= provider.getScannerInformation(project);
}
if (linkageID == ILinkage.C_LINKAGE_ID) {
final Map<String, String> definedSymbols = scanInfo.getDefinedSymbols();
definedSymbols.remove("__cplusplus__"); //$NON-NLS-1$
definedSymbols.remove("__cplusplus"); //$NON-NLS-1$
}
} else {
scanInfo= new ScannerInfo();
}
return scanInfo;
}
private ICProject getProject() {
return getIndexer().getProject();
}

View file

@ -88,7 +88,7 @@ public class PDOMRebuildTask implements IPDOMIndexerTask {
private void clearIndex(ICProject project, IWritableIndex index) throws CoreException, InterruptedException {
// First clear the pdom
index.acquireWriteLock(0);
index.acquireWriteLock();
try {
index.clear();
IWritableIndexFragment wf= index.getWritableFragment();
@ -96,7 +96,7 @@ public class PDOMRebuildTask implements IPDOMIndexerTask {
PDOMManager.writeProjectPDOMProperties((WritablePDOM) wf, project.getProject());
}
} finally {
index.releaseWriteLock(0);
index.releaseWriteLock();
}
}

View file

@ -15,11 +15,13 @@ import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
@ -42,6 +44,7 @@ import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
@ -55,12 +58,14 @@ 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.CModelException;
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.ExtendedScannerInfo;
import org.eclipse.cdt.core.parser.IScannerInfoProvider;
import org.eclipse.cdt.core.parser.ISignificantMacros;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager;
@ -76,6 +81,7 @@ import org.eclipse.cdt.internal.ui.editor.ASTProvider;
@SuppressWarnings("nls")
public class CreateParserLogAction implements IObjectActionDelegate {
private static final String INDENT = " ";
private static final class MyVisitor extends ASTVisitor {
List<IASTProblem> fProblems= new ArrayList<IASTProblem>();
@ -118,6 +124,8 @@ public class CreateParserLogAction implements IObjectActionDelegate {
private ISelection fSelection;
private IWorkbenchPartSite fSite;
private boolean fWroteUnresolvedTitle;
public void setActivePart(IAction action, IWorkbenchPart targetPart) {
fSite= targetPart.getSite();
@ -209,81 +217,90 @@ public class CreateParserLogAction implements IObjectActionDelegate {
IStatus status = Status.OK_STATUS;
final ICProject cproject = tu.getCProject();
final String projectName= cproject == null ? null : cproject.getElementName();
String scannerInfoProvider= "null";
if (cproject != null) {
IScannerInfoProvider provider = CCorePlugin.getDefault().getScannerInfoProvider(cproject.getProject());
if (provider != null) {
scannerInfoProvider= provider.getClass().getName();
}
}
ITranslationUnit ctx= tu;
final IIndex index = ast.getIndex();
ITranslationUnit configureWith = tu;
int ctxLinkage= 0;
ISignificantMacros ctxSigMacros= null;
if (tu instanceof TranslationUnit) {
TranslationUnit itu= (TranslationUnit) tu;
ctx= itu.getSourceContextTU(ast.getIndex(), ITranslationUnit.AST_CONFIGURE_USING_SOURCE_CONTEXT);
IIndexFile[] ctxToHeader = itu.getContextToHeader(index, ITranslationUnit.AST_CONFIGURE_USING_SOURCE_CONTEXT);
if (ctxToHeader != null) {
try {
final IIndexFile ctxFile = ctxToHeader[0];
ctxLinkage= ctxToHeader[0].getLinkageID();
ctxSigMacros= ctxFile.getSignificantMacros();
configureWith = CoreModelUtil.findTranslationUnitForLocation(ctxFile.getLocation(), cproject);
} catch (CoreException e) {
}
if (configureWith == null) {
configureWith= tu;
ctxToHeader= null;
}
}
}
final ExtendedScannerInfo scfg= new ExtendedScannerInfo(ctx.getScannerInfo(true));
final String indent= " ";
final ExtendedScannerInfo scfg= new ExtendedScannerInfo(configureWith.getScannerInfo(true));
final MyVisitor visitor= new MyVisitor();
ast.accept(visitor);
out.println("Project: " + projectName);
out.println("File: " + tu.getLocationURI());
out.println("Language: " + lang.getName());
out.println("Index Version: " + PDOM.versionString(PDOM.getDefaultVersion()));
out.println("Scanner Info Provider: " + scannerInfoProvider);
out.println("Build Configuration: " + getBuildConfig(cproject));
out.println("File: " + tu.getLocationURI());
out.println("Context: " + ctx.getLocationURI());
out.println("Language: " + lang.getName());
out.println();
out.println("Include Search Path (option -I):");
output(out, indent, scfg.getIncludePaths());
out.println();
out.println("Local Include Search Path (option -iquote):");
output(out, indent, scfg.getLocalIncludePath());
out.println();
out.println("Preincluded files (option -include):");
output(out, indent, scfg.getIncludeFiles());
out.println();
out.println("Preincluded macro files (option -imacros):");
output(out, indent, scfg.getMacroFiles());
out.println();
out.println("Macro definitions (option -D):");
HashSet<String> reported= new HashSet<String>();
output(out, indent, scfg.getDefinedSymbols(), reported);
out.println();
out.println("Macro definitions (from configuration + headers in index):");
output(out, indent, ast.getBuiltinMacroDefinitions(), reported);
out.println();
out.println("Macro definitions (from files actually parsed):");
output(out, indent, ast.getMacroDefinitions(), reported);
out.println();
out.println("Unresolved includes (from headers in index):");
if (configureWith == tu) {
out.println("Context: none");
} else {
out.println("Context: " + configureWith.getLocationURI());
out.println(INDENT + getLinkageName(ctxLinkage) + ", " + ctxSigMacros);
}
try {
outputUnresolvedIncludes(cproject, ast.getIndex(), out, indent, ast.getIncludeDirectives(), ast.getLinkage().getLinkageID());
IIndexFile[] versions= index.getFiles(IndexLocationFactory.getIFL(tu));
out.println("Versions in Index: " + versions.length);
for (IIndexFile f : versions) {
out.println(INDENT + getLinkageName(f.getLinkageID()) + ": " + f.getSignificantMacros());
}
} catch (CoreException e) {
status= e.getStatus();
}
out.println();
output(out, "Include Search Path (option -I):", scfg.getIncludePaths());
output(out, "Local Include Search Path (option -iquote):", scfg.getLocalIncludePath());
output(out, "Preincluded files (option -include):", scfg.getIncludeFiles());
output(out, "Preincluded macro files (option -imacros):", scfg.getMacroFiles());
out.println();
out.println("Scanner problems:");
output(out, indent, ast.getPreprocessorProblems());
out.println();
out.println("Parser problems:");
output(out, indent, visitor.fProblems.toArray(new IASTProblem[visitor.fProblems.size()]));
out.println();
out.println("Unresolved names:");
output(out, indent, visitor.fProblemBindings);
out.println();
out.println("Exceptions in name resolution:");
output(out, visitor.fExceptions);
HashSet<String> reported= new HashSet<String>();
output(out, "Macro definitions (option -D):", scfg.getDefinedSymbols(), reported);
output(out, "Macro definitions (from language + headers in index):", ast.getBuiltinMacroDefinitions(), reported);
output(out, "Macro definitions (from files actually parsed):", ast.getMacroDefinitions(), reported);
try {
outputUnresolvedIncludes(cproject, ast.getIndex(), out, ast.getIncludeDirectives(), ast.getLinkage().getLinkageID());
} catch (CoreException e) {
status= e.getStatus();
}
output(out, "Scanner problems:", ast.getPreprocessorProblems());
output(out, "Parser problems:", visitor.fProblems.toArray(new IASTProblem[0]));
output(out, "Unresolved names:", visitor.fProblemBindings.toArray(new IProblemBinding[0]));
output(out, "Exceptions in name resolution:", visitor.fExceptions);
out.println("Written on " + new Date().toString());
return status;
}
private String getLinkageName(int linkageID) {
switch(linkageID) {
case ILinkage.NO_LINKAGE_ID: return ILinkage.NO_LINKAGE_NAME;
case ILinkage.C_LINKAGE_ID: return ILinkage.C_LINKAGE_NAME;
case ILinkage.CPP_LINKAGE_ID: return ILinkage.CPP_LINKAGE_NAME;
case ILinkage.FORTRAN_LINKAGE_ID: return ILinkage.FORTRAN_LINKAGE_NAME;
case ILinkage.OBJC_LINKAGE_ID: return ILinkage.OBJC_LINKAGE_NAME;
}
return String.valueOf(linkageID);
}
private String getBuildConfig(ICProject cproject) {
ICProjectDescriptionManager prjDescMgr= CCorePlugin.getDefault().getProjectDescriptionManager();
ICProjectDescription prefs= prjDescMgr.getProjectDescription(cproject.getProject(), false);
@ -295,35 +312,37 @@ public class CreateParserLogAction implements IObjectActionDelegate {
return "unknown";
}
private void outputUnresolvedIncludes(ICProject prj, IIndex index, PrintStream out, String indent,
private void outputUnresolvedIncludes(ICProject prj, IIndex index, PrintStream out,
IASTPreprocessorIncludeStatement[] includeDirectives, int linkageID) throws CoreException {
fWroteUnresolvedTitle= false;
ASTFilePathResolver resolver= new ProjectIndexerInputAdapter(prj);
HashSet<IIndexFileLocation> handled= new HashSet<IIndexFileLocation>();
HashSet<IIndexFile> handled= new HashSet<IIndexFile>();
for (IASTPreprocessorIncludeStatement include : includeDirectives) {
if (include.isActive() && include.isResolved()) {
outputUnresolvedIncludes(index, out, indent, resolver.resolveASTPath(include.getPath()), linkageID, handled);
if (include.isResolved()) {
IIndexFileLocation ifl = resolver.resolveASTPath(include.getPath());
IIndexFile ifile= index.getFile(linkageID, ifl, include.getSignificantMacros());
outputUnresolvedIncludes(index, out, ifl, ifile, handled);
}
}
if (fWroteUnresolvedTitle)
out.println();
}
private void outputUnresolvedIncludes(IIndex index, PrintStream out, String indent,
IIndexFileLocation ifl, int linkageID, HashSet<IIndexFileLocation> handled) throws CoreException {
if (!handled.add(ifl)) {
return;
}
IIndexFile ifile= index.getFile(linkageID, ifl);
private void outputUnresolvedIncludes(IIndex index, PrintStream out,
IIndexFileLocation ifl, IIndexFile ifile, Set<IIndexFile> handled) throws CoreException {
if (ifile == null) {
out.println(indent + ifl.getURI() + " is not indexed");
}
else {
writeUnresolvedTitle(out);
out.println(INDENT + ifl.getURI() + " is not indexed");
} else if (handled.add(ifile)) {
IIndexInclude[] includes = ifile.getIncludes();
for (IIndexInclude inc : includes) {
if (inc.isActive()) {
if (inc.isResolved()) {
outputUnresolvedIncludes(index, out, indent, inc.getIncludesLocation(), linkageID, handled);
}
else {
out.println(indent + "Unresolved inclusion: " + inc.getFullName() + " in file " +
IIndexFile next = index.resolveInclude(inc);
outputUnresolvedIncludes(index, out, inc.getIncludesLocation(), next, handled);
} else {
writeUnresolvedTitle(out);
out.println(INDENT + "Unresolved inclusion: " + inc.getFullName() + " in file " +
inc.getIncludedByLocation().getURI());
}
}
@ -331,53 +350,85 @@ public class CreateParserLogAction implements IObjectActionDelegate {
}
}
private void output(PrintStream out, String indent, String[] list) {
for (String line : list) {
out.println(indent + line);
public void writeUnresolvedTitle(PrintStream out) {
if (!fWroteUnresolvedTitle) {
fWroteUnresolvedTitle= true;
out.println("Unresolved includes (from headers in index):");
}
}
private void output(PrintStream out, String indent, Map<String, String> definedSymbols, HashSet<String> reported) {
SortedMap<String, String> sorted= new TreeMap<String, String>(COMP_INSENSITIVE);
sorted.putAll(definedSymbols);
for (Entry<String, String> entry : sorted.entrySet()) {
final String macro = entry.getKey() + '=' + entry.getValue();
if (reported.add(macro)) {
out.println(indent + macro);
private void output(PrintStream out, String label, String[] list) {
if (list.length > 0) {
out.println(label);
for (String line : list) {
out.println(INDENT + line);
}
out.println();
}
}
private void output(PrintStream out, String label, Map<String, String> definedSymbols, HashSet<String> reported) {
if (!definedSymbols.isEmpty()) {
out.println(label);
SortedMap<String, String> sorted= new TreeMap<String, String>(COMP_INSENSITIVE);
sorted.putAll(definedSymbols);
for (Entry<String, String> entry : sorted.entrySet()) {
final String macro = entry.getKey() + '=' + entry.getValue();
if (reported.add(macro)) {
out.println(INDENT + macro);
}
}
out.println();
}
}
private void output(PrintStream out, String indent, IASTPreprocessorMacroDefinition[] defs, HashSet<String> reported) {
SortedSet<String> macros= new TreeSet<String>(COMP_INSENSITIVE);
for (IASTPreprocessorMacroDefinition def : defs) {
macros.add(def.toString());
private void output(PrintStream out, String label, IASTPreprocessorMacroDefinition[] defs, HashSet<String> reported) {
if (defs.length > 0) {
out.println(label);
SortedSet<String> macros= new TreeSet<String>(COMP_INSENSITIVE);
for (IASTPreprocessorMacroDefinition def : defs) {
macros.add(def.toString());
}
for (String macro : macros) {
if (reported.add(macro)) {
out.println(INDENT + macro);
}
}
out.println();
}
}
private void output(PrintStream out, String label, IASTProblem[] preprocessorProblems) {
if (preprocessorProblems.length > 0) {
out.println(label);
for (IASTProblem problem : preprocessorProblems) {
out.println(INDENT + problem.getMessageWithLocation());
}
out.println();
}
}
for (String macro : macros) {
if (reported.add(macro)) {
out.println(indent + macro);
private void output(PrintStream out, String label, IProblemBinding[] list) {
if (list.length > 0) {
out.println(label);
for (IProblemBinding problem : list) {
String file= problem.getFileName();
int line = problem.getLineNumber();
out.println(INDENT + problem.getMessage() + " in file " + file + ':' + line);
}
}
}
private void output(PrintStream out, String indent, IASTProblem[] preprocessorProblems) {
for (IASTProblem problem : preprocessorProblems) {
out.println(indent + problem.getMessageWithLocation());
}
}
private void output(PrintStream out, String indent, List<IProblemBinding> list) {
for (IProblemBinding problem : list) {
String file= problem.getFileName();
int line = problem.getLineNumber();
out.println(indent + problem.getMessage() + " in file " + file + ':' + line);
out.println();
}
}
private void output(PrintStream out, List<Exception> list) {
for (Exception problem : list) {
problem.printStackTrace(out);
private void output(PrintStream out, String label, List<Exception> list) {
if (!list.isEmpty()) {
out.println(label);
for (Exception problem : list) {
problem.printStackTrace(out);
}
out.println();
}
}
}