1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-11 02:05:39 +02:00

Fixed Bug 84451 - [Offsets] simple multiple #include throws offsets off

Fixed Bug 84356 - [DOM] stdio.h - Location/offsets degrade as parse continues on
This commit is contained in:
John Camelon 2005-02-08 21:42:45 +00:00
parent cd55cc5761
commit 69d98316f4
4 changed files with 501 additions and 417 deletions

View file

@ -54,195 +54,258 @@ import org.eclipse.core.resources.IFile;
*/ */
public class DOMLocationInclusionTests extends FileBasePluginTest { public class DOMLocationInclusionTests extends FileBasePluginTest {
private static final IScannerInfo SCANNER_INFO = new ScannerInfo(); private static final IScannerInfo SCANNER_INFO = new ScannerInfo();
private static final IParserLogService NULL_LOG = new NullLogService(); private static final IParserLogService NULL_LOG = new NullLogService();
private static final ICodeReaderFactory factory = CDOM.getInstance() private static final ICodeReaderFactory factory = CDOM
.getCodeReaderFactory(CDOM.PARSE_SAVED_RESOURCES); .getInstance()
.getCodeReaderFactory(
CDOM.PARSE_SAVED_RESOURCES);
/** /**
* @param name * @param name
* @param className * @param className
*/ */
public DOMLocationInclusionTests(String name) { public DOMLocationInclusionTests(String name) {
super(name, DOMLocationInclusionTests.class); super(name, DOMLocationInclusionTests.class);
} }
protected IASTTranslationUnit parse(IFile code, ParserLanguage language) protected IASTTranslationUnit parse(IFile code, ParserLanguage language)
throws Exception { throws Exception {
InputStream stream = code.getContents(); InputStream stream = code.getContents();
IScanner scanner = new DOMScanner(new CodeReader(code.getLocation() IScanner scanner = new DOMScanner(new CodeReader(code.getLocation()
.toOSString(), stream), SCANNER_INFO, .toOSString(), stream), SCANNER_INFO, ParserMode.COMPLETE_PARSE,
ParserMode.COMPLETE_PARSE, language, NULL_LOG, language, NULL_LOG, getScannerConfig(language), factory);
getScannerConfig(language), factory); ISourceCodeParser parser = null;
ISourceCodeParser parser = null; if (language == ParserLanguage.CPP) {
if (language == ParserLanguage.CPP) { parser = new GNUCPPSourceParser(scanner, ParserMode.COMPLETE_PARSE,
parser = new GNUCPPSourceParser(scanner, ParserMode.COMPLETE_PARSE, NULL_LOG, new GPPParserExtensionConfiguration());
NULL_LOG, new GPPParserExtensionConfiguration()); } else {
} else { parser = new GNUCSourceParser(scanner, ParserMode.COMPLETE_PARSE,
parser = new GNUCSourceParser(scanner, ParserMode.COMPLETE_PARSE, NULL_LOG, new GCCParserExtensionConfiguration());
NULL_LOG, new GCCParserExtensionConfiguration()); }
} stream.close();
stream.close(); IASTTranslationUnit parseResult = parser.parse();
IASTTranslationUnit parseResult = parser.parse();
if (parser.encounteredError()) if (parser.encounteredError())
throw new ParserException("FAILURE"); //$NON-NLS-1$ throw new ParserException("FAILURE"); //$NON-NLS-1$
if (language == ParserLanguage.C) { if (language == ParserLanguage.C) {
IASTProblem[] problems = CVisitor.getProblems(parseResult); IASTProblem[] problems = CVisitor.getProblems(parseResult);
assertEquals(problems.length, 0); assertEquals(problems.length, 0);
} else if (language == ParserLanguage.CPP) { } else if (language == ParserLanguage.CPP) {
IASTProblem[] problems = CPPVisitor.getProblems(parseResult); IASTProblem[] problems = CPPVisitor.getProblems(parseResult);
assertEquals(problems.length, 0); assertEquals(problems.length, 0);
} }
return parseResult; return parseResult;
} }
/** /**
* @param language * @param language
* @return * @return
*/ */
private IScannerExtensionConfiguration getScannerConfig( private IScannerExtensionConfiguration getScannerConfig(
ParserLanguage language) { ParserLanguage language) {
if (language == ParserLanguage.CPP) if (language == ParserLanguage.CPP)
return new GPPScannerExtensionConfiguration(); return new GPPScannerExtensionConfiguration();
return new GCCScannerExtensionConfiguration(); return new GCCScannerExtensionConfiguration();
} }
/** /**
* @param pathEndsWith * @param pathEndsWith
* TODO * TODO
* @param offset * @param offset
* @param length * @param length
* @param declarator * @param declarator
*/ */
private void assertSoleFileLocation(IASTNode n, String pathEndsWith, private void assertSoleFileLocation(IASTNode n, String pathEndsWith,
int offset, int length) { int offset, int length) {
IASTNodeLocation[] locations = n.getNodeLocations(); IASTNodeLocation[] locations = n.getNodeLocations();
assertEquals(locations.length, 1); assertEquals(locations.length, 1);
IASTFileLocation nodeLocation = (IASTFileLocation) locations[0]; IASTFileLocation nodeLocation = (IASTFileLocation) locations[0];
assertTrue(nodeLocation.getFileName().endsWith(pathEndsWith)); assertTrue(nodeLocation.getFileName().endsWith(pathEndsWith));
assertEquals(offset, nodeLocation.getNodeOffset()); assertEquals(offset, nodeLocation.getNodeOffset());
assertEquals(length, nodeLocation.getNodeLength()); assertEquals(length, nodeLocation.getNodeLength());
} }
public void testSimpleInclusion() throws Exception { public void testSimpleInclusion() throws Exception {
String foo = "int FOO;"; //$NON-NLS-1$ String foo = "int FOO;"; //$NON-NLS-1$
String code = "int bar;\n#include \"foo.h\"\n"; //$NON-NLS-1$ String code = "int bar;\n#include \"foo.h\"\n"; //$NON-NLS-1$
importFile("foo.h", foo); //$NON-NLS-1$ importFile("foo.h", foo); //$NON-NLS-1$
IFile cpp = importFile("code.cpp", code); //$NON-NLS-1$ IFile cpp = importFile("code.cpp", code); //$NON-NLS-1$
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
: null) { : null) {
IASTTranslationUnit tu = parse(cpp, p); //$NON-NLS-1$ IASTTranslationUnit tu = parse(cpp, p); //$NON-NLS-1$
IASTDeclaration[] declarations = tu.getDeclarations(); IASTDeclaration[] declarations = tu.getDeclarations();
assertEquals(declarations.length, 2); assertEquals(declarations.length, 2);
IASTSimpleDeclaration bar = (IASTSimpleDeclaration) declarations[0]; IASTSimpleDeclaration bar = (IASTSimpleDeclaration) declarations[0];
IASTSimpleDeclaration FOO = (IASTSimpleDeclaration) declarations[1]; IASTSimpleDeclaration FOO = (IASTSimpleDeclaration) declarations[1];
assertSoleFileLocation(bar, assertSoleFileLocation(bar,
"code.cpp", code.indexOf("int"), code.indexOf(";") + 1); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ "code.cpp", code.indexOf("int"), code.indexOf(";") + 1); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
assertSoleFileLocation(FOO, assertSoleFileLocation(FOO,
"foo.h", foo.indexOf("int"), foo.indexOf(";") + 1); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ "foo.h", foo.indexOf("int"), foo.indexOf(";") + 1); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
IASTPreprocessorIncludeStatement[] incs = tu.getIncludeDirectives(); IASTPreprocessorIncludeStatement[] incs = tu.getIncludeDirectives();
assertNotNull(incs); assertNotNull(incs);
assertEquals(incs.length, 1); assertEquals(incs.length, 1);
assertSoleFileLocation( assertSoleFileLocation(
incs[0], incs[0],
"code.cpp", code.indexOf("#inc"), code.indexOf(".h\"\n") + ".h\"".length() - code.indexOf("#inc")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ "code.cpp", code.indexOf("#inc"), code.indexOf(".h\"\n") + ".h\"".length() - code.indexOf("#inc")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
} }
} }
public void testSimpleInclusion2() throws Exception { public void testSimpleInclusion2() throws Exception {
String foo = "int FOO;"; //$NON-NLS-1$ String foo = "int FOO;"; //$NON-NLS-1$
String code = "int bar;\n#include \"foo.h\"\nfloat byob;\n"; //$NON-NLS-1$ String code = "int bar;\n#include \"foo.h\"\nfloat byob;\n"; //$NON-NLS-1$
importFile("foo.h", foo); //$NON-NLS-1$ importFile("foo.h", foo); //$NON-NLS-1$
IFile cpp = importFile("code.cpp", code); //$NON-NLS-1$ IFile cpp = importFile("code.cpp", code); //$NON-NLS-1$
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
: null) { : null) {
IASTTranslationUnit tu = parse(cpp, p); //$NON-NLS-1$ IASTTranslationUnit tu = parse(cpp, p); //$NON-NLS-1$
IASTDeclaration[] declarations = tu.getDeclarations(); IASTDeclaration[] declarations = tu.getDeclarations();
assertEquals(declarations.length, 3); assertEquals(declarations.length, 3);
IASTSimpleDeclaration bar = (IASTSimpleDeclaration) declarations[0]; IASTSimpleDeclaration bar = (IASTSimpleDeclaration) declarations[0];
IASTSimpleDeclaration FOO = (IASTSimpleDeclaration) declarations[1]; IASTSimpleDeclaration FOO = (IASTSimpleDeclaration) declarations[1];
IASTSimpleDeclaration byob = (IASTSimpleDeclaration) declarations[2]; IASTSimpleDeclaration byob = (IASTSimpleDeclaration) declarations[2];
assertSoleFileLocation( assertSoleFileLocation(
bar, bar,
"code.cpp", code.indexOf("int"), code.indexOf("r;") + 2 - code.indexOf("int")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ "code.cpp", code.indexOf("int"), code.indexOf("r;") + 2 - code.indexOf("int")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
assertSoleFileLocation( assertSoleFileLocation(
FOO, FOO,
"foo.h", foo.indexOf("int"), foo.indexOf(";") + 1 - foo.indexOf("int")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ "foo.h", foo.indexOf("int"), foo.indexOf(";") + 1 - foo.indexOf("int")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
assertSoleFileLocation( assertSoleFileLocation(
byob, byob,
"code.cpp", code.indexOf("float"), code.indexOf("b;") + 2 - code.indexOf("float")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ "code.cpp", code.indexOf("float"), code.indexOf("b;") + 2 - code.indexOf("float")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
IASTPreprocessorIncludeStatement[] incs = tu.getIncludeDirectives(); IASTPreprocessorIncludeStatement[] incs = tu.getIncludeDirectives();
assertNotNull(incs); assertNotNull(incs);
assertEquals(incs.length, 1); assertEquals(incs.length, 1);
assertSoleFileLocation( assertSoleFileLocation(
incs[0], incs[0],
"code.cpp", code.indexOf("#inc"), code.indexOf(".h\"\n") + ".h\"".length() - code.indexOf("#inc")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ "code.cpp", code.indexOf("#inc"), code.indexOf(".h\"\n") + ".h\"".length() - code.indexOf("#inc")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
} }
} }
public void testMacrosInIncludeFile() throws Exception { public void testMacrosInIncludeFile() throws Exception {
String c_file_code = "#define X 4\n\n#include \"blarg.h\"\n\n#define POST_INCLUDE\n\n"; //$NON-NLS-1$ String c_file_code = "#define X 4\n\n#include \"blarg.h\"\n\n#define POST_INCLUDE\n\n"; //$NON-NLS-1$
String h_file_code = "#ifndef _BLARG_H_\r\n#define _BLARG_H_\r\n// macro\r\n#define PRINT(s,m) printf(s,m)\r\n#endif //_BLARG_H_\r\n"; //$NON-NLS-1$ String h_file_code = "#ifndef _BLARG_H_\r\n#define _BLARG_H_\r\n// macro\r\n#define PRINT(s,m) printf(s,m)\r\n#endif //_BLARG_H_\r\n"; //$NON-NLS-1$
importFile( "blarg.h", h_file_code ); //$NON-NLS-1$ importFile("blarg.h", h_file_code); //$NON-NLS-1$
IFile c_file = importFile( "blarg.c", c_file_code ); //$NON-NLS-1$ IFile c_file = importFile("blarg.c", c_file_code); //$NON-NLS-1$
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
: null) { : null) {
IASTTranslationUnit tu = parse(c_file, p); //$NON-NLS-1$ IASTTranslationUnit tu = parse(c_file, p); //$NON-NLS-1$
assertEquals( tu.getDeclarations().length, 0 ); assertEquals(tu.getDeclarations().length, 0);
IASTPreprocessorMacroDefinition[] macroDefinitions = tu.getMacroDefinitions(); IASTPreprocessorMacroDefinition[] macroDefinitions = tu
assertNotNull( macroDefinitions ); .getMacroDefinitions();
assertEquals( macroDefinitions.length, 4 ); assertNotNull(macroDefinitions);
assertSoleFileLocation( macroDefinitions[0], "blarg.c", c_file_code.indexOf( "#define"), c_file_code.indexOf( "4" ) + 1- c_file_code.indexOf( "#define" ) ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ assertEquals(macroDefinitions.length, 4);
assertSoleFileLocation( macroDefinitions[0].getName(), "blarg.c", c_file_code.indexOf( "X"), 1 ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ assertSoleFileLocation(
assertSoleFileLocation( macroDefinitions[1], "blarg.h", h_file_code.indexOf( "#define _BLARG_H_"), "#define _BLARG_H_\r".length() ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ macroDefinitions[0],
assertSoleFileLocation( macroDefinitions[1].getName(), "blarg.h", h_file_code.indexOf( "e _BLARG_H_") + 2, "_BLARG_H_".length() ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ "blarg.c", c_file_code.indexOf("#define"), c_file_code.indexOf("4") + 1 - c_file_code.indexOf("#define")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
assertSoleFileLocation( macroDefinitions[2], "blarg.h", h_file_code.indexOf( "#define PRINT(s,m) printf(s,m)\r"), "#define PRINT(s,m) printf(s,m)".length() ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ assertSoleFileLocation(macroDefinitions[0].getName(),
assertSoleFileLocation( macroDefinitions[2].getName(), "blarg.h", h_file_code.indexOf( "PRINT"), "PRINT".length() ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ "blarg.c", c_file_code.indexOf("X"), 1); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
assertSoleFileLocation( macroDefinitions[3], "blarg.c", c_file_code.indexOf( "#define POST_INCLUDE"), "#define POST_INCLUDE".length() ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ assertSoleFileLocation(
assertSoleFileLocation( macroDefinitions[3].getName(), "blarg.c", c_file_code.indexOf( "POST_INCLUDE"), "POST_INCLUDE".length() ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ macroDefinitions[1],
} "blarg.h", h_file_code.indexOf("#define _BLARG_H_"), "#define _BLARG_H_\r".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
} assertSoleFileLocation(
macroDefinitions[1].getName(),
"blarg.h", h_file_code.indexOf("e _BLARG_H_") + 2, "_BLARG_H_".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
assertSoleFileLocation(
macroDefinitions[2],
"blarg.h", h_file_code.indexOf("#define PRINT(s,m) printf(s,m)\r"), "#define PRINT(s,m) printf(s,m)".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
assertSoleFileLocation(macroDefinitions[2].getName(),
"blarg.h", h_file_code.indexOf("PRINT"), "PRINT".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
assertSoleFileLocation(
macroDefinitions[3],
"blarg.c", c_file_code.indexOf("#define POST_INCLUDE"), "#define POST_INCLUDE".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
assertSoleFileLocation(
macroDefinitions[3].getName(),
"blarg.c", c_file_code.indexOf("POST_INCLUDE"), "POST_INCLUDE".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}
// public void testMacrosInIncludeFile2() throws Exception { public void testBug84451() throws Exception {
// String c_file_code = "#define X 4\n\n#include \"blarg.h\"\n\n#define POST_INCLUDE\n#include \"second.h\"\n#define POST_SECOND\n"; //$NON-NLS-1$ String header1_code = "int x;\n"; //$NON-NLS-1$
// String h_file_code = "#ifndef _BLARG_H_\r\n#define _BLARG_H_\r\n// macro\r\n#define PRINT(s,m) printf(s,m)\r\n#endif //_BLARG_H_\r\n"; //$NON-NLS-1$ String header2_code = "int y;\n"; //$NON-NLS-1$
// String h_file2_code = "#ifndef _SECOND_H_ \n#define _SECOND_H_\n#endif\n"; //$NON-NLS-1$ String cpp_code = "#include \"header1.h\"\n#include \"header2.h\"\nint z;\n"; //$NON-NLS-1$
// importFile( "blarg.h", h_file_code ); //$NON-NLS-1$ importFile("header1.h", header1_code); //$NON-NLS-1$
// importFile( "second.h", h_file2_code ); //$NON-NLS-1$ importFile("header2.h", header2_code); //$NON-NLS-1$
// IFile c_file = importFile( "blarg.c", c_file_code ); //$NON-NLS-1$ IFile f = importFile("source.c", cpp_code); //$NON-NLS-1$
// for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
// : null) { : null) {
// IASTTranslationUnit tu = parse(c_file, p); //$NON-NLS-1$ IASTTranslationUnit tu = parse(f, p);
// assertEquals( tu.getDeclarations().length, 0 ); IASTDeclaration[] declarations = tu.getDeclarations();
// IASTPreprocessorMacroDefinition[] macroDefinitions = tu.getMacroDefinitions(); IASTPreprocessorIncludeStatement[] includeDirectives = tu
// assertNotNull( macroDefinitions ); .getIncludeDirectives();
// assertEquals( macroDefinitions.length, 6 ); assertSoleFileLocation(
// assertSoleFileLocation( macroDefinitions[0], "blarg.c", c_file_code.indexOf( "#define"), c_file_code.indexOf( "4" ) + 1- c_file_code.indexOf( "#define" ) ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ includeDirectives[0],
// assertSoleFileLocation( macroDefinitions[0].getName(), "blarg.c", c_file_code.indexOf( "X"), 1 ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ "source.c", cpp_code.indexOf("#include \"header1.h\""), "#include \"header1.h\"".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
// assertSoleFileLocation( macroDefinitions[1], "blarg.h", h_file_code.indexOf( "#define _BLARG_H_"), "#define _BLARG_H_\r".length() ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ assertSoleFileLocation(declarations[0],
// assertSoleFileLocation( macroDefinitions[1].getName(), "blarg.h", h_file_code.indexOf( "e _BLARG_H_") + 2, "_BLARG_H_".length() ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ "header1.h", 0, "int x;".length()); //$NON-NLS-1$ //$NON-NLS-2$
// assertSoleFileLocation( macroDefinitions[2], "blarg.h", h_file_code.indexOf( "#define PRINT(s,m) printf(s,m)\r"), "#define PRINT(s,m) printf(s,m)".length() ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ assertSoleFileLocation(declarations[1],
// assertSoleFileLocation( macroDefinitions[2].getName(), "blarg.h", h_file_code.indexOf( "PRINT"), "PRINT".length() ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ "header2.h", 0, "int y;".length()); //$NON-NLS-1$ //$NON-NLS-2$
// assertSoleFileLocation( macroDefinitions[3], "blarg.c", c_file_code.indexOf( "#define POST_INCLUDE"), "#define POST_INCLUDE".length() ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ assertSoleFileLocation(
// assertSoleFileLocation( macroDefinitions[3].getName(), "blarg.c", c_file_code.indexOf( "POST_INCLUDE"), "POST_INCLUDE".length() ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ includeDirectives[1],
// assertSoleFileLocation( macroDefinitions[4], "second.h", h_file2_code.indexOf( "#define _SECOND_H_"), "#define _SECOND_H_".length() ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ "source.c", cpp_code.indexOf("#include \"header2.h\""), "#include \"header2.h\"".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
// assertSoleFileLocation( macroDefinitions[5], "blarg.c", c_file_code.indexOf( "#define POST_SECOND"), "#define POST_SECOND".length() ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ assertSoleFileLocation(declarations[2],
// } "source.c", cpp_code.indexOf("int z;"), "int z;".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
// } }
}
public static Test suite() {
TestSuite suite = new TestSuite(DOMLocationInclusionTests.class); public void testMacrosInIncludeFile2() throws Exception {
suite.addTest(new DOMLocationInclusionTests("cleanupProject")); //$NON-NLS-1$ String c_file_code = "#define X 4\n\n#include \"blarg.h\"\n\n#define POST_INCLUDE\n#include \"second.h\"\n#define POST_SECOND\n"; //$NON-NLS-1$
return suite; String h_file_code = "#ifndef _BLARG_H_\r\n#define _BLARG_H_\r\n//macro\r\n#define PRINT(s,m) printf(s,m)\r\n#endif //_BLARG_H_\r\n"; //$NON-NLS-1$
} String h_file2_code = "#ifndef _SECOND_H_ \n#define _SECOND_H_\n#endif\n"; //$NON-NLS-1$
importFile("blarg.h", h_file_code); //$NON-NLS-1$
importFile("second.h", h_file2_code); //$NON-NLS-1$
IFile c_file = importFile("blarg.c", c_file_code); //$NON-NLS-1$
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
: null) {
IASTTranslationUnit tu = parse(c_file, p); //$NON-NLS-1$
assertEquals(tu.getDeclarations().length, 0);
IASTPreprocessorMacroDefinition[] macroDefinitions = tu
.getMacroDefinitions();
assertNotNull(macroDefinitions);
assertEquals(macroDefinitions.length, 6);
assertSoleFileLocation(
macroDefinitions[0],
"blarg.c", c_file_code.indexOf("#define"), c_file_code.indexOf("4") + 1 - c_file_code.indexOf("#define")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
assertSoleFileLocation(macroDefinitions[0].getName(),
"blarg.c", c_file_code.indexOf("X"), 1); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
assertSoleFileLocation(
macroDefinitions[1],
"blarg.h", h_file_code.indexOf("#define _BLARG_H_"), "#define _BLARG_H_\r".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
assertSoleFileLocation(
macroDefinitions[1].getName(),
"blarg.h", h_file_code.indexOf("e _BLARG_H_") + 2, "_BLARG_H_".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
assertSoleFileLocation(
macroDefinitions[2],
"blarg.h", h_file_code.indexOf("#define PRINT(s,m) printf(s,m)\r"), "#define PRINT(s,m) printf(s,m)".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
assertSoleFileLocation(macroDefinitions[2].getName(),
"blarg.h", h_file_code.indexOf("PRINT"), "PRINT".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
assertSoleFileLocation(
macroDefinitions[3],
"blarg.c", c_file_code.indexOf("#define POST_INCLUDE"), "#define POST_INCLUDE".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
assertSoleFileLocation(
macroDefinitions[3].getName(),
"blarg.c", c_file_code.indexOf("POST_INCLUDE"), "POST_INCLUDE".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
assertSoleFileLocation(
macroDefinitions[4],
"second.h", h_file2_code.indexOf("#define _SECOND_H_"), "#define _SECOND_H_".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
assertSoleFileLocation(
macroDefinitions[5],
"blarg.c", c_file_code.indexOf("#define POST_SECOND"), "#define POST_SECOND".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
}
public static Test suite() {
TestSuite suite = new TestSuite(DOMLocationInclusionTests.class);
suite.addTest(new DOMLocationInclusionTests("cleanupProject")); //$NON-NLS-1$
return suite;
}
} }

View file

@ -334,7 +334,7 @@ abstract class BaseScanner implements IScanner {
long r1 = unaryExpression(); long r1 = unaryExpression();
for (int t = LA(); t == tMULT || t == tDIV; t = LA()) { for (int t = LA(); t == tMULT || t == tDIV; t = LA()) {
int position = pos; // for IProblem /0 below, need position before int position = pos; // for IProblem /0 below, need position before
// consume() // consume()
consume(); consume();
long r2 = unaryExpression(); long r2 = unaryExpression();
if (t == tMULT) if (t == tMULT)
@ -973,7 +973,7 @@ abstract class BaseScanner implements IScanner {
} }
continue; continue;
} else if (buffer[p + 1] == '*') { // C comment, find } else if (buffer[p + 1] == '*') { // C comment, find
// closing */ // closing */
for (bufferPos[bufferStackPos] += 2; bufferPos[bufferStackPos] < limit; ++bufferPos[bufferStackPos]) { for (bufferPos[bufferStackPos] += 2; bufferPos[bufferStackPos] < limit; ++bufferPos[bufferStackPos]) {
p = bufferPos[bufferStackPos]; p = bufferPos[bufferStackPos];
if (buffer[p] == '*' && p + 1 < limit if (buffer[p] == '*' && p + 1 < limit
@ -1247,6 +1247,7 @@ abstract class BaseScanner implements IScanner {
System.arraycopy(oldLineOffsets, 0, lineOffsets, 0, System.arraycopy(oldLineOffsets, 0, lineOffsets, 0,
oldLineOffsets.length); oldLineOffsets.length);
} }
bufferStack[bufferStackPos] = buffer; bufferStack[bufferStackPos] = buffer;
@ -1283,6 +1284,8 @@ abstract class BaseScanner implements IScanner {
} }
protected Object popContext() { protected Object popContext() {
//NOTE - do not set counters to 0 or -1 or something
//Subclasses may require those values in their popContext()
bufferStack[bufferStackPos] = null; bufferStack[bufferStackPos] = null;
Object result = bufferData[bufferStackPos]; Object result = bufferData[bufferStackPos];
@ -1293,7 +1296,6 @@ abstract class BaseScanner implements IScanner {
pushForcedInclusion(); pushForcedInclusion();
return result; return result;
} }
/** /**
* *
*/ */
@ -2466,19 +2468,19 @@ abstract class BaseScanner implements IScanner {
skipOverConditionalCode(true); skipOverConditionalCode(true);
if (isLimitReached()) if (isLimitReached())
handleInvalidCompletion(); handleInvalidCompletion();
processIf( pos, bufferPos[bufferStackPos], true ); processIf(pos, bufferPos[bufferStackPos], true);
} }
processIf( pos, bufferPos[bufferStackPos], false ); processIf(pos, bufferPos[bufferStackPos], false);
return; return;
case ppElse: case ppElse:
case ppElif: case ppElif:
// Condition must have been true, skip over the rest // Condition must have been true, skip over the rest
if (branchState(type == ppElse ? BRANCH_ELSE : BRANCH_ELIF)) { if (branchState(type == ppElse ? BRANCH_ELSE : BRANCH_ELIF)) {
if( type == ppElse ) if (type == ppElse)
processElse( pos, bufferPos[bufferStackPos], false ); processElse(pos, bufferPos[bufferStackPos], false);
else else
processElsif( pos, bufferPos[bufferStackPos], false ); processElsif(pos, bufferPos[bufferStackPos], false);
skipToNewLine(); skipToNewLine();
skipOverConditionalCode(false); skipOverConditionalCode(false);
} else { } else {
@ -2501,17 +2503,17 @@ abstract class BaseScanner implements IScanner {
len = bufferPos[bufferStackPos] - start; len = bufferPos[bufferStackPos] - start;
handleProblem(IProblem.PREPROCESSOR_POUND_ERROR, start, handleProblem(IProblem.PREPROCESSOR_POUND_ERROR, start,
CharArrayUtils.extract(buffer, start, len)); CharArrayUtils.extract(buffer, start, len));
processError( pos, pos + len ); processError(pos, pos + len);
break; break;
case ppEndif: case ppEndif:
if (!branchState(BRANCH_END)) if (!branchState(BRANCH_END))
handleProblem(IProblem.PREPROCESSOR_UNBALANCE_CONDITION, handleProblem(IProblem.PREPROCESSOR_UNBALANCE_CONDITION,
start, ppKeywords.findKey(buffer, start, len)); start, ppKeywords.findKey(buffer, start, len));
processEndif( pos, bufferPos[bufferStackPos ] ); processEndif(pos, bufferPos[bufferStackPos]);
break; break;
case ppPragma: case ppPragma:
skipToNewLine(); skipToNewLine();
processPragma( pos, bufferPos[bufferStackPos ]); processPragma(pos, bufferPos[bufferStackPos]);
default: default:
problem = true; problem = true;
break; break;
@ -2545,17 +2547,20 @@ abstract class BaseScanner implements IScanner {
* @param endPos * @param endPos
*/ */
protected abstract void processError(int startPos, int endPos); protected abstract void processError(int startPos, int endPos);
protected abstract void processElsif(int startPos, int endPos, boolean taken); protected abstract void processElsif(int startPos, int endPos, boolean taken);
protected abstract void processElse(int startPos, int endPos, boolean taken); protected abstract void processElse(int startPos, int endPos, boolean taken);
/** /**
* @param pos * @param pos
* @param i * @param i
* @param b * @param b
*/ */
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, int startingLineNumber) { protected void handlePPInclude(int pos2, boolean include_next,
int startingLineNumber) {
char[] buffer = bufferStack[bufferStackPos]; char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos]; int limit = bufferLimit[bufferStackPos];
@ -2576,95 +2581,95 @@ abstract class BaseScanner implements IScanner {
char c = buffer[pos]; char c = buffer[pos];
int start; int start;
int length; int length;
switch (c) { switch (c) {
case '\n' : case '\n':
return; return;
case '"' : case '"':
nameLine = getLineNumber(bufferPos[bufferStackPos]); nameLine = getLineNumber(bufferPos[bufferStackPos]);
local = true; local = true;
start = bufferPos[bufferStackPos] + 1; start = bufferPos[bufferStackPos] + 1;
length = 0; length = 0;
boolean escaped = false; boolean escaped = false;
while (++bufferPos[bufferStackPos] < limit) { while (++bufferPos[bufferStackPos] < limit) {
++length; ++length;
c = buffer[bufferPos[bufferStackPos]]; c = buffer[bufferPos[bufferStackPos]];
if (c == '"') { if (c == '"') {
if (!escaped) if (!escaped)
break; break;
} else if (c == '\\') { } else if (c == '\\') {
escaped = !escaped; escaped = !escaped;
continue; continue;
}
escaped = false;
} }
escaped = false; --length;
}
--length;
filename = new String(buffer, start, length); filename = new String(buffer, start, length);
nameOffset = start; nameOffset = start;
nameEndOffset = start + length; nameEndOffset = start + length;
endOffset = start + length + 1; endOffset = start + length + 1;
break;
case '<' :
nameLine = getLineNumber(bufferPos[bufferStackPos]);
local = false;
start = bufferPos[bufferStackPos] + 1;
length = 0;
while (++bufferPos[bufferStackPos] < limit
&& buffer[bufferPos[bufferStackPos]] != '>')
++length;
endOffset = start + length + 1;
nameOffset = start;
nameEndOffset = start + length;
filename = new String(buffer, start, length);
break;
default:
// handle macro expansions
int startPos = pos;
int len = 1;
while (++bufferPos[bufferStackPos] < limit) {
c = buffer[bufferPos[bufferStackPos]];
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'
|| (c >= '0' && c <= '9')
|| Character.isUnicodeIdentifierPart(c)) {
++len;
continue;
} else if (c == '\\'
&& bufferPos[bufferStackPos] + 1 < buffer.length
&& buffer[bufferPos[bufferStackPos] + 1] == '\n') {
// escaped newline
++bufferPos[bufferStackPos];
len += 2;
continue;
}
break; break;
} case '<':
nameLine = getLineNumber(bufferPos[bufferStackPos]);
local = false;
start = bufferPos[bufferStackPos] + 1;
length = 0;
Object expObject = definitions.get(buffer, startPos, len); while (++bufferPos[bufferStackPos] < limit
&& buffer[bufferPos[bufferStackPos]] != '>')
++length;
endOffset = start + length + 1;
nameOffset = start;
nameEndOffset = start + length;
if (expObject != null) { filename = new String(buffer, start, length);
--bufferPos[bufferStackPos]; break;
char[] t = null; default:
if (expObject instanceof FunctionStyleMacro) { // handle macro expansions
t = handleFunctionStyleMacro((FunctionStyleMacro) expObject, int startPos = pos;
false); int len = 1;
} else if (expObject instanceof ObjectStyleMacro) { while (++bufferPos[bufferStackPos] < limit) {
t = ((ObjectStyleMacro) expObject).expansion; c = buffer[bufferPos[bufferStackPos]];
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'
|| (c >= '0' && c <= '9')
|| Character.isUnicodeIdentifierPart(c)) {
++len;
continue;
} else if (c == '\\'
&& bufferPos[bufferStackPos] + 1 < buffer.length
&& buffer[bufferPos[bufferStackPos] + 1] == '\n') {
// escaped newline
++bufferPos[bufferStackPos];
len += 2;
continue;
}
break;
} }
if (t != null) {
t = replaceArgumentMacros(t); Object expObject = definitions.get(buffer, startPos, len);
if ((t[t.length - 1] == t[0]) && (t[0] == '\"')) {
local = true; if (expObject != null) {
filename = new String(t, 1, t.length - 2); --bufferPos[bufferStackPos];
} else if (t[0] == '<' && t[t.length - 1] == '>') { char[] t = null;
local = false; if (expObject instanceof FunctionStyleMacro) {
filename = new String(t, 1, t.length - 2); t = handleFunctionStyleMacro((FunctionStyleMacro) expObject,
false);
} else if (expObject instanceof ObjectStyleMacro) {
t = ((ObjectStyleMacro) expObject).expansion;
}
if (t != null) {
t = replaceArgumentMacros(t);
if ((t[t.length - 1] == t[0]) && (t[0] == '\"')) {
local = true;
filename = new String(t, 1, t.length - 2);
} else if (t[0] == '<' && t[t.length - 1] == '>') {
local = false;
filename = new String(t, 1, t.length - 2);
}
} }
} }
} break;
break;
} }
if (filename == null || filename == EMPTY_STRING) { if (filename == null || filename == EMPTY_STRING) {
@ -2684,94 +2689,92 @@ abstract class BaseScanner implements IScanner {
quickParsePushPopInclusion(inclusion); quickParsePushPopInclusion(inclusion);
return; return;
} }
CodeReader reader = null; CodeReader reader = null;
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 then we need to know what the current directory is! // if the include is eclosed in quotes OR we are in an include_next
File file = new File(String.valueOf(getCurrentFilename())); // then we need to know what the current directory is!
currentDirectory = file.getParentFile(); File file = new File(String.valueOf(getCurrentFilename()));
} currentDirectory = file.getParentFile();
}
if (local && !include_next) { if (local && !include_next) {
// 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 = createReader(absolutePath, filename);
if (reader != null) { if (reader != null) {
pushContext(reader.buffer, new InclusionData(reader, pushContext(reader.buffer, new InclusionData(reader,
createInclusionConstruct(fileNameArray, createInclusionConstruct(fileNameArray, reader.filename,
reader.filename, local, startOffset, local, startOffset, startingLineNumber, nameOffset,
startingLineNumber, nameOffset, nameEndOffset, nameLine, endOffset, endLine, false)));
nameEndOffset, nameLine, endOffset, return;
endLine, false))); }
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 (includePaths != null) {
int startpos = 0;
if (include_next)
startpos = findIncludePos(includePaths, currentDirectory) + 1;
for (int i = startpos; i < includePaths.length; ++i) {
reader = createReader(includePaths[i], filename);
if (reader != null) {
pushContext(reader.buffer, new InclusionData(reader,
createInclusionConstruct(fileNameArray,
reader.filename, local, startOffset,
startingLineNumber, nameOffset,
nameEndOffset, nameLine, endOffset,
endLine, false)));
return;
}
}
} }
}
handleProblem(IProblem.PREPROCESSOR_INCLUSION_NOT_FOUND, startOffset, fileNameArray);
} // if we're not include_next, then we are looking for the
// first occurance of the file, otherwise, we ignore all the paths before
private CodeReader createReader(String path, String fileName) // the
{ // current directory
String finalPath = ScannerUtility.createReconciledPath(path, fileName); if (includePaths != null) {
char [] finalPathc = finalPath.toCharArray(); int startpos = 0;
CodeReader reader = (CodeReader) fileCache.get(finalPathc); if (include_next)
if (reader != null) startpos = findIncludePos(includePaths, currentDirectory) + 1;
return reader; // found the file in the cache for (int i = startpos; i < includePaths.length; ++i) {
reader = createReader(includePaths[i], filename);
// create a new reader on this file (if the file does not exist we will get null) if (reader != null) {
reader = createReaderDuple(finalPath); pushContext(reader.buffer, new InclusionData(reader,
if (reader == null) createInclusionConstruct(fileNameArray, reader.filename,
return null; // the file was not found local, startOffset, startingLineNumber, nameOffset,
nameEndOffset, nameLine, endOffset, endLine, false)));
if (reader.filename != null) return;
// put the full requested path in the cache -- it is more likely }
// to match next time than the reader.filename }
fileCache.put(finalPathc, reader); }
return reader;
handleProblem(IProblem.PREPROCESSOR_INCLUSION_NOT_FOUND, startOffset,
fileNameArray);
} }
private int findIncludePos( String[] paths, File currentDirectory) protected CodeReader createReader(String path, String fileName) {
{ String finalPath = ScannerUtility.createReconciledPath(path, fileName);
for (int i = 0; i < paths.length; ++i) char[] finalPathc = finalPath.toCharArray();
try { CodeReader reader = (CodeReader) fileCache.get(finalPathc);
String path = new File(paths[i]).getCanonicalPath(); if (reader != null)
String parent = currentDirectory.getCanonicalPath(); return reader; // found the file in the cache
if (path.equals(parent))
return i;
} catch (IOException e) {
}
return -1; // create a new reader on this file (if the file does not exist we will
// get null)
reader = createReaderDuple(finalPath);
if (reader == null)
return null; // the file was not found
if (reader.filename != null)
// put the full requested path in the cache -- it is more likely
// to match next time than the reader.filename
fileCache.put(finalPathc, reader);
return reader;
} }
private int findIncludePos(String[] paths, File currentDirectory) {
for (int i = 0; i < paths.length; ++i)
try {
String path = new File(paths[i]).getCanonicalPath();
String parent = currentDirectory.getCanonicalPath();
if (path.equals(parent))
return i;
} catch (IOException e) {
}
return -1;
}
/** /**
* @param finalPath * @param finalPath
* @return * @return
*/ */
protected abstract CodeReader createReaderDuple(String finalPath); protected abstract CodeReader createReaderDuple(String finalPath);
/** /**
@ -2859,7 +2862,7 @@ abstract class BaseScanner implements IScanner {
if (CharArrayUtils.equals(buffer, bufferPos[bufferStackPos] + 1, if (CharArrayUtils.equals(buffer, bufferPos[bufferStackPos] + 1,
VA_ARGS_CHARARRAY.length, VA_ARGS_CHARARRAY)) { VA_ARGS_CHARARRAY.length, VA_ARGS_CHARARRAY)) {
usesVarArgInDefinition = true; // __VA_ARGS__ is in definition, used usesVarArgInDefinition = true; // __VA_ARGS__ is in definition, used
// to check C99 6.10.3-5 // to check C99 6.10.3-5
varArgDefinitionInd = bufferPos[bufferStackPos] + 1; varArgDefinitionInd = bufferPos[bufferStackPos] + 1;
} }
@ -2874,7 +2877,7 @@ abstract class BaseScanner implements IScanner {
boolean isArg = false; boolean isArg = false;
if (bufferPos[bufferStackPos] + 1 < limit) { if (bufferPos[bufferStackPos] + 1 < limit) {
++bufferPos[bufferStackPos]; //advances us past the # (or last ++bufferPos[bufferStackPos]; //advances us past the # (or last
// whitespace) // whitespace)
for (int i = 0; i < arglist.length && arglist[i] != null; i++) { for (int i = 0; i < arglist.length && arglist[i] != null; i++) {
if (bufferPos[bufferStackPos] + arglist[i].length - 1 < limit) { if (bufferPos[bufferStackPos] + arglist[i].length - 1 < limit) {
if (arglist[i].length > 3 if (arglist[i].length > 3
@ -2994,7 +2997,7 @@ abstract class BaseScanner implements IScanner {
&& bufferPos[bufferStackPos] + 2 < limit && bufferPos[bufferStackPos] + 2 < limit
&& buffer[bufferPos[bufferStackPos] + 2] == '.') { && buffer[bufferPos[bufferStackPos] + 2] == '.') {
bufferPos[bufferStackPos]--; // move back and let skipOverIdentifier bufferPos[bufferStackPos]--; // move back and let skipOverIdentifier
// handle the ellipsis // handle the ellipsis
} else if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') } else if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
|| c == '_' || Character.isUnicodeIdentifierPart(c))) { || c == '_' || Character.isUnicodeIdentifierPart(c))) {
if (reportProblems) { if (reportProblems) {
@ -3103,7 +3106,7 @@ abstract class BaseScanner implements IScanner {
handleCompletionOnDefinition(new String(buffer, idstart, idlen)); handleCompletionOnDefinition(new String(buffer, idstart, idlen));
skipToNewLine(); skipToNewLine();
processUndef( pos, bufferPos[bufferStackPos] ); processUndef(pos, bufferPos[bufferStackPos]);
definitions.remove(buffer, idstart, idlen); definitions.remove(buffer, idstart, idlen);
} }
@ -3114,7 +3117,8 @@ abstract class BaseScanner implements IScanner {
*/ */
protected abstract void processUndef(int pos, int endPos); protected abstract void processUndef(int pos, int endPos);
protected void handlePPIfdef(int pos, boolean positive) throws EndOfFileException { protected void handlePPIfdef(int pos, boolean positive)
throws EndOfFileException {
char[] buffer = bufferStack[bufferStackPos]; char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos]; int limit = bufferLimit[bufferStackPos];
@ -3161,18 +3165,19 @@ abstract class BaseScanner implements IScanner {
branchState(BRANCH_IF); branchState(BRANCH_IF);
if ((definitions.get(buffer, idstart, idlen) != null) == positive) { if ((definitions.get(buffer, idstart, idlen) != null) == positive) {
processIfdef( pos, bufferPos[bufferStackPos], positive, true ); processIfdef(pos, bufferPos[bufferStackPos], positive, true);
return; return;
} }
processIfdef( pos, bufferPos[bufferStackPos], positive, false ); processIfdef(pos, bufferPos[bufferStackPos], positive, false);
// skip over this group // skip over this group
skipOverConditionalCode(true); skipOverConditionalCode(true);
if (isLimitReached()) if (isLimitReached())
handleInvalidCompletion(); handleInvalidCompletion();
} }
protected abstract void processIfdef(int startPos, int endPos, boolean positive, boolean taken); protected abstract void processIfdef(int startPos, int endPos,
boolean positive, boolean taken);
// checkelse - if potential for more, otherwise skip to endif // checkelse - if potential for more, otherwise skip to endif
protected void skipOverConditionalCode(boolean checkelse) { protected void skipOverConditionalCode(boolean checkelse) {
@ -3218,21 +3223,25 @@ abstract class BaseScanner implements IScanner {
++nesting; ++nesting;
branchState(BRANCH_IF); branchState(BRANCH_IF);
skipToNewLine(); skipToNewLine();
if( type == ppIfdef ) if (type == ppIfdef)
processIfdef( startPos, bufferPos[bufferStackPos], true, false ); processIfdef(startPos, bufferPos[bufferStackPos],
else if( type == ppIfndef ) true, false);
processIfdef( startPos, bufferPos[bufferStackPos], false, false ); else if (type == ppIfndef)
processIfdef(startPos, bufferPos[bufferStackPos],
false, false);
else else
processIf( startPos, bufferPos[bufferStackPos], false ); processIf(startPos, bufferPos[bufferStackPos], false);
break; break;
case ppElse: case ppElse:
if (branchState(BRANCH_ELSE)) { if (branchState(BRANCH_ELSE)) {
skipToNewLine(); skipToNewLine();
if (checkelse && nesting == 0) { if (checkelse && nesting == 0) {
processElse( startPos, bufferPos[ bufferStackPos], true ); processElse(startPos, bufferPos[bufferStackPos],
true);
return; return;
} }
processElse( startPos, bufferPos[ bufferStackPos], false ); processElse(startPos, bufferPos[bufferStackPos],
false);
} else { } else {
//problem, ignore this one. //problem, ignore this one.
handleProblem( handleProblem(
@ -3251,18 +3260,18 @@ abstract class BaseScanner implements IScanner {
if (expressionEvaluator.evaluate(buffer, start, if (expressionEvaluator.evaluate(buffer, start,
len, definitions, len, definitions,
getLineNumber(bufferPos[bufferStackPos]), getLineNumber(bufferPos[bufferStackPos]),
getCurrentFilename()) != 0) getCurrentFilename()) != 0) {
{
// condition passed, we're good // condition passed, we're good
processElsif( start, bufferPos[bufferStackPos], true); processElsif(start, bufferPos[bufferStackPos],
true);
return; return;
} }
processElsif( start, bufferPos[bufferStackPos], false ); processElsif(start, bufferPos[bufferStackPos],
} false);
else } else {
{
skipToNewLine(); skipToNewLine();
processElsif( start, bufferPos[bufferStackPos], false ); processElsif(start, bufferPos[bufferStackPos],
false);
} }
} else { } else {
//problem, ignore this one. //problem, ignore this one.
@ -3274,7 +3283,7 @@ abstract class BaseScanner implements IScanner {
break; break;
case ppEndif: case ppEndif:
if (branchState(BRANCH_END)) { if (branchState(BRANCH_END)) {
processEndif( startPos, bufferPos[ bufferStackPos ]); processEndif(startPos, bufferPos[bufferStackPos]);
if (nesting > 0) { if (nesting > 0) {
--nesting; --nesting;
} else { } else {
@ -3593,7 +3602,7 @@ abstract class BaseScanner implements IScanner {
if (c2 == ')') { // good if (c2 == ')') { // good
bufferPos[bufferStackPos] = end; // point at the end of ... to bufferPos[bufferStackPos] = end; // point at the end of ... to
// get the argument // get the argument
return; return;
} }
@ -4395,8 +4404,7 @@ abstract class BaseScanner implements IScanner {
return language; return language;
} }
protected CodeReader getMainReader() protected CodeReader getMainReader() {
{
if (bufferData != null && bufferData[0] != null if (bufferData != null && bufferData[0] != null
&& bufferData[0] instanceof CodeReader) && bufferData[0] instanceof CodeReader)
return ((CodeReader) bufferData[0]); return ((CodeReader) bufferData[0]);
@ -4430,25 +4438,25 @@ abstract class BaseScanner implements IScanner {
return 0; return 0;
} }
protected final CharArrayIntMap keywords; protected final CharArrayIntMap keywords;
protected static CharArrayIntMap ckeywords; protected static CharArrayIntMap ckeywords;
protected static CharArrayIntMap cppkeywords; protected static CharArrayIntMap cppkeywords;
protected static CharArrayIntMap ppKeywords; protected static CharArrayIntMap ppKeywords;
protected static final int ppIf = 0; protected static final int ppIf = 0;
protected static final int ppIfdef = 1; protected static final int ppIfdef = 1;
protected static final int ppIfndef = 2; protected static final int ppIfndef = 2;
protected static final int ppElif = 3; protected static final int ppElif = 3;
protected static final int ppElse = 4; protected static final int ppElse = 4;
protected static final int ppEndif = 5; protected static final int ppEndif = 5;
protected static final int ppInclude = 6; protected static final int ppInclude = 6;
protected static final int ppDefine = 7; protected static final int ppDefine = 7;
protected static final int ppUndef = 8; protected static final int ppUndef = 8;
protected static final int ppError = 9; protected static final int ppError = 9;
protected static final int ppInclude_next = 10; protected static final int ppInclude_next = 10;
protected static final int ppPragma = 11; protected static final int ppPragma = 11;
protected static final char[] TAB = { '\t' }; protected static final char[] TAB = { '\t' };
protected static final char[] SPACE = { ' ' }; protected static final char[] SPACE = { ' ' };
private static final MacroExpansionToken EXPANSION_TOKEN = new MacroExpansionToken(); private static final MacroExpansionToken EXPANSION_TOKEN = new MacroExpansionToken();
static { static {

View file

@ -13,7 +13,6 @@ package org.eclipse.cdt.internal.core.parser.scanner2;
import org.eclipse.cdt.core.dom.ICodeReaderFactory; import org.eclipse.cdt.core.dom.ICodeReaderFactory;
import org.eclipse.cdt.core.dom.ast.IASTProblem; import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.EndOfFileException;
import org.eclipse.cdt.core.parser.IMacro; import org.eclipse.cdt.core.parser.IMacro;
import org.eclipse.cdt.core.parser.IParserLogService; import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfo;
@ -31,9 +30,8 @@ import org.eclipse.cdt.internal.core.parser.token.SimpleToken;
*/ */
public class DOMScanner extends BaseScanner { public class DOMScanner extends BaseScanner {
private final ICodeReaderFactory codeReaderFactory; protected final ICodeReaderFactory codeReaderFactory;
private int globalCounter = 0; protected int [] bufferDelta = new int[ bufferInitialSize ];
private int contextDelta = 0;
private static class DOMInclusion { private static class DOMInclusion {
public final char[] pt; public final char[] pt;
@ -138,16 +136,25 @@ public class DOMScanner extends BaseScanner {
* java.lang.Object) * java.lang.Object)
*/ */
protected void pushContext(char[] buffer, Object data) { protected void pushContext(char[] buffer, Object data) {
if( bufferStackPos + 1 == bufferDelta.length )
{
int size = bufferDelta.length * 2;
int[] oldBufferDelta = bufferDelta;
bufferDelta = new int[size];
System.arraycopy(oldBufferDelta, 0, bufferDelta, 0, oldBufferDelta.length);
}
if (data instanceof InclusionData) { if (data instanceof InclusionData) {
if (log.isTracing()) { if (log.isTracing()) {
StringBuffer b = new StringBuffer("Entering inclusion "); //$NON-NLS-1$ StringBuffer b = new StringBuffer("Entering inclusion "); //$NON-NLS-1$
b.append(((InclusionData) data).reader.filename); b.append(((InclusionData) data).reader.filename);
log.traceLog(b.toString()); log.traceLog(b.toString());
} }
DOMInclusion inc = ((DOMInclusion) ((InclusionData) data).inclusion); DOMInclusion inc = ((DOMInclusion) ((InclusionData) data).inclusion);
globalCounter += getCurrentOffset(); locationMap.startInclusion(((InclusionData)data).reader, inc.o, resolveOffset( getCurrentOffset() ));
locationMap.startInclusion(((InclusionData)data).reader, inc.o, globalCounter); bufferDelta[bufferStackPos + 1 ] = 0;
contextDelta = 0;
} }
super.pushContext(buffer, data); super.pushContext(buffer, data);
} }
@ -161,23 +168,37 @@ public class DOMScanner extends BaseScanner {
//TODO calibrate offsets //TODO calibrate offsets
Object result = super.popContext(); Object result = super.popContext();
if (result instanceof CodeReader) { if (result instanceof CodeReader) {
globalCounter += (((CodeReader) result).buffer.length - contextDelta); locationMap.endTranslationUnit( bufferDelta[0] + ((CodeReader)result).buffer.length );
locationMap.endTranslationUnit(globalCounter);
} }
if (result instanceof InclusionData) { if (result instanceof InclusionData) {
CodeReader codeReader = ((InclusionData) result).reader;
if (log.isTracing()) { if (log.isTracing()) {
StringBuffer buffer = new StringBuffer("Exiting inclusion "); //$NON-NLS-1$ StringBuffer buffer = new StringBuffer("Exiting inclusion "); //$NON-NLS-1$
buffer buffer.append(codeReader.filename);
.append(((InclusionData) bufferData[bufferStackPos]).reader.filename);
log.traceLog(buffer.toString()); log.traceLog(buffer.toString());
} }
globalCounter += (((InclusionData) result).reader.buffer.length - contextDelta); locationMap.endInclusion(getGlobalCounter( bufferStackPos + 1 ) + bufferPos[ bufferStackPos + 1 ]);
contextDelta = getCurrentOffset(); bufferDelta[ bufferStackPos ] += bufferDelta[ bufferStackPos + 1 ] + codeReader.buffer.length;
locationMap.endInclusion(globalCounter);
} }
return result; return result;
} }
protected int getGlobalCounter( int value )
{
if( value < 0 ) return 0;
int result = bufferDelta[ value ];
for( int i = value - 1; i >= 0; --i )
result += bufferPos[ i ] + bufferDelta[ i ];
return result;
}
protected int getGlobalCounter()
{
return getGlobalCounter( bufferStackPos );
}
/** /**
* @return * @return
@ -252,7 +273,7 @@ public class DOMScanner extends BaseScanner {
* @return * @return
*/ */
private int resolveOffset(int offset) { private int resolveOffset(int offset) {
return globalCounter - contextDelta + offset; return getGlobalCounter() + offset;
} }
/* /*
@ -266,16 +287,6 @@ public class DOMScanner extends BaseScanner {
locationMap.startTranslationUnit(getMainReader()); locationMap.startTranslationUnit(getMainReader());
} }
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#throwEOF()
*/
protected void throwEOF() throws EndOfFileException {
locationMap.endTranslationUnit(globalCounter);
super.throwEOF();
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processIfdef(int, int, boolean, boolean) * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processIfdef(int, int, boolean, boolean)
*/ */

View file

@ -839,6 +839,8 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog {
if (tu == null) if (tu == null)
return EMPTY_LOCATION_ARRAY; return EMPTY_LOCATION_ARRAY;
_Context c = findContextForOffset(offset); _Context c = findContextForOffset(offset);
if( c == null )
return EMPTY_LOCATION_ARRAY;
if (c.context_ends >= offset + length) if (c.context_ends >= offset + length)
return createSoleLocation(c, offset, length); return createSoleLocation(c, offset, length);