mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-28 19:35:36 +02:00
Fix for 167100, using include guards outside of header.
This commit is contained in:
parent
633b10b954
commit
b21be9a7d0
11 changed files with 232 additions and 127 deletions
|
@ -740,24 +740,43 @@ public class IndexBugsTests extends BaseTestCase {
|
||||||
// #include "header2.h"
|
// #include "header2.h"
|
||||||
// int M;
|
// int M;
|
||||||
|
|
||||||
public void _testIncludeGuardsOutsideOfHeader_Bug167100() throws Exception {
|
// #include "header2.h"
|
||||||
|
// #ifndef _h1
|
||||||
|
// #include "header1.h"
|
||||||
|
// #endif
|
||||||
|
public void testIncludeGuardsOutsideOfHeader_Bug167100() throws Exception {
|
||||||
final IIndexManager indexManager = CCorePlugin.getIndexManager();
|
final IIndexManager indexManager = CCorePlugin.getIndexManager();
|
||||||
StringBuffer[] contents= getContentsForTest(4);
|
StringBuffer[] contents= getContentsForTest(5);
|
||||||
IFile f1= TestSourceReader.createFile(fCProject.getProject(), "header1.h", contents[0].toString());
|
IFile f1= TestSourceReader.createFile(fCProject.getProject(), "header1.h", contents[0].toString());
|
||||||
IFile f2= TestSourceReader.createFile(fCProject.getProject(), "header2.h", contents[1].toString());
|
IFile f2= TestSourceReader.createFile(fCProject.getProject(), "header2.h", contents[1].toString());
|
||||||
IFile f3= TestSourceReader.createFile(fCProject.getProject(), "src.cpp", contents[2].toString());
|
IFile f3= TestSourceReader.createFile(fCProject.getProject(), "src.cpp", contents[2].toString());
|
||||||
indexManager.reindex(fCProject);
|
indexManager.reindex(fCProject);
|
||||||
waitForIndexer();
|
waitForIndexer();
|
||||||
IFile f4= TestSourceReader.createFile(fCProject.getProject(), "src2.cpp", contents[2].toString());
|
IFile f4= TestSourceReader.createFile(fCProject.getProject(), "src2.cpp", contents[3].toString());
|
||||||
|
IFile f5= TestSourceReader.createFile(fCProject.getProject(), "src3.cpp", contents[4].toString());
|
||||||
waitForIndexer();
|
waitForIndexer();
|
||||||
|
|
||||||
IIndex index= indexManager.getIndex(fCProject);
|
IIndex index= indexManager.getIndex(fCProject);
|
||||||
IIndexBinding[] bindings= index.findBindings("v".toCharArray(), null, NPM);
|
index.acquireReadLock();
|
||||||
assertEquals(1, bindings.length);
|
try {
|
||||||
IIndexBinding binding= bindings[0];
|
IIndexBinding[] bindings = index.findBindings("v".toCharArray(), IndexFilter.ALL, NPM);
|
||||||
assertTrue(binding instanceof IVariable);
|
assertEquals(1, bindings.length);
|
||||||
IIndexName[] names= index.findNames(binding, IIndex.FIND_ALL_OCCURENCES);
|
IIndexBinding binding = bindings[0];
|
||||||
assertEquals(1, names.length);
|
assertTrue(binding instanceof IVariable);
|
||||||
assertEquals(f4.getFullPath().toString(), names[0].getFile().getLocation().getFullPath());
|
IIndexName[] names = index.findNames(binding,
|
||||||
|
IIndex.FIND_ALL_OCCURENCES);
|
||||||
|
assertEquals(1, names.length);
|
||||||
|
assertEquals(f4.getFullPath().toString(), names[0].getFile().getLocation().getFullPath());
|
||||||
|
|
||||||
|
IIndexFile idxFile= index.getFile(IndexLocationFactory.getWorkspaceIFL(f5));
|
||||||
|
IIndexInclude[] includes= idxFile.getIncludes();
|
||||||
|
assertEquals(2, includes.length);
|
||||||
|
assertTrue(includes[0].isActive());
|
||||||
|
assertTrue(includes[0].isResolved());
|
||||||
|
assertFalse(includes[1].isActive());
|
||||||
|
assertTrue(includes[1].isResolved());
|
||||||
|
} finally {
|
||||||
|
index.releaseReadLock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ public interface IIndexInclude {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the IIndexFileLocation of the file that is included by this
|
* Returns the IIndexFileLocation of the file that is included by this
|
||||||
* directive. In case of an unresolved or inactive include <code>null</code>
|
* directive. In case of an unresolved include <code>null</code>
|
||||||
* will be returned.
|
* will be returned.
|
||||||
*
|
*
|
||||||
* @return the IIndexFileLocation of the file that is included by this
|
* @return the IIndexFileLocation of the file that is included by this
|
||||||
|
@ -59,7 +59,7 @@ public interface IIndexInclude {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the simple name of the directive. This skips any leading
|
* Returns the simple name of the directive. This skips any leading
|
||||||
* direcories. E.g.: for '<sys/types.h>' 'types.h' will be returned.
|
* directories. E.g.: for '<sys/types.h>' 'types.h' will be returned.
|
||||||
* @throws CoreException
|
* @throws CoreException
|
||||||
*/
|
*/
|
||||||
String getName() throws CoreException;
|
String getName() throws CoreException;
|
||||||
|
@ -87,7 +87,6 @@ public interface IIndexInclude {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test whether this include is in active code (not skipped by conditional preprocessing).
|
* Test whether this include is in active code (not skipped by conditional preprocessing).
|
||||||
*
|
|
||||||
* @return whether this include is in active code
|
* @return whether this include is in active code
|
||||||
* @throws CoreException
|
* @throws CoreException
|
||||||
*/
|
*/
|
||||||
|
@ -95,6 +94,13 @@ public interface IIndexInclude {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test whether this include has been resolved (found in the file system).
|
* Test whether this include has been resolved (found in the file system).
|
||||||
|
* Inactive includes are not resolved, unless they constitute a hidden dependency.
|
||||||
|
* This is the case when an include is inactive because it has been included before:
|
||||||
|
* <code>
|
||||||
|
* #ifndef _header_h
|
||||||
|
* #include "header.h"
|
||||||
|
* #endif
|
||||||
|
* <code>
|
||||||
*
|
*
|
||||||
* @return whether this is a resolved include
|
* @return whether this is a resolved include
|
||||||
* @throws CoreException
|
* @throws CoreException
|
||||||
|
|
|
@ -39,15 +39,20 @@ import org.eclipse.cdt.core.parser.CodeReader;
|
||||||
import org.eclipse.cdt.core.parser.ICodeReaderCache;
|
import org.eclipse.cdt.core.parser.ICodeReaderCache;
|
||||||
import org.eclipse.cdt.core.parser.IMacro;
|
import org.eclipse.cdt.core.parser.IMacro;
|
||||||
import org.eclipse.cdt.core.parser.ParserUtil;
|
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.parser.scanner2.ObjectStyleMacro;
|
||||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMacro;
|
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMacro;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Doug Schaefer
|
* Code reader factory, that fakes code readers for header files already stored in the
|
||||||
*
|
* index.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This interface is not intended to be implemented by clients.
|
||||||
|
* </p>
|
||||||
*/
|
*/
|
||||||
public class IndexBasedCodeReaderFactory implements ICodeReaderFactory {
|
public class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderFactory {
|
||||||
public static interface CallbackHandler {
|
public static interface CallbackHandler {
|
||||||
boolean needToUpdate(IndexFileInfo fileInfo) throws CoreException;
|
boolean needToUpdate(IndexFileInfo fileInfo) throws CoreException;
|
||||||
}
|
}
|
||||||
|
@ -78,7 +83,7 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory {
|
||||||
private Map/*<String,IIndexFileLocation>*/ iflCache;
|
private Map/*<String,IIndexFileLocation>*/ iflCache;
|
||||||
private List usedMacros = new ArrayList();
|
private List usedMacros = new ArrayList();
|
||||||
private Set/*<FileInfo>*/ fIncluded= new HashSet();
|
private Set/*<FileInfo>*/ fIncluded= new HashSet();
|
||||||
/** The fallback code reader factory used in case a header file is not indexed */
|
/** The fall-back code reader factory used in case a header file is not indexed */
|
||||||
private ICodeReaderFactory fFallBackFactory;
|
private ICodeReaderFactory fFallBackFactory;
|
||||||
private CallbackHandler fCallbackHandler;
|
private CallbackHandler fCallbackHandler;
|
||||||
private final ICProject cproject;
|
private final ICProject cproject;
|
||||||
|
@ -166,6 +171,7 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory {
|
||||||
}
|
}
|
||||||
// record the macros we used.
|
// record the macros we used.
|
||||||
usedMacros.add(fi.fMacros);
|
usedMacros.add(fi.fMacros);
|
||||||
|
setIncluded(fi);
|
||||||
}
|
}
|
||||||
return new CodeReader(canonicalPath, EMPTY_CHARS);
|
return new CodeReader(canonicalPath, EMPTY_CHARS);
|
||||||
} catch (NeedToParseException e) {
|
} catch (NeedToParseException e) {
|
||||||
|
@ -184,6 +190,25 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory {
|
||||||
return ParserUtil.createReader(canonicalPath, null);
|
return ParserUtil.createReader(canonicalPath, 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.
|
* Mark the given inclusion as included.
|
||||||
* @param info
|
* @param info
|
||||||
|
@ -234,7 +259,6 @@ public class IndexBasedCodeReaderFactory implements ICodeReaderFactory {
|
||||||
getInfosForMacroDictionary(nextInfo, target);
|
getInfosForMacroDictionary(nextInfo, target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setIncluded(fileInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearMacroAttachements() {
|
public void clearMacroAttachements() {
|
||||||
|
|
|
@ -129,6 +129,16 @@ abstract class BaseScanner implements IScanner {
|
||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected interface IIncludeFileTester {
|
||||||
|
Object checkFile(String path, String fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
final private IIncludeFileTester createCodeReaderTester= new IIncludeFileTester() {
|
||||||
|
public Object checkFile(String path, String fileName) {
|
||||||
|
return createReader(path, fileName);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
protected ParserLanguage language;
|
protected ParserLanguage language;
|
||||||
|
|
||||||
|
@ -1800,8 +1810,7 @@ abstract class BaseScanner implements IScanner {
|
||||||
*/
|
*/
|
||||||
protected abstract void processIf(int startPos, int endPos, boolean taken);
|
protected abstract void processIf(int startPos, int endPos, boolean taken);
|
||||||
|
|
||||||
protected void handlePPInclude(int pos2, boolean include_next,
|
protected void handlePPInclude(int pos2, boolean include_next, int startingLineNumber, boolean active) {
|
||||||
int startingLineNumber, boolean active) {
|
|
||||||
char[] buffer = bufferStack[bufferStackPos];
|
char[] buffer = bufferStack[bufferStackPos];
|
||||||
int limit = bufferLimit[bufferStackPos];
|
int limit = bufferLimit[bufferStackPos];
|
||||||
|
|
||||||
|
@ -1929,78 +1938,55 @@ abstract class BaseScanner implements IScanner {
|
||||||
endLine = getLineNumber(bufferPos[bufferStackPos]);
|
endLine = getLineNumber(bufferPos[bufferStackPos]);
|
||||||
skipToNewLine();
|
skipToNewLine();
|
||||||
|
|
||||||
if (active) {
|
if (parserMode == ParserMode.QUICK_PARSE && active) {
|
||||||
findAndPushInclusion(filename, fileNameArray, local, include_next, false, startOffset, nameOffset, nameEndOffset, endOffset, startingLineNumber, nameLine, endLine);
|
final Object inc= createInclusionConstruct(
|
||||||
} else {
|
fileNameArray, EMPTY_CHAR_ARRAY, local, startOffset, startingLineNumber,
|
||||||
processInclude(fileNameArray, local, active, startOffset, nameOffset, nameEndOffset, endOffset, startingLineNumber, nameLine, endLine);
|
nameOffset, nameEndOffset, nameLine, endOffset, endLine, false);
|
||||||
|
quickParsePushPopInclusion(inc);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CodeReader reader= null;
|
||||||
|
if (active) {
|
||||||
|
reader= findInclusion(filename, local, include_next);
|
||||||
|
if (reader != null) {
|
||||||
|
final Object inc = createInclusionConstruct(
|
||||||
|
fileNameArray, reader.filename, local, startOffset, startingLineNumber,
|
||||||
|
nameOffset, nameEndOffset, nameLine, endOffset, endLine, false);
|
||||||
|
pushContext(reader.buffer, new InclusionData(reader, inc, false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (reader == null) {
|
||||||
|
processInclude(fileNameArray, local, include_next, active, startOffset, nameOffset, nameEndOffset, endOffset, startingLineNumber, nameLine, endLine);
|
||||||
|
if (active) {
|
||||||
|
handleProblem(IProblem.PREPROCESSOR_INCLUSION_NOT_FOUND, startOffset, fileNameArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process an include directive without following the inclusion.
|
* Process an include directive without following the inclusion.
|
||||||
*
|
|
||||||
* @param fileName
|
|
||||||
* @param local
|
|
||||||
* @param active
|
|
||||||
* @param startOffset
|
|
||||||
* @param nameOffset
|
|
||||||
* @param nameEndOffset
|
|
||||||
* @param endOffset
|
|
||||||
* @param startingLineNumber
|
|
||||||
* @param nameLine
|
|
||||||
* @param endLine
|
|
||||||
*/
|
*/
|
||||||
protected void processInclude(char[] fileName, boolean local, boolean active, int startOffset, int nameOffset,
|
protected void processInclude(char[] fileName, boolean local, boolean include_next, boolean active, int startOffset, int nameOffset,
|
||||||
int nameEndOffset, int endOffset, int startingLineNumber, int nameLine, int endLine) {
|
int nameEndOffset, int endOffset, int startingLineNumber, int nameLine, int endLine) {
|
||||||
// default: do nothing
|
// default: do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private CodeReader findInclusion(final String filename, final boolean local, final boolean include_next) {
|
||||||
* @param filename
|
return (CodeReader) findInclusion(filename, local, include_next, createCodeReaderTester);
|
||||||
* @param fileNameArray
|
}
|
||||||
* @param local
|
|
||||||
* @param include_next
|
protected Object findInclusion(final String filename, final boolean local, final boolean include_next,
|
||||||
* @param includeOnce
|
final IIncludeFileTester tester) {
|
||||||
* @param startOffset
|
Object reader = null;
|
||||||
* @param nameOffset
|
|
||||||
* @param nameEndOffset
|
|
||||||
* @param endOffset
|
|
||||||
* @param startingLine
|
|
||||||
* @param nameLine
|
|
||||||
* @param endLine
|
|
||||||
*/
|
|
||||||
protected void findAndPushInclusion(String filename, char[] fileNameArray, boolean local, boolean include_next, boolean includeOnce, int startOffset, int nameOffset, int nameEndOffset, int endOffset, int startingLine, int nameLine, int endLine) {
|
|
||||||
if (parserMode == ParserMode.QUICK_PARSE) {
|
|
||||||
Object inclusion = createInclusionConstruct(fileNameArray,
|
|
||||||
EMPTY_CHAR_ARRAY, local, startOffset, startingLine,
|
|
||||||
nameOffset, nameEndOffset, nameLine, endOffset, endLine,
|
|
||||||
false);
|
|
||||||
quickParsePushPopInclusion(inclusion);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CodeReader reader = null;
|
|
||||||
// filename is an absolute path or it is a Linux absolute path on a windows machine
|
// filename is an absolute path or it is a Linux absolute path on a windows machine
|
||||||
if (new File(filename).isAbsolute() || filename.startsWith("/")) { //$NON-NLS-1$
|
if (new File(filename).isAbsolute() || filename.startsWith("/")) { //$NON-NLS-1$
|
||||||
reader = createReader( EMPTY_STRING, filename );
|
return tester.checkFile( EMPTY_STRING, filename );
|
||||||
if (reader != null) {
|
|
||||||
pushContext(reader.buffer, new InclusionData(reader,
|
|
||||||
createInclusionConstruct(fileNameArray,
|
|
||||||
reader.filename, local, startOffset,
|
|
||||||
startingLine, nameOffset,
|
|
||||||
nameEndOffset, nameLine, endOffset,
|
|
||||||
endLine, false), includeOnce));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
processInclude(fileNameArray, local, true, startOffset, nameOffset, nameEndOffset, endOffset, startingLine, nameLine, endLine);
|
|
||||||
handleProblem(IProblem.PREPROCESSOR_INCLUSION_NOT_FOUND, startOffset,
|
|
||||||
fileNameArray);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
File currentDirectory = null;
|
File currentDirectory = null;
|
||||||
if (local || include_next) {
|
if (local || include_next) {
|
||||||
// if the include is eclosed in quotes OR we are in an include_next
|
// if the include is enclosed in quotes OR we are in an include_next
|
||||||
// then we need to know what the current directory is!
|
// then we need to know what the current directory is!
|
||||||
File file = new File(String.valueOf(getCurrentFilename()));
|
File file = new File(String.valueOf(getCurrentFilename()));
|
||||||
currentDirectory = file.getParentFile();
|
currentDirectory = file.getParentFile();
|
||||||
|
@ -2010,24 +1996,15 @@ abstract class BaseScanner implements IScanner {
|
||||||
// Check to see if we find a match in the current directory
|
// Check to see if we find a match in the current directory
|
||||||
if (currentDirectory != null) {
|
if (currentDirectory != null) {
|
||||||
String absolutePath = currentDirectory.getAbsolutePath();
|
String absolutePath = currentDirectory.getAbsolutePath();
|
||||||
reader = createReader(absolutePath, filename);
|
reader = tester.checkFile(absolutePath, filename);
|
||||||
if (reader != null) {
|
if (reader != null) {
|
||||||
pushContext(reader.buffer, new InclusionData(reader,
|
return reader;
|
||||||
createInclusionConstruct(fileNameArray,
|
|
||||||
reader.filename, local, startOffset,
|
|
||||||
startingLine, nameOffset,
|
|
||||||
nameEndOffset, nameLine, endOffset,
|
|
||||||
endLine, false), includeOnce));
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if we're not include_next, then we are looking for the
|
|
||||||
// first occurance of the file, otherwise, we ignore all the paths
|
|
||||||
// before
|
|
||||||
// the
|
|
||||||
// current directory
|
|
||||||
|
|
||||||
|
// if we're not include_next, then we are looking for the first occurrence of
|
||||||
|
// the file, otherwise, we ignore all the paths before the current directory
|
||||||
String [] includePathsToUse = stdIncludePaths;
|
String [] includePathsToUse = stdIncludePaths;
|
||||||
if( local && locIncludePaths != null && locIncludePaths.length > 0 ) {
|
if( local && locIncludePaths != null && locIncludePaths.length > 0 ) {
|
||||||
includePathsToUse = new String[locIncludePaths.length + stdIncludePaths.length];
|
includePathsToUse = new String[locIncludePaths.length + stdIncludePaths.length];
|
||||||
|
@ -2040,21 +2017,13 @@ abstract class BaseScanner implements IScanner {
|
||||||
if (include_next)
|
if (include_next)
|
||||||
startpos = findIncludePos(includePathsToUse, currentDirectory) + 1;
|
startpos = findIncludePos(includePathsToUse, currentDirectory) + 1;
|
||||||
for (int i = startpos; i < includePathsToUse.length; ++i) {
|
for (int i = startpos; i < includePathsToUse.length; ++i) {
|
||||||
reader = createReader(includePathsToUse[i], filename);
|
reader = tester.checkFile(includePathsToUse[i], filename);
|
||||||
if (reader != null) {
|
if (reader != null) {
|
||||||
pushContext(reader.buffer, new InclusionData(reader,
|
return reader;
|
||||||
createInclusionConstruct(fileNameArray,
|
|
||||||
reader.filename, local, startOffset,
|
|
||||||
startingLine, nameOffset,
|
|
||||||
nameEndOffset, nameLine, endOffset,
|
|
||||||
endLine, false), includeOnce));
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
processInclude(fileNameArray, local, true, startOffset, nameOffset, nameEndOffset, endOffset, startingLine, nameLine, endLine);
|
return null;
|
||||||
handleProblem(IProblem.PREPROCESSOR_INCLUSION_NOT_FOUND, startOffset,
|
|
||||||
fileNameArray);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract CodeReader createReader(String path, String fileName);
|
protected abstract CodeReader createReader(String path, String fileName);
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.parser.scanner2;
|
package org.eclipse.cdt.internal.core.parser.scanner2;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -39,6 +40,17 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||||
public class DOMScanner extends BaseScanner {
|
public class DOMScanner extends BaseScanner {
|
||||||
private static final Class CHAR_ARRAY_CLASS = new char[]{}.getClass();
|
private static final Class CHAR_ARRAY_CLASS = new char[]{}.getClass();
|
||||||
|
|
||||||
|
private final IScannerPreprocessorLog locationMap = new LocationMap();
|
||||||
|
private final IIncludeFileTester createPathTester= new IIncludeFileTester() {
|
||||||
|
public Object checkFile(String path, String fileName) {
|
||||||
|
path= ScannerUtility.createReconciledPath(path, fileName);
|
||||||
|
if (new File(path).exists()) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
protected final ICodeReaderFactory codeReaderFactory;
|
protected final ICodeReaderFactory codeReaderFactory;
|
||||||
protected int[] bufferDelta = new int[bufferInitialSize];
|
protected int[] bufferDelta = new int[bufferInitialSize];
|
||||||
|
|
||||||
|
@ -123,8 +135,6 @@ public class DOMScanner extends BaseScanner {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final IScannerPreprocessorLog locationMap = new LocationMap();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
|
@ -176,9 +186,30 @@ public class DOMScanner extends BaseScanner {
|
||||||
/*
|
/*
|
||||||
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processInclude(char[], boolean, boolean, int, int, int, int, int, int, int)
|
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processInclude(char[], boolean, boolean, int, int, int, int, int, int, int)
|
||||||
*/
|
*/
|
||||||
protected void processInclude(char[] filename, boolean local, boolean active, int startOffset, int nameOffset,
|
protected void processInclude(char[] filename, boolean local, boolean include_next, boolean active,
|
||||||
int nameEndOffset, int endOffset, int startingLineNumber, int nameLine, int endLine) {
|
int startOffset, int nameOffset, int nameEndOffset, int endOffset, int startingLineNumber,
|
||||||
locationMap.encounterPoundInclude(getGlobalOffset(startOffset), getGlobalOffset(nameOffset), getGlobalOffset(nameEndOffset), getGlobalOffset(endOffset), filename, !local, active);
|
int nameLine, int endLine) {
|
||||||
|
char[] pchars= null;
|
||||||
|
String path= (String) findInclusion(new String(filename), local, include_next, createPathTester);
|
||||||
|
if (path != null) {
|
||||||
|
if (codeReaderFactory instanceof IIndexBasedCodeReaderFactory) {
|
||||||
|
// fast indexer
|
||||||
|
if (((IIndexBasedCodeReaderFactory) codeReaderFactory).hasFileBeenIncludedInCurrentTranslationUnit(path)) {
|
||||||
|
pchars= path.toCharArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// full indexer
|
||||||
|
pchars= path.toCharArray();
|
||||||
|
if (!includedFiles.containsKey(pchars)) {
|
||||||
|
// not a hidden dependency, don't report it.
|
||||||
|
pchars= null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
locationMap.encounterPoundInclude(getGlobalOffset(startOffset), getGlobalOffset(nameOffset),
|
||||||
|
getGlobalOffset(nameEndOffset), getGlobalOffset(endOffset),
|
||||||
|
filename, pchars, !local, active);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -221,6 +252,7 @@ public class DOMScanner extends BaseScanner {
|
||||||
locationMap.startInclusion(((InclusionData) data).reader, inc.o, getGlobalOffset(getCurrentOffset())+1,
|
locationMap.startInclusion(((InclusionData) data).reader, inc.o, getGlobalOffset(getCurrentOffset())+1,
|
||||||
inc.nameOffset, inc.nameEndoffset, inc.name, inc.systemInclude);
|
inc.nameOffset, inc.nameEndoffset, inc.name, inc.systemInclude);
|
||||||
bufferDelta[bufferStackPos + 1] = 0;
|
bufferDelta[bufferStackPos + 1] = 0;
|
||||||
|
includedFiles.put(inc.pt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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.parser.scanner2;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index based code-reader factory fakes the inclusion of files that are already indexed.
|
||||||
|
* When trying to figure out whether a specific header has been included or not, the factory
|
||||||
|
* has to be consulted.
|
||||||
|
* @since 4.0.1
|
||||||
|
*/
|
||||||
|
public interface IIndexBasedCodeReaderFactory extends ICodeReaderFactory {
|
||||||
|
/**
|
||||||
|
* Returns whether or not the file has been included.
|
||||||
|
*/
|
||||||
|
boolean hasFileBeenIncludedInCurrentTranslationUnit(String path);
|
||||||
|
}
|
|
@ -78,8 +78,25 @@ public interface IScannerPreprocessorLog {
|
||||||
public void encounterPoundUndef(int startOffset, int endOffset,
|
public void encounterPoundUndef(int startOffset, int endOffset,
|
||||||
char[] symbol, int nameOffset, IMacroDefinition macroDefinition);
|
char[] symbol, int nameOffset, IMacroDefinition macroDefinition);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use {@link #encounterPoundInclude(int, int, int, int, char[], char[], boolean, boolean)}.
|
||||||
|
*/
|
||||||
public void encounterPoundInclude(int startOffset, int nameOffset, int nameEndOffset, int endOffset, char[] name, boolean systemInclude, boolean active);
|
public void encounterPoundInclude(int startOffset, int nameOffset, int nameEndOffset, int endOffset, char[] name, boolean systemInclude, boolean active);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report an include that is not actually processed ({@link #startInclusion(CodeReader, int, int, int, int, char[], boolean)}
|
||||||
|
* To report hidden dependencies (bug 167100) you can use the path parameter.
|
||||||
|
* @param startOffset
|
||||||
|
* @param nameOffset
|
||||||
|
* @param nameEndOffset
|
||||||
|
* @param endOffset
|
||||||
|
* @param name the name of the include as found in the source
|
||||||
|
* @param hiddenDependency a file-path in case the include is a hidden dependency, or <code>null</code>.
|
||||||
|
* @param systemInclude
|
||||||
|
* @param active
|
||||||
|
*/
|
||||||
|
public void encounterPoundInclude(int startOffset, int nameOffset, int nameEndOffset, int endOffset, char[] name, char[] hiddenDependency, boolean systemInclude, boolean active);
|
||||||
|
|
||||||
public void encounterProblem(IASTProblem problem);
|
public void encounterProblem(IASTProblem problem);
|
||||||
|
|
||||||
public IMacroDefinition registerBuiltinObjectStyleMacro(ObjectStyleMacro macro);
|
public IMacroDefinition registerBuiltinObjectStyleMacro(ObjectStyleMacro macro);
|
||||||
|
|
|
@ -581,16 +581,18 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog {
|
||||||
public final int fNameOffset;
|
public final int fNameOffset;
|
||||||
public final int fNameEndOffset;
|
public final int fNameEndOffset;
|
||||||
public final char[] fName;
|
public final char[] fName;
|
||||||
|
public final char[] fPath;
|
||||||
public final boolean fSystemInclude;
|
public final boolean fSystemInclude;
|
||||||
public final boolean fIsActive;
|
public final boolean fIsActive;
|
||||||
public final boolean fIsResolved;
|
public final boolean fIsResolved;
|
||||||
|
|
||||||
public _Include(_CompositeContext parent, int startOffset, int endOffset, int nameOffset, int nameEndoffset,
|
public _Include(_CompositeContext parent, int startOffset, int endOffset, int nameOffset, int nameEndoffset,
|
||||||
char[] name, boolean systemInclude, boolean active, boolean resolved) {
|
char[] name, char[] path, boolean systemInclude, boolean active, boolean resolved) {
|
||||||
super(parent, startOffset, endOffset);
|
super(parent, startOffset, endOffset);
|
||||||
fNameOffset= nameOffset;
|
fNameOffset= nameOffset;
|
||||||
fNameEndOffset= nameEndoffset;
|
fNameEndOffset= nameEndoffset;
|
||||||
fName= name;
|
fName= name;
|
||||||
|
fPath= path == null ? name : path;
|
||||||
fSystemInclude= systemInclude;
|
fSystemInclude= systemInclude;
|
||||||
fIsActive= active;
|
fIsActive= active;
|
||||||
fIsResolved= resolved;
|
fIsResolved= resolved;
|
||||||
|
@ -1754,7 +1756,7 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog {
|
||||||
}
|
}
|
||||||
|
|
||||||
private IASTPreprocessorIncludeStatement createASTInclusion(_Include inc) {
|
private IASTPreprocessorIncludeStatement createASTInclusion(_Include inc) {
|
||||||
ASTInclusionStatement result = new ASTInclusionStatement(inc.fName);
|
ASTInclusionStatement result = new ASTInclusionStatement(inc.fPath);
|
||||||
result.setOffsetAndLength(inc.context_directive_start, inc.getDirectiveLength());
|
result.setOffsetAndLength(inc.context_directive_start, inc.getDirectiveLength());
|
||||||
result.startOffset = inc.getContextStart();
|
result.startOffset = inc.getContextStart();
|
||||||
result.endOffset = inc.context_directive_end;
|
result.endOffset = inc.context_directive_end;
|
||||||
|
@ -2413,9 +2415,14 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog {
|
||||||
/*
|
/*
|
||||||
* @see org.eclipse.cdt.internal.core.parser.scanner2.IScannerPreprocessorLog#encounterPoundInclude(int, int, int, int, char[], boolean, boolean)
|
* @see org.eclipse.cdt.internal.core.parser.scanner2.IScannerPreprocessorLog#encounterPoundInclude(int, int, int, int, char[], boolean, boolean)
|
||||||
*/
|
*/
|
||||||
public void encounterPoundInclude(int startOffset, int nameOffset, int nameEndOffset, int endOffset, char[] name,
|
public void encounterPoundInclude(int startOffset, int nameOffset, int nameEndOffset, int endOffset,
|
||||||
boolean systemInclude, boolean active) {
|
char[] name, boolean systemInclude, boolean active) {
|
||||||
currentContext.addSubContext(new _Include(currentContext, startOffset, endOffset, nameOffset, nameEndOffset, name, systemInclude, active, false));
|
encounterPoundInclude(startOffset, nameOffset, nameEndOffset, endOffset, name, null, systemInclude, active);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void encounterPoundInclude(int startOffset, int nameOffset, int nameEndOffset, int endOffset,
|
||||||
|
char[] name, char[] path, boolean systemInclude, boolean active) {
|
||||||
|
currentContext.addSubContext(new _Include(currentContext, startOffset, endOffset, nameOffset, nameEndOffset, name, path, systemInclude, active, path != null));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -462,8 +462,9 @@ abstract public class PDOMWriter {
|
||||||
info.fStatement= include;
|
info.fStatement= include;
|
||||||
if (include.isResolved()) {
|
if (include.isResolved()) {
|
||||||
info.fLocation= findLocation(include.getPath());
|
info.fLocation= findLocation(include.getPath());
|
||||||
info.fIsContext= contextIncludes.contains(include) ||
|
info.fIsContext= include.isActive() &&
|
||||||
clearedContexts.contains(info.fLocation);
|
(contextIncludes.contains(include) ||
|
||||||
|
clearedContexts.contains(info.fLocation));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
index.setFileContent(file, includeInfos, macros, names);
|
index.setFileContent(file, includeInfos, macros, names);
|
||||||
|
|
|
@ -31,24 +31,23 @@ import org.eclipse.core.runtime.CoreException;
|
||||||
*/
|
*/
|
||||||
public class PDOMInclude implements IIndexFragmentInclude {
|
public class PDOMInclude implements IIndexFragmentInclude {
|
||||||
|
|
||||||
|
private static final int INCLUDES_FILE_OR_NAME = 0;
|
||||||
|
private static final int INCLUDED_BY = 4;
|
||||||
|
private static final int INCLUDES_NEXT = 8;
|
||||||
|
private static final int INCLUDED_BY_NEXT = 12;
|
||||||
|
private static final int INCLUDED_BY_PREV = 16;
|
||||||
|
private static final int NODE_OFFSET_OFFSET = 20;
|
||||||
|
private static final int NODE_LENGTH_OFFSET = 24;
|
||||||
|
private static final int FLAG_OFFSET = 26;
|
||||||
|
private static final int RECORD_SIZE = 27;
|
||||||
|
|
||||||
|
private static final int FLAG_SYSTEM_INCLUDE = 1;
|
||||||
|
private static final int FLAG_INACTIVE_INCLUDE = 2;
|
||||||
|
private static final int FLAG_UNRESOLVED_INCLUDE = 4;
|
||||||
|
|
||||||
private final PDOM pdom;
|
private final PDOM pdom;
|
||||||
private final int record;
|
private final int record;
|
||||||
|
|
||||||
private final int INCLUDES_FILE_OR_NAME = 0;
|
|
||||||
private final int INCLUDED_BY = 4;
|
|
||||||
private final int INCLUDES_NEXT = 8;
|
|
||||||
private final int INCLUDED_BY_NEXT = 12;
|
|
||||||
private final int INCLUDED_BY_PREV = 16;
|
|
||||||
private static final int NODE_OFFSET_OFFSET = 20;
|
|
||||||
private static final int NODE_LENGTH_OFFSET = 24;
|
|
||||||
private static final int FLAG_OFFSET = 26;
|
|
||||||
|
|
||||||
private static final int FLAG_SYSTEM_INCLUDE = 1;
|
|
||||||
private static final int FLAG_INACTIVE_INCLUDE = 2;
|
|
||||||
private static final int FLAG_UNRESOLVED_INCLUDE = 4;
|
|
||||||
|
|
||||||
private final int RECORD_SIZE = 27;
|
|
||||||
|
|
||||||
// cached fields
|
// cached fields
|
||||||
private String fName= null;
|
private String fName= null;
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ import org.eclipse.ui.PlatformUI;
|
||||||
import org.eclipse.ui.WorkbenchException;
|
import org.eclipse.ui.WorkbenchException;
|
||||||
import org.eclipse.ui.handlers.IHandlerService;
|
import org.eclipse.ui.handlers.IHandlerService;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
import org.eclipse.cdt.core.index.IIndex;
|
import org.eclipse.cdt.core.index.IIndex;
|
||||||
import org.eclipse.cdt.core.index.IIndexFile;
|
import org.eclipse.cdt.core.index.IIndexFile;
|
||||||
|
@ -104,6 +105,10 @@ public class BaseUITestCase extends BaseTestCase {
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
index.releaseReadLock();
|
index.releaseReadLock();
|
||||||
|
int time= (int) (endTime- System.currentTimeMillis());
|
||||||
|
if (time > 0) {
|
||||||
|
CCorePlugin.getIndexManager().joinIndexer(time, NPM);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new Exception("Indexer did not complete in time!");
|
throw new Exception("Indexer did not complete in time!");
|
||||||
|
|
Loading…
Add table
Reference in a new issue