mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Include next directive, bug 286081.
This commit is contained in:
parent
fc1f0fe229
commit
cf75226ce6
4 changed files with 56 additions and 9 deletions
|
@ -152,6 +152,35 @@ public class InclusionTests extends PreprocessorTestsBase {
|
||||||
validateEOF();
|
validateEOF();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testIncludeNext_286081() throws Exception {
|
||||||
|
String baseFile = "0 \n#include \"foo.h\""; //$NON-NLS-1$
|
||||||
|
String foo1 = "1 \n#include \"intermed.h\""; //$NON-NLS-1$
|
||||||
|
String intermed = "2 \n#include_next <foo.h>"; //$NON-NLS-1$
|
||||||
|
String foo2 = "3 \n"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
IFolder one = importFolder("one"); //$NON-NLS-1$
|
||||||
|
IFolder two = importFolder("two"); //$NON-NLS-1$
|
||||||
|
IFile base = importFile("base.cpp", baseFile); //$NON-NLS-1$
|
||||||
|
importFile("one/foo.h", foo1); //$NON-NLS-1$
|
||||||
|
importFile("one/intermed.h", intermed); //$NON-NLS-1$
|
||||||
|
importFile("two/foo.h", foo2); //$NON-NLS-1$
|
||||||
|
|
||||||
|
String[] path = new String[2];
|
||||||
|
path[0] = one.getLocation().toOSString();
|
||||||
|
path[1] = two.getLocation().toOSString();
|
||||||
|
|
||||||
|
IScannerInfo scannerInfo = new ExtendedScannerInfo(Collections.EMPTY_MAP, path, new String[]{}, null);
|
||||||
|
CodeReader reader= new CodeReader(base.getLocation().toString());
|
||||||
|
initializeScanner(reader, ParserLanguage.C, ParserMode.COMPLETE_PARSE, scannerInfo);
|
||||||
|
|
||||||
|
validateInteger("0");
|
||||||
|
validateInteger("1");
|
||||||
|
validateInteger("2");
|
||||||
|
validateInteger("3");
|
||||||
|
|
||||||
|
validateEOF();
|
||||||
|
}
|
||||||
|
|
||||||
public void testIncludePathOrdering() throws Exception {
|
public void testIncludePathOrdering() throws Exception {
|
||||||
// create directory structure:
|
// create directory structure:
|
||||||
// project/base.cpp
|
// project/base.cpp
|
||||||
|
|
|
@ -893,14 +893,20 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're not include_next, then we are looking for the first occurrence of
|
// Now we need to search for the file on the include search path.
|
||||||
// the file, otherwise, we ignore all the paths before the current directory.
|
// If this is a include_next directive then the search starts with the directory
|
||||||
|
// in the search path after the one where the current file was found.
|
||||||
IncludeSearchPathElement searchAfter= null;
|
IncludeSearchPathElement searchAfter= null;
|
||||||
if (includeNext) {
|
if (includeNext && currentFile != null) {
|
||||||
searchAfter = fCurrentContext.getFoundOnPath();
|
searchAfter = fCurrentContext.getFoundOnPath();
|
||||||
if (searchAfter == null) {
|
if (searchAfter == null) {
|
||||||
searchAfter = findFileInIncludePath(currentFile, includeDirective);
|
// the current file was found without search path
|
||||||
|
String directive= fCurrentContext.getFoundViaDirective();
|
||||||
|
if (directive == null) {
|
||||||
|
directive= new File(currentFile).getName();
|
||||||
|
}
|
||||||
|
searchAfter = findFileInIncludePath(currentFile, directive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1171,16 +1177,17 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
boolean reported= false;
|
boolean reported= false;
|
||||||
boolean isHeuristic= false;
|
boolean isHeuristic= false;
|
||||||
|
|
||||||
|
final String includeDirective = new String(headerName);
|
||||||
if (!active) {
|
if (!active) {
|
||||||
// test if the include is inactive just because it was included before (bug 167100)
|
// test if the include is inactive just because it was included before (bug 167100)
|
||||||
final IncludeResolution resolved= findInclusion(new String(headerName), userInclude, include_next,
|
final IncludeResolution resolved= findInclusion(includeDirective, userInclude, include_next,
|
||||||
getCurrentFilename(), createPathTester);
|
getCurrentFilename(), createPathTester);
|
||||||
if (resolved != null && fCodeReaderFactory.hasFileBeenIncludedInCurrentTranslationUnit(resolved.fLocation)) {
|
if (resolved != null && fCodeReaderFactory.hasFileBeenIncludedInCurrentTranslationUnit(resolved.fLocation)) {
|
||||||
path= resolved.fLocation;
|
path= resolved.fLocation;
|
||||||
isHeuristic= resolved.fHeuristic;
|
isHeuristic= resolved.fHeuristic;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final IncludeFileContent fi= findInclusion(new String(headerName), userInclude, include_next,
|
final IncludeFileContent fi= findInclusion(includeDirective, userInclude, include_next,
|
||||||
getCurrentFilename(), createCodeReaderTester);
|
getCurrentFilename(), createCodeReaderTester);
|
||||||
if (fi != null) {
|
if (fi != null) {
|
||||||
path= fi.getFileLocation();
|
path= fi.getFileLocation();
|
||||||
|
@ -1198,7 +1205,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
condEndOffset, reader.buffer, path, headerName, userInclude, isHeuristic, fi.isSource());
|
condEndOffset, reader.buffer, path, headerName, userInclude, isHeuristic, fi.isSource());
|
||||||
ScannerContext fctx= new ScannerContext(ctx, fCurrentContext, new Lexer(reader.buffer,
|
ScannerContext fctx= new ScannerContext(ctx, fCurrentContext, new Lexer(reader.buffer,
|
||||||
fLexOptions, this, this));
|
fLexOptions, this, this));
|
||||||
fctx.setFoundOnPath(fi.getFoundOnPath());
|
fctx.setFoundOnPath(fi.getFoundOnPath(), includeDirective);
|
||||||
fCurrentContext= fctx;
|
fCurrentContext= fctx;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -45,6 +45,7 @@ final class ScannerContext {
|
||||||
private ArrayList<Conditional> fConditionals= null;
|
private ArrayList<Conditional> fConditionals= null;
|
||||||
private CodeState fCurrentState= CodeState.eActive;
|
private CodeState fCurrentState= CodeState.eActive;
|
||||||
private IncludeSearchPathElement fFoundOnPath;
|
private IncludeSearchPathElement fFoundOnPath;
|
||||||
|
private String fFoundViaDirective;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ctx
|
* @param ctx
|
||||||
|
@ -277,10 +278,18 @@ final class ScannerContext {
|
||||||
return fFoundOnPath;
|
return fFoundOnPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the directive with which the this context was found, or <code>null</code> if not applicable.
|
||||||
|
*/
|
||||||
|
public String getFoundViaDirective() {
|
||||||
|
return fFoundViaDirective;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the element of the include search path that was used to find this context, or <code>null</code> if not applicable.
|
* Returns the element of the include search path that was used to find this context, or <code>null</code> if not applicable.
|
||||||
*/
|
*/
|
||||||
public void setFoundOnPath(IncludeSearchPathElement foundOnPath) {
|
public void setFoundOnPath(IncludeSearchPathElement foundOnPath, String viaDirective) {
|
||||||
fFoundOnPath= foundOnPath;
|
fFoundOnPath= foundOnPath;
|
||||||
|
fFoundViaDirective= viaDirective;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -396,6 +396,8 @@ class OpenDeclarationsJob extends Job implements ASTRunnable {
|
||||||
private boolean isSameName(IName n1, IName n2) {
|
private boolean isSameName(IName n1, IName n2) {
|
||||||
IASTFileLocation loc1 = n1.getFileLocation();
|
IASTFileLocation loc1 = n1.getFileLocation();
|
||||||
IASTFileLocation loc2 = n2.getFileLocation();
|
IASTFileLocation loc2 = n2.getFileLocation();
|
||||||
|
if (loc1 == null || loc2 == null)
|
||||||
|
return false;
|
||||||
return loc1.getFileName().equals(loc2.getFileName()) &&
|
return loc1.getFileName().equals(loc2.getFileName()) &&
|
||||||
loc1.getNodeOffset() == loc2.getNodeOffset() &&
|
loc1.getNodeOffset() == loc2.getNodeOffset() &&
|
||||||
loc1.getNodeLength() == loc2.getNodeLength();
|
loc1.getNodeLength() == loc2.getNodeLength();
|
||||||
|
|
Loading…
Add table
Reference in a new issue