1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Manage the removal of an include guard

This commit is contained in:
Markus Schorn 2011-10-05 16:54:24 +02:00
parent 333559e5ea
commit 098712b4d9
6 changed files with 214 additions and 77 deletions

View file

@ -61,4 +61,10 @@ public interface IIndexFragmentFile extends IIndexFile {
* The file 'source' must belong to the same fragment as this file. * The file 'source' must belong to the same fragment as this file.
*/ */
void transferIncluders(IIndexFragmentFile source) throws CoreException; void transferIncluders(IIndexFragmentFile source) throws CoreException;
/**
* Changes the inclusion from the context of 'source' to point to this file, instead.
* The file 'source' must belong to the same fragment as this file.
*/
void transferContext(IIndexFragmentFile source) throws CoreException;
} }

View file

@ -59,6 +59,12 @@ public interface IWritableIndex extends IIndex {
IIndexFragmentFile getWritableFile(int linkageID, IIndexFileLocation location, IIndexFragmentFile getWritableFile(int linkageID, IIndexFileLocation location,
ISignificantMacros macroDictionary) throws CoreException; ISignificantMacros macroDictionary) throws CoreException;
/**
* Returns the writable files for the given location and linkage. This method
* returns file objects without content, also.
*/
IIndexFragmentFile[] getWritableFiles(int linkageID, IIndexFileLocation location) throws CoreException;
/** /**
* Returns the writable files for the given location in any linkage. This method * Returns the writable files for the given location in any linkage. This method
* returns file objects without content, also. * returns file objects without content, also.
@ -178,4 +184,10 @@ public interface IWritableIndex extends IIndex {
* Both files must belong to the writable fragment. * Both files must belong to the writable fragment.
*/ */
void transferIncluders(IIndexFragmentFile source, IIndexFragmentFile target) throws CoreException; void transferIncluders(IIndexFragmentFile source, IIndexFragmentFile target) throws CoreException;
/**
* Changes the inclusion from the context of 'source' to point to 'target', instead.
* Both files must belong to the writable fragment.
*/
void transferContext(IIndexFragmentFile source, IIndexFragmentFile target) throws CoreException;
} }

View file

@ -47,6 +47,10 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
return fWritableFragment.getFile(linkageID, location, macroDictionary); return fWritableFragment.getFile(linkageID, location, macroDictionary);
} }
public IIndexFragmentFile[] getWritableFiles(int linkageID, IIndexFileLocation location) throws CoreException {
return fWritableFragment.getFiles(linkageID, location);
}
public IIndexFragmentFile[] getWritableFiles(IIndexFileLocation location) throws CoreException { public IIndexFragmentFile[] getWritableFiles(IIndexFileLocation location) throws CoreException {
return fWritableFragment.getFiles(location); return fWritableFragment.getFiles(location);
} }
@ -185,4 +189,12 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
return; return;
target.transferIncluders(source); target.transferIncluders(source);
} }
public void transferContext(IIndexFragmentFile source, IIndexFragmentFile target) throws CoreException {
if (source == null || target == null || !isWritableFile(source) || !isWritableFile(target))
throw new IllegalArgumentException();
if (source.equals(target))
return;
target.transferContext(source);
}
} }

View file

@ -20,10 +20,10 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMIndexerTask; import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
@ -802,7 +802,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
if (monitor.isCanceled() || hasUrgentTasks()) if (monitor.isCanceled() || hasUrgentTasks())
return; return;
parseVersionInContext(linkageID, map, ifl, versionTask, locTask.fTu, parseVersionInContext(linkageID, map, ifl, versionTask, locTask.fTu,
new HashSet<IIndexFile>(), monitor); new LinkedHashSet<IIndexFile>(), monitor);
} }
} }
} }
@ -857,18 +857,59 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
} }
private void parseVersionInContext(int linkageID, LinkageTask map, IIndexFileLocation ifl, private void parseVersionInContext(int linkageID, LinkageTask map, IIndexFileLocation ifl,
final FileVersionTask versionTask, Object tu, Set<IIndexFile> safeGuard, final FileVersionTask versionTask, Object tu, LinkedHashSet<IIndexFile> safeGuard,
IProgressMonitor monitor) throws CoreException, InterruptedException { IProgressMonitor monitor) throws CoreException, InterruptedException {
final IIndexFragmentFile headerFile = versionTask.fIndexFile; final IIndexFragmentFile headerFile = versionTask.fIndexFile;
IIndexFragmentFile ctx= headerFile;
for(;;) {
IIndexInclude ctxInclude= ctx.getParsedInContext();
if (ctxInclude == null)
break;
final IIndexFragmentFile nextCtx= (IIndexFragmentFile) ctxInclude.getIncludedBy(); final int safeguardSize= safeGuard.size();
if (!fIndex.isWritableFile(nextCtx) || !safeGuard.add(nextCtx)) for(;;) {
break; // Look for a context and parse the file
IIndexFragmentFile ctxFile = findContextFile(linkageID, map, versionTask, safeGuard, monitor);
if (ctxFile == null || ctxFile == headerFile)
return;
Object contextTu= fResolver.getInputFile(ctxFile.getLocation());
if (contextTu == null)
return;
final IScannerInfo scannerInfo= fResolver.getBuildConfiguration(linkageID, contextTu);
FileContext ctx= new FileContext(ctxFile, headerFile);
parseFile(tu, linkageID, ifl, scannerInfo, ctx, monitor);
if (!ctx.fLostPragmaOnceSemantics)
return;
// Try the next context
restoreSet(safeGuard, safeguardSize);
}
}
private void restoreSet(LinkedHashSet<?> set, int restoreSize) {
for (Iterator<?> it = set.iterator(); it.hasNext();) {
it.next();
if (restoreSize == 0) {
it.remove();
} else {
restoreSize--;
}
}
}
private IIndexFragmentFile findContextFile(int linkageID, LinkageTask map,
final FileVersionTask versionTask, LinkedHashSet<IIndexFile> safeGuard, IProgressMonitor monitor)
throws CoreException, InterruptedException {
IIndexFragmentFile ctxFile= versionTask.fIndexFile;
for(;;) {
IIndexInclude ctxInclude= ctxFile.getParsedInContext();
if (ctxInclude == null)
return ctxFile;
IIndexFragmentFile nextCtx= (IIndexFragmentFile) ctxInclude.getIncludedBy();
if (!fIndex.isWritableFile(nextCtx))
return ctxFile;
// Found a recursion
if (!safeGuard.add(nextCtx))
return null;
final IIndexFileLocation ctxIfl = nextCtx.getLocation(); final IIndexFileLocation ctxIfl = nextCtx.getLocation();
LocationTask ctxTask= map.find(ctxIfl); LocationTask ctxTask= map.find(ctxIfl);
@ -880,30 +921,19 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
safeGuard, monitor); safeGuard, monitor);
if (ctxVersionTask.fOutdated // This is unexpected. if (ctxVersionTask.fOutdated // This is unexpected.
|| !versionTask.fOutdated) // Our file was parsed. || !versionTask.fOutdated) // Our file was parsed.
return; return null;
// The file is no longer a context, look for a different one. // The file is no longer a context, look for a different one.
ctxInclude= ctx.getParsedInContext(); nextCtx= ctxFile;
continue;
} }
} }
ctx= nextCtx; ctxFile= nextCtx;
}
// See if we found a context and parse the file
if (ctx != headerFile) {
Object contextTu= fResolver.getInputFile(ctx.getLocation());
if (contextTu != null) {
final IScannerInfo scannerInfo= fResolver.getBuildConfiguration(linkageID, contextTu);
IIndexFragmentFile[] ctx2header= {ctx, headerFile};
parseFile(tu, linkageID, ifl, scannerInfo, ctx2header, monitor);
}
} }
} }
private void parseFile(Object tu, int linkageID, IIndexFileLocation ifl, IScannerInfo scanInfo, private void parseFile(Object tu, int linkageID, IIndexFileLocation ifl, IScannerInfo scanInfo,
IIndexFragmentFile[] ctx2header, IProgressMonitor pm) throws CoreException, InterruptedException { FileContext ctx, IProgressMonitor pm) throws CoreException, InterruptedException {
IPath path= getLabel(ifl); IPath path= getLabel(ifl);
AbstractLanguage[] langs= fResolver.getLanguages(tu, true); AbstractLanguage[] langs= fResolver.getLanguages(tu, true);
AbstractLanguage lang= null; AbstractLanguage lang= null;
@ -926,11 +956,12 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
path.lastSegment(), path.removeLastSegments(1).toString())); path.lastSegment(), path.removeLastSegments(1).toString()));
long start= System.currentTimeMillis(); long start= System.currentTimeMillis();
FileContent codeReader= fResolver.getCodeReader(tu); FileContent codeReader= fResolver.getCodeReader(tu);
IASTTranslationUnit ast= createAST(tu, lang, codeReader, scanInfo, fASTOptions, ctx2header, pm); IIndexFile[] ctxFiles = ctx == null ? null : new IIndexFile[] {ctx.fContext, ctx.fOldFile};
IASTTranslationUnit ast= createAST(tu, lang, codeReader, scanInfo, fASTOptions, ctxFiles, pm);
fStatistics.fParsingTime += System.currentTimeMillis() - start; fStatistics.fParsingTime += System.currentTimeMillis() - start;
if (ast != null) { if (ast != null) {
IIndexFragmentFile rewrite= ctx2header == null ? null : ctx2header[1]; writeToIndex(linkageID, ast, codeReader.getContentsHash(), ctx, pm);
writeToIndex(linkageID, ast, codeReader.getContentsHash(), rewrite, pm);
} }
} catch (CoreException e) { } catch (CoreException e) {
th= e; th= e;
@ -1055,7 +1086,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
} }
private void writeToIndex(final int linkageID, IASTTranslationUnit ast, long fileContentsHash, private void writeToIndex(final int linkageID, IASTTranslationUnit ast, long fileContentsHash,
IIndexFragmentFile replace, IProgressMonitor pm) throws CoreException, InterruptedException { FileContext ctx, IProgressMonitor pm) throws CoreException, InterruptedException {
HashSet<FileContentKey> enteredFiles= new HashSet<FileContentKey>(); HashSet<FileContentKey> enteredFiles= new HashSet<FileContentKey>();
ArrayList<FileInAST> orderedFileKeys= new ArrayList<FileInAST>(); ArrayList<FileInAST> orderedFileKeys= new ArrayList<FileInAST>();
@ -1068,13 +1099,20 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
collectOrderedFileKeys(linkageID, inclusion, enteredFiles, orderedFileKeys); collectOrderedFileKeys(linkageID, inclusion, enteredFiles, orderedFileKeys);
} }
if (replace != null || needToStoreInIndex(linkageID, topIfl, ast.getSignificantMacros())) { IIndexFile newFile= selectIndexFile(linkageID, topIfl, ast.getSignificantMacros());
if (ctx != null) {
orderedFileKeys.add(new FileInAST(null, topKey, fileContentsHash));
if (newFile != null && fIndex.isWritableFile(newFile)) {
// File can be reused
ctx.fNewFile= (IIndexFragmentFile) newFile;
}
} else if (newFile == null) {
orderedFileKeys.add(new FileInAST(null, topKey, fileContentsHash)); orderedFileKeys.add(new FileInAST(null, topKey, fileContentsHash));
} }
FileInAST[] fileKeys= orderedFileKeys.toArray(new FileInAST[orderedFileKeys.size()]); FileInAST[] fileKeys= orderedFileKeys.toArray(new FileInAST[orderedFileKeys.size()]);
try { try {
addSymbols(ast, fileKeys, fIndex, false, replace, fTodoTaskUpdater, pm); addSymbols(ast, fileKeys, fIndex, false, ctx, fTodoTaskUpdater, pm);
} catch (CoreException e) { } catch (CoreException e) {
// Avoid parsing files again, that caused an exception to be thrown. // Avoid parsing files again, that caused an exception to be thrown.
withdrawRequests(linkageID, fileKeys); withdrawRequests(linkageID, fileKeys);
@ -1099,37 +1137,12 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
for (IASTInclusionNode element : nested) { for (IASTInclusionNode element : nested) {
collectOrderedFileKeys(linkageID, element, enteredFiles, orderedFileKeys); collectOrderedFileKeys(linkageID, element, enteredFiles, orderedFileKeys);
} }
if (isFirstEntry && needToStoreInIndex(linkageID, ifl, include.getSignificantMacros())) { if (isFirstEntry && selectIndexFile(linkageID, ifl, include.getSignificantMacros()) == null) {
orderedFileKeys.add(new FileInAST(include, fileKey, include.getContentsHash())); orderedFileKeys.add(new FileInAST(include, fileKey, include.getContentsHash()));
} }
} }
} }
private boolean needToStoreInIndex(int linkageID, IIndexFileLocation ifl, ISignificantMacros sigMacros) throws CoreException {
LinkageTask map = findRequestMap(linkageID);
if (map != null) {
LocationTask locTask= map.find(ifl);
if (locTask != null) {
FileVersionTask task = locTask.findVersion(sigMacros);
if (task != null) {
return task.fOutdated;
}
}
}
IIndexFile ifile= null;
if (fResolver.canBePartOfSDK(ifl)) {
// Check for a version in potentially another pdom.
ifile = fIndex.getFile(linkageID, ifl, sigMacros);
} else {
// Search the writable PDOM, only.
IIndexFragmentFile fragFile = fIndex.getWritableFile(linkageID, ifl, sigMacros);
if (fragFile != null && fragFile.hasContent()) {
ifile= fragFile;
}
}
return ifile == null;
}
private void withdrawRequests(int linkageID, FileInAST[] fileKeys) { private void withdrawRequests(int linkageID, FileInAST[] fileKeys) {
LinkageTask map = findRequestMap(linkageID); LinkageTask map = findRequestMap(linkageID);
if (map != null) { if (map != null) {
@ -1171,6 +1184,26 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
return fc; return fc;
} }
IIndexFile selectIndexFile(int linkageID, IIndexFileLocation ifl, ISignificantMacros sigMacros) throws CoreException {
LinkageTask map = findRequestMap(linkageID);
if (map != null) {
LocationTask locTask= map.find(ifl);
if (locTask != null) {
FileVersionTask task = locTask.findVersion(sigMacros);
if (task != null) {
return task.fOutdated ? null : task.fIndexFile;
}
}
}
IIndexFile[] files = getAvailableIndexFiles(linkageID, ifl);
for (IIndexFile file : files) {
if (sigMacros.equals(file.getSignificantMacros()))
return file;
}
return null;
}
public IIndexFile selectIndexFile(int linkageID, IIndexFileLocation ifl, IMacroDictionary md) throws CoreException { public IIndexFile selectIndexFile(int linkageID, IIndexFileLocation ifl, IMacroDictionary md) throws CoreException {
LinkageTask map = findRequestMap(linkageID); LinkageTask map = findRequestMap(linkageID);
if (map != null) { if (map != null) {
@ -1187,11 +1220,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
} }
} }
IIndexFile[] files= fIndexFilesCache.get(ifl); IIndexFile[] files = getAvailableIndexFiles(linkageID, ifl);
if (files == null) {
files= fIndex.getFiles(linkageID, ifl);
fIndexFilesCache.put(ifl, files);
}
for (IIndexFile indexFile : files) { for (IIndexFile indexFile : files) {
if (md.satisfies(indexFile.getSignificantMacros())) { if (md.satisfies(indexFile.getSignificantMacros())) {
return indexFile; return indexFile;
@ -1199,4 +1228,33 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
} }
return null; return null;
} }
public IIndexFile[] getAvailableIndexFiles(int linkageID, IIndexFileLocation ifl)
throws CoreException {
IIndexFile[] files= fIndexFilesCache.get(ifl);
if (files == null) {
if (fResolver.canBePartOfSDK(ifl)) {
// Check for a version in potentially another pdom.
files= fIndex.getFiles(linkageID, ifl);
} else {
IIndexFragmentFile[] fragFiles = fIndex.getWritableFiles(linkageID, ifl);
int j= 0;
for (int i = 0; i < fragFiles.length; i++) {
if (fragFiles[i].hasContent()) {
if (j != i)
fragFiles[j]= fragFiles[i];
j++;
}
}
if (j == fragFiles.length) {
files= fragFiles;
} else {
files= new IIndexFile[j];
System.arraycopy(fragFiles, 0, files, 0, j);
}
}
fIndexFilesCache.put(ifl, files);
}
return files;
}
} }

View file

@ -88,6 +88,19 @@ abstract public class PDOMWriter {
} }
} }
public static class FileContext {
final IIndexFragmentFile fContext;
final IIndexFragmentFile fOldFile;
IIndexFragmentFile fNewFile;
public boolean fLostPragmaOnceSemantics;
public FileContext(IIndexFragmentFile context, IIndexFragmentFile oldFile) {
fContext= context;
fOldFile= oldFile;
fNewFile= null;
}
}
public static int SKIP_ALL_REFERENCES= -1; public static int SKIP_ALL_REFERENCES= -1;
public static int SKIP_TYPE_REFERENCES= 1; public static int SKIP_TYPE_REFERENCES= 1;
public static int SKIP_MACRO_REFERENCES= 2; public static int SKIP_MACRO_REFERENCES= 2;
@ -174,7 +187,7 @@ abstract public class PDOMWriter {
* the index after your last write operation. * the index after your last write operation.
*/ */
final protected void addSymbols(IASTTranslationUnit ast, FileInAST[] selectedFiles, final protected void addSymbols(IASTTranslationUnit ast, FileInAST[] selectedFiles,
IWritableIndex index, boolean flushIndex, IIndexFragmentFile replaceFile, IWritableIndex index, boolean flushIndex, FileContext ctx,
ITodoTaskUpdater taskUpdater, IProgressMonitor pm) throws InterruptedException, ITodoTaskUpdater taskUpdater, IProgressMonitor pm) throws InterruptedException,
CoreException { CoreException {
if (fShowProblems) { if (fShowProblems) {
@ -196,7 +209,7 @@ abstract public class PDOMWriter {
resolveNames(data, pm); resolveNames(data, pm);
// Index update // Index update
storeSymbolsInIndex(data, replaceFile, flushIndex, pm); storeSymbolsInIndex(data, ctx, flushIndex, pm);
// Tasks update // Tasks update
if (taskUpdater != null) { if (taskUpdater != null) {
@ -228,8 +241,9 @@ abstract public class PDOMWriter {
} }
} }
private void storeSymbolsInIndex(final Data data, IIndexFragmentFile replaceFile, boolean flushIndex, IProgressMonitor pm) private void storeSymbolsInIndex(final Data data, FileContext ctx, boolean flushIndex, IProgressMonitor pm)
throws InterruptedException, CoreException { throws InterruptedException, CoreException {
final IIndexFragmentFile newFile= ctx == null ? null : ctx.fNewFile;
final int linkageID= data.fAST.getLinkage().getLinkageID(); final int linkageID= data.fAST.getLinkage().getLinkageID();
for (int i= 0; i < data.fSelectedFiles.length; i++) { for (int i= 0; i < data.fSelectedFiles.length; i++) {
if (pm.isCanceled()) if (pm.isCanceled())
@ -244,14 +258,27 @@ abstract public class PDOMWriter {
YieldableIndexLock lock = new YieldableIndexLock(data.fIndex, flushIndex); YieldableIndexLock lock = new YieldableIndexLock(data.fIndex, flushIndex);
lock.acquire(); lock.acquire();
try { try {
IIndexFragmentFile ifile= storeFileInIndex(data, fileInAST, linkageID, lock); final boolean isReplacement= ctx != null && fileInAST.fIncludeStatement == null;
if (fileInAST.fIncludeStatement == null && replaceFile != null && !replaceFile.equals(ifile)) { IIndexFragmentFile ifile= null;
data.fIndex.transferIncluders(replaceFile, ifile); if (!isReplacement || newFile == null) {
reportFileWrittenToIndex(fileInAST, ifile); ifile= storeFileInIndex(data, fileInAST, linkageID, lock);
} else {
reportFileWrittenToIndex(fileInAST, ifile); reportFileWrittenToIndex(fileInAST, ifile);
} }
} catch (RuntimeException e) {
if (isReplacement) {
if (ifile == null)
ifile= newFile;
if (ctx != null && !ctx.fOldFile.equals(ifile) && ifile != null) {
if (ctx.fOldFile.hasPragmaOnceSemantics() &&
!ifile.hasPragmaOnceSemantics()) {
data.fIndex.transferContext(ctx.fOldFile, ifile);
ctx.fLostPragmaOnceSemantics= true;
} else {
data.fIndex.transferIncluders(ctx.fOldFile, ifile);
}
}
}
} catch (RuntimeException e) {
th= e; th= e;
} catch (StackOverflowError e) { } catch (StackOverflowError e) {
th= e; th= e;

View file

@ -219,9 +219,13 @@ public class PDOMFile implements IIndexFragmentFile {
PDOMFile source= (PDOMFile) sourceFile; PDOMFile source= (PDOMFile) sourceFile;
PDOMInclude include = source.getFirstIncludedBy(); PDOMInclude include = source.getFirstIncludedBy();
if (include != null) { if (include != null) {
// Detach the includes
source.setFirstIncludedBy(null);
// Adjust the includes
for (PDOMInclude i=include; i != null; i= i.getNextInIncludedBy()) { for (PDOMInclude i=include; i != null; i= i.getNextInIncludedBy()) {
i.setIncludes(this); i.setIncludes(this);
} }
// Append the includes
PDOMInclude last= getFirstIncludedBy(); PDOMInclude last= getFirstIncludedBy();
if (last == null) { if (last == null) {
setFirstIncludedBy(include); setFirstIncludedBy(include);
@ -233,7 +237,25 @@ public class PDOMFile implements IIndexFragmentFile {
include.setPrevInIncludedBy(last); include.setPrevInIncludedBy(last);
} }
} }
source.setFirstIncludedBy(null); }
public void transferContext(IIndexFragmentFile sourceFile) throws CoreException {
PDOMFile source= (PDOMFile) sourceFile;
PDOMInclude include = source.getFirstIncludedBy();
if (include != null) {
// Detach the include
final PDOMInclude next = include.getNextInIncludedBy();
include.setNextInIncludedBy(null);
source.setFirstIncludedBy(next);
if (next != null)
next.setPrevInIncludedBy(null);
// Adjust the include
include.setIncludes(this);
// Insert the include
addIncludedBy(include, false);
}
} }
/** /**