mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-25 18:05:33 +02:00
Merge branch 'bug_197989_B'
This commit is contained in:
commit
c2cec226b3
91 changed files with 4384 additions and 1808 deletions
|
@ -1,13 +1,13 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2008 IBM Corporation and others.
|
||||
* Copyright (c) 2004, 2011 IBM Corporation 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:
|
||||
* IBM - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* IBM - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.parser.tests.ast2;
|
||||
|
||||
|
@ -35,6 +35,7 @@ import org.eclipse.cdt.core.parser.ExtendedScannerInfo;
|
|||
import org.eclipse.cdt.core.parser.IExtendedScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||
import org.eclipse.cdt.core.parser.ScannerInfo;
|
||||
import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
|
@ -70,9 +71,9 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest {
|
|||
String code = "int main() { return BEAST * sizeof( Include ); } "; //$NON-NLS-1$
|
||||
for (ParserLanguage p : ParserLanguage.values()) {
|
||||
String filename = (p == ParserLanguage.CPP) ? "main.cc" : "main.c"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
IFile c = importFile(filename, code); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
IFile c = importFile(filename, code);
|
||||
|
||||
IASTTranslationUnit tu = parse(c, scannerInfo); //$NON-NLS-1$
|
||||
IASTTranslationUnit tu = parse(c, scannerInfo);
|
||||
IASTFunctionDefinition fd = (IASTFunctionDefinition) tu.getDeclarations()[3];
|
||||
IASTFileLocation floc = fd.getFileLocation();
|
||||
assertEquals(floc.getNodeOffset(),
|
||||
|
@ -102,11 +103,11 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest {
|
|||
|
||||
for (ParserLanguage p : ParserLanguage.values()) {
|
||||
String filename = (p == ParserLanguage.CPP) ? "blah.cc" : "blah.c"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
IFile source = importFile(filename, code); //$NON-NLS-1$
|
||||
IASTTranslationUnit tu = parse(source); //$NON-NLS-1$
|
||||
IFile source = importFile(filename, code);
|
||||
IASTTranslationUnit tu = parse(source);
|
||||
IASTSimpleDeclaration declaration = (IASTSimpleDeclaration) tu.getDeclarations()[0];
|
||||
assertSoleFileLocation(declaration.getDeclarators()[0], filename,
|
||||
code.indexOf("SomeStructure"), "SomeStructure".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
code.indexOf("SomeStructure"), "SomeStructure".length()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -206,13 +207,13 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest {
|
|||
|
||||
for (ParserLanguage p : ParserLanguage.values()) {
|
||||
String filename = (p == ParserLanguage.CPP) ? "code.cc" : "code.c"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
IFile cpp = importFile(filename, code); //$NON-NLS-1$
|
||||
IASTTranslationUnit tu = parse(cpp); //$NON-NLS-1$
|
||||
IFile cpp = importFile(filename, code);
|
||||
IASTTranslationUnit tu = parse(cpp);
|
||||
IASTDeclaration[] declarations = tu.getDeclarations();
|
||||
assertEquals(declarations.length, 2);
|
||||
IASTSimpleDeclaration bar = (IASTSimpleDeclaration) declarations[0];
|
||||
IASTSimpleDeclaration FOO = (IASTSimpleDeclaration) declarations[1];
|
||||
assertSoleFileLocation(bar, filename, code.indexOf("int"), code.indexOf(";") + 1); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
assertSoleFileLocation(bar, filename, code.indexOf("int"), code.indexOf(";") + 1); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
assertSoleFileLocation(FOO, "foo.h", foo.indexOf("int"), foo.indexOf(";") + 1); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
IASTPreprocessorIncludeStatement[] incs = tu.getIncludeDirectives();
|
||||
|
@ -243,8 +244,8 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest {
|
|||
|
||||
for (ParserLanguage p : ParserLanguage.values()) {
|
||||
String filename = (p == ParserLanguage.CPP) ? "code.cc" : "code.c"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
IFile cpp = importFile(filename, code); //$NON-NLS-1$
|
||||
IASTTranslationUnit tu = parse(cpp); //$NON-NLS-1$
|
||||
IFile cpp = importFile(filename, code);
|
||||
IASTTranslationUnit tu = parse(cpp);
|
||||
IASTDeclaration[] declarations = tu.getDeclarations();
|
||||
assertEquals(declarations.length, 3);
|
||||
IASTSimpleDeclaration bar = (IASTSimpleDeclaration) declarations[0];
|
||||
|
@ -253,21 +254,21 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest {
|
|||
assertSoleFileLocation(
|
||||
bar,
|
||||
filename,
|
||||
code.indexOf("int"), code.indexOf("r;") + 2 - code.indexOf("int")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
code.indexOf("int"), code.indexOf("r;") + 2 - code.indexOf("int")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
assertSoleFileLocation(
|
||||
FOO,
|
||||
"foo.h", foo.indexOf("int"), foo.indexOf(";") + 1 - foo.indexOf("int")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
assertSoleFileLocation(
|
||||
byob,
|
||||
filename,
|
||||
code.indexOf("float"), code.indexOf("b;") + 2 - code.indexOf("float")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
code.indexOf("float"), code.indexOf("b;") + 2 - code.indexOf("float")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
IASTPreprocessorIncludeStatement[] incs = tu.getIncludeDirectives();
|
||||
assertNotNull(incs);
|
||||
assertEquals(incs.length, 1);
|
||||
assertSoleFileLocation(
|
||||
incs[0],
|
||||
filename,
|
||||
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.indexOf("#inc"), code.indexOf(".h\"\n") + ".h\"".length() - code.indexOf("#inc")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,8 +279,8 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest {
|
|||
|
||||
for (ParserLanguage p : ParserLanguage.values()) {
|
||||
String filename = (p == ParserLanguage.CPP) ? "blah.cc" : "blah.c"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
IFile c_file = importFile(filename, c_file_code); //$NON-NLS-1$
|
||||
IASTTranslationUnit tu = parse(c_file); //$NON-NLS-1$
|
||||
IFile c_file = importFile(filename, c_file_code);
|
||||
IASTTranslationUnit tu = parse(c_file);
|
||||
assertEquals(tu.getDeclarations().length, 0);
|
||||
IASTPreprocessorMacroDefinition[] macroDefinitions = tu
|
||||
.getMacroDefinitions();
|
||||
|
@ -288,9 +289,9 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest {
|
|||
assertSoleFileLocation(
|
||||
macroDefinitions[0],
|
||||
filename,
|
||||
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$
|
||||
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$
|
||||
assertSoleFileLocation(macroDefinitions[0].getName(), filename,
|
||||
c_file_code.indexOf("X"), 1); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
c_file_code.indexOf("X"), 1); //$NON-NLS-1$
|
||||
assertSoleFileLocation(
|
||||
macroDefinitions[1],
|
||||
"blarg.h", h_file_code.indexOf("#define _BLARG_H_"), "#define _BLARG_H_".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
|
@ -299,17 +300,17 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest {
|
|||
"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$
|
||||
"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$
|
||||
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.h", h_file_code.indexOf("PRINT"), "PRINT".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
assertSoleFileLocation(
|
||||
macroDefinitions[3],
|
||||
filename,
|
||||
c_file_code.indexOf("#define POST_INCLUDE"), "#define POST_INCLUDE".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
c_file_code.indexOf("#define POST_INCLUDE"), "#define POST_INCLUDE".length()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
assertSoleFileLocation(
|
||||
macroDefinitions[3].getName(),
|
||||
filename,
|
||||
c_file_code.indexOf("POST_INCLUDE"), "POST_INCLUDE".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
c_file_code.indexOf("POST_INCLUDE"), "POST_INCLUDE".length()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -322,7 +323,7 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest {
|
|||
|
||||
for (ParserLanguage p : ParserLanguage.values()) {
|
||||
String filename = (p == ParserLanguage.CPP) ? "source.cc" : "source.c"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
IFile f = importFile(filename, cpp_code); //$NON-NLS-1$
|
||||
IFile f = importFile(filename, cpp_code);
|
||||
IASTTranslationUnit tu = parse(f);
|
||||
IASTDeclaration[] declarations = tu.getDeclarations();
|
||||
IASTPreprocessorIncludeStatement[] includeDirectives = tu
|
||||
|
@ -330,7 +331,7 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest {
|
|||
assertSoleFileLocation(
|
||||
includeDirectives[0],
|
||||
filename,
|
||||
cpp_code.indexOf("#include \"header1.h\""), "#include \"header1.h\"".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
cpp_code.indexOf("#include \"header1.h\""), "#include \"header1.h\"".length()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
assertSoleFileLocation(declarations[0],
|
||||
"header1.h", 0, "int x;".length()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
assertSoleFileLocation(declarations[1],
|
||||
|
@ -338,9 +339,9 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest {
|
|||
assertSoleFileLocation(
|
||||
includeDirectives[1],
|
||||
filename,
|
||||
cpp_code.indexOf("#include \"header2.h\""), "#include \"header2.h\"".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
cpp_code.indexOf("#include \"header2.h\""), "#include \"header2.h\"".length()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
assertSoleFileLocation(declarations[2], filename, cpp_code
|
||||
.indexOf("int z;"), "int z;".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
.indexOf("int z;"), "int z;".length()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
IASTTranslationUnit.IDependencyTree tree = tu.getDependencyTree();
|
||||
assertEquals(tree.getInclusions().length, 2);
|
||||
|
@ -357,8 +358,8 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest {
|
|||
|
||||
for (ParserLanguage p : ParserLanguage.values()) {
|
||||
String filename = (p == ParserLanguage.CPP) ? "blah.cc" : "blah.c"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
IFile c_file = importFile(filename, c_file_code); //$NON-NLS-1$
|
||||
IASTTranslationUnit tu = parse(c_file); //$NON-NLS-1$
|
||||
IFile c_file = importFile(filename, c_file_code);
|
||||
IASTTranslationUnit tu = parse(c_file);
|
||||
assertEquals(tu.getDeclarations().length, 0);
|
||||
IASTPreprocessorMacroDefinition[] macroDefinitions = tu.getMacroDefinitions();
|
||||
assertNotNull(macroDefinitions);
|
||||
|
@ -366,9 +367,9 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest {
|
|||
assertSoleFileLocation(
|
||||
macroDefinitions[0],
|
||||
filename,
|
||||
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$
|
||||
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$
|
||||
assertSoleFileLocation(macroDefinitions[0].getName(), filename,
|
||||
c_file_code.indexOf("X"), 1); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
c_file_code.indexOf("X"), 1); //$NON-NLS-1$
|
||||
assertSoleFileLocation(
|
||||
macroDefinitions[1],
|
||||
"blarg.h", h_file_code.indexOf("#define _BLARG_H_"), "#define _BLARG_H_".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
|
@ -377,24 +378,24 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest {
|
|||
"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$
|
||||
"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$
|
||||
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.h", h_file_code.indexOf("PRINT"), "PRINT".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
assertSoleFileLocation(
|
||||
macroDefinitions[3],
|
||||
filename,
|
||||
c_file_code.indexOf("#define POST_INCLUDE"), "#define POST_INCLUDE".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
c_file_code.indexOf("#define POST_INCLUDE"), "#define POST_INCLUDE".length()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
assertSoleFileLocation(
|
||||
macroDefinitions[3].getName(),
|
||||
filename,
|
||||
c_file_code.indexOf("POST_INCLUDE"), "POST_INCLUDE".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
c_file_code.indexOf("POST_INCLUDE"), "POST_INCLUDE".length()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
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],
|
||||
filename,
|
||||
c_file_code.indexOf("#define POST_SECOND"), "#define POST_SECOND".length()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
c_file_code.indexOf("#define POST_SECOND"), "#define POST_SECOND".length()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -411,15 +412,15 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest {
|
|||
buffer.append("};\n"); //$NON-NLS-1$
|
||||
buffer.append("#endif /*_INCLUDE_H_*/\n"); //$NON-NLS-1$
|
||||
final String inc_file_code = buffer.toString();
|
||||
IFile include_file = importFile("include.h", inc_file_code); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
IFile include_file = importFile("include.h", inc_file_code); //$NON-NLS-1$
|
||||
String[] macros = { imacro_file.getLocation().toOSString() };
|
||||
String[] includes = { include_file.getLocation().toOSString() };
|
||||
IExtendedScannerInfo scannerInfo = new ExtendedScannerInfo(Collections.EMPTY_MAP, EMPTY_STRING_ARRAY, macros, includes);
|
||||
|
||||
for (ParserLanguage p : ParserLanguage.values()) {
|
||||
String filename = (p == ParserLanguage.CPP) ? "main.cc" : "main.c"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
IFile code = importFile(filename, "int main() { return BEAST * sizeof( Include ); } "); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
IASTTranslationUnit tu = parse(code, scannerInfo); //$NON-NLS-1$
|
||||
IFile code = importFile(filename, "int main() { return BEAST * sizeof( Include ); } "); //$NON-NLS-1$
|
||||
IASTTranslationUnit tu = parse(code, scannerInfo);
|
||||
IASTPreprocessorMacroDefinition[] macro_defs = tu.getMacroDefinitions();
|
||||
assertEquals(macro_defs.length, 2);
|
||||
IASTPreprocessorMacroDefinition BEAST = macro_defs[0];
|
||||
|
@ -443,8 +444,8 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest {
|
|||
|
||||
for (ParserLanguage p : ParserLanguage.values()) {
|
||||
String filename = (p == ParserLanguage.CPP) ? "blah.cc" : "blah.c"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
IFile f = importFile(filename, code); //$NON-NLS-1$
|
||||
IASTTranslationUnit tu = parse(f); //$NON-NLS-1$
|
||||
IFile f = importFile(filename, code);
|
||||
IASTTranslationUnit tu = parse(f);
|
||||
IASTProblem[] prbs = tu.getPreprocessorProblems();
|
||||
assertEquals(prbs.length, 1);
|
||||
IASTNodeLocation[] locs = prbs[0].getNodeLocations();
|
||||
|
@ -474,16 +475,16 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest {
|
|||
buffer.append("};\n"); //$NON-NLS-1$
|
||||
buffer.append("#endif /*_INCLUDE_H_*/\n"); //$NON-NLS-1$
|
||||
final String inc_file_code = buffer.toString();
|
||||
IFile include_file = importFile("include.h", inc_file_code); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
IFile include_file = importFile("include.h", inc_file_code); //$NON-NLS-1$
|
||||
String[] macros = { imacro_file.getLocation().toOSString() };
|
||||
String[] includes = { include_file.getLocation().toOSString() };
|
||||
IExtendedScannerInfo scannerInfo = new ExtendedScannerInfo(
|
||||
Collections.EMPTY_MAP, EMPTY_STRING_ARRAY, macros, includes);
|
||||
for (ParserLanguage p : ParserLanguage.values()) {
|
||||
String filename = (p == ParserLanguage.CPP) ? "main.cc" : "main.c"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
IFile code = importFile(filename, "int main() { return BEAST * sizeof( Include ); } "); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
IFile code = importFile(filename, "int main() { return BEAST * sizeof( Include ); } "); //$NON-NLS-1$
|
||||
|
||||
IASTTranslationUnit tu = parse(code, scannerInfo); //$NON-NLS-1$
|
||||
IASTTranslationUnit tu = parse(code, scannerInfo);
|
||||
IASTPreprocessorMacroDefinition[] macro_defs = tu.getMacroDefinitions();
|
||||
assertEquals(macro_defs.length, 4);
|
||||
IASTPreprocessorMacroDefinition BEAST = macro_defs[0];
|
||||
|
@ -515,14 +516,14 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest {
|
|||
buffer.append("};\n"); //$NON-NLS-1$
|
||||
buffer.append("#endif /*_INCLUDE_H_*/\n"); //$NON-NLS-1$
|
||||
final String inc_file_code = buffer.toString();
|
||||
IFile include_file = importFile("include.h", inc_file_code); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
IFile include_file = importFile("include.h", inc_file_code); //$NON-NLS-1$
|
||||
String[] macros = { imacro_file1.getLocation().toOSString(), imacro_file2.getLocation().toOSString() };
|
||||
String[] includes = { include_file.getLocation().toOSString() };
|
||||
IExtendedScannerInfo scannerInfo = new ExtendedScannerInfo(Collections.EMPTY_MAP, EMPTY_STRING_ARRAY, macros, includes);
|
||||
|
||||
for (ParserLanguage p : ParserLanguage.values()) {
|
||||
String filename = (p == ParserLanguage.CPP) ? "main.cc" : "main.c"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
IFile code = importFile(filename, "int main() { return BEAST * sizeof( Include ); } "); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
IFile code = importFile(filename, "int main() { return BEAST * sizeof( Include ); } "); //$NON-NLS-1$
|
||||
|
||||
IASTTranslationUnit tu = parse(code, scannerInfo);
|
||||
IASTPreprocessorMacroDefinition[] macro_defs = tu.getMacroDefinitions();
|
||||
|
@ -611,4 +612,182 @@ public class DOMLocationInclusionTests extends AST2FileBasePluginTest {
|
|||
tmpFile.getParentFile().delete();
|
||||
}
|
||||
}
|
||||
|
||||
// // comment
|
||||
//
|
||||
// #ifndef guard
|
||||
// #define guard
|
||||
// bla bla
|
||||
// #if 1
|
||||
// #endif
|
||||
// bla bla
|
||||
// #endif
|
||||
// //comment
|
||||
|
||||
// // comment
|
||||
//
|
||||
// #if !defined(guard)
|
||||
// #define guard
|
||||
// bla bla
|
||||
// #if 1
|
||||
// #endif
|
||||
// bla bla
|
||||
// #endif
|
||||
// //comment
|
||||
|
||||
// // comment
|
||||
//
|
||||
// #if ((!defined guard))
|
||||
// #define guard
|
||||
// bla bla
|
||||
// #if 1
|
||||
// #endif
|
||||
// bla bla
|
||||
// #endif
|
||||
// //comment
|
||||
|
||||
// // comment
|
||||
// #pragma once
|
||||
|
||||
// // Some comment
|
||||
//
|
||||
// #ifndef AN_UNIQUE_INCLUDE_GUARD_H_
|
||||
// #define AN_UNIQUE_INCLUDE_GUARD_H_
|
||||
//
|
||||
// #include <string>
|
||||
//
|
||||
// Some code without any macro references
|
||||
//
|
||||
// #endif // AN_UNIQUE_INCLUDE_GUARD_H_
|
||||
public void testPragmaOnceDetection_197989a() throws Exception {
|
||||
CharSequence[] contents= getContents(5);
|
||||
|
||||
int i= 0;
|
||||
for (CharSequence content : contents) {
|
||||
String headerName = i + ".h";
|
||||
IFile base = importFile("base" + headerName, "#include \"" + headerName + "\"");
|
||||
importFile(headerName, content.toString());
|
||||
IASTTranslationUnit tu = parse(base, new ScannerInfo());
|
||||
IASTPreprocessorIncludeStatement[] incs = tu.getIncludeDirectives();
|
||||
assertTrue(incs.length > 0);
|
||||
assertTrue(incs[0].hasPragmaOnceSemantics());
|
||||
}
|
||||
}
|
||||
|
||||
// #ifndef guard
|
||||
// #define guard2
|
||||
// #endif
|
||||
|
||||
// #if !defined guard
|
||||
// #define guard2
|
||||
// #endif
|
||||
|
||||
// #if !defined(guard) && !defined(guard2)
|
||||
// #define guard
|
||||
// #endif
|
||||
|
||||
// #if (0)
|
||||
// #pragma once
|
||||
// #endif
|
||||
|
||||
// leading
|
||||
// #ifndef guard
|
||||
// #define guard2
|
||||
// #endif
|
||||
|
||||
// #ifndef guard
|
||||
// #define guard2
|
||||
// #endif
|
||||
// #ifdef xx
|
||||
// trailing
|
||||
// #endif
|
||||
public void testPragmaOnceDetection_197989b() throws Exception {
|
||||
CharSequence[] contents= getContents(6);
|
||||
|
||||
int i= 0;
|
||||
for (CharSequence content : contents) {
|
||||
String headerName = i + ".h";
|
||||
IFile base = importFile("base" + headerName, "#include \"" + headerName + "\"");
|
||||
importFile(headerName, content.toString());
|
||||
IASTTranslationUnit tu = parse(base, new ScannerInfo());
|
||||
IASTPreprocessorIncludeStatement[] incs = tu.getIncludeDirectives();
|
||||
assertEquals(1, incs.length);
|
||||
assertFalse(incs[0].hasPragmaOnceSemantics());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// // header.h
|
||||
// #ifdef AH
|
||||
// #endif
|
||||
// #ifndef BH
|
||||
// #endif
|
||||
// #define h
|
||||
// #if CH || DH
|
||||
// #elif EH==1
|
||||
// #endif
|
||||
|
||||
// #define BH
|
||||
// #define DH 0
|
||||
// #define EH 1
|
||||
// #include "header.h"
|
||||
// #ifdef h // defined in header
|
||||
// #endif
|
||||
// #ifdef A
|
||||
// #ifdef a // inactive
|
||||
// #endif
|
||||
// #else
|
||||
// #ifndef B
|
||||
// #endif
|
||||
// #endif
|
||||
// #if defined C
|
||||
// #elif ((!((defined(D)))))
|
||||
// #endif
|
||||
// #define A
|
||||
// #define B
|
||||
// #define AH
|
||||
// #define h
|
||||
// #undef u
|
||||
// #ifdef h // locally defined
|
||||
// #endif
|
||||
// #ifndef u // locally undefined
|
||||
// #endif
|
||||
public void testSignificantMacros_197989a() throws Exception {
|
||||
CharSequence[] contents= getContents(2);
|
||||
|
||||
IFile h = importFile("header.h", contents[0].toString());
|
||||
IFile c = importFile("source.c", contents[1].toString());
|
||||
|
||||
IASTTranslationUnit tu = parse(c, new ScannerInfo());
|
||||
IASTPreprocessorIncludeStatement[] incs = tu.getIncludeDirectives();
|
||||
assertEquals(1, incs.length);
|
||||
assertEquals("{AH=null,BH=*,CH=null,DH=0,EH=1}",
|
||||
incs[0].getSignificantMacros().toString());
|
||||
assertEquals("{A=null,AH=null,B=null,C=null,CH=null,D=null}",
|
||||
tu.getSignificantMacros().toString());
|
||||
}
|
||||
|
||||
// // header.h
|
||||
// #if EQ(A,B)
|
||||
// #endif
|
||||
|
||||
// #define EQ(x,y) x==y
|
||||
// #define A A1
|
||||
// #define B 1
|
||||
// #include "header.h"
|
||||
public void testSignificantMacros_197989b() throws Exception {
|
||||
CharSequence[] contents= getContents(2);
|
||||
|
||||
IFile h = importFile("header.h", contents[0].toString());
|
||||
IFile c = importFile("source.c", contents[1].toString());
|
||||
|
||||
IASTTranslationUnit tu = parse(c, new ScannerInfo());
|
||||
IASTPreprocessorIncludeStatement[] incs = tu.getIncludeDirectives();
|
||||
assertEquals(1, incs.length);
|
||||
assertEquals("{A=A1,A1=null,B=1,EQ=x==y}",
|
||||
incs[0].getSignificantMacros().toString());
|
||||
assertEquals("{A1=null}",
|
||||
tu.getSignificantMacros().toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2009 IBM Corporation and others.
|
||||
* Copyright (c) 2004, 2011 IBM Corporation 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:
|
||||
* IBM - Initial API and implementation
|
||||
* IBM - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.parser.tests.scanner;
|
||||
|
||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||
import org.eclipse.cdt.core.parser.FileContent;
|
||||
import org.eclipse.cdt.internal.core.parser.IMacroDictionary;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContent;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContentProvider;
|
||||
|
||||
public class FileCodeReaderFactory extends InternalFileContentProvider {
|
||||
|
||||
private static FileCodeReaderFactory instance;
|
||||
|
||||
private FileCodeReaderFactory() {}
|
||||
|
||||
|
||||
@Override
|
||||
public InternalFileContent getContentForInclusion(String path) {
|
||||
public InternalFileContent getContentForInclusion(String path,
|
||||
IMacroDictionary macroDictionary) {
|
||||
return (InternalFileContent) FileContent.createForExternalFileLocation(path);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.parser.tests.scanner;
|
||||
|
||||
|
@ -37,10 +37,10 @@ import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorUndefStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTProblem;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree.IASTInclusionNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||
import org.eclipse.cdt.core.testplugin.CTestPlugin;
|
||||
import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
|
||||
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
|
||||
|
@ -49,8 +49,8 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit;
|
|||
import org.eclipse.cdt.internal.core.parser.scanner.CharArray;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.ILocationCtx;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.ImageLocationInfo;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.LocationMap;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.LocationMap;
|
||||
|
||||
public class LocationMapTests extends BaseTestCase {
|
||||
public class Loc implements IASTFileLocation {
|
||||
|
@ -80,6 +80,9 @@ public class LocationMapTests extends BaseTestCase {
|
|||
public IASTFileLocation asFileLocation() {
|
||||
return this;
|
||||
}
|
||||
public IASTPreprocessorIncludeStatement getContextInclusionStatement() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static final String FN = "filename";
|
||||
|
@ -336,8 +339,8 @@ public class LocationMapTests extends BaseTestCase {
|
|||
|
||||
public void testIncludes() {
|
||||
init(DIGITS);
|
||||
fLocationMap.encounterPoundInclude(0, 0, 0, 0, "n1".toCharArray(), null, true, false, false);
|
||||
fLocationMap.encounterPoundInclude(0, 1, 3, 16, "n2".toCharArray(), "f2", false , true, false);
|
||||
fLocationMap.encounterPoundInclude(0, 0, 0, 0, "n1".toCharArray(), null, true, false, false, null);
|
||||
fLocationMap.encounterPoundInclude(0, 1, 3, 16, "n2".toCharArray(), "f2", false , true, false, null);
|
||||
IASTPreprocessorIncludeStatement[] includes= fLocationMap.getIncludeDirectives();
|
||||
assertEquals(2, includes.length);
|
||||
checkInclude(includes[0], "", "", "n1", "", true, false, FN, 0, 0, 1, 0, 0);
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.eclipse.cdt.core.index.IIndexFileLocation;
|
|||
import org.eclipse.cdt.core.index.IIndexLinkage;
|
||||
import org.eclipse.cdt.core.index.IIndexMacro;
|
||||
import org.eclipse.cdt.core.index.IndexFilter;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexFragment;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
|
||||
|
@ -100,13 +101,24 @@ public class EmptyIndexFragment implements IIndexFragment {
|
|||
return 0;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public IIndexFragmentFile getFile(int linkageID, IIndexFileLocation location)
|
||||
throws CoreException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public IIndexFragmentFile getFile(int linkageID, IIndexFileLocation location,
|
||||
ISignificantMacros sigMacros) throws CoreException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public IIndexFragmentFile[] getFiles(int linkageID, IIndexFileLocation location)
|
||||
throws CoreException {
|
||||
return IIndexFragmentFile.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
public IIndexFragmentFile[] getFiles(IIndexFileLocation location) throws CoreException {
|
||||
return new IIndexFragmentFile[0];
|
||||
return IIndexFragmentFile.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
public long getLastWriteAccess() {
|
||||
|
|
|
@ -6,13 +6,16 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Andrew Ferguson (Symbian) - Initial implementation
|
||||
* IBM Corporation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* Andrew Ferguson (Symbian) - Initial implementation
|
||||
* IBM Corporation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.index.tests;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.IPDOMManager;
|
||||
|
@ -81,14 +84,19 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
|
|||
}
|
||||
|
||||
protected IASTName findName(String section, int len) {
|
||||
IASTTranslationUnit ast = strategy.getAst();
|
||||
final IASTNodeSelector nodeSelector = ast.getNodeSelector(null);
|
||||
final int offset = strategy.getTestData()[1].indexOf(section);
|
||||
IASTName name= nodeSelector.findName(offset, len);
|
||||
if (name == null)
|
||||
name= nodeSelector.findImplicitName(offset, len);
|
||||
for (int i = 0; i < strategy.getAstCount(); i++) {
|
||||
IASTTranslationUnit ast = strategy.getAst(i);
|
||||
final IASTNodeSelector nodeSelector = ast.getNodeSelector(null);
|
||||
final int offset = strategy.getAstSource(i).indexOf(section);
|
||||
if (offset >= 0) {
|
||||
IASTName name= nodeSelector.findName(offset, len);
|
||||
if (name == null)
|
||||
name= nodeSelector.findImplicitName(offset, len);
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -210,7 +218,9 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
|
|||
IIndex getIndex();
|
||||
void setUp() throws Exception;
|
||||
void tearDown() throws Exception;
|
||||
public IASTTranslationUnit getAst();
|
||||
public int getAstCount();
|
||||
public IASTTranslationUnit getAst(int index);
|
||||
public StringBuilder getAstSource(int index);
|
||||
public StringBuilder[] getTestData();
|
||||
public ICProject getCProject();
|
||||
public boolean isCompositeIndex();
|
||||
|
@ -258,13 +268,25 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
|
|||
return testData;
|
||||
}
|
||||
|
||||
public IASTTranslationUnit getAst() {
|
||||
public int getAstCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public IASTTranslationUnit getAst(int index) {
|
||||
if (index != 0)
|
||||
throw new IllegalArgumentException();
|
||||
return ast;
|
||||
}
|
||||
|
||||
public StringBuilder getAstSource(int index) {
|
||||
if (index != 0)
|
||||
throw new IllegalArgumentException();
|
||||
return testData[1];
|
||||
}
|
||||
|
||||
public void setUp() throws Exception {
|
||||
cproject = cpp ? CProjectHelper.createCCProject(getName()+System.currentTimeMillis(), "bin", IPDOMManager.ID_NO_INDEXER)
|
||||
: CProjectHelper.createCProject(getName()+System.currentTimeMillis(), "bin", IPDOMManager.ID_NO_INDEXER);
|
||||
cproject = cpp ? CProjectHelper.createCCProject(getName() + System.currentTimeMillis(), "bin", IPDOMManager.ID_NO_INDEXER)
|
||||
: CProjectHelper.createCProject(getName() + System.currentTimeMillis(), "bin", IPDOMManager.ID_NO_INDEXER);
|
||||
Bundle b = CTestPlugin.getDefault().getBundle();
|
||||
testData = TestSourceReader.getContentsForTest(b, "parser", IndexBindingResolutionTestBase.this.getClass(), getName(), 2);
|
||||
|
||||
|
@ -275,7 +297,7 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
|
|||
assertTrue(CCorePlugin.getIndexManager().joinIndexer(360000, new NullProgressMonitor()));
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println("Project PDOM: "+getName());
|
||||
System.out.println("Project PDOM: " + getName());
|
||||
((PDOM)CCoreInternals.getPDOMManager().getPDOM(cproject)).accept(new PDOMPrettyPrinter());
|
||||
}
|
||||
|
||||
|
@ -304,7 +326,6 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
class SinglePDOMTestStrategy implements ITestStrategy {
|
||||
private IIndex index;
|
||||
private ICProject cproject;
|
||||
|
@ -324,10 +345,22 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
|
|||
return testData;
|
||||
}
|
||||
|
||||
public IASTTranslationUnit getAst() {
|
||||
public int getAstCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public IASTTranslationUnit getAst(int index) {
|
||||
if (index != 0)
|
||||
throw new IllegalArgumentException();
|
||||
return ast;
|
||||
}
|
||||
|
||||
public StringBuilder getAstSource(int index) {
|
||||
if (index != 0)
|
||||
throw new IllegalArgumentException();
|
||||
return testData[1];
|
||||
}
|
||||
|
||||
public void setUp() throws Exception {
|
||||
cproject = cpp ? CProjectHelper.createCCProject(getName()+System.currentTimeMillis(), "bin", IPDOMManager.ID_NO_INDEXER)
|
||||
: CProjectHelper.createCProject(getName()+System.currentTimeMillis(), "bin", IPDOMManager.ID_NO_INDEXER);
|
||||
|
@ -370,6 +403,108 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This strategy allows tests to create an arbitrary number of header and source files
|
||||
* and to obtain ASTs of any subset of the created files.
|
||||
*
|
||||
* The first line of each comment section preceding the test contains the name of the file
|
||||
* to put the contents of the section to. To request the AST of a file, put an asterisk after
|
||||
* the file name.
|
||||
*/
|
||||
class SinglePDOMTestNamedFilesStrategy implements ITestStrategy {
|
||||
private IIndex index;
|
||||
private ICProject cproject;
|
||||
private StringBuilder[] testData;
|
||||
private final List<StringBuilder> astSources;
|
||||
private final List<IASTTranslationUnit> asts;
|
||||
private final boolean cpp;
|
||||
|
||||
public SinglePDOMTestNamedFilesStrategy(boolean cpp) {
|
||||
this.cpp = cpp;
|
||||
astSources = new ArrayList<StringBuilder>();
|
||||
asts = new ArrayList<IASTTranslationUnit>();
|
||||
}
|
||||
|
||||
public ICProject getCProject() {
|
||||
return cproject;
|
||||
}
|
||||
|
||||
public StringBuilder[] getTestData() {
|
||||
return testData;
|
||||
}
|
||||
|
||||
public int getAstCount() {
|
||||
return asts.size();
|
||||
}
|
||||
|
||||
public IASTTranslationUnit getAst(int index) {
|
||||
return asts.get(index);
|
||||
}
|
||||
|
||||
public StringBuilder getAstSource(int index) {
|
||||
return astSources.get(index);
|
||||
}
|
||||
|
||||
public void setUp() throws Exception {
|
||||
cproject = cpp ? CProjectHelper.createCCProject(getName() + System.currentTimeMillis(), "bin", IPDOMManager.ID_NO_INDEXER)
|
||||
: CProjectHelper.createCProject(getName() + System.currentTimeMillis(), "bin", IPDOMManager.ID_NO_INDEXER);
|
||||
Bundle b = CTestPlugin.getDefault().getBundle();
|
||||
testData = TestSourceReader.getContentsForTest(b, "parser", IndexBindingResolutionTestBase.this.getClass(), getName(), 0);
|
||||
|
||||
List<IFile> astFiles = new ArrayList<IFile>();
|
||||
for (int i = 0; i < testData.length; i++) {
|
||||
StringBuilder contents = testData[i];
|
||||
int endOfLine = contents.indexOf("\n");
|
||||
if (endOfLine >= 0)
|
||||
endOfLine++;
|
||||
else
|
||||
endOfLine = contents.length();
|
||||
String filename = contents.substring(0, endOfLine).trim();
|
||||
contents.delete(0, endOfLine); // Remove first line from the file contents
|
||||
boolean astRequested = filename.endsWith("*");
|
||||
if (astRequested) {
|
||||
filename = filename.substring(0, filename.length() - 1).trim();
|
||||
}
|
||||
IFile file = TestSourceReader.createFile(cproject.getProject(), new Path(filename), contents.toString());
|
||||
if (astRequested || (i == testData.length - 1 && astFiles.isEmpty())) {
|
||||
astSources.add(contents);
|
||||
astFiles.add(file);
|
||||
}
|
||||
}
|
||||
CCorePlugin.getIndexManager().setIndexerId(cproject, IPDOMManager.ID_FAST_INDEXER);
|
||||
assertTrue(CCorePlugin.getIndexManager().joinIndexer(360000, new NullProgressMonitor()));
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println("Project PDOM: "+getName());
|
||||
((PDOM) CCoreInternals.getPDOMManager().getPDOM(cproject)).accept(new PDOMPrettyPrinter());
|
||||
}
|
||||
|
||||
index= CCorePlugin.getIndexManager().getIndex(cproject);
|
||||
|
||||
index.acquireReadLock();
|
||||
for (IFile file : astFiles) {
|
||||
asts.add(TestSourceReader.createIndexBasedAST(index, cproject, file));
|
||||
}
|
||||
}
|
||||
|
||||
public void tearDown() throws Exception {
|
||||
if (index != null) {
|
||||
index.releaseReadLock();
|
||||
}
|
||||
if (cproject != null) {
|
||||
cproject.getProject().delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, new NullProgressMonitor());
|
||||
}
|
||||
}
|
||||
|
||||
public IIndex getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public boolean isCompositeIndex() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class ReferencedProject implements ITestStrategy {
|
||||
private IIndex index;
|
||||
private ICProject cproject, referenced;
|
||||
|
@ -445,10 +580,22 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
|
|||
return referenced;
|
||||
}
|
||||
|
||||
public IASTTranslationUnit getAst() {
|
||||
public int getAstCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public IASTTranslationUnit getAst(int index) {
|
||||
if (index != 0)
|
||||
throw new IllegalArgumentException();
|
||||
return ast;
|
||||
}
|
||||
|
||||
public StringBuilder getAstSource(int index) {
|
||||
if (index != 0)
|
||||
throw new IllegalArgumentException();
|
||||
return testData[1];
|
||||
}
|
||||
|
||||
public IIndex getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
|
|
@ -289,6 +289,17 @@ public class IndexBugsTests extends BaseTestCase {
|
|||
return TestSourceReader.createFile(container, new Path(fileName), contents);
|
||||
}
|
||||
|
||||
private IIndexFile getIndexFile(IFile file) throws CoreException {
|
||||
return getIndexFile(fIndex, file);
|
||||
}
|
||||
|
||||
private IIndexFile getIndexFile(IIndex index, IFile file) throws CoreException {
|
||||
IIndexFile[] files = index.getFiles(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file));
|
||||
assertTrue("Can't find " + file.getLocation(), files.length > 0);
|
||||
assertEquals("Found " + files.length + " files for " + file.getLocation() + " instead of one", 1, files.length);
|
||||
return files[0];
|
||||
}
|
||||
|
||||
private void waitForIndexer() throws InterruptedException {
|
||||
final IIndexManager indexManager = CCorePlugin.getIndexManager();
|
||||
assertTrue(indexManager.joinIndexer(INDEX_WAIT_TIME, npm()));
|
||||
|
@ -459,8 +470,7 @@ public class IndexBugsTests extends BaseTestCase {
|
|||
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file));
|
||||
assertNotNull(ifile);
|
||||
IIndexFile ifile= getIndexFile(file);
|
||||
IIndexInclude[] includes= ifile.getIncludes();
|
||||
assertEquals(1, includes.length);
|
||||
IIndexInclude i= includes[0];
|
||||
|
@ -484,8 +494,7 @@ public class IndexBugsTests extends BaseTestCase {
|
|||
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file));
|
||||
assertNotNull(ifile);
|
||||
IIndexFile ifile= getIndexFile(file);
|
||||
IIndexInclude[] includes= ifile.getIncludes();
|
||||
assertEquals(1, includes.length);
|
||||
IIndexInclude i= includes[0];
|
||||
|
@ -561,8 +570,7 @@ public class IndexBugsTests extends BaseTestCase {
|
|||
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file));
|
||||
assertNotNull(ifile);
|
||||
IIndexFile ifile= getIndexFile(file);
|
||||
IIndexInclude[] includes= ifile.getIncludes();
|
||||
assertEquals(1, includes.length);
|
||||
IIndexInclude i= includes[0];
|
||||
|
@ -585,8 +593,7 @@ public class IndexBugsTests extends BaseTestCase {
|
|||
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file));
|
||||
assertNotNull(ifile);
|
||||
IIndexFile ifile= getIndexFile(file);
|
||||
IIndexInclude[] includes= ifile.getIncludes();
|
||||
assertEquals(1, includes.length);
|
||||
IIndexInclude i= includes[0];
|
||||
|
@ -612,8 +619,7 @@ public class IndexBugsTests extends BaseTestCase {
|
|||
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file));
|
||||
assertNotNull(ifile);
|
||||
IIndexFile ifile= getIndexFile(file);
|
||||
IIndexMacro[] macros= ifile.getMacros();
|
||||
assertEquals(3, macros.length);
|
||||
IIndexMacro m= macros[0];
|
||||
|
@ -1116,7 +1122,7 @@ public class IndexBugsTests extends BaseTestCase {
|
|||
// #endif
|
||||
|
||||
// #ifndef _h1
|
||||
// #include "header1.h"
|
||||
// #include "header1.h" // is inactive, but must be resolved
|
||||
// #endif
|
||||
|
||||
// #include "header1.h"
|
||||
|
@ -1127,7 +1133,7 @@ public class IndexBugsTests extends BaseTestCase {
|
|||
|
||||
// #include "header2.h"
|
||||
// #ifndef _h1
|
||||
// #include "header1.h"
|
||||
// #include "header1.h" // inactive but resolved.
|
||||
// #endif
|
||||
public void testIncludeGuardsOutsideOfHeader_Bug167100() throws Exception {
|
||||
final IIndexManager indexManager = CCorePlugin.getIndexManager();
|
||||
|
@ -1152,13 +1158,15 @@ public class IndexBugsTests extends BaseTestCase {
|
|||
assertEquals(1, names.length);
|
||||
assertEquals(f4.getFullPath().toString(), names[0].getFile().getLocation().getFullPath());
|
||||
|
||||
IIndexFile idxFile= index.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(f5));
|
||||
IIndexFile[] idxFiles= index.getFiles(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(f5));
|
||||
assertEquals(1, idxFiles.length);
|
||||
IIndexFile idxFile= idxFiles[0];
|
||||
IIndexInclude[] includes= idxFile.getIncludes();
|
||||
assertEquals(2, includes.length);
|
||||
assertTrue(includes[0].isActive());
|
||||
assertTrue(includes[0].isResolved());
|
||||
assertFalse(includes[1].isActive());
|
||||
assertTrue(includes[1].isResolved());
|
||||
// includes[1].isResolved()); May or may not be resolved.
|
||||
} finally {
|
||||
index.releaseReadLock();
|
||||
}
|
||||
|
@ -1658,11 +1666,11 @@ public class IndexBugsTests extends BaseTestCase {
|
|||
waitForIndexer();
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
IIndexFile f= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(f1));
|
||||
IIndexFile f= getIndexFile(f1);
|
||||
IIndexInclude i= f.getIncludes()[0];
|
||||
assertTrue(i.isResolvedByHeuristics());
|
||||
|
||||
f= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(f2));
|
||||
f= getIndexFile(f2);
|
||||
i= f.getIncludes()[0];
|
||||
assertFalse(i.isResolvedByHeuristics());
|
||||
} finally {
|
||||
|
@ -1683,7 +1691,7 @@ public class IndexBugsTests extends BaseTestCase {
|
|||
waitForIndexer();
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
IIndexFile f= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(f1));
|
||||
IIndexFile f= getIndexFile(f1);
|
||||
IIndexInclude[] is= f.getIncludes();
|
||||
assertFalse(is[0].isResolved());
|
||||
assertTrue(is[1].isResolvedByHeuristics());
|
||||
|
@ -1702,12 +1710,12 @@ public class IndexBugsTests extends BaseTestCase {
|
|||
// int aOK;
|
||||
// #endif /* A_H_ */
|
||||
|
||||
// #ifndef B_H_
|
||||
// #define B_H_
|
||||
// #ifndef A_H_
|
||||
// #include "a.h"
|
||||
// #endif
|
||||
//
|
||||
// #ifndef B_H_
|
||||
// #define B_H_
|
||||
// int bOK;
|
||||
// #endif
|
||||
|
||||
|
@ -2125,7 +2133,7 @@ public class IndexBugsTests extends BaseTestCase {
|
|||
IIndex index= indexManager.getIndex(fCProject);
|
||||
index.acquireReadLock();
|
||||
try {
|
||||
IIndexFile file= index.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(f));
|
||||
IIndexFile file= getIndexFile(index, f);
|
||||
// check order of includes
|
||||
IIndexInclude[] incs = file.getIncludes();
|
||||
assertEquals(2, incs.length);
|
||||
|
@ -2157,7 +2165,7 @@ public class IndexBugsTests extends BaseTestCase {
|
|||
IIndex index= indexManager.getIndex(fCProject);
|
||||
index.acquireReadLock();
|
||||
try {
|
||||
IIndexFile file= index.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(f));
|
||||
IIndexFile file= getIndexFile(index, f);
|
||||
int idx= testData.indexOf("f(");
|
||||
IIndexName[] names = file.findNames(idx, idx+1);
|
||||
assertEquals(1, names.length);
|
||||
|
@ -2423,4 +2431,4 @@ public class IndexBugsTests extends BaseTestCase {
|
|||
index.releaseReadLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.index.tests;
|
||||
|
||||
|
@ -64,6 +65,7 @@ public class IndexIncludeTest extends IndexTestBase {
|
|||
CoreModel.newIncludeEntry(fProject.getPath(), null,
|
||||
fProject.getResource().getLocation()) };
|
||||
fProject.setRawPathEntries(entries, npm());
|
||||
IndexerPreferences.set(fProject.getProject(), IndexerPreferences.KEY_INDEX_UNUSED_HEADERS_WITH_DEFAULT_LANG, "false");
|
||||
}
|
||||
fIndex= CCorePlugin.getIndexManager().getIndex(fProject);
|
||||
}
|
||||
|
@ -114,17 +116,16 @@ public class IndexIncludeTest extends IndexTestBase {
|
|||
|
||||
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
|
||||
public void run(IProgressMonitor monitor) throws CoreException {
|
||||
file.setContents(new ByteArrayInputStream( "int included; int CONTEXT;\n".getBytes()), false, false, npm());
|
||||
file.setLocalTimeStamp(timestamp+1000);
|
||||
file.setContents(new ByteArrayInputStream("int included; int CONTEXT;\n".getBytes()), false, false, npm());
|
||||
file.setLocalTimeStamp(timestamp + 1000);
|
||||
}
|
||||
}, npm());
|
||||
assertTrue("Timestamp was not increased", file.getLocalTimeStamp() >= timestamp);
|
||||
TestSourceReader.waitUntilFileIsIndexed(fIndex, file, 4000);
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file));
|
||||
assertNotNull("Can't find " + file.getLocation(), ifile);
|
||||
assertTrue("timestamp not ok", ifile.getTimestamp() >= timestamp);
|
||||
IIndexFile ifile= getIndexFile(file);
|
||||
assertTrue("Timestamp not ok", ifile.getTimestamp() >= timestamp);
|
||||
|
||||
IIndexBinding[] result= fIndex.findBindings(Pattern.compile("testInclude_cpp"), true, IndexFilter.ALL, npm());
|
||||
assertEquals(1, result.length);
|
||||
|
@ -134,6 +135,13 @@ public class IndexIncludeTest extends IndexTestBase {
|
|||
} finally {
|
||||
fIndex.releaseReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
private IIndexFile getIndexFile(IFile file) throws CoreException {
|
||||
IIndexFile[] files = fIndex.getFiles(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file));
|
||||
assertTrue("Can't find " + file.getLocation(), files.length > 0);
|
||||
assertEquals("Found " + files.length + " files for " + file.getLocation() + " instead of one", 1, files.length);
|
||||
return files[0];
|
||||
}
|
||||
|
||||
// {source20061107}
|
||||
|
@ -150,8 +158,7 @@ public class IndexIncludeTest extends IndexTestBase {
|
|||
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file));
|
||||
assertNotNull(ifile);
|
||||
IIndexFile ifile= getIndexFile(file);
|
||||
IIndexInclude[] includes= ifile.getIncludes();
|
||||
assertEquals(2, includes.length);
|
||||
|
||||
|
@ -174,8 +181,7 @@ public class IndexIncludeTest extends IndexTestBase {
|
|||
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file));
|
||||
assertNotNull(ifile);
|
||||
IIndexFile ifile= getIndexFile(file);
|
||||
IIndexInclude[] includes= ifile.getIncludes();
|
||||
assertEquals(1, includes.length);
|
||||
|
||||
|
@ -194,8 +200,7 @@ public class IndexIncludeTest extends IndexTestBase {
|
|||
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file));
|
||||
assertNotNull(ifile);
|
||||
IIndexFile ifile= getIndexFile(file);
|
||||
IIndexInclude[] includes= ifile.getIncludes();
|
||||
assertEquals(1, includes.length);
|
||||
|
||||
|
@ -215,8 +220,7 @@ public class IndexIncludeTest extends IndexTestBase {
|
|||
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file));
|
||||
assertNotNull(ifile);
|
||||
IIndexFile ifile= getIndexFile(file);
|
||||
IIndexInclude[] includes= ifile.getIncludes();
|
||||
assertEquals(1, includes.length);
|
||||
|
||||
|
@ -238,7 +242,10 @@ public class IndexIncludeTest extends IndexTestBase {
|
|||
public void testUpdateOfIncluded() throws Exception {
|
||||
String content1 = "int CONTEXT_20070404(x);\n";
|
||||
String content2 = "int CONTEXT_20070404(y);\n";
|
||||
String content3 = "#define CONTEXT_20070404(x) ctx_20070404##x\n #include \"included_20070404.h\"\n int source_20070404;\n";
|
||||
String content3 =
|
||||
"#define CONTEXT_20070404(x) ctx_20070404##x\n" +
|
||||
"#include \"included_20070404.h\"\n" +
|
||||
"int source_20070404;\n";
|
||||
TestSourceReader.createFile(fProject.getProject(), "included_20070404.h", content1);
|
||||
TestSourceReader.createFile(fProject.getProject(), "notIncluded_20070404.h", "int notIncluded_20070404\n;");
|
||||
TestSourceReader.createFile(fProject.getProject(), "includer_20070404.cpp", content3);
|
||||
|
@ -332,8 +339,7 @@ public class IndexIncludeTest extends IndexTestBase {
|
|||
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(header));
|
||||
assertNotNull(ifile);
|
||||
IIndexFile ifile= getIndexFile(header);
|
||||
IIndexInclude[] includes= fIndex.findIncludedBy(ifile);
|
||||
assertEquals(2, includes.length);
|
||||
|
||||
|
@ -352,8 +358,7 @@ public class IndexIncludeTest extends IndexTestBase {
|
|||
fIndex.acquireReadLock();
|
||||
try {
|
||||
assertEquals(1, fIndex.findBindings("a20070426".toCharArray(), IndexFilter.ALL_DECLARED, npm()).length);
|
||||
IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(header));
|
||||
assertNotNull(ifile);
|
||||
IIndexFile ifile= getIndexFile(header);
|
||||
IIndexInclude[] includes= fIndex.findIncludedBy(ifile);
|
||||
assertEquals(2, includes.length);
|
||||
assertEquals(s1.getFullPath().toString(), includes[0].getIncludedByLocation().getFullPath());
|
||||
|
@ -370,8 +375,7 @@ public class IndexIncludeTest extends IndexTestBase {
|
|||
fIndex.acquireReadLock();
|
||||
try {
|
||||
assertEquals(1, fIndex.findBindings("b20070426".toCharArray(), IndexFilter.ALL_DECLARED, npm()).length);
|
||||
IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(header));
|
||||
assertNotNull(ifile);
|
||||
IIndexFile ifile= getIndexFile(header);
|
||||
IIndexInclude[] includes= fIndex.findIncludedBy(ifile);
|
||||
assertEquals(2, includes.length);
|
||||
assertEquals(s1.getFullPath().toString(), includes[0].getIncludedByLocation().getFullPath());
|
||||
|
@ -448,14 +452,188 @@ public class IndexIncludeTest extends IndexTestBase {
|
|||
standardCheckUpdateIncludes(header, s1, "h20070427");
|
||||
}
|
||||
|
||||
// #ifdef A
|
||||
// static const int a = 0;
|
||||
// #endif
|
||||
// #ifdef B
|
||||
// static const int b = 0;
|
||||
// #endif
|
||||
// #ifdef C
|
||||
// static const int c = 0;
|
||||
// #endif
|
||||
|
||||
// #define A
|
||||
// #include "h1.h"
|
||||
// #undef A
|
||||
// #define B
|
||||
// #include "h1.h"
|
||||
// #undef B
|
||||
|
||||
// #define C
|
||||
// #include "h1.h"
|
||||
|
||||
// #include "h2.h"
|
||||
public void testMultiVariantHeaderUpdate() throws Exception {
|
||||
waitForIndexer();
|
||||
TestScannerProvider.sIncludes= new String[] { fProject.getProject().getLocation().toOSString() };
|
||||
StringBuilder[] contents= getContentsForTest(4);
|
||||
final StringBuilder h1Contents = contents[0];
|
||||
final IFile h1= TestSourceReader.createFile(fProject.getProject(), "h1.h", h1Contents.toString());
|
||||
IFile h2= TestSourceReader.createFile(fProject.getProject(), "h2.h", contents[1].toString());
|
||||
IFile s1= TestSourceReader.createFile(fProject.getProject(), "s1.cpp", contents[2].toString());
|
||||
IFile s2= TestSourceReader.createFile(fProject.getProject(), "s2.cpp", contents[3].toString());
|
||||
TestSourceReader.waitUntilFileIsIndexed(fIndex, s1, INDEXER_WAIT_TIME);
|
||||
TestSourceReader.waitUntilFileIsIndexed(fIndex, s2, INDEXER_WAIT_TIME);
|
||||
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
IIndexFile[] indexFiles = fIndex.getFiles(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(h1));
|
||||
assertEquals(3, indexFiles.length);
|
||||
} finally {
|
||||
fIndex.releaseReadLock();
|
||||
}
|
||||
|
||||
final long timestamp= System.currentTimeMillis();
|
||||
while (true) {
|
||||
int pos = h1Contents.indexOf("int");
|
||||
if (pos < 0)
|
||||
break;
|
||||
h1Contents.replace(pos, pos + "int".length(), "float");
|
||||
}
|
||||
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
|
||||
public void run(IProgressMonitor monitor) throws CoreException {
|
||||
h1.setContents(new ByteArrayInputStream(h1Contents.toString().getBytes()), false, false, npm());
|
||||
h1.setLocalTimeStamp(timestamp + 1000);
|
||||
}
|
||||
}, npm());
|
||||
waitForIndexer();
|
||||
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
IIndexFile[] indexFiles = fIndex.getFiles(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(h1));
|
||||
assertEquals(3, indexFiles.length);
|
||||
for (IIndexFile indexFile : indexFiles) {
|
||||
assertTrue("Timestamp not ok", indexFile.getTimestamp() >= timestamp);
|
||||
}
|
||||
} finally {
|
||||
fIndex.releaseReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
// #ifdef A
|
||||
// static const int a = 0;
|
||||
// #endif
|
||||
// #ifdef B
|
||||
// static const int b = 0;
|
||||
// #endif
|
||||
// #ifdef C
|
||||
// static const int c = 0;
|
||||
// #endif
|
||||
|
||||
// #define A
|
||||
// #include "h1.h"
|
||||
// #undef A
|
||||
// #define B
|
||||
// #include "h1.h"
|
||||
// #undef B
|
||||
|
||||
// #define C
|
||||
// #include "h1.h"
|
||||
|
||||
// #include "h2.h"
|
||||
|
||||
// #ifndef H1_H_
|
||||
// #define H1_H_
|
||||
// #ifdef A
|
||||
// static const int a = 0;
|
||||
// #endif
|
||||
// #ifdef B
|
||||
// static const int b = 0;
|
||||
// #endif
|
||||
// #ifdef C
|
||||
// static const int c = 0;
|
||||
// #endif
|
||||
// #endif // H1_H_
|
||||
public void testPragmaOnceChange() throws Exception {
|
||||
waitForIndexer();
|
||||
TestScannerProvider.sIncludes= new String[] { fProject.getProject().getLocation().toOSString() };
|
||||
CharSequence[] contents= getContentsForTest(5);
|
||||
final CharSequence h1Contents = contents[0];
|
||||
final IFile h1= TestSourceReader.createFile(fProject.getProject(), "h1.h", h1Contents.toString());
|
||||
IFile h2= TestSourceReader.createFile(fProject.getProject(), "h2.h", contents[1].toString());
|
||||
IFile s1= TestSourceReader.createFile(fProject.getProject(), "s1.cpp", contents[2].toString());
|
||||
IFile s2= TestSourceReader.createFile(fProject.getProject(), "s2.cpp", contents[3].toString());
|
||||
TestSourceReader.waitUntilFileIsIndexed(fIndex, s1, INDEXER_WAIT_TIME);
|
||||
TestSourceReader.waitUntilFileIsIndexed(fIndex, s2, INDEXER_WAIT_TIME);
|
||||
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
IIndexFile[] indexFiles = fIndex.getFiles(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(h1));
|
||||
assertEquals(3, indexFiles.length);
|
||||
for (IIndexFile indexFile : indexFiles) {
|
||||
assertFalse(indexFile.hasPragmaOnceSemantics());
|
||||
assertEquals(1, fIndex.findIncludedBy(indexFile).length);
|
||||
}
|
||||
} finally {
|
||||
fIndex.releaseReadLock();
|
||||
}
|
||||
|
||||
// Change h1.h so that it has the pragma-once semantics.
|
||||
final long t1= System.currentTimeMillis();
|
||||
final String changedContents = contents[4].toString();
|
||||
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
|
||||
public void run(IProgressMonitor monitor) throws CoreException {
|
||||
h1.setContents(new ByteArrayInputStream(changedContents.getBytes()), false, false, npm());
|
||||
h1.setLocalTimeStamp(t1 + 1000);
|
||||
}
|
||||
}, npm());
|
||||
waitForIndexer();
|
||||
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
IIndexFile[] indexFiles = fIndex.getFiles(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(h1));
|
||||
assertEquals(1, indexFiles.length);
|
||||
for (IIndexFile indexFile : indexFiles) {
|
||||
assertTrue("Timestamp not ok", indexFile.getTimestamp() >= t1);
|
||||
assertTrue(indexFile.hasPragmaOnceSemantics());
|
||||
// Included twice by h2.h and once by s1.cpp
|
||||
assertEquals(2, fIndex.findIncludedBy(indexFile).length);
|
||||
}
|
||||
} finally {
|
||||
fIndex.releaseReadLock();
|
||||
}
|
||||
|
||||
// Change h1.h back to the original state without the pragma-once semantics.
|
||||
final long t2= System.currentTimeMillis();
|
||||
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
|
||||
public void run(IProgressMonitor monitor) throws CoreException {
|
||||
h1.setContents(new ByteArrayInputStream(h1Contents.toString().getBytes()), false, false, npm());
|
||||
h1.setLocalTimeStamp(t2 + 2000);
|
||||
}
|
||||
}, npm());
|
||||
waitForIndexer();
|
||||
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
IIndexFile[] indexFiles = fIndex.getFiles(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(h1));
|
||||
assertEquals(3, indexFiles.length);
|
||||
for (IIndexFile indexFile : indexFiles) {
|
||||
assertTrue("Timestamp not ok", indexFile.getTimestamp() >= t2);
|
||||
assertFalse(indexFile.hasPragmaOnceSemantics());
|
||||
assertEquals(1, fIndex.findIncludedBy(indexFile).length);
|
||||
}
|
||||
} finally {
|
||||
fIndex.releaseReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
private void standardCheckUpdateIncludes(IFile header, IFile s1, String tag) throws Exception {
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
assertEquals(1, fIndex.findBindings(tag.toCharArray(), IndexFilter.ALL_DECLARED, npm()).length);
|
||||
|
||||
IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(header));
|
||||
IIndexFile sfile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(s1));
|
||||
assertNotNull(ifile);
|
||||
IIndexFile ifile= getIndexFile(header);
|
||||
IIndexFile sfile= getIndexFile(s1);
|
||||
IIndexInclude[] includes= fIndex.findIncludedBy(ifile);
|
||||
assertEquals(1, includes.length);
|
||||
assertEquals(s1.getFullPath().toString(), includes[0].getIncludedByLocation().getFullPath());
|
||||
|
@ -464,7 +642,6 @@ public class IndexIncludeTest extends IndexTestBase {
|
|||
assertTrue(includes[0].isResolved());
|
||||
assertFalse(includes[0].isSystemInclude());
|
||||
|
||||
assertNotNull(sfile);
|
||||
includes= fIndex.findIncludes(sfile);
|
||||
assertEquals(3, includes.length);
|
||||
assertEquals(header.getFullPath().toString(), includes[0].getIncludesLocation().getFullPath());
|
||||
|
@ -494,13 +671,11 @@ public class IndexIncludeTest extends IndexTestBase {
|
|||
try {
|
||||
assertEquals(1, fIndex.findBindings(tag.toCharArray(), IndexFilter.ALL_DECLARED, npm()).length);
|
||||
|
||||
IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(header));
|
||||
IIndexFile sfile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(s1));
|
||||
assertNotNull(ifile);
|
||||
IIndexFile ifile= getIndexFile(header);
|
||||
IIndexFile sfile= getIndexFile(s1);
|
||||
IIndexInclude[] includes= fIndex.findIncludedBy(ifile);
|
||||
assertEquals(0, includes.length);
|
||||
|
||||
assertNotNull(sfile);
|
||||
includes= fIndex.findIncludes(sfile);
|
||||
assertEquals(2, includes.length);
|
||||
|
||||
|
@ -525,9 +700,8 @@ public class IndexIncludeTest extends IndexTestBase {
|
|||
try {
|
||||
assertEquals(1, fIndex.findBindings(tag.toCharArray(), IndexFilter.ALL_DECLARED, npm()).length);
|
||||
|
||||
IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(header));
|
||||
IIndexFile sfile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(s1));
|
||||
assertNotNull(ifile);
|
||||
IIndexFile ifile= getIndexFile(header);
|
||||
IIndexFile sfile= getIndexFile(s1);
|
||||
IIndexInclude[] includes= fIndex.findIncludedBy(ifile);
|
||||
assertEquals(1, includes.length);
|
||||
assertEquals(s1.getFullPath().toString(), includes[0].getIncludedByLocation().getFullPath());
|
||||
|
@ -536,7 +710,6 @@ public class IndexIncludeTest extends IndexTestBase {
|
|||
assertTrue(includes[0].isResolved());
|
||||
assertTrue(includes[0].isSystemInclude());
|
||||
|
||||
assertNotNull(sfile);
|
||||
includes= fIndex.findIncludes(sfile);
|
||||
assertEquals(2, includes.length);
|
||||
assertEquals(header.getFullPath().toString(), includes[0].getIncludesLocation().getFullPath());
|
||||
|
@ -560,9 +733,8 @@ public class IndexIncludeTest extends IndexTestBase {
|
|||
try {
|
||||
assertEquals(1, fIndex.findBindings(tag.toCharArray(), IndexFilter.ALL_DECLARED, npm()).length);
|
||||
|
||||
IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(header));
|
||||
IIndexFile sfile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(s1));
|
||||
assertNotNull(ifile);
|
||||
IIndexFile ifile= getIndexFile(header);
|
||||
IIndexFile sfile= getIndexFile(s1);
|
||||
IIndexInclude[] includes= fIndex.findIncludedBy(ifile);
|
||||
assertEquals(1, includes.length);
|
||||
assertEquals(s1.getFullPath().toString(), includes[0].getIncludedByLocation().getFullPath());
|
||||
|
@ -571,7 +743,6 @@ public class IndexIncludeTest extends IndexTestBase {
|
|||
assertTrue(includes[0].isResolved());
|
||||
assertFalse(includes[0].isSystemInclude());
|
||||
|
||||
assertNotNull(sfile);
|
||||
includes= fIndex.findIncludes(sfile);
|
||||
assertEquals(2, includes.length);
|
||||
assertEquals(header.getFullPath().toString(), includes[0].getIncludesLocation().getFullPath());
|
||||
|
|
|
@ -101,9 +101,11 @@ public class IndexListenerTest extends BaseTestCase {
|
|||
assertTrue(im.joinIndexer(10000, npm()));
|
||||
IIndexChangeListener listener = new IIndexChangeListener() {
|
||||
public void indexChanged(IIndexChangeEvent event) {
|
||||
synchronized (mutex) {
|
||||
projects.add(event.getAffectedProject());
|
||||
mutex.notify();
|
||||
if (!event.getFilesWritten().isEmpty()) {
|
||||
synchronized (mutex) {
|
||||
projects.add(event.getAffectedProject());
|
||||
mutex.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -119,7 +121,6 @@ public class IndexListenerTest extends BaseTestCase {
|
|||
assertTrue(projects.contains(fProject1));
|
||||
projects.clear();
|
||||
|
||||
|
||||
IFile file1= TestSourceReader.createFile(fProject1.getProject(), "test.cpp", "int b;");
|
||||
IFile file2= TestSourceReader.createFile(fProject2.getProject(), "test.cpp", "int c;");
|
||||
synchronized (mutex) {
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011 Google, 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:
|
||||
* Sergey Prigogin (Google) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.index.tests;
|
||||
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
|
||||
|
||||
/**
|
||||
* Tests for header files included in multiple variants.
|
||||
*
|
||||
* The first line of each comment section preceding a test contains the name of the file
|
||||
* to put the contents of the section to. To request the AST of a file, put an asterisk after
|
||||
* the file name.
|
||||
*/
|
||||
public class IndexMultiVariantHeaderTest extends IndexBindingResolutionTestBase {
|
||||
|
||||
public IndexMultiVariantHeaderTest() {
|
||||
setStrategy(new SinglePDOMTestNamedFilesStrategy(true));
|
||||
}
|
||||
|
||||
public static TestSuite suite() {
|
||||
return suite(IndexMultiVariantHeaderTest.class);
|
||||
}
|
||||
|
||||
// test.h
|
||||
// #ifdef func
|
||||
// #undef func
|
||||
// #endif
|
||||
//
|
||||
// #define func(x) foo ## x
|
||||
|
||||
// test.c *
|
||||
// #include "test.h"
|
||||
//
|
||||
// void func(1)() {}
|
||||
//
|
||||
// #undef func
|
||||
// #define func(x) bar ## x
|
||||
//
|
||||
// void func(2)() {}
|
||||
//
|
||||
// #include "test.h"
|
||||
// void func(3)() {}
|
||||
public void testExampleFromBug197989_Comment0() throws Exception {
|
||||
IFunction f1 = getBindingFromASTName("func(1)", 7, IFunction.class);
|
||||
assertEquals("foo1", f1.getName());
|
||||
IFunction f2 = getBindingFromASTName("func(2)", 7, IFunction.class);
|
||||
assertEquals("bar2", f2.getName());
|
||||
IFunction f3 = getBindingFromASTName("func(3)", 7, IFunction.class);
|
||||
assertEquals("foo3", f3.getName());
|
||||
}
|
||||
|
||||
// stddef.h
|
||||
// #if !defined(_STDDEF_H) || defined(__need_NULL)
|
||||
//
|
||||
// #if !defined(__need_NULL)
|
||||
// #define _STDDEF_H
|
||||
// #endif /* !defined(__need_NULL) */
|
||||
//
|
||||
// #if defined(_STDDEF_H) || defined(__need_NULL)
|
||||
// #define NULL 0
|
||||
// #endif /* defined(_STDDEF_H) || defined(__need_NULL) */
|
||||
// #undef __need_NULL
|
||||
//
|
||||
// #if defined(_STDDEF_H)
|
||||
// typedef unsigned int size_t;
|
||||
// #endif /* defined(_STDDEF_H) */
|
||||
//
|
||||
// #endif /* !defined(_STDDEF_H) || defined(__need_NULL) */
|
||||
|
||||
// a.h
|
||||
// #ifndef A_H_
|
||||
// #define A_H_
|
||||
// #include "stddef.h"
|
||||
// #endif /* A_H_ */
|
||||
|
||||
// a.cpp *
|
||||
// #define __need_NULL
|
||||
// #include "stddef.h"
|
||||
// void f1(char* p) {}
|
||||
// void test() {
|
||||
// f1(NULL);
|
||||
// }
|
||||
|
||||
// b.cpp
|
||||
// #include "stddef.h"
|
||||
// #include "a.h"
|
||||
|
||||
// c.cpp *
|
||||
// #include "a.h"
|
||||
// void f2(char* p, size_t t) {}
|
||||
// void test() {
|
||||
// f2(NULL, 1);
|
||||
// }
|
||||
public void testExampleFromBug197989_Comment73() throws Exception {
|
||||
getBindingFromASTName("f1(NULL)", 2, ICPPFunction.class);
|
||||
getBindingFromASTName("f2(NULL, 1)", 2, ICPPFunction.class);
|
||||
}
|
||||
|
||||
// a.h
|
||||
// external int X;
|
||||
|
||||
// b.h
|
||||
// #define X y
|
||||
// #include "a.h"
|
||||
// #undef X
|
||||
// #define X z
|
||||
// #include "a.h"
|
||||
|
||||
// a.cpp *
|
||||
// #define X x
|
||||
// #include "a.h"
|
||||
// static void test() {
|
||||
// x = 0;
|
||||
// }
|
||||
|
||||
// b.cpp *
|
||||
// #include "b.h"
|
||||
// static void test() {
|
||||
// y = 0;
|
||||
// z = 0;
|
||||
// }
|
||||
public void _testSignificantMacroDetection() throws Exception {
|
||||
// TODO(sprigogin): For this test to work REPORT_SIGNIFICANT_MACROS flag
|
||||
// should be passed to CPreprocessor.expandMacro method. See
|
||||
// http://bugs.eclipse.org/bugs/show_bug.cgi?id=197989#c92 for details.
|
||||
getBindingFromASTName("x = 0", 1, ICPPVariable.class);
|
||||
getBindingFromASTName("y = 0", 1, ICPPVariable.class);
|
||||
getBindingFromASTName("z = 0", 1, ICPPVariable.class);
|
||||
}
|
||||
}
|
|
@ -88,6 +88,13 @@ public class IndexNamesTests extends BaseTestCase {
|
|||
return result;
|
||||
}
|
||||
|
||||
private IIndexFile getIndexFile(int linkageID, IFile file) throws CoreException {
|
||||
IIndexFile[] files = fIndex.getFiles(linkageID, IndexLocationFactory.getWorkspaceIFL(file));
|
||||
assertTrue("Can't find " + file.getLocation(), files.length > 0);
|
||||
assertEquals("Found " + files.length + " files for " + file.getLocation() + " instead of one", 1, files.length);
|
||||
return files[0];
|
||||
}
|
||||
|
||||
protected void waitUntilFileIsIndexed(IFile file, int time) throws Exception {
|
||||
TestSourceReader.waitUntilFileIsIndexed(fIndex, file, time);
|
||||
}
|
||||
|
@ -263,7 +270,7 @@ public class IndexNamesTests extends BaseTestCase {
|
|||
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
IIndexFile ifile= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file));
|
||||
IIndexFile ifile= getIndexFile(ILinkage.CPP_LINKAGE_ID, file);
|
||||
IIndexName[] names= ifile.findNames(0, content.length());
|
||||
int j= 0;
|
||||
for (IIndexName indexName : names) {
|
||||
|
@ -321,7 +328,7 @@ public class IndexNamesTests extends BaseTestCase {
|
|||
CoreException {
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
IIndexFile ifile= fIndex.getFile(linkageID, IndexLocationFactory.getWorkspaceIFL(file));
|
||||
IIndexFile ifile= getIndexFile(linkageID, file);
|
||||
IIndexName[] names= ifile.findNames(0, Integer.MAX_VALUE);
|
||||
int j= 0;
|
||||
for (IIndexName indexName : names) {
|
||||
|
|
|
@ -30,6 +30,7 @@ public class IndexTests extends TestSuite {
|
|||
suite.addTest(IndexNamesTests.suite());
|
||||
suite.addTest(TeamSharedIndexTest.suite());
|
||||
suite.addTest(IndexProviderManagerTest.suite());
|
||||
suite.addTest(IndexMultiVariantHeaderTest.suite());
|
||||
|
||||
IndexCPPBindingResolutionBugs.addTests(suite);
|
||||
IndexCPPBindingResolutionTest.addTests(suite);
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* QNX - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.pdom.tests;
|
||||
|
||||
|
@ -183,6 +183,11 @@ public class DefDeclTests extends PDOMTestBase {
|
|||
checkReference(binding, "ref" + testNum, ref);
|
||||
}
|
||||
|
||||
private IIndexFile getSingleFile(IIndexFileLocation ifl) throws CoreException {
|
||||
IIndexFile[] files= pdom.getFiles(ILinkage.C_LINKAGE_ID, ifl);
|
||||
assertEquals(1, files.length);
|
||||
return files[0];
|
||||
}
|
||||
/* ------------------ Tests Started Here ------------------------ */
|
||||
public void testInit() {
|
||||
// will fail if setUp fails, maybe timelimit is too small for warm-up
|
||||
|
@ -237,7 +242,7 @@ public class DefDeclTests extends PDOMTestBase {
|
|||
String elName = "foo" + "08";
|
||||
|
||||
IIndexFileLocation ifl= IndexLocationFactory.getIFL((ITranslationUnit) cproject.findElement(new Path("func.c")));
|
||||
IIndexFile file= pdom.getFile(ILinkage.C_LINKAGE_ID, ifl);
|
||||
IIndexFile file= getSingleFile(ifl);
|
||||
int offset= TestSourceReader.indexOfInFile("foo08();", new Path(ifl.getFullPath()));
|
||||
IIndexName[] names= file.findNames(offset, 5);
|
||||
assertEquals(1, names.length);
|
||||
|
@ -249,7 +254,7 @@ public class DefDeclTests extends PDOMTestBase {
|
|||
|
||||
// check the other file
|
||||
ifl= IndexLocationFactory.getIFL((ITranslationUnit) cproject.findElement(new Path("second.c")));
|
||||
file= pdom.getFile(ILinkage.C_LINKAGE_ID, ifl);
|
||||
file= getSingleFile(ifl);
|
||||
offset= TestSourceReader.indexOfInFile("foo08();", new Path(ifl.getFullPath()));
|
||||
names= file.findNames(offset, 5);
|
||||
assertEquals(1, names.length);
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.eclipse.cdt.core.index.IndexLocationFactory;
|
|||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
|
||||
/**
|
||||
|
@ -47,26 +48,30 @@ public class IncludesTests extends PDOMTestBase {
|
|||
index.releaseReadLock();
|
||||
}
|
||||
|
||||
private IIndexFile getIndexFile(IFile file) throws CoreException {
|
||||
IIndexFile[] files = index.getFiles(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file));
|
||||
assertTrue("Can't find " + file.getLocation(), files.length > 0);
|
||||
assertEquals("Found " + files.length + " files for " + file.getLocation() + " instead of one", 1, files.length);
|
||||
return files[0];
|
||||
}
|
||||
|
||||
public void testIncludedBy() throws Exception {
|
||||
IResource loc = project.getProject().findMember("I2.h");
|
||||
IIndexFile file = index.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL((IFile) loc));
|
||||
assertNotNull(file);
|
||||
IIndexFile file = getIndexFile((IFile) loc);
|
||||
IIndexInclude[] allIncludedBy = index.findIncludedBy(file, -1);
|
||||
assertEquals(9, allIncludedBy.length); // i.e. all of them
|
||||
}
|
||||
|
||||
|
||||
public void testIncludes() throws Exception {
|
||||
IResource loc = project.getProject().findMember("I1.cpp");
|
||||
IIndexFile file = index.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL((IFile) loc));
|
||||
assertNotNull(file);
|
||||
IIndexFile file = getIndexFile((IFile) loc);
|
||||
IIndexInclude[] allIncludesTo= index.findIncludes(file, -1);
|
||||
assertEquals(2, allIncludesTo.length); // i.e. I1.h, I2.h
|
||||
}
|
||||
|
||||
public void testIncludeName() throws Exception {
|
||||
IResource loc = project.getProject().findMember("a/b/I6.h");
|
||||
IIndexFile file = index.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL((IFile) loc));
|
||||
assertNotNull(file);
|
||||
IIndexFile file = getIndexFile((IFile) loc);
|
||||
IIndexInclude[] allIncludedBy = index.findIncludedBy(file, -1);
|
||||
assertEquals(2, allIncludedBy.length);
|
||||
for (IIndexInclude include : allIncludedBy) {
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.eclipse.cdt.internal.core.CCoreInternals;
|
|||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase;
|
||||
import org.eclipse.cdt.internal.core.pdom.CModelListener;
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOMManager;
|
||||
import org.eclipse.cdt.internal.core.pdom.indexer.AbstractPDOMIndexer;
|
||||
import org.eclipse.core.resources.IResourceStatus;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.ILogListener;
|
||||
|
@ -66,6 +67,7 @@ public class BaseTestCase extends TestCase {
|
|||
CPPASTNameBase.sAllowRecursionBindings= false;
|
||||
CPPASTNameBase.sAllowNameComputation= false;
|
||||
CModelListener.sSuppressUpdateOfLastRecentlyUsed= true;
|
||||
AbstractPDOMIndexer.noFilesUpFront= true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -294,4 +296,4 @@ public class BaseTestCase extends TestCase {
|
|||
}
|
||||
assertTrue(indexManager.joinIndexer(10000, npm()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,9 +63,10 @@ public class TestSourceReader {
|
|||
* @param srcRoot the directory inside the bundle containing the packages
|
||||
* @param clazz the name of the class containing the test
|
||||
* @param testName the name of the test
|
||||
* @param sections the number of comment sections preceding the named test to return
|
||||
* @param sections the number of comment sections preceding the named test to return. Pass zero
|
||||
* to get all available sections.
|
||||
* @return an array of StringBuilder objects for each comment section found preceding the named
|
||||
* test in the source code.
|
||||
* test in the source code.
|
||||
* @throws IOException
|
||||
*/
|
||||
public static StringBuilder[] getContentsForTest(Bundle bundle, String srcRoot, Class clazz,
|
||||
|
@ -100,7 +101,7 @@ public class TestSourceReader {
|
|||
} else {
|
||||
if (content.length() > 0) {
|
||||
contents.add(content);
|
||||
if (contents.size() == sections + 1)
|
||||
if (sections > 0 && contents.size() == sections + 1)
|
||||
contents.remove(0);
|
||||
content = new StringBuilder();
|
||||
}
|
||||
|
@ -285,12 +286,12 @@ public class TestSourceReader {
|
|||
Assert.assertTrue(CCorePlugin.getIndexManager().joinIndexer(timeLeft, new NullProgressMonitor()));
|
||||
index.acquireReadLock();
|
||||
try {
|
||||
IIndexFile pfile= index.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file));
|
||||
if (pfile != null && pfile.getTimestamp() >= file.getLocalTimeStamp()) {
|
||||
IIndexFile[] files= index.getFiles(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file));
|
||||
if (files.length > 0 && areAllFilesNotOlderThan(files, file.getLocalTimeStamp())) {
|
||||
return;
|
||||
}
|
||||
pfile= index.getFile(ILinkage.C_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file));
|
||||
if (pfile != null && pfile.getTimestamp() >= file.getLocalTimeStamp()) {
|
||||
files= index.getFiles(ILinkage.C_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(file));
|
||||
if (files.length > 0 && areAllFilesNotOlderThan(files, file.getLocalTimeStamp())) {
|
||||
return;
|
||||
}
|
||||
} finally {
|
||||
|
@ -303,7 +304,16 @@ public class TestSourceReader {
|
|||
Assert.fail("Indexing " + file.getFullPath() + " did not complete in time!");
|
||||
}
|
||||
|
||||
public static IASTTranslationUnit createIndexBasedAST(IIndex index, ICProject project, IFile file) throws CModelException, CoreException {
|
||||
private static boolean areAllFilesNotOlderThan(IIndexFile[] files, long timestamp) throws CoreException {
|
||||
for (IIndexFile file : files) {
|
||||
if (file.getTimestamp() < timestamp) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static IASTTranslationUnit createIndexBasedAST(IIndex index, ICProject project, IFile file) throws CModelException, CoreException {
|
||||
ICElement elem= project.findElement(file.getFullPath());
|
||||
if (elem instanceof ITranslationUnit) {
|
||||
ITranslationUnit tu= (ITranslationUnit) elem;
|
||||
|
|
|
@ -12,6 +12,9 @@ org.eclipse.cdt.core/debug/parser/exceptions=false
|
|||
# Reports scanner activity
|
||||
org.eclipse.cdt.core/debug/scanner=false
|
||||
|
||||
# Reports scanner activity
|
||||
org.eclipse.cdt.core/debug/scanner/missingIncludeGuards=false
|
||||
|
||||
# Reports search activity
|
||||
org.eclipse.cdt.core/debug/search=false
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
* Anton Leherbauer (Wind River Systems)
|
||||
* Warren Paul (Nokia) - Bug 218266
|
||||
* James Blackburn (Broadcom Corp.)
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.model;
|
||||
|
||||
|
@ -655,18 +656,26 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
|||
}
|
||||
|
||||
public boolean isHeaderUnit() {
|
||||
return CCorePlugin.CONTENT_TYPE_CHEADER.equals(contentTypeId)
|
||||
|| CCorePlugin.CONTENT_TYPE_CXXHEADER.equals(contentTypeId);
|
||||
return isHeaderContentType(contentTypeId);
|
||||
}
|
||||
|
||||
public boolean isSourceUnit() {
|
||||
if (isHeaderUnit())
|
||||
return isSourceContentType(contentTypeId);
|
||||
}
|
||||
|
||||
private static boolean isHeaderContentType(String contentType) {
|
||||
return CCorePlugin.CONTENT_TYPE_CHEADER.equals(contentType)
|
||||
|| CCorePlugin.CONTENT_TYPE_CXXHEADER.equals(contentType);
|
||||
}
|
||||
|
||||
private static boolean isSourceContentType(String contentType) {
|
||||
if (isHeaderContentType(contentType))
|
||||
return false;
|
||||
|
||||
return CCorePlugin.CONTENT_TYPE_CSOURCE.equals(contentTypeId)
|
||||
|| CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(contentTypeId)
|
||||
|| CCorePlugin.CONTENT_TYPE_ASMSOURCE.equals(contentTypeId)
|
||||
|| LanguageManager.getInstance().isContributedContentType(contentTypeId);
|
||||
return CCorePlugin.CONTENT_TYPE_CSOURCE.equals(contentType)
|
||||
|| CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(contentType)
|
||||
|| CCorePlugin.CONTENT_TYPE_ASMSOURCE.equals(contentType)
|
||||
|| LanguageManager.getInstance().isContributedContentType(contentType);
|
||||
}
|
||||
|
||||
public boolean isCLanguage() {
|
||||
|
@ -769,7 +778,10 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
|||
}
|
||||
|
||||
public IASTTranslationUnit getAST(IIndex index, int style, IProgressMonitor monitor) throws CoreException {
|
||||
ITranslationUnit configureWith = getSourceContextTU(index, style);
|
||||
IIndexFile[] contextToHeader = getContextToHeader(index, style);
|
||||
ITranslationUnit configureWith = getConfigureWith(contextToHeader);
|
||||
if (configureWith == this)
|
||||
contextToHeader= null;
|
||||
|
||||
IScannerInfo scanInfo= configureWith.getScannerInfo((style & AST_SKIP_IF_NO_BUILD_INFO) == 0);
|
||||
if (scanInfo == null) {
|
||||
|
@ -786,7 +798,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
|||
return null;
|
||||
}
|
||||
|
||||
IncludeFileContentProvider crf= getIncludeFileContentProvider(style, index, language.getLinkageID());
|
||||
IncludeFileContentProvider crf= getIncludeFileContentProvider(style, index, language.getLinkageID(), contextToHeader);
|
||||
int options= 0;
|
||||
if ((style & AST_SKIP_FUNCTION_BODIES) != 0) {
|
||||
options |= ILanguage.OPTION_SKIP_FUNCTION_BODIES;
|
||||
|
@ -812,7 +824,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
|||
return ast;
|
||||
}
|
||||
|
||||
private IncludeFileContentProvider getIncludeFileContentProvider(int style, IIndex index, int linkageID) {
|
||||
private IncludeFileContentProvider getIncludeFileContentProvider(int style, IIndex index, int linkageID, IIndexFile[] contextToHeader) {
|
||||
final ICProject cprj= getCProject();
|
||||
final ProjectIndexerInputAdapter pathResolver = new ProjectIndexerInputAdapter(cprj);
|
||||
IncludeFileContentProvider fileContentsProvider;
|
||||
|
@ -825,9 +837,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
|||
if (index != null && (style & AST_SKIP_INDEXED_HEADERS) != 0) {
|
||||
IndexBasedFileContentProvider ibcf= new IndexBasedFileContentProvider(index, pathResolver, linkageID,
|
||||
fileContentsProvider);
|
||||
if ((style & AST_CONFIGURE_USING_SOURCE_CONTEXT) != 0) {
|
||||
ibcf.setSupportFillGapFromContextToHeader(true);
|
||||
}
|
||||
ibcf.setContextToHeaderGap(contextToHeader);
|
||||
fileContentsProvider= ibcf;
|
||||
}
|
||||
|
||||
|
@ -839,52 +849,83 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
|||
return fileContentsProvider;
|
||||
}
|
||||
|
||||
private static int[] CTX_LINKAGES= {ILinkage.CPP_LINKAGE_ID, ILinkage.C_LINKAGE_ID};
|
||||
public ITranslationUnit getSourceContextTU(IIndex index, int style) {
|
||||
private static final int[] CTX_LINKAGES= { ILinkage.CPP_LINKAGE_ID, ILinkage.C_LINKAGE_ID };
|
||||
public IIndexFile[] getContextToHeader(IIndex index, int style) {
|
||||
if (index != null && (style & AST_CONFIGURE_USING_SOURCE_CONTEXT) != 0) {
|
||||
try {
|
||||
fLanguageOfContext= null;
|
||||
for (int element : CTX_LINKAGES) {
|
||||
IIndexFile context= null;
|
||||
final IIndexFileLocation ifl = IndexLocationFactory.getIFL(this);
|
||||
if (ifl != null) {
|
||||
IIndexFile indexFile= index.getFile(element, ifl);
|
||||
if (indexFile != null) {
|
||||
// bug 199412, when a source-file includes itself the context may recurse.
|
||||
HashSet<IIndexFile> visited= new HashSet<IIndexFile>();
|
||||
visited.add(indexFile);
|
||||
indexFile = getParsedInContext(indexFile);
|
||||
while (indexFile != null && visited.add(indexFile)) {
|
||||
context= indexFile;
|
||||
indexFile= getParsedInContext(indexFile);
|
||||
}
|
||||
}
|
||||
if (context != null) {
|
||||
ITranslationUnit tu= CoreModelUtil.findTranslationUnitForLocation(context.getLocation(), getCProject());
|
||||
if (tu != null && tu.isSourceUnit()) {
|
||||
return tu;
|
||||
final IIndexFileLocation ifl = IndexLocationFactory.getIFL(this);
|
||||
if (ifl != null) {
|
||||
IIndexFile best = null;
|
||||
IIndexFile contextOfBest = null;
|
||||
int bestScore= -1;
|
||||
// Find file variant that has the most content and preferably was parsed in
|
||||
// context of a source file.
|
||||
for (int linkageID : CTX_LINKAGES) {
|
||||
for (IIndexFile indexFile : index.getFiles(linkageID, ifl)) {
|
||||
int score= indexFile.getMacros().length * 2;
|
||||
IIndexFile context= getParsedInContext(indexFile);
|
||||
if (isSourceFile(context))
|
||||
score++;
|
||||
if (score > bestScore) {
|
||||
bestScore= score;
|
||||
best= indexFile;
|
||||
contextOfBest = context;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (best != null && contextOfBest != best) {
|
||||
return new IIndexFile[] { contextOfBest, best };
|
||||
}
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private IIndexFile getParsedInContext(IIndexFile indexFile)
|
||||
throws CoreException {
|
||||
IIndexInclude include= indexFile.getParsedInContext();
|
||||
if (include != null) {
|
||||
return include.getIncludedBy();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private IIndexFile getParsedInContext(IIndexFile indexFile) throws CoreException {
|
||||
HashSet<IIndexFile> visited= new HashSet<IIndexFile>();
|
||||
// Bug 199412, may recurse.
|
||||
while (visited.add(indexFile)) {
|
||||
IIndexInclude include= indexFile.getParsedInContext();
|
||||
if (include == null)
|
||||
break;
|
||||
indexFile = include.getIncludedBy();
|
||||
}
|
||||
return indexFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the given file was parsed in a context of a source file.
|
||||
* @throws CoreException
|
||||
*/
|
||||
private boolean isSourceFile(IIndexFile indexFile) throws CoreException {
|
||||
String path = indexFile.getLocation().getURI().getPath();
|
||||
IContentType cType = CCorePlugin.getContentType(getCProject().getProject(), path);
|
||||
if (cType == null)
|
||||
return false;
|
||||
|
||||
return isSourceContentType(cType.getId());
|
||||
}
|
||||
|
||||
private ITranslationUnit getConfigureWith(IIndexFile[] contextToHeader) throws CoreException {
|
||||
if (contextToHeader != null) {
|
||||
ITranslationUnit configureWith = CoreModelUtil.findTranslationUnitForLocation(
|
||||
contextToHeader[0].getLocation(), getCProject());
|
||||
if (configureWith != null)
|
||||
return configureWith;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public IASTCompletionNode getCompletionNode(IIndex index, int style, int offset) throws CoreException {
|
||||
ITranslationUnit configureWith= getSourceContextTU(index, style);
|
||||
IIndexFile[] contextToHeader = getContextToHeader(index, style);
|
||||
ITranslationUnit configureWith = getConfigureWith(contextToHeader);
|
||||
if (configureWith == this)
|
||||
contextToHeader= null;
|
||||
|
||||
IScannerInfo scanInfo = configureWith.getScannerInfo((style & ITranslationUnit.AST_SKIP_IF_NO_BUILD_INFO) == 0);
|
||||
if (scanInfo == null) {
|
||||
|
@ -896,7 +937,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
|||
ILanguage language= configureWith.getLanguage();
|
||||
fLanguageOfContext= language;
|
||||
if (language != null) {
|
||||
IncludeFileContentProvider crf= getIncludeFileContentProvider(style, index, language.getLinkageID());
|
||||
IncludeFileContentProvider crf= getIncludeFileContentProvider(style, index, language.getLinkageID(), contextToHeader);
|
||||
IASTCompletionNode result = language.getCompletionNode(fileContent, scanInfo, crf, index,
|
||||
ParserUtil.getParserLogService(), offset);
|
||||
if (result != null) {
|
||||
|
|
|
@ -50,4 +50,13 @@ public interface IASTFileLocation extends IASTNodeLocation {
|
|||
* @return int representing line number or <code>0</code> if not applicable
|
||||
*/
|
||||
public int getEndingLineNumber();
|
||||
|
||||
/**
|
||||
* Returns the inclusion statement that included this file, or <code>null</code> for
|
||||
* a top-level file.
|
||||
* Also <code>null</code> when the file location does not belong to an AST node, e.g.
|
||||
* if it is obtained from a name in the index.
|
||||
* @since 5.4
|
||||
*/
|
||||
public IASTPreprocessorIncludeStatement getContextInclusionStatement();
|
||||
}
|
||||
|
|
|
@ -6,20 +6,22 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* IBM - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast;
|
||||
|
||||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
|
||||
|
||||
/**
|
||||
* This interface represent a preprocessor #include statement.
|
||||
*
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface IASTPreprocessorIncludeStatement extends
|
||||
IASTPreprocessorStatement {
|
||||
|
||||
public interface IASTPreprocessorIncludeStatement extends IASTPreprocessorStatement, IFileNomination {
|
||||
/**
|
||||
* <code>INCLUDE_NAME</code> describes the relationship between an include directive and
|
||||
* it's name.
|
||||
|
@ -64,4 +66,33 @@ public interface IASTPreprocessorIncludeStatement extends
|
|||
* @since 5.1
|
||||
*/
|
||||
public boolean isResolvedByHeuristics();
|
||||
|
||||
/**
|
||||
* Returns the list of versions of the target file, each of which is
|
||||
* identified by its significant macros, that had been included
|
||||
* in this translation-unit prior to this statement.
|
||||
* @noreference This method is not intended to be referenced by clients.
|
||||
*/
|
||||
public ISignificantMacros[] getLoadedVersions();
|
||||
|
||||
/**
|
||||
* Returns a hash-code for the contents of the file included, or <code>0</code>
|
||||
* if the content has not been parsed.
|
||||
* @since 5.4
|
||||
*/
|
||||
public long getContentsHash();
|
||||
|
||||
/**
|
||||
* Returns true, if an attempt will be or has been made to create AST for the target
|
||||
* of this inclusion.
|
||||
* @since 5.4
|
||||
*/
|
||||
public boolean createsAST();
|
||||
|
||||
/**
|
||||
* Returns the file from the index that this include statement has pulled in, or <code>null</code>
|
||||
* if the include creates AST or is unresolved or skipped.
|
||||
* @since 5.4
|
||||
*/
|
||||
public IIndexFile getImportedIndexFile();
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.eclipse.cdt.core.dom.IName;
|
|||
import org.eclipse.cdt.core.index.IIndex;
|
||||
import org.eclipse.cdt.core.index.IIndexFileSet;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||
import org.eclipse.core.runtime.IAdaptable;
|
||||
|
||||
|
@ -28,7 +29,7 @@ import org.eclipse.core.runtime.IAdaptable;
|
|||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface IASTTranslationUnit extends IASTDeclarationListOwner, IAdaptable {
|
||||
public interface IASTTranslationUnit extends IASTDeclarationListOwner, IFileNomination, IAdaptable {
|
||||
|
||||
/**
|
||||
* <code>OWNED_DECLARATION</code> represents the relationship between an <code>IASTTranslationUnit</code> and
|
||||
|
@ -343,4 +344,16 @@ public interface IASTTranslationUnit extends IASTDeclarationListOwner, IAdaptabl
|
|||
* @since 5.3
|
||||
*/
|
||||
public ITranslationUnit getOriginatingTranslationUnit();
|
||||
|
||||
/**
|
||||
* @since 5.4
|
||||
* @noreference This method is not intended to be referenced by clients.
|
||||
*/
|
||||
public void setSignificantMacros(ISignificantMacros sigMacros);
|
||||
|
||||
/**
|
||||
* @since 5.4
|
||||
* @noreference This method is not intended to be referenced by clients.
|
||||
*/
|
||||
public void setPragmaOnceSemantics(boolean value);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011 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.core.dom.ast;
|
||||
|
||||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
* Interface for constructs that nominate a file for an AST:
|
||||
* {@link IASTTranslationUnit}, {@link IASTPreprocessorIncludeStatement}, {@link IIndexFile}.
|
||||
* @since 5.4
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
*/
|
||||
public interface IFileNomination {
|
||||
/**
|
||||
* Returns macros relevant to parsing of the file included by this include statement and their
|
||||
* definitions at the point of the include.
|
||||
* <p>
|
||||
* This method should only be called after the included file has been parsed. The method will
|
||||
* return {@link ISignificantMacros#NONE}</code> if it is called prematurely.
|
||||
* @throws CoreException
|
||||
*/
|
||||
public ISignificantMacros getSignificantMacros() throws CoreException;
|
||||
|
||||
/**
|
||||
* Returns whether pragma once semantics has been detected when parsing the translation unit.
|
||||
*/
|
||||
public boolean hasPragmaOnceSemantics() throws CoreException;
|
||||
}
|
|
@ -19,6 +19,7 @@ import java.util.regex.Pattern;
|
|||
import org.eclipse.cdt.core.dom.IName;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
|
@ -133,16 +134,53 @@ public interface IIndex {
|
|||
public long getLastWriteAccess();
|
||||
|
||||
/**
|
||||
* Returns the file-object for the given location and linkage or returns
|
||||
* <code>null</code> if the file was not indexed in this linkage.
|
||||
* Returns the file object for the given location and linkage or <code>null</code> if the file
|
||||
* was not indexed in this linkage.
|
||||
* <p>
|
||||
* When a header file is stored in the index in multiple variants for different sets of macro
|
||||
* definitions, this method will return an arbitrary one of these variants.
|
||||
* @param location an IIndexFileLocation representing the location of the file
|
||||
* @return the file in the index or <code>null</code>
|
||||
* @throws CoreException
|
||||
* @deprecated Use {@link #getFile(int, IIndexFileLocation, ISignificantMacros)} or
|
||||
* {@link #getFiles(int, IIndexFileLocation)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public IIndexFile getFile(int linkageID, IIndexFileLocation location) throws CoreException;
|
||||
|
||||
/**
|
||||
* Returns the file-objects for the given location in any linkage.
|
||||
* Returns the file for the given location, linkage, and significant macros
|
||||
* May return <code>null</code>, if no such file exists.
|
||||
*
|
||||
* @param linkageID the id of the linkage in which the file has been parsed.
|
||||
* @param location the IIndexFileLocation representing the location of the file
|
||||
* @param macroDictionary The names and definitions of the macros used to disambiguate between
|
||||
* variants of the file contents corresponding to different inclusion points.
|
||||
* @return the file for the location, or <code>null</code> if the file is not present in
|
||||
* the index
|
||||
* @throws CoreException
|
||||
* @since 5.4
|
||||
*/
|
||||
IIndexFile getFile(int linkageID, IIndexFileLocation location, ISignificantMacros significantMacros)
|
||||
throws CoreException;
|
||||
|
||||
/**
|
||||
* Returns the file objects for the given location and linkage.
|
||||
* Multiple files are returned when a header file is stored in the index in multiple variants
|
||||
* for different sets of macro definitions.
|
||||
* This method may only return files that are actually managed by this fragment.
|
||||
* This method returns files without content, also.
|
||||
*
|
||||
* @param linkageID the id of the linkage in which the file has been parsed.
|
||||
* @param location the IIndexFileLocation representing the location of the file
|
||||
* @return the files for the location and the linkage.
|
||||
* @throws CoreException
|
||||
* @since 5.4
|
||||
*/
|
||||
IIndexFile[] getFiles(int linkageID, IIndexFileLocation location) throws CoreException;
|
||||
|
||||
/**
|
||||
* Returns the file objects for the given location in any linkage.
|
||||
* @param location an IIndexFileLocation representing the location of the file
|
||||
* @return an array of file-objects.
|
||||
* @throws CoreException
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2010 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2006, 2011 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
|
||||
|
@ -8,10 +8,13 @@
|
|||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Andrew Ferguson (Symbian)
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.index;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IFileNomination;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
|
@ -22,7 +25,7 @@ import org.eclipse.core.runtime.CoreException;
|
|||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public interface IIndexFile {
|
||||
public interface IIndexFile extends IFileNomination {
|
||||
IIndexFile[] EMPTY_FILE_ARRAY = {};
|
||||
|
||||
/**
|
||||
|
@ -32,6 +35,13 @@ public interface IIndexFile {
|
|||
*/
|
||||
IIndexFileLocation getLocation() throws CoreException;
|
||||
|
||||
/**
|
||||
* Returns the significant macros for this version of the file.
|
||||
* @throws CoreException
|
||||
* @since 5.4
|
||||
*/
|
||||
ISignificantMacros getSignificantMacros() throws CoreException;
|
||||
|
||||
/**
|
||||
* Returns all includes found in this file.
|
||||
* @return an array of all includes found in this file
|
||||
|
@ -69,11 +79,9 @@ public interface IIndexFile {
|
|||
long getContentsHash() throws CoreException;
|
||||
|
||||
/**
|
||||
* Returns the hash-code of the scanner configuration that was used to parse the file.
|
||||
* <code>0</code> will be returned in case the hash-code is unknown.
|
||||
* @return the hash-code of the scanner configuration or <code>0</code>.
|
||||
* @throws CoreException
|
||||
* @deprecated Returns 0.
|
||||
*/
|
||||
@Deprecated
|
||||
int getScannerConfigurationHashcode() throws CoreException;
|
||||
|
||||
/**
|
||||
|
@ -93,7 +101,14 @@ public interface IIndexFile {
|
|||
* Returns the include that was used to parse this file, may be <code>null</code>.
|
||||
*/
|
||||
IIndexInclude getParsedInContext() throws CoreException;
|
||||
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the file is a header with #pragma once statement or an include
|
||||
* guard, or if it is a source file.
|
||||
* @since 5.4
|
||||
*/
|
||||
public boolean hasPragmaOnceSemantics() throws CoreException;
|
||||
|
||||
/**
|
||||
* Returns the id of the linkage this file was parsed in.
|
||||
* @since 5.0
|
||||
|
|
|
@ -54,4 +54,10 @@ public interface IIndexFileSet {
|
|||
* @noreference This method is not intended to be referenced by clients.
|
||||
*/
|
||||
void add(IIndexFile indexFile);
|
||||
|
||||
/**
|
||||
* Removes a file from this set.
|
||||
* @noreference This method is not intended to be referenced by clients.
|
||||
*/
|
||||
void remove(IIndexFile indexFile);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2008 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2006, 2011 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
|
||||
|
@ -10,12 +10,39 @@
|
|||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.core.parser;
|
||||
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ParserLogServiceWrapper;
|
||||
|
||||
public abstract class AbstractParserLogService implements IParserLogService {
|
||||
|
||||
/**
|
||||
* @since 5.4
|
||||
*/
|
||||
public static AbstractParserLogService convert(IParserLogService log) {
|
||||
if (log instanceof AbstractParserLogService)
|
||||
return (AbstractParserLogService) log;
|
||||
return new ParserLogServiceWrapper(log);
|
||||
}
|
||||
|
||||
public void traceLog(String message) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param traceOption an option as defined in the .options file.
|
||||
* @since 5.4
|
||||
*/
|
||||
public boolean isTracing(String traceOption) {
|
||||
return isTracing();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param traceOption an option as defined in the .options file.
|
||||
* @since 5.4
|
||||
*/
|
||||
public void traceLog(String traceOption, String message) {
|
||||
traceLog(message);
|
||||
}
|
||||
|
||||
public void errorLog(String message) {
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2010 IBM Corporation and others.
|
||||
* Copyright (c) 2000, 2011 IBM Corporation 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
|
||||
|
@ -323,6 +323,12 @@ public interface IProblem
|
|||
*/
|
||||
public final static int PREPROCESSOR_POUND_WARNING = PREPROCESSOR_RELATED | 0x00E;
|
||||
|
||||
/**
|
||||
* Maximum inclusion depth is exceeded
|
||||
* @since 5.4
|
||||
*/
|
||||
public final static int PREPROCESSOR_EXCEEDS_MAXIMUM_INCLUSION_DEPTH= PREPROCESSOR_RELATED | 0x00F;
|
||||
|
||||
/**
|
||||
* Syntax error, detected by the parser.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011 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.core.parser;
|
||||
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.SignificantMacros;
|
||||
|
||||
/**
|
||||
* Significant macros describe the conditions under which the preprocessor selects
|
||||
* the same active code branches in a file.
|
||||
* @since 5.4
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface ISignificantMacros {
|
||||
interface IVisitor {
|
||||
/**
|
||||
* Returns whether to continue the visit.
|
||||
*/
|
||||
boolean visitDefined(char[] macro);
|
||||
|
||||
/**
|
||||
* Returns whether to continue the visit.
|
||||
*/
|
||||
boolean visitUndefined(char[] macro);
|
||||
|
||||
/**
|
||||
* Returns whether to continue the visit.
|
||||
*/
|
||||
boolean visitValue(char[] macro, char[] value);
|
||||
}
|
||||
|
||||
ISignificantMacros NONE = new SignificantMacros(CharArrayUtils.EMPTY);
|
||||
|
||||
/**
|
||||
* Returns whether visitor continued its visit till the end.
|
||||
*/
|
||||
boolean accept(IVisitor visitor);
|
||||
|
||||
/**
|
||||
* Returns the significant macros encoded as an array of characters.
|
||||
*/
|
||||
char[] encode();
|
||||
}
|
|
@ -19,8 +19,8 @@ import java.util.List;
|
|||
/**
|
||||
* @author Doug Schaefer
|
||||
*/
|
||||
public class CharArrayObjectMap extends CharTable {
|
||||
public static final CharArrayObjectMap EMPTY_MAP = new CharArrayObjectMap(0) {
|
||||
public class CharArrayObjectMap <T> extends CharTable {
|
||||
public static final CharArrayObjectMap<Object> EMPTY_MAP = new CharArrayObjectMap<Object>(0) {
|
||||
@Override
|
||||
public Object clone() { return this; }
|
||||
@Override
|
||||
|
@ -30,6 +30,14 @@ public class CharArrayObjectMap extends CharTable {
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @since 5.4
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> CharArrayObjectMap<T> emptyMap() {
|
||||
return (CharArrayObjectMap<T>) EMPTY_MAP;
|
||||
}
|
||||
|
||||
|
||||
private Object[] valueTable;
|
||||
|
||||
|
@ -38,40 +46,44 @@ public class CharArrayObjectMap extends CharTable {
|
|||
valueTable = new Object[capacity()];
|
||||
}
|
||||
|
||||
public Object put(char[] key, int start, int length, Object value) {
|
||||
public T put(char[] key, int start, int length, T value) {
|
||||
int i = addIndex(key, start, length);
|
||||
Object oldvalue = valueTable[i];
|
||||
@SuppressWarnings("unchecked")
|
||||
T oldvalue = (T) valueTable[i];
|
||||
valueTable[i] = value;
|
||||
return oldvalue;
|
||||
}
|
||||
|
||||
final public Object put(char[] key, Object value) {
|
||||
final public T put(char[] key, T value) {
|
||||
return put(key, 0, key.length, value);
|
||||
}
|
||||
|
||||
final public Object get(char[] key, int start, int length) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final public T get(char[] key, int start, int length) {
|
||||
int i = lookup(key, start, length);
|
||||
if (i >= 0)
|
||||
return valueTable[i];
|
||||
return (T) valueTable[i];
|
||||
return null;
|
||||
}
|
||||
|
||||
final public Object get(char[] key) {
|
||||
final public T get(char[] key) {
|
||||
return get(key, 0, key.length);
|
||||
}
|
||||
|
||||
final public Object getAt(int i) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final public T getAt(int i) {
|
||||
if (i < 0 || i > currEntry)
|
||||
return null;
|
||||
return valueTable[i];
|
||||
return (T) valueTable[i];
|
||||
}
|
||||
|
||||
final public Object remove(char[] key, int start, int length) {
|
||||
final public T remove(char[] key, int start, int length) {
|
||||
int i = lookup(key, start, length);
|
||||
if (i < 0)
|
||||
return null;
|
||||
|
||||
Object value = valueTable[i];
|
||||
@SuppressWarnings("unchecked")
|
||||
T value = (T) valueTable[i];
|
||||
|
||||
if (i < currEntry)
|
||||
System.arraycopy(valueTable, i + 1, valueTable, i, currEntry - i);
|
||||
|
@ -85,7 +97,8 @@ public class CharArrayObjectMap extends CharTable {
|
|||
|
||||
@Override
|
||||
public Object clone() {
|
||||
CharArrayObjectMap newTable = (CharArrayObjectMap) super.clone();
|
||||
@SuppressWarnings("unchecked")
|
||||
CharArrayObjectMap<T> newTable = (CharArrayObjectMap<T>) super.clone();
|
||||
newTable.valueTable = new Object[capacity()];
|
||||
System.arraycopy(valueTable, 0, newTable.valueTable, 0, valueTable.length);
|
||||
|
||||
|
@ -149,4 +162,5 @@ public class CharArrayObjectMap extends CharTable {
|
|||
System.arraycopy(valueTable, 0, values, 0, values.length);
|
||||
return values;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2010 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2006, 2011 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
|
||||
|
@ -10,6 +10,7 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
|
@ -71,7 +72,7 @@ public class ASTInternal {
|
|||
}
|
||||
}
|
||||
|
||||
public static String getDeclaredInSourceFileOnly(IBinding binding, boolean requireDefinition, PDOMBinding nonLocal) {
|
||||
public static IASTNode getDeclaredInSourceFileOnly(IBinding binding, boolean requireDefinition, PDOMBinding nonLocal) {
|
||||
IASTNode[] decls;
|
||||
IASTNode def;
|
||||
if (binding instanceof ICPPInternalBinding) {
|
||||
|
@ -88,18 +89,19 @@ public class ASTInternal {
|
|||
if (requireDefinition && def == null) {
|
||||
return null;
|
||||
}
|
||||
String filePath= null;
|
||||
IASTNode result= null;
|
||||
if (def != null) {
|
||||
if ((filePath= isPartOfSource(filePath, def)) == null) {
|
||||
if (!isPartOfSource(def))
|
||||
return null;
|
||||
}
|
||||
result= def;
|
||||
}
|
||||
if (decls != null) {
|
||||
for (final IASTNode node : decls) {
|
||||
if (node != null) {
|
||||
if ((filePath= isPartOfSource(filePath, node)) == null) {
|
||||
if (!isPartOfSource(node))
|
||||
return null;
|
||||
if ((result= resolveConflict(result, node)) == null)
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -110,23 +112,29 @@ public class ASTInternal {
|
|||
} catch (CoreException e) {
|
||||
}
|
||||
}
|
||||
return filePath;
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String isPartOfSource(String filePath, IASTNode decl) {
|
||||
if (decl instanceof ASTNode) {
|
||||
if (((ASTNode) decl).isPartOfSourceFile()) {
|
||||
if (filePath == null)
|
||||
return decl.getContainingFilename();
|
||||
|
||||
if (filePath.equals(decl.getContainingFilename()))
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
private static boolean isPartOfSource(IASTNode decl) {
|
||||
return decl instanceof ASTNode && ((ASTNode) decl).isPartOfSourceFile();
|
||||
}
|
||||
|
||||
public static String getDeclaredInOneFileOnly(IBinding binding) {
|
||||
private static IASTNode resolveConflict(IASTNode n1, IASTNode n2) {
|
||||
if (n1 == null)
|
||||
return n2;
|
||||
|
||||
IASTFileLocation loc1= n1.getFileLocation();
|
||||
if (loc1 == null)
|
||||
return n2;
|
||||
|
||||
IASTFileLocation loc2= n2.getFileLocation();
|
||||
if (loc2 != null && loc1.getContextInclusionStatement() != loc2.getContextInclusionStatement())
|
||||
return null;
|
||||
|
||||
return n1;
|
||||
}
|
||||
|
||||
public static IASTNode getDeclaredInOneFileOnly(IBinding binding) {
|
||||
IASTNode[] decls;
|
||||
IASTNode def;
|
||||
if (binding instanceof ICPPInternalBinding) {
|
||||
|
@ -140,23 +148,19 @@ public class ASTInternal {
|
|||
} else {
|
||||
return null;
|
||||
}
|
||||
String filePath= null;
|
||||
IASTNode result= null;
|
||||
if (def != null) {
|
||||
filePath= def.getContainingFilename();
|
||||
result= def;
|
||||
}
|
||||
if (decls != null) {
|
||||
for (final IASTNode node : decls) {
|
||||
if (node != null) {
|
||||
final String fn = node.getContainingFilename();
|
||||
if (filePath == null) {
|
||||
filePath= fn;
|
||||
} else if (!filePath.equals(fn)) {
|
||||
if ((result= resolveConflict(result, node)) == null)
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return filePath;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void addDeclaration(IBinding b, IASTNode declaration) {
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.eclipse.cdt.core.index.IIndex;
|
|||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
import org.eclipse.cdt.core.index.IIndexFileSet;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||
import org.eclipse.cdt.internal.core.index.IndexBasedFileContentProvider;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver;
|
||||
|
@ -71,6 +72,9 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat
|
|||
private INodeFactory fNodeFactory;
|
||||
private boolean fForContentAssist;
|
||||
private ITranslationUnit fOriginatingTranslationUnit;
|
||||
private ISignificantMacros fSignificantMacros= ISignificantMacros.NONE;
|
||||
private boolean fPragmaOnceSemantics;
|
||||
|
||||
/** The semaphore controlling exclusive access to the AST. */
|
||||
private final Semaphore fSemaphore= new Semaphore(1);
|
||||
|
||||
|
@ -367,6 +371,7 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat
|
|||
if (fIndexFileSet != null) {
|
||||
List<IIndexFile> files= fileContent.getFilesIncluded();
|
||||
for (IIndexFile indexFile : files) {
|
||||
fASTFileSet.remove(indexFile);
|
||||
fIndexFileSet.add(indexFile);
|
||||
}
|
||||
}
|
||||
|
@ -376,13 +381,14 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat
|
|||
return fIndexFileSet;
|
||||
}
|
||||
|
||||
public void replacingFile(InternalFileContentProvider provider, InternalFileContent fc) {
|
||||
public void parsingFile(InternalFileContentProvider provider, InternalFileContent fc) {
|
||||
if (fASTFileSet != null) {
|
||||
if (provider instanceof IndexBasedFileContentProvider) {
|
||||
try {
|
||||
IIndexFile file= ((IndexBasedFileContentProvider) provider).findIndexFile(fc);
|
||||
if (file != null) {
|
||||
fASTFileSet.add(file);
|
||||
for (IIndexFile file : ((IndexBasedFileContentProvider) provider).findIndexFiles(fc)) {
|
||||
if (!fIndexFileSet.contains(file)) {
|
||||
fASTFileSet.add(file);
|
||||
}
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
// Ignore, tracking of replaced files fails.
|
||||
|
@ -450,6 +456,25 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat
|
|||
this.fOriginatingTranslationUnit = tu;
|
||||
}
|
||||
|
||||
public ISignificantMacros getSignificantMacros() {
|
||||
return fSignificantMacros;
|
||||
}
|
||||
|
||||
public void setSignificantMacros(ISignificantMacros sigMacros) {
|
||||
assertNotFrozen();
|
||||
if (sigMacros != null)
|
||||
fSignificantMacros= sigMacros;
|
||||
}
|
||||
|
||||
public boolean hasPragmaOnceSemantics() {
|
||||
return fPragmaOnceSemantics;
|
||||
}
|
||||
|
||||
public void setPragmaOnceSemantics(boolean value) {
|
||||
assertNotFrozen();
|
||||
fPragmaOnceSemantics= value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts exclusive access
|
||||
* @throws InterruptedException
|
||||
|
|
|
@ -200,7 +200,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
|
||||
private final INodeFactory nodeFactory;
|
||||
private boolean fActiveCode= true;
|
||||
private int fEndOffset= -1;
|
||||
|
||||
protected AbstractGNUSourceCodeParser(IScanner scanner,
|
||||
IParserLogService logService, ParserMode parserMode,
|
||||
|
@ -435,7 +434,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
try {
|
||||
return LA(i);
|
||||
} catch (EndOfFileException e) {
|
||||
fEndOffset= e.getEndOffset();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -456,7 +454,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
try {
|
||||
return LT(i);
|
||||
} catch (EndOfFileException e) {
|
||||
fEndOffset= e.getEndOffset();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1281,9 +1278,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
protected void parseTranslationUnit() {
|
||||
final IASTTranslationUnit tu= getTranslationUnit();
|
||||
declarationList(tu, DeclarationOptions.GLOBAL, false, 0);
|
||||
// Bug 3033152: getEndOffset() is computed off the last node and ignores trailing macros.
|
||||
final int length= Math.max(getEndOffset(), fEndOffset);
|
||||
((ASTNode) tu).setLength(length);
|
||||
}
|
||||
|
||||
protected final void declarationListInBraces(final IASTDeclarationListOwner tu, int offset, DeclarationOptions options) throws EndOfFileException, BacktrackException {
|
||||
|
@ -1356,7 +1350,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
IASTDeclaration declaration= skipProblemDeclaration(offset);
|
||||
addDeclaration(tu, declaration, active);
|
||||
if (!e.endsInactiveCode()) {
|
||||
fEndOffset= e.getEndOffset();
|
||||
break;
|
||||
}
|
||||
} finally {
|
||||
|
|
|
@ -227,7 +227,7 @@ public class TemplateArgumentDeduction {
|
|||
ICPPTemplateInstance pInst = (ICPPTemplateInstance) pcheck;
|
||||
ICPPClassTemplate pTemplate= getPrimaryTemplate(pInst);
|
||||
if (pTemplate != null) {
|
||||
ICPPClassType aInst= findBaseInstance((ICPPClassType) argcheck, pTemplate, CPPSemantics.MAX_INHERITANCE_DEPTH);
|
||||
ICPPClassType aInst= findBaseInstance((ICPPClassType) argcheck, pTemplate);
|
||||
if (aInst != null && aInst != argcheck) {
|
||||
par= pcheck;
|
||||
arg= aInst;
|
||||
|
@ -467,10 +467,15 @@ public class TemplateArgumentDeduction {
|
|||
return result.toArray(new ICPPTemplateArgument[result.size()]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 14.8.2.1.3 If P is a class and has the form template-id, then A can be a derived class of the deduced A.
|
||||
*/
|
||||
private static ICPPClassType findBaseInstance(ICPPClassType a, ICPPClassTemplate pTemplate, int maxdepth) throws DOMException {
|
||||
private static ICPPClassType findBaseInstance(ICPPClassType a, ICPPClassTemplate pTemplate) throws DOMException {
|
||||
return findBaseInstance(a, pTemplate, CPPSemantics.MAX_INHERITANCE_DEPTH, new HashSet<Object>());
|
||||
}
|
||||
|
||||
private static ICPPClassType findBaseInstance(ICPPClassType a, ICPPClassTemplate pTemplate, int maxdepth, HashSet<Object> handled) throws DOMException {
|
||||
if (a instanceof ICPPTemplateInstance) {
|
||||
final ICPPTemplateInstance inst = (ICPPTemplateInstance) a;
|
||||
ICPPClassTemplate tmpl= getPrimaryTemplate(inst);
|
||||
|
@ -480,8 +485,8 @@ public class TemplateArgumentDeduction {
|
|||
if (maxdepth-- > 0) {
|
||||
for (ICPPBase cppBase : a.getBases()) {
|
||||
IBinding base= cppBase.getBaseClass();
|
||||
if (base instanceof ICPPClassType) {
|
||||
final ICPPClassType inst= findBaseInstance((ICPPClassType) base, pTemplate, maxdepth);
|
||||
if (base instanceof ICPPClassType && handled.add(base)) {
|
||||
final ICPPClassType inst= findBaseInstance((ICPPClassType) base, pTemplate, maxdepth, handled);
|
||||
if (inst != null)
|
||||
return inst;
|
||||
}
|
||||
|
|
|
@ -17,13 +17,13 @@ package org.eclipse.cdt.internal.core.index;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.BitSet;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
|
@ -42,6 +42,7 @@ import org.eclipse.cdt.core.index.IIndexInclude;
|
|||
import org.eclipse.cdt.core.index.IIndexMacro;
|
||||
import org.eclipse.cdt.core.index.IIndexName;
|
||||
import org.eclipse.cdt.core.index.IndexFilter;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.internal.core.dom.Linkage;
|
||||
import org.eclipse.cdt.internal.core.index.composite.CompositingNotImplementedError;
|
||||
import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
|
||||
|
@ -208,6 +209,7 @@ public class CIndex implements IIndex {
|
|||
return findNames(binding, FIND_REFERENCES);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public IIndexFile getFile(int linkageID, IIndexFileLocation location) throws CoreException {
|
||||
for (int i = 0; i < fPrimaryFragmentCount; i++) {
|
||||
IIndexFragmentFile candidate= fFragments[i].getFile(linkageID, location);
|
||||
|
@ -218,19 +220,53 @@ public class CIndex implements IIndex {
|
|||
return null;
|
||||
}
|
||||
|
||||
public IIndexFile getFile(int linkageID, IIndexFileLocation location,
|
||||
ISignificantMacros significantMacros) throws CoreException {
|
||||
for (int i = 0; i < fPrimaryFragmentCount; i++) {
|
||||
IIndexFragmentFile candidate= fFragments[i].getFile(linkageID, location, significantMacros);
|
||||
if (candidate != null && candidate.hasContent()) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public IIndexFile[] getFiles(int linkageID, IIndexFileLocation location) throws CoreException {
|
||||
if (location == null) {
|
||||
return IIndexFile.EMPTY_FILE_ARRAY;
|
||||
}
|
||||
Set<ISignificantMacros> handled = new HashSet<ISignificantMacros>();
|
||||
ArrayList<IIndexFragmentFile> result= new ArrayList<IIndexFragmentFile>();
|
||||
for (int i = 0; i < fPrimaryFragmentCount; i++) {
|
||||
IIndexFragmentFile[] candidates= fFragments[i].getFiles(linkageID, location);
|
||||
for (IIndexFragmentFile candidate : candidates) {
|
||||
if (candidate.hasContent()) {
|
||||
ISignificantMacros macroKey = candidate.getSignificantMacros();
|
||||
if (handled.add(macroKey)) {
|
||||
result.add(candidate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result.isEmpty()) {
|
||||
return IIndexFile.EMPTY_FILE_ARRAY;
|
||||
}
|
||||
return result.toArray(new IIndexFile[result.size()]);
|
||||
}
|
||||
|
||||
public IIndexFile[] getFiles(IIndexFileLocation location) throws CoreException {
|
||||
if (location == null) {
|
||||
return IIndexFile.EMPTY_FILE_ARRAY;
|
||||
}
|
||||
Set<FileContentKey> keys = new HashSet<FileContentKey>();
|
||||
ArrayList<IIndexFragmentFile> result= new ArrayList<IIndexFragmentFile>();
|
||||
BitSet linkages= new BitSet();
|
||||
for (int i = 0; i < fPrimaryFragmentCount; i++) {
|
||||
IIndexFragmentFile[] candidates= fFragments[i].getFiles(location);
|
||||
for (IIndexFragmentFile candidate : candidates) {
|
||||
int linkage= candidate.getLinkageID();
|
||||
if (!linkages.get(linkage) && candidate.hasContent()) {
|
||||
result.add(candidate);
|
||||
linkages.set(linkage);
|
||||
if (candidate.hasContent()) {
|
||||
if (keys.add(new FileContentKey(candidate.getLinkageID(), candidate.getLocation(), candidate.getSignificantMacros()))) {
|
||||
result.add(candidate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -241,16 +277,16 @@ public class CIndex implements IIndex {
|
|||
}
|
||||
|
||||
public IIndexFile resolveInclude(IIndexInclude include) throws CoreException {
|
||||
if (!include.isResolved()) {
|
||||
return null;
|
||||
}
|
||||
IIndexFragmentInclude fragmentInclude = (IIndexFragmentInclude) include;
|
||||
IIndexFragmentFile result= fragmentInclude.getIncludes();
|
||||
if (result != null && result.hasContent()) {
|
||||
if (result == null)
|
||||
return null;
|
||||
|
||||
if (result.hasContent()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return getFile(include.getIncludedBy().getLinkageID(), include.getIncludesLocation());
|
||||
return getFile(result.getLinkageID(), result.getLocation(), result.getSignificantMacros());
|
||||
}
|
||||
|
||||
public IIndexInclude[] findIncludedBy(IIndexFile file) throws CoreException {
|
||||
|
@ -259,22 +295,25 @@ public class CIndex implements IIndex {
|
|||
|
||||
public IIndexInclude[] findIncludedBy(IIndexFile file, int depth) throws CoreException {
|
||||
List<IIndexInclude> result= new ArrayList<IIndexInclude>();
|
||||
findIncludedBy(Collections.singletonList(file), result, depth, new HashSet<IIndexFileLocation>());
|
||||
findIncludedBy(file.getLinkageID(), Collections.singletonList(file), result, depth,
|
||||
new HashSet<FileContentKey>());
|
||||
return result.toArray(new IIndexInclude[result.size()]);
|
||||
}
|
||||
|
||||
public void findIncludedBy(List<IIndexFile> in, List<IIndexInclude> out, int depth,
|
||||
HashSet<IIndexFileLocation> handled) throws CoreException {
|
||||
public void findIncludedBy(int linkageID, List<IIndexFile> in, List<IIndexInclude> out, int depth,
|
||||
HashSet<FileContentKey> handled) throws CoreException {
|
||||
List<IIndexFile> nextLevel= depth != 0 ? new LinkedList<IIndexFile>() : null;
|
||||
for (IIndexFile iIndexFile : in) {
|
||||
IIndexFragmentFile file = (IIndexFragmentFile) iIndexFile;
|
||||
for (int j = 0; j < fPrimaryFragmentCount; j++) {
|
||||
IIndexInclude[] includedBy= fFragments[j].findIncludedBy(file);
|
||||
for (IIndexInclude include : includedBy) {
|
||||
if (handled.add(include.getIncludedByLocation())) {
|
||||
final IIndexFile includer = include.getIncludedBy();
|
||||
FileContentKey key= new FileContentKey(linkageID, includer.getLocation(), includer.getSignificantMacros());
|
||||
if (handled.add(key)) {
|
||||
out.add(include);
|
||||
if (nextLevel != null) {
|
||||
nextLevel.add(include.getIncludedBy());
|
||||
nextLevel.add(includer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -286,10 +325,9 @@ public class CIndex implements IIndex {
|
|||
if (depth > 0) {
|
||||
depth--;
|
||||
}
|
||||
findIncludedBy(nextLevel, out, depth, handled);
|
||||
findIncludedBy(linkageID, nextLevel, out, depth, handled);
|
||||
}
|
||||
|
||||
|
||||
public IIndexInclude[] findIncludes(IIndexFile file) throws CoreException {
|
||||
return findIncludes(file, 0);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.eclipse.cdt.core.index.IIndexInclude;
|
|||
import org.eclipse.cdt.core.index.IIndexMacro;
|
||||
import org.eclipse.cdt.core.index.IIndexName;
|
||||
import org.eclipse.cdt.core.index.IndexFilter;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
|
@ -54,10 +55,20 @@ final public class EmptyCIndex implements IIndex {
|
|||
return IIndexFragmentName.EMPTY_NAME_ARRAY;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public IIndexFile getFile(int linkageID, IIndexFileLocation location) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public IIndexFile getFile(int linkageID, IIndexFileLocation location,
|
||||
ISignificantMacros significantFiles) throws CoreException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public IIndexFile[] getFiles(int linkageID, IIndexFileLocation location) throws CoreException {
|
||||
return IIndexFile.EMPTY_FILE_ARRAY;
|
||||
}
|
||||
|
||||
public IIndexFile[] getFiles(IIndexFileLocation location) {
|
||||
return IIndexFile.EMPTY_FILE_ARRAY;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011 Google, 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:
|
||||
* Sergey Prigogin (Google) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.index;
|
||||
|
||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
|
||||
/**
|
||||
* A key that uniquely determines the preprocessed contents of a file.
|
||||
*/
|
||||
public class FileContentKey {
|
||||
private final int linkageID;
|
||||
private final IIndexFileLocation location;
|
||||
private final ISignificantMacros significantMacros;
|
||||
|
||||
/**
|
||||
* Creates a file content key.
|
||||
* @param location the file location.
|
||||
*/
|
||||
public FileContentKey(int linkageID, IIndexFileLocation location, ISignificantMacros sigMacros) {
|
||||
this.linkageID= linkageID;
|
||||
this.location = location;
|
||||
this.significantMacros = sigMacros;
|
||||
}
|
||||
|
||||
public int getLinkageID() {
|
||||
return linkageID;
|
||||
}
|
||||
|
||||
public IIndexFileLocation getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public ISignificantMacros getSignificantMacros() {
|
||||
return significantMacros;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (linkageID + location.hashCode() * 31) * 31 + significantMacros.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
FileContentKey other = (FileContentKey) obj;
|
||||
if (linkageID != other.linkageID)
|
||||
return false;
|
||||
|
||||
if (!location.equals(other.location))
|
||||
return false;
|
||||
|
||||
if (!significantMacros.equals(other.significantMacros))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("nls")
|
||||
@Override
|
||||
public String toString() {
|
||||
return linkageID + ": " + location.getURI().toString() + "[" + significantMacros.hashCode() + "]";
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@ import org.eclipse.cdt.core.index.IIndexFileLocation;
|
|||
import org.eclipse.cdt.core.index.IIndexLinkage;
|
||||
import org.eclipse.cdt.core.index.IIndexMacro;
|
||||
import org.eclipse.cdt.core.index.IndexFilter;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
|
@ -92,14 +93,55 @@ public interface IIndexFragment {
|
|||
* May return <code>null</code>, if no such file exists.
|
||||
* This method may only return files that are actually managed by this fragment.
|
||||
* This method returns files without content, also.
|
||||
* <p>
|
||||
* When a header file is stored in the index in multiple variants for different sets of macro
|
||||
* definitions, this method will return an arbitrary one of these variants.
|
||||
*
|
||||
* @param linkageID the id of the linkage in which the file has been parsed.
|
||||
* @param location the IIndexFileLocation representing the location of the file
|
||||
* @return the file for the location, or <code>null</code> if the file is not present in
|
||||
* the index
|
||||
* @throws CoreException
|
||||
* @deprecated Use {@link #getFile(int, IIndexFileLocation, ISignificantMacros)} or
|
||||
* {@link #getFiles(int, IIndexFileLocation)}.
|
||||
*/
|
||||
@Deprecated
|
||||
IIndexFragmentFile getFile(int linkageID, IIndexFileLocation location) throws CoreException;
|
||||
|
||||
/**
|
||||
* Returns the file for the given location, linkage, and a set of macro definitions.
|
||||
* May return <code>null</code>, if no such file exists.
|
||||
* This method may only return files that are actually managed by this fragment.
|
||||
* This method returns files without content, also.
|
||||
*
|
||||
* @param linkageID the id of the linkage in which the file has been parsed.
|
||||
* @param location the IIndexFileLocation representing the location of the file
|
||||
* @param macroDictionary The names and definitions of the macros used to disambiguate between
|
||||
* variants of the file contents corresponding to different inclusion points.
|
||||
* @return the file for the location, or <code>null</code> if the file is not present in
|
||||
* the index
|
||||
* @throws CoreException
|
||||
*/
|
||||
IIndexFragmentFile getFile(int linkageID, IIndexFileLocation location,
|
||||
ISignificantMacros significantMacros) throws CoreException;
|
||||
|
||||
/**
|
||||
* Returns the files for the given location and linkage.
|
||||
* Multiple files are returned when a header file is stored in the index in multiple variants
|
||||
* for different sets of macro definitions.
|
||||
* This method may only return files that are actually managed by this fragment.
|
||||
* This method returns files without content, also.
|
||||
* <p>
|
||||
* When a header file is stored in the index in multiple variants for different sets of macro
|
||||
* definitions, this method will return an arbitrary one of these variants.
|
||||
*
|
||||
* @param linkageID the id of the linkage in which the file has been parsed.
|
||||
* @param location the IIndexFileLocation representing the location of the file
|
||||
* @return the files for the location and the linkage.
|
||||
* @throws CoreException
|
||||
*/
|
||||
IIndexFragmentFile[] getFiles(int linkageID, IIndexFileLocation location) throws CoreException;
|
||||
|
||||
/**
|
||||
* Returns the files in all linkages for the given location.
|
||||
* This method may only return files that are actually managed by this fragment.
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2010 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2006, 2011 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
|
||||
* Andrew Ferguson (Symbian)
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Andrew Ferguson (Symbian)
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.core.index;
|
||||
|
||||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
|
@ -33,19 +33,18 @@ public interface IIndexFragmentFile extends IIndexFile {
|
|||
*/
|
||||
void setContentsHash(long hash) throws CoreException;
|
||||
|
||||
/**
|
||||
* Sets the hash-code of the scanner configuration.
|
||||
* @param hashcode a hash-code or <code>0</code> if it is unknown.
|
||||
* @throws CoreException
|
||||
*/
|
||||
void setScannerConfigurationHashcode(int hashcode) throws CoreException;
|
||||
|
||||
/**
|
||||
* Sets the hash-code of the file encoding.
|
||||
* @param hashcode a hash-code or <code>0</code> if it is unknown.
|
||||
*/
|
||||
void setEncodingHashcode(int hashcode) throws CoreException;
|
||||
|
||||
/**
|
||||
* Sets the flag that determines whether the file is a header with #pragma once statement
|
||||
* or an include guard, or it is a source file and parsed only once because of that.
|
||||
*/
|
||||
void setPragmaOnceSemantics(boolean value) throws CoreException;
|
||||
|
||||
/**
|
||||
* Returns whether this file contains content in its
|
||||
* associated fragment. Files without content are inserted to track includes.
|
||||
|
@ -56,4 +55,16 @@ public interface IIndexFragmentFile extends IIndexFile {
|
|||
* Returns the id of the linkage this file belongs to.
|
||||
*/
|
||||
int getLinkageID() throws CoreException;
|
||||
|
||||
/**
|
||||
* Changes the inclusions pointing to 'source' to point to this file, instead.
|
||||
* The file 'source' must belong to the same fragment as this file.
|
||||
*/
|
||||
void transferIncluders(IIndexFragmentFile source) throws CoreException;
|
||||
|
||||
/**
|
||||
* Changes the inclusion from the context of 'source' to point to this file, instead.
|
||||
* The file 'source' must belong to the same fragment as this file.
|
||||
*/
|
||||
void transferContext(IIndexFragmentFile source) throws CoreException;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,11 @@ public interface IIndexFragmentFileSet {
|
|||
*/
|
||||
void add(IIndexFragmentFile fragFile);
|
||||
|
||||
/**
|
||||
* Removes the fragment file from the file-set.
|
||||
*/
|
||||
void remove(IIndexFragmentFile fragFile);
|
||||
|
||||
/**
|
||||
* Returns whether the file set contains the given file.
|
||||
*/
|
||||
|
|
|
@ -6,20 +6,19 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Andrew Ferguson (Symbian)
|
||||
* Sergey Prigogin (Google)
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Andrew Ferguson (Symbian)
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.index;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
|
||||
import org.eclipse.cdt.core.index.IIndex;
|
||||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver;
|
||||
import org.eclipse.cdt.internal.core.pdom.YieldableIndexLock;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
@ -33,10 +32,19 @@ import org.eclipse.core.runtime.CoreException;
|
|||
public interface IWritableIndex extends IIndex {
|
||||
|
||||
static class IncludeInformation {
|
||||
public IASTPreprocessorIncludeStatement fStatement;
|
||||
public IIndexFileLocation fLocation;
|
||||
public final IASTPreprocessorIncludeStatement fStatement;
|
||||
public final IIndexFileLocation fLocation;
|
||||
public final ISignificantMacros fSignificantMacros;
|
||||
public final boolean fIsContext;
|
||||
public IIndexFragmentFile fTargetFile;
|
||||
public boolean fIsContext= false;
|
||||
|
||||
public IncludeInformation(IASTPreprocessorIncludeStatement stmt,
|
||||
IIndexFileLocation location, ISignificantMacros sig, boolean isContext) {
|
||||
fStatement= stmt;
|
||||
fSignificantMacros= sig;
|
||||
fLocation= location;
|
||||
fIsContext= isContext;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,14 +53,21 @@ public interface IWritableIndex extends IIndex {
|
|||
boolean isWritableFile(IIndexFile file);
|
||||
|
||||
/**
|
||||
* Returns a writable file for the given location and linkage, or null. This method
|
||||
* returns file-objects without content, also.
|
||||
* Returns a writable file for the given location, linkage, and the set of macro definitions,
|
||||
* or null. This method returns file objects without content, also.
|
||||
*/
|
||||
IIndexFragmentFile getWritableFile(int linkageID, IIndexFileLocation location) throws CoreException;
|
||||
IIndexFragmentFile getWritableFile(int linkageID, IIndexFileLocation location,
|
||||
ISignificantMacros macroDictionary) throws CoreException;
|
||||
|
||||
/**
|
||||
* Returns the writable files for the given location and linkage. This method
|
||||
* returns file objects without content, also.
|
||||
*/
|
||||
IIndexFragmentFile[] getWritableFiles(int linkageID, IIndexFileLocation location) throws CoreException;
|
||||
|
||||
/**
|
||||
* Returns the writable files for the given location in any linkage. This method
|
||||
* returns file-objects without content, also.
|
||||
* returns file objects without content, also.
|
||||
*/
|
||||
IIndexFragmentFile[] getWritableFiles(IIndexFileLocation location) throws CoreException;
|
||||
|
||||
|
@ -62,21 +77,28 @@ public interface IWritableIndex extends IIndex {
|
|||
* @param a collection that receives IndexFileLocation objects for files that
|
||||
* had the cleared file as a context. May be <code>null</code>.
|
||||
*/
|
||||
void clearFile(IIndexFragmentFile file, Collection<IIndexFileLocation> clearedContexts) throws CoreException;
|
||||
void clearFile(IIndexFragmentFile file) throws CoreException;
|
||||
|
||||
/**
|
||||
* Creates a file object for the given location or returns an existing one.
|
||||
* @param linkageID the id of the linkage in which the file has been parsed.
|
||||
* @param location the IIndexFileLocation representing the location of the file
|
||||
* @param macroDictionary The names and definitions of the macros used to disambiguate between
|
||||
* variants of the file contents corresponding to different inclusion points.
|
||||
* @return A created or an existing file.
|
||||
*/
|
||||
IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location) throws CoreException;
|
||||
IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location,
|
||||
ISignificantMacros macroDictionary) throws CoreException;
|
||||
|
||||
/**
|
||||
* Creates a uncommitted file object for the given location.
|
||||
*/
|
||||
IIndexFragmentFile addUncommittedFile(int linkageID, IIndexFileLocation location) throws CoreException;
|
||||
IIndexFragmentFile addUncommittedFile(int linkageID, IIndexFileLocation location,
|
||||
ISignificantMacros macroDictionary) throws CoreException;
|
||||
|
||||
/**
|
||||
* Makes an uncommitted file that was created earlier by calling
|
||||
* {@link #addUncommittedFile(int, IIndexFileLocation)} method visible in the index.
|
||||
* {@link #addUncommittedFile(int, IIndexFileLocation, ISignificantMacros)} method visible in the index.
|
||||
*
|
||||
* @return The file that was updated.
|
||||
* @throws CoreException
|
||||
|
@ -106,20 +128,20 @@ public interface IWritableIndex extends IIndex {
|
|||
/**
|
||||
* Acquires a write lock, while giving up a certain amount of read locks.
|
||||
*/
|
||||
void acquireWriteLock(int giveupReadLockCount) throws InterruptedException;
|
||||
void acquireWriteLock() throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Releases a write lock, reestablishing a certain amount of read locks.
|
||||
* Fully equivalent to <code>releaseWriteLock(int, true)</code>.
|
||||
*/
|
||||
void releaseWriteLock(int establishReadLockCount);
|
||||
void releaseWriteLock();
|
||||
|
||||
/**
|
||||
* Releases a write lock, reestablishing a certain amount of read locks.
|
||||
* @param establishReadLockCount amount of read-locks to establish.
|
||||
* @param flushDatabase when true the changes are flushed to disk.
|
||||
*/
|
||||
void releaseWriteLock(int establishReadLockCount, boolean flushDatabase);
|
||||
void releaseWriteLock(boolean flushDatabase);
|
||||
|
||||
/**
|
||||
* Resets the counters for cache-hits
|
||||
|
@ -156,4 +178,16 @@ public interface IWritableIndex extends IIndex {
|
|||
* Clears the result cache, caller needs to hold a write-lock.
|
||||
*/
|
||||
void clearResultCache();
|
||||
|
||||
/**
|
||||
* Changes the inclusions pointing to 'source' to point to 'target', instead.
|
||||
* Both files must belong to the writable fragment.
|
||||
*/
|
||||
void transferIncluders(IIndexFragmentFile source, IIndexFragmentFile target) throws CoreException;
|
||||
|
||||
/**
|
||||
* Changes the inclusion from the context of 'source' to point to 'target', instead.
|
||||
* Both files must belong to the writable fragment.
|
||||
*/
|
||||
void transferContext(IIndexFragmentFile source, IIndexFragmentFile target) throws CoreException;
|
||||
}
|
||||
|
|
|
@ -6,18 +6,17 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Andrew Ferguson (Symbian)
|
||||
* Sergey Prigogin (Google)
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Andrew Ferguson (Symbian)
|
||||
* Sergey Prigogin (Google)
|
||||
******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.core.index;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
|
||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
|
||||
import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver;
|
||||
import org.eclipse.cdt.internal.core.pdom.YieldableIndexLock;
|
||||
|
@ -39,28 +38,32 @@ public interface IWritableIndexFragment extends IIndexFragment {
|
|||
* @param a collection that receives IndexFileLocation objects for files that
|
||||
* had the cleared file as a context.
|
||||
*/
|
||||
void clearFile(IIndexFragmentFile file, Collection<IIndexFileLocation> contextsRemoved) throws CoreException;
|
||||
void clearFile(IIndexFragmentFile file) throws CoreException;
|
||||
|
||||
/**
|
||||
* Creates a file object for the given location and linkage or returns an existing one.
|
||||
* @param fileLocation an IIndexFileLocation representing the location of the file.
|
||||
* @param sigMacros the macro definitions at the inclusion point.
|
||||
* @return the existing IIndexFragmentFile for this location, or a newly created one.
|
||||
* @throws CoreException
|
||||
*/
|
||||
IIndexFragmentFile addFile(int linkageID, IIndexFileLocation fileLocation) throws CoreException;
|
||||
IIndexFragmentFile addFile(int linkageID, IIndexFileLocation fileLocation,
|
||||
ISignificantMacros sigMacros) throws CoreException;
|
||||
|
||||
/**
|
||||
* Creates a file object for the given location and linkage. The created file object is not added to
|
||||
* the file index.
|
||||
* @param fileLocation an IIndexFileLocation representing the location of the file.
|
||||
* @param sigMacros the macro definitions at the inclusion point.
|
||||
* @return a newly created IIndexFragmentFile.
|
||||
* @throws CoreException
|
||||
*/
|
||||
IIndexFragmentFile addUncommittedFile(int linkageID, IIndexFileLocation fileLocation) throws CoreException;
|
||||
IIndexFragmentFile addUncommittedFile(int linkageID, IIndexFileLocation fileLocation,
|
||||
ISignificantMacros sigMacros) throws CoreException;
|
||||
|
||||
/**
|
||||
* Makes an uncommitted file that was created earlier by calling
|
||||
* {@link #addUncommittedFile(int, IIndexFileLocation)} method visible in the index.
|
||||
* {@link #addUncommittedFile(int, IIndexFileLocation, ISignificantMacros)} method visible in the index.
|
||||
*
|
||||
* @return The file that was updated.
|
||||
* @throws CoreException
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2010 QNX Software Systems and others.
|
||||
* Copyright (c) 2005, 2011 QNX Software Systems 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
|
||||
|
@ -11,16 +11,21 @@
|
|||
* Andrew Ferguson (Symbian)
|
||||
* Anton Leherbauer (Wind River Systems)
|
||||
* IBM Corporation
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.index;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.ast.IFileNomination;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
|
||||
import org.eclipse.cdt.core.index.IIndex;
|
||||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
|
@ -28,7 +33,9 @@ import org.eclipse.cdt.core.index.IIndexFileLocation;
|
|||
import org.eclipse.cdt.core.index.IIndexInclude;
|
||||
import org.eclipse.cdt.core.index.IIndexMacro;
|
||||
import org.eclipse.cdt.core.parser.IncludeFileContentProvider;
|
||||
import org.eclipse.cdt.internal.core.parser.IMacroDictionary;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContent;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContent.FileVersion;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContent.InclusionKind;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContentProvider;
|
||||
import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver;
|
||||
|
@ -37,8 +44,7 @@ import org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask.IndexFileContent;
|
|||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
* Code reader factory, that fakes code readers for header files already stored in the
|
||||
* index.
|
||||
* Code reader factory, that fakes code readers for header files already stored in the index.
|
||||
*/
|
||||
public final class IndexBasedFileContentProvider extends InternalFileContentProvider {
|
||||
private static final class NeedToParseException extends Exception {}
|
||||
|
@ -46,14 +52,14 @@ public final class IndexBasedFileContentProvider extends InternalFileContentProv
|
|||
|
||||
private final IIndex fIndex;
|
||||
private int fLinkage;
|
||||
private Set<IIndexFileLocation> fIncludedFiles= new HashSet<IIndexFileLocation>();
|
||||
/** The fall-back code reader factory used in case a header file is not indexed */
|
||||
private final InternalFileContentProvider fFallBackFactory;
|
||||
private final ASTFilePathResolver fPathResolver;
|
||||
private final AbstractIndexerTask fRelatedIndexerTask;
|
||||
private boolean fSupportFillGapFromContextToHeader= false;
|
||||
private long fFileSizeLimit= 0;
|
||||
|
||||
private IIndexFile[] fContextToHeaderGap;
|
||||
private final Map<IIndexFileLocation, IFileNomination> fPragmaOnce= new HashMap<IIndexFileLocation, IFileNomination>();
|
||||
|
||||
public IndexBasedFileContentProvider(IIndex index,
|
||||
ASTFilePathResolver pathResolver, int linkage, IncludeFileContentProvider fallbackFactory) {
|
||||
this(index, pathResolver, linkage, fallbackFactory, null);
|
||||
|
@ -68,8 +74,8 @@ public final class IndexBasedFileContentProvider extends InternalFileContentProv
|
|||
fLinkage= linkage;
|
||||
}
|
||||
|
||||
public void setSupportFillGapFromContextToHeader(boolean val) {
|
||||
fSupportFillGapFromContextToHeader= val;
|
||||
public void setContextToHeaderGap(IIndexFile[] ctxToHeader) {
|
||||
fContextToHeaderGap= ctxToHeader;
|
||||
}
|
||||
|
||||
public void setFileSizeLimit(long limit) {
|
||||
|
@ -79,60 +85,63 @@ public final class IndexBasedFileContentProvider extends InternalFileContentProv
|
|||
public void setLinkage(int linkageID) {
|
||||
fLinkage= linkageID;
|
||||
}
|
||||
|
||||
public void cleanupAfterTranslationUnit() {
|
||||
fIncludedFiles.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetForTranslationUnit() {
|
||||
super.resetForTranslationUnit();
|
||||
fPragmaOnce.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports detection of pragma once semantics.
|
||||
*/
|
||||
@Override
|
||||
public void reportPragmaOnceSemantics(String filePath, IFileNomination nom) {
|
||||
fPragmaOnce.put(fPathResolver.resolveIncludeFile(filePath), nom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given file has been included with pragma once semantics.
|
||||
*/
|
||||
@Override
|
||||
public IFileNomination isIncludedWithPragmaOnceSemantics(String filePath) {
|
||||
return fPragmaOnce.get(fPathResolver.resolveIncludeFile(filePath));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getInclusionExists(String path) {
|
||||
return fPathResolver.doesIncludeFileExist(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportTranslationUnitFile(String path) {
|
||||
IIndexFileLocation ifl= fPathResolver.resolveASTPath(path);
|
||||
fIncludedFiles.add(ifl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean hasFileBeenIncludedInCurrentTranslationUnit(String path) {
|
||||
IIndexFileLocation ifl= fPathResolver.resolveASTPath(path);
|
||||
return fIncludedFiles.contains(ifl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InternalFileContent getContentForInclusion(String path) {
|
||||
public InternalFileContent getContentForInclusion(String path, IMacroDictionary macroDictionary) {
|
||||
IIndexFileLocation ifl= fPathResolver.resolveIncludeFile(path);
|
||||
if (ifl == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
path= fPathResolver.getASTPath(ifl);
|
||||
|
||||
// Include files once, only.
|
||||
if (!fIncludedFiles.add(ifl)) {
|
||||
return new InternalFileContent(path, InclusionKind.SKIP_FILE);
|
||||
}
|
||||
|
||||
try {
|
||||
IIndexFile file= fIndex.getFile(fLinkage, ifl);
|
||||
IIndexFile file = selectIndexFile(macroDictionary, ifl);
|
||||
if (file != null) {
|
||||
try {
|
||||
List<IIndexFile> files= new ArrayList<IIndexFile>();
|
||||
List<IIndexMacro> macros= new ArrayList<IIndexMacro>();
|
||||
List<ICPPUsingDirective> directives= new ArrayList<ICPPUsingDirective>();
|
||||
Set<IIndexFileLocation> ifls= new HashSet<IIndexFileLocation>();
|
||||
collectFileContent(file, ifls, files, macros, directives, false);
|
||||
// add included files only, if no exception was thrown
|
||||
fIncludedFiles.addAll(ifls);
|
||||
return new InternalFileContent(path, macros, directives, files);
|
||||
Map<IIndexFileLocation, IFileNomination> newPragmaOnce= new HashMap<IIndexFileLocation, IFileNomination>();
|
||||
LinkedHashSet<IIndexFile> preLoaded= new LinkedHashSet<IIndexFile>();
|
||||
collectFileContent(file, null, newPragmaOnce, preLoaded, files, macros, directives, null);
|
||||
// Report pragma once inclusions, only if no exception was thrown.
|
||||
fPragmaOnce.putAll(newPragmaOnce);
|
||||
return new InternalFileContent(path, macros, directives, files, toList(preLoaded));
|
||||
} catch (NeedToParseException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
|
||||
|
||||
// Skip large files
|
||||
if (fFileSizeLimit > 0 && fPathResolver.getFileSize(path) > fFileSizeLimit) {
|
||||
return new InternalFileContent(path, InclusionKind.SKIP_FILE);
|
||||
|
@ -147,6 +156,26 @@ public final class IndexBasedFileContentProvider extends InternalFileContentProv
|
|||
return null;
|
||||
}
|
||||
|
||||
public List<String> toPathList(Collection<IIndexFileLocation> newPragmaOnce) {
|
||||
List<String> newPragmaOncePaths= new ArrayList<String>(newPragmaOnce.size());
|
||||
for (IIndexFileLocation l : newPragmaOnce) {
|
||||
newPragmaOncePaths.add(fPathResolver.getASTPath(l));
|
||||
}
|
||||
return newPragmaOncePaths;
|
||||
}
|
||||
|
||||
public IIndexFile selectIndexFile(IMacroDictionary macroDictionary, IIndexFileLocation ifl)
|
||||
throws CoreException {
|
||||
if (fRelatedIndexerTask != null)
|
||||
return fRelatedIndexerTask.selectIndexFile(fLinkage, ifl, macroDictionary);
|
||||
|
||||
for (IIndexFile file : fIndex.getFiles(fLinkage, ifl)) {
|
||||
if (macroDictionary.satisfies(file.getSignificantMacros()))
|
||||
return file;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InternalFileContent getContentForInclusion(IIndexFileLocation ifl, String astPath) {
|
||||
if (fFallBackFactory != null) {
|
||||
|
@ -155,145 +184,122 @@ public final class IndexBasedFileContentProvider extends InternalFileContentProv
|
|||
return null;
|
||||
}
|
||||
|
||||
private void collectFileContent(IIndexFile file, Set<IIndexFileLocation> ifls, List<IIndexFile> files,
|
||||
List<IIndexMacro> macros, List<ICPPUsingDirective> usingDirectives, boolean checkIncluded)
|
||||
throws CoreException, NeedToParseException {
|
||||
private boolean collectFileContent(IIndexFile file, IIndexFile stopAt,
|
||||
Map<IIndexFileLocation, IFileNomination> newPragmaOnce,
|
||||
LinkedHashSet<IIndexFile> preLoaded, List<IIndexFile> files,
|
||||
List<IIndexMacro> macros, List<ICPPUsingDirective> usingDirectives,
|
||||
Set<IIndexFile> preventRecursion) throws CoreException, NeedToParseException {
|
||||
if (file.equals(stopAt))
|
||||
return true;
|
||||
|
||||
IIndexFileLocation ifl= file.getLocation();
|
||||
if (!ifls.add(ifl) || (checkIncluded && fIncludedFiles.contains(ifl))) {
|
||||
return;
|
||||
}
|
||||
IndexFileContent content;
|
||||
if (fRelatedIndexerTask != null) {
|
||||
content= fRelatedIndexerTask.getFileContent(fLinkage, ifl);
|
||||
if (content == null) {
|
||||
throw new NeedToParseException();
|
||||
}
|
||||
if (newPragmaOnce.containsKey(ifl))
|
||||
return false;
|
||||
if (file.hasPragmaOnceSemantics())
|
||||
newPragmaOnce.put(ifl, file);
|
||||
|
||||
if (preventRecursion != null) {
|
||||
if (fPragmaOnce.containsKey(ifl))
|
||||
return false;
|
||||
} else {
|
||||
content= new IndexFileContent();
|
||||
content.setPreprocessorDirectives(file.getIncludes(), file.getMacros());
|
||||
content.setUsingDirectives(file.getUsingDirectives());
|
||||
preventRecursion= new HashSet<IIndexFile>();
|
||||
}
|
||||
if (!preventRecursion.add(file))
|
||||
return false;
|
||||
|
||||
final ICPPUsingDirective[] uds;
|
||||
final Object[] pds;
|
||||
if (fRelatedIndexerTask != null) {
|
||||
IndexFileContent content= fRelatedIndexerTask.getFileContent(fLinkage, ifl, file);
|
||||
if (content == null)
|
||||
throw new NeedToParseException();
|
||||
uds= content.getUsingDirectives();
|
||||
pds= content.getPreprocessingDirectives();
|
||||
} else {
|
||||
uds= file.getUsingDirectives();
|
||||
pds= IndexFileContent.merge(file.getIncludes(), file.getMacros());
|
||||
}
|
||||
|
||||
files.add(file);
|
||||
usingDirectives.addAll(Arrays.asList(content.getUsingDirectives()));
|
||||
Object[] dirs= content.getPreprocessingDirectives();
|
||||
for (Object d : dirs) {
|
||||
if (!file.hasPragmaOnceSemantics()) {
|
||||
preLoaded.add(file);
|
||||
}
|
||||
int udx= 0;
|
||||
for (Object d : pds) {
|
||||
if (d instanceof IIndexMacro) {
|
||||
macros.add((IIndexMacro) d);
|
||||
} else if (d instanceof IIndexInclude) {
|
||||
IIndexInclude inc= (IIndexInclude) d;
|
||||
IIndexFile includedFile= fIndex.resolveInclude((IIndexInclude) d);
|
||||
if (includedFile != null) {
|
||||
collectFileContent(includedFile, ifls, files, macros, usingDirectives, true);
|
||||
// Add in using directives that appear before the inclusion
|
||||
final int offset= inc.getNameOffset();
|
||||
for (; udx < uds.length && uds[udx].getPointOfDeclaration() <= offset; udx++) {
|
||||
usingDirectives.add(uds[udx]);
|
||||
}
|
||||
if (collectFileContent(includedFile, stopAt, newPragmaOnce, preLoaded, files, macros, usingDirectives, preventRecursion))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add in remaining using directives
|
||||
for (; udx < uds.length; udx++) {
|
||||
usingDirectives.add(uds[udx]);
|
||||
}
|
||||
preventRecursion.remove(file);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InternalFileContent getContentForContextToHeaderGap(String path) {
|
||||
if (!fSupportFillGapFromContextToHeader) {
|
||||
return null;
|
||||
}
|
||||
|
||||
IIndexFileLocation ifl= fPathResolver.resolveASTPath(path);
|
||||
if (ifl == null) {
|
||||
public InternalFileContent getContentForContextToHeaderGap(String path,
|
||||
IMacroDictionary macroDictionary) {
|
||||
if (fContextToHeaderGap == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
IIndexFile targetFile= fIndex.getFile(fLinkage, ifl);
|
||||
if (targetFile == null) {
|
||||
IIndexFile contextFile= fContextToHeaderGap[0];
|
||||
IIndexFile targetFile = fContextToHeaderGap[1];
|
||||
if (contextFile == null || targetFile == null || contextFile == targetFile)
|
||||
return null;
|
||||
}
|
||||
|
||||
IIndexFile contextFile= findContext(targetFile);
|
||||
if (contextFile == targetFile || contextFile == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
HashSet<IIndexFile> filesIncluded= new HashSet<IIndexFile>();
|
||||
|
||||
Map<IIndexFileLocation, IFileNomination> newPragmaOnce= new HashMap<IIndexFileLocation, IFileNomination>();
|
||||
List<IIndexFile> filesIncluded= new ArrayList<IIndexFile>();
|
||||
ArrayList<IIndexMacro> macros= new ArrayList<IIndexMacro>();
|
||||
ArrayList<ICPPUsingDirective> directives= new ArrayList<ICPPUsingDirective>();
|
||||
if (!collectFileContentForGap(contextFile, ifl, filesIncluded, macros, directives)) {
|
||||
LinkedHashSet<IIndexFile> preLoaded= new LinkedHashSet<IIndexFile>();
|
||||
try {
|
||||
if (!collectFileContent(contextFile, targetFile, newPragmaOnce, preLoaded,
|
||||
filesIncluded, macros, directives, new HashSet<IIndexFile>())) {
|
||||
return null;
|
||||
}
|
||||
} catch (NeedToParseException e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// mark the files in the gap as included
|
||||
for (IIndexFile file : filesIncluded) {
|
||||
fIncludedFiles.add(file.getLocation());
|
||||
}
|
||||
return new InternalFileContent(GAP, macros, directives, new ArrayList<IIndexFile>(filesIncluded));
|
||||
// Report pragma once inclusions.
|
||||
fPragmaOnce.putAll(newPragmaOnce);
|
||||
return new InternalFileContent(GAP, macros, directives, filesIncluded, toList(preLoaded));
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private IIndexFile findContext(IIndexFile file) throws CoreException {
|
||||
final HashSet<IIndexFile> ifiles= new HashSet<IIndexFile>();
|
||||
ifiles.add(file);
|
||||
IIndexInclude include= file.getParsedInContext();
|
||||
while (include != null) {
|
||||
final IIndexFile context= include.getIncludedBy();
|
||||
if (!ifiles.add(context)) {
|
||||
return file;
|
||||
}
|
||||
file= context;
|
||||
include= context.getParsedInContext();
|
||||
private List<FileVersion> toList(LinkedHashSet<IIndexFile> preLoaded) throws CoreException {
|
||||
List<FileVersion> result= new ArrayList<InternalFileContent.FileVersion>(preLoaded.size());
|
||||
for (IIndexFile file : preLoaded) {
|
||||
String path= fPathResolver.getASTPath(file.getLocation());
|
||||
result.add(new FileVersion(path, file.getSignificantMacros()));
|
||||
}
|
||||
return file;
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean collectFileContentForGap(IIndexFile from, IIndexFileLocation to,
|
||||
Set<IIndexFile> filesIncluded, List<IIndexMacro> macros,
|
||||
List<ICPPUsingDirective> directives) throws CoreException {
|
||||
final IIndexFileLocation ifl= from.getLocation();
|
||||
if (ifl.equals(to)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fIncludedFiles.contains(ifl) || !filesIncluded.add(from)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final IIndexInclude[] ids= from.getIncludes();
|
||||
final IIndexMacro[] ms= from.getMacros();
|
||||
final Object[] dirs= IndexFileContent.merge(ids, ms);
|
||||
IIndexInclude success= null;
|
||||
for (Object d : dirs) {
|
||||
if (d instanceof IIndexMacro) {
|
||||
macros.add((IIndexMacro) d);
|
||||
} else if (d instanceof IIndexInclude) {
|
||||
IIndexFile includedFile= fIndex.resolveInclude((IIndexInclude) d);
|
||||
if (includedFile != null) {
|
||||
if (collectFileContentForGap(includedFile, to, filesIncluded, macros, directives)) {
|
||||
success= (IIndexInclude) d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final ICPPUsingDirective[] uds= from.getUsingDirectives();
|
||||
if (success == null) {
|
||||
directives.addAll(Arrays.asList(uds));
|
||||
return false;
|
||||
}
|
||||
|
||||
final int offset= success.getNameOffset();
|
||||
for (ICPPUsingDirective ud : uds) {
|
||||
if (ud.getPointOfDeclaration() > offset)
|
||||
break;
|
||||
directives.add(ud);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public IIndexFile findIndexFile(InternalFileContent fc) throws CoreException {
|
||||
public IIndexFile[] findIndexFiles(InternalFileContent fc) throws CoreException {
|
||||
IIndexFileLocation ifl = fPathResolver.resolveASTPath(fc.getFileLocation());
|
||||
if (ifl != null) {
|
||||
return fIndex.getFile(fLinkage, ifl);
|
||||
return fIndex.getFiles(fLinkage, ifl);
|
||||
}
|
||||
return null;
|
||||
return IIndexFile.EMPTY_FILE_ARRAY;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,15 @@ public class IndexFileSet implements IIndexFileSet {
|
|||
subSet.add(fragFile);
|
||||
}
|
||||
|
||||
public void remove(IIndexFile indexFile) {
|
||||
final IIndexFragmentFile fragFile = (IIndexFragmentFile) indexFile;
|
||||
final IIndexFragment frag= fragFile.getIndexFragment();
|
||||
IIndexFragmentFileSet subSet= fSubSets.get(frag);
|
||||
if (subSet != null) {
|
||||
subSet.remove(fragFile);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean containsDeclaration(IIndexBinding binding) {
|
||||
return containsDeclaration(binding, false);
|
||||
}
|
||||
|
@ -163,6 +172,10 @@ public class IndexFileSet implements IIndexFileSet {
|
|||
public void add(IIndexFile indexFile) {
|
||||
Assert.isLegal(false);
|
||||
}
|
||||
|
||||
public void remove(IIndexFile indexFile) {
|
||||
Assert.isLegal(false);
|
||||
}
|
||||
};
|
||||
}
|
||||
return fInverse;
|
||||
|
|
|
@ -12,12 +12,11 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.index;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
|
||||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver;
|
||||
import org.eclipse.cdt.internal.core.pdom.YieldableIndexLock;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
@ -43,20 +42,27 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
|
|||
return fWritableFragment;
|
||||
}
|
||||
|
||||
public IIndexFragmentFile getWritableFile(int linkageID, IIndexFileLocation location) throws CoreException {
|
||||
return fWritableFragment.getFile(linkageID, location);
|
||||
public IIndexFragmentFile getWritableFile(int linkageID, IIndexFileLocation location,
|
||||
ISignificantMacros macroDictionary) throws CoreException {
|
||||
return fWritableFragment.getFile(linkageID, location, macroDictionary);
|
||||
}
|
||||
|
||||
|
||||
public IIndexFragmentFile[] getWritableFiles(int linkageID, IIndexFileLocation location) throws CoreException {
|
||||
return fWritableFragment.getFiles(linkageID, location);
|
||||
}
|
||||
|
||||
public IIndexFragmentFile[] getWritableFiles(IIndexFileLocation location) throws CoreException {
|
||||
return fWritableFragment.getFiles(location);
|
||||
}
|
||||
|
||||
public IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location) throws CoreException {
|
||||
return fWritableFragment.addFile(linkageID, location);
|
||||
public IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location,
|
||||
ISignificantMacros macroDictionary) throws CoreException {
|
||||
return fWritableFragment.addFile(linkageID, location, macroDictionary);
|
||||
}
|
||||
|
||||
public IIndexFragmentFile addUncommittedFile(int linkageID, IIndexFileLocation location) throws CoreException {
|
||||
return fWritableFragment.addUncommittedFile(linkageID, location);
|
||||
public IIndexFragmentFile addUncommittedFile(int linkageID, IIndexFileLocation location,
|
||||
ISignificantMacros macroDictionary) throws CoreException {
|
||||
return fWritableFragment.addUncommittedFile(linkageID, location, macroDictionary);
|
||||
}
|
||||
|
||||
public IIndexFragmentFile commitUncommittedFile() throws CoreException {
|
||||
|
@ -78,9 +84,10 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
|
|||
if (!isWritableFragment(indexFragment)) {
|
||||
assert false : "Attempt to update file of read-only fragment"; //$NON-NLS-1$
|
||||
} else {
|
||||
for (IncludeInformation ii : includes) {
|
||||
if (ii.fLocation != null) {
|
||||
ii.fTargetFile= addFile(linkageID, ii.fLocation);
|
||||
for (IncludeInformation include : includes) {
|
||||
if (include.fLocation != null) {
|
||||
include.fTargetFile= addFile(linkageID, include.fLocation,
|
||||
include.fSignificantMacros);
|
||||
}
|
||||
}
|
||||
((IWritableIndexFragment) indexFragment).addFileContent(file, includes, macros, names, resolver, lock);
|
||||
|
@ -96,12 +103,12 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
|
|||
isWritableFragment(((IIndexFragmentFile)file).getIndexFragment());
|
||||
}
|
||||
|
||||
public void clearFile(IIndexFragmentFile file, Collection<IIndexFileLocation> clearedContexts) throws CoreException {
|
||||
public void clearFile(IIndexFragmentFile file) throws CoreException {
|
||||
IIndexFragment indexFragment = file.getIndexFragment();
|
||||
if (!isWritableFragment(indexFragment)) {
|
||||
assert false : "Attempt to clear file of read-only fragment"; //$NON-NLS-1$
|
||||
} else {
|
||||
((IWritableIndexFragment) indexFragment).clearFile(file, clearedContexts);
|
||||
((IWritableIndexFragment) indexFragment).clearFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,25 +128,25 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
|
|||
fThread= null;
|
||||
}
|
||||
|
||||
public void acquireWriteLock(int giveupReadlockCount) throws InterruptedException {
|
||||
public void acquireWriteLock() throws InterruptedException {
|
||||
checkThread();
|
||||
assert !fIsWriteLocked: "Multiple write locks is not allowed"; //$NON-NLS-1$
|
||||
assert giveupReadlockCount == getReadLockCount(): "Unexpected read lock is not allowed"; //$NON-NLS-1$
|
||||
|
||||
fWritableFragment.acquireWriteLock(giveupReadlockCount);
|
||||
fWritableFragment.acquireWriteLock(getReadLockCount());
|
||||
fIsWriteLocked= true;
|
||||
}
|
||||
|
||||
public void releaseWriteLock(int establishReadlockCount) {
|
||||
releaseWriteLock(establishReadlockCount, true);
|
||||
public void releaseWriteLock() {
|
||||
releaseWriteLock(true);
|
||||
}
|
||||
|
||||
public void releaseWriteLock(int establishReadlockCount, boolean flush) {
|
||||
public void releaseWriteLock(boolean flush) {
|
||||
checkThread();
|
||||
assert fIsWriteLocked: "No write lock to be released"; //$NON-NLS-1$
|
||||
assert establishReadlockCount == getReadLockCount(): "Unexpected read lock is not allowed"; //$NON-NLS-1$
|
||||
|
||||
|
||||
// Bug 297641: Result cache of read only providers needs to be cleared.
|
||||
int establishReadlockCount = getReadLockCount();
|
||||
if (establishReadlockCount == 0) {
|
||||
clearResultCache();
|
||||
}
|
||||
|
@ -171,10 +178,23 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
|
|||
fWritableFragment.flush();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.index.IWritableIndex#getDatabaseSizeBytes()
|
||||
*/
|
||||
public long getDatabaseSizeBytes() {
|
||||
return fWritableFragment.getDatabaseSizeBytes();
|
||||
}
|
||||
|
||||
public void transferIncluders(IIndexFragmentFile source, IIndexFragmentFile target) throws CoreException {
|
||||
if (source == null || target == null || !isWritableFile(source) || !isWritableFile(target))
|
||||
throw new IllegalArgumentException();
|
||||
if (source.equals(target))
|
||||
return;
|
||||
target.transferIncluders(source);
|
||||
}
|
||||
|
||||
public void transferContext(IIndexFragmentFile source, IIndexFragmentFile target) throws CoreException {
|
||||
if (source == null || target == null || !isWritableFile(source) || !isWritableFile(target))
|
||||
throw new IllegalArgumentException();
|
||||
if (source.equals(target))
|
||||
return;
|
||||
target.transferContext(source);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -358,12 +358,12 @@ public abstract class StandaloneIndexer {
|
|||
private void clearIndex() throws CoreException, InterruptedException {
|
||||
IWritableIndex index= getIndex();
|
||||
// First clear the pdom
|
||||
index.acquireWriteLock(0);
|
||||
index.acquireWriteLock();
|
||||
try {
|
||||
index.clear();
|
||||
}
|
||||
finally {
|
||||
index.releaseWriteLock(0);
|
||||
index.releaseWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,13 +15,8 @@ import java.text.NumberFormat;
|
|||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.icu.text.MessageFormat;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ILinkage;
|
||||
import org.eclipse.cdt.core.model.AbstractLanguage;
|
||||
import org.eclipse.cdt.core.model.ILanguage;
|
||||
import org.eclipse.cdt.core.parser.IParserLogService;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||
import org.eclipse.cdt.internal.core.index.IWritableIndex;
|
||||
import org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask;
|
||||
import org.eclipse.cdt.internal.core.pdom.IndexerProgress;
|
||||
|
@ -29,6 +24,8 @@ import org.eclipse.core.runtime.IProgressMonitor;
|
|||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
|
||||
import com.ibm.icu.text.MessageFormat;
|
||||
|
||||
/**
|
||||
* A task for index updates.
|
||||
*
|
||||
|
@ -111,15 +108,6 @@ public abstract class StandaloneIndexerTask extends AbstractIndexerTask {
|
|||
return getIndexer().getIndexAllFiles();
|
||||
}
|
||||
|
||||
@Override
|
||||
final protected AbstractLanguage[] getLanguages(String filename) {
|
||||
ILanguage l = fIndexer.getLanguageMapper().getLanguage(filename);
|
||||
if (l instanceof AbstractLanguage) {
|
||||
return new AbstractLanguage[] {(AbstractLanguage) l};
|
||||
}
|
||||
return new AbstractLanguage[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final IWritableIndex createIndex() {
|
||||
return fIndexer.getIndex();
|
||||
|
@ -249,20 +237,6 @@ public abstract class StandaloneIndexerTask extends AbstractIndexerTask {
|
|||
protected void logException(Throwable e) {
|
||||
trace(e.getMessage());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
protected IScannerInfo createDefaultScannerConfig(int linkageID) {
|
||||
IStandaloneScannerInfoProvider provider = fIndexer.getScannerInfoProvider();
|
||||
if(provider != null)
|
||||
return provider.getDefaultScannerInformation(linkageID);
|
||||
|
||||
IScannerInfo scannerInfo = fIndexer.getScannerInfo();
|
||||
if(scannerInfo != null)
|
||||
return scannerInfo;
|
||||
|
||||
return super.createDefaultScannerConfig(linkageID);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask#getLinkagesToParse()
|
||||
|
|
|
@ -45,7 +45,7 @@ public class CodeReaderFactoryAdapter extends AbstractCodeReaderFactory {
|
|||
}
|
||||
|
||||
public org.eclipse.cdt.core.parser.CodeReader createCodeReaderForInclusion(String path) {
|
||||
return CodeReaderAdapter.adapt(fDelegate.getContentForInclusion(path));
|
||||
return CodeReaderAdapter.adapt(fDelegate.getContentForInclusion(path, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -55,7 +55,7 @@ public class CodeReaderFactoryAdapter extends AbstractCodeReaderFactory {
|
|||
}
|
||||
|
||||
public org.eclipse.cdt.core.parser.CodeReader createCodeReaderForTranslationUnit(String path) {
|
||||
return CodeReaderAdapter.adapt(fDelegate.getContentForInclusion(path));
|
||||
return CodeReaderAdapter.adapt(fDelegate.getContentForInclusion(path, null));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
|
|
|
@ -27,7 +27,8 @@ public class EmptyFilesProvider extends InternalFileContentProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public InternalFileContent getContentForInclusion(String path) {
|
||||
public InternalFileContent getContentForInclusion(String path,
|
||||
IMacroDictionary macroDictionary) {
|
||||
if (!getInclusionExists(path))
|
||||
return null;
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser;
|
||||
|
||||
|
@ -26,7 +26,7 @@ import org.eclipse.core.runtime.CoreException;
|
|||
public class FileContentProviderAdapter extends InternalFileContentProvider {
|
||||
|
||||
/**
|
||||
* @deprecated avoid using the adapter, its for backwards compatibility, only.
|
||||
* @deprecated avoid using the adapter, it's for backwards compatibility, only.
|
||||
*/
|
||||
@Deprecated
|
||||
public static InternalFileContentProvider adapt(ICodeReaderFactory fileCreator) {
|
||||
|
@ -57,7 +57,7 @@ public class FileContentProviderAdapter extends InternalFileContentProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public InternalFileContent getContentForInclusion(String path) {
|
||||
public InternalFileContent getContentForInclusion(String path, IMacroDictionary macroDictionary) {
|
||||
return (InternalFileContent) FileContent.adapt(fDelegate.createCodeReaderForInclusion(path));
|
||||
}
|
||||
|
||||
|
@ -72,5 +72,4 @@ public class FileContentProviderAdapter extends InternalFileContentProvider {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011 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;
|
||||
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
|
||||
|
||||
/**
|
||||
* Interface for accessing the macro dictionary of the preprocessor.
|
||||
*/
|
||||
public interface IMacroDictionary {
|
||||
|
||||
boolean satisfies(ISignificantMacros significantMacros);
|
||||
}
|
|
@ -30,7 +30,8 @@ public class SavedFilesProvider extends InternalFileContentProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public InternalFileContent getContentForInclusion(String path) {
|
||||
public InternalFileContent getContentForInclusion(String path,
|
||||
IMacroDictionary macroDictionary) {
|
||||
if (!getInclusionExists(path))
|
||||
return null;
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
|
@ -40,11 +40,15 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree.IASTInclusionNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IFileNomination;
|
||||
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.core.parser.IToken;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeSpecification;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
* Models various AST-constructs obtained from the preprocessor.
|
||||
|
@ -188,7 +192,7 @@ class ASTIfndef extends ASTDirectiveWithCondition implements IASTPreprocessorIfn
|
|||
}
|
||||
|
||||
class ASTIfdef extends ASTDirectiveWithCondition implements IASTPreprocessorIfdefStatement {
|
||||
ASTMacroReferenceName fMacroRef;
|
||||
private ASTMacroReferenceName fMacroRef;
|
||||
public ASTIfdef(IASTTranslationUnit parent, int startNumber, int condNumber, int condEndNumber, boolean taken, IMacroBinding macro) {
|
||||
super(parent, startNumber, condNumber, condEndNumber, taken);
|
||||
if (macro != null) {
|
||||
|
@ -253,21 +257,33 @@ class ASTPragmaOperator extends ASTPragma {
|
|||
}
|
||||
|
||||
class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreprocessorIncludeStatement {
|
||||
private static final ISignificantMacros[] NO_VERSIONS = {};
|
||||
|
||||
private final ASTPreprocessorName fName;
|
||||
private final String fPath;
|
||||
private final boolean fIsResolved;
|
||||
private final boolean fIsSystemInclude;
|
||||
private final boolean fFoundByHeuristics;
|
||||
private final IFileNomination fNominationDelegate;
|
||||
private boolean fPragmaOnce;
|
||||
private boolean fCreatesAST;
|
||||
private ISignificantMacros fSignificantMacros;
|
||||
private ISignificantMacros[] fLoadedVersions = NO_VERSIONS;
|
||||
private long fContentsHash;
|
||||
|
||||
public ASTInclusionStatement(IASTTranslationUnit parent,
|
||||
int startNumber, int nameStartNumber, int nameEndNumber, int endNumber,
|
||||
char[] headerName, String filePath, boolean userInclude, boolean active, boolean heuristic) {
|
||||
char[] headerName, String filePath, boolean userInclude, boolean active, boolean heuristic,
|
||||
IFileNomination nominationDelegate) {
|
||||
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber);
|
||||
fName= new ASTPreprocessorName(this, IASTPreprocessorIncludeStatement.INCLUDE_NAME, nameStartNumber, nameEndNumber, headerName, null);
|
||||
fName= new ASTPreprocessorName(this, IASTPreprocessorIncludeStatement.INCLUDE_NAME,
|
||||
nameStartNumber, nameEndNumber, headerName, null);
|
||||
fPath= filePath == null ? "" : filePath; //$NON-NLS-1$
|
||||
fIsResolved= filePath != null;
|
||||
fIsSystemInclude= !userInclude;
|
||||
fFoundByHeuristics= heuristic;
|
||||
fSignificantMacros= ISignificantMacros.NONE;
|
||||
fNominationDelegate= nominationDelegate;
|
||||
if (!active) {
|
||||
setInactive();
|
||||
}
|
||||
|
@ -298,6 +314,69 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
|
|||
public boolean isResolvedByHeuristics() {
|
||||
return fFoundByHeuristics;
|
||||
}
|
||||
|
||||
public boolean hasPragmaOnceSemantics() {
|
||||
if (fNominationDelegate != null) {
|
||||
try {
|
||||
return fNominationDelegate.hasPragmaOnceSemantics();
|
||||
} catch (CoreException e) {
|
||||
}
|
||||
}
|
||||
return fPragmaOnce;
|
||||
}
|
||||
|
||||
public void setPragamOnceSemantics(boolean value) {
|
||||
assert fNominationDelegate == null;
|
||||
fPragmaOnce= value;
|
||||
}
|
||||
|
||||
public ISignificantMacros getSignificantMacros() {
|
||||
if (fNominationDelegate != null) {
|
||||
try {
|
||||
return fNominationDelegate.getSignificantMacros();
|
||||
} catch (CoreException e) {
|
||||
}
|
||||
}
|
||||
return fSignificantMacros;
|
||||
}
|
||||
|
||||
public void setSignificantMacros(ISignificantMacros sig) {
|
||||
assert sig != null;
|
||||
assert fNominationDelegate == null;
|
||||
fSignificantMacros= sig;
|
||||
}
|
||||
|
||||
public void setLoadedVersions(ISignificantMacros[] versions) {
|
||||
fLoadedVersions= versions;
|
||||
}
|
||||
|
||||
public ISignificantMacros[] getLoadedVersions() {
|
||||
return fLoadedVersions;
|
||||
}
|
||||
|
||||
public long getContentsHash() {
|
||||
if (fNominationDelegate != null) {
|
||||
return 0;
|
||||
}
|
||||
return fContentsHash;
|
||||
}
|
||||
|
||||
public void setContentsHash(long hash) {
|
||||
assert fNominationDelegate == null;
|
||||
fCreatesAST= true;
|
||||
fContentsHash= hash;
|
||||
}
|
||||
|
||||
public boolean createsAST() {
|
||||
return fCreatesAST;
|
||||
}
|
||||
|
||||
public IIndexFile getImportedIndexFile() {
|
||||
if (fNominationDelegate instanceof IIndexFile)
|
||||
return (IIndexFile) fNominationDelegate;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessorObjectStyleMacroDefinition {
|
||||
|
@ -579,6 +658,10 @@ class ASTFileLocation implements IASTFileLocation {
|
|||
public LocationCtxFile getLocationContext() {
|
||||
return fLocationCtx;
|
||||
}
|
||||
|
||||
public IASTPreprocessorIncludeStatement getContextInclusionStatement() {
|
||||
return fLocationCtx.getInclusionStatement();
|
||||
}
|
||||
}
|
||||
|
||||
class ASTMacroExpansion extends ASTPreprocessorNode implements IASTPreprocessorMacroExpansion {
|
||||
|
@ -708,6 +791,10 @@ class ASTFileLocationForBuiltins implements IASTFileLocation {
|
|||
public int getStartingLineNumber() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public IASTPreprocessorIncludeStatement getContextInclusionStatement() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -723,4 +810,3 @@ class ASTImageLocation extends ASTFileLocationForBuiltins implements IASTImageLo
|
|||
return fKind;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2010 IBM Corporation and others.
|
||||
* Copyright (c) 2004, 2011 IBM Corporation 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
|
||||
|
@ -19,12 +19,17 @@ import java.util.HashMap;
|
|||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IFileNomination;
|
||||
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||
import org.eclipse.cdt.core.dom.parser.IScannerExtensionConfiguration;
|
||||
import org.eclipse.cdt.core.index.IIndexMacro;
|
||||
import org.eclipse.cdt.core.parser.AbstractParserLogService;
|
||||
import org.eclipse.cdt.core.parser.EndOfFileException;
|
||||
import org.eclipse.cdt.core.parser.FileContent;
|
||||
import org.eclipse.cdt.core.parser.IExtendedScannerInfo;
|
||||
|
@ -34,6 +39,7 @@ import org.eclipse.cdt.core.parser.IPreprocessorDirective;
|
|||
import org.eclipse.cdt.core.parser.IProblem;
|
||||
import org.eclipse.cdt.core.parser.IScanner;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.core.parser.IToken;
|
||||
import org.eclipse.cdt.core.parser.IncludeFileContentProvider;
|
||||
import org.eclipse.cdt.core.parser.Keywords;
|
||||
|
@ -42,16 +48,21 @@ import org.eclipse.cdt.core.parser.ParseError;
|
|||
import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayIntMap;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayMap;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
|
||||
import org.eclipse.cdt.core.parser.util.CharArraySet;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics;
|
||||
import org.eclipse.cdt.internal.core.parser.EmptyFilesProvider;
|
||||
import org.eclipse.cdt.internal.core.parser.IMacroDictionary;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContent.FileVersion;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContent.InclusionKind;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.MacroDefinitionParser.InvalidMacroDefinitionException;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.ScannerContext.BranchKind;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.ScannerContext.CodeState;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.ScannerContext.Conditional;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IAdaptable;
|
||||
|
||||
/**
|
||||
|
@ -88,11 +99,42 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
private static final DynamicMacro __DATE__= new DateMacro("__DATE__".toCharArray()); //$NON-NLS-1$
|
||||
private static final DynamicMacro __TIME__ = new TimeMacro("__TIME__".toCharArray()); //$NON-NLS-1$
|
||||
private static final DynamicMacro __LINE__ = new LineMacro("__LINE__".toCharArray()); //$NON-NLS-1$
|
||||
private static final char[] ONCE = "once".toCharArray(); //$NON-NLS-1$
|
||||
|
||||
private static final int NO_EXPANSION = 0x01;
|
||||
private static final int PROTECT_DEFINED = 0x02;
|
||||
private static final int STOP_AT_NL = 0x04;
|
||||
private static final int CHECK_NUMBERS = 0x08;
|
||||
static final int NO_EXPANSION = 0x01;
|
||||
static final int PROTECT_DEFINED = 0x02;
|
||||
static final int STOP_AT_NL = 0x04;
|
||||
static final int CHECK_NUMBERS = 0x08;
|
||||
static final int REPORT_SIGNIFICANT_MACROS = 0x10;
|
||||
static final int IGNORE_UNDEFINED_SIGNIFICANT_MACROS = 0x20;
|
||||
|
||||
private static final int MAX_INCLUSION_DEPTH = 200;
|
||||
|
||||
private static final String TRACE_NO_GUARD = CCorePlugin.PLUGIN_ID + "/debug/scanner/missingIncludeGuards"; //$NON-NLS-1$
|
||||
|
||||
|
||||
private final class MacroDictionary implements IMacroDictionary, ISignificantMacros.IVisitor {
|
||||
public boolean satisfies(ISignificantMacros significantMacros) {
|
||||
return significantMacros.accept(this);
|
||||
}
|
||||
|
||||
public boolean visitDefined(char[] macro) {
|
||||
return isDefined(macro);
|
||||
}
|
||||
|
||||
public boolean visitUndefined(char[] macro) {
|
||||
return !isDefined(macro);
|
||||
}
|
||||
|
||||
public boolean visitValue(char[] macro, char[] value) {
|
||||
PreprocessorMacro m = fMacroDictionary.get(macro);
|
||||
return m != null && CharArrayUtils.equals(m.getExpansion(), value);
|
||||
}
|
||||
|
||||
private boolean isDefined(char[] macro) {
|
||||
return fMacroDictionary.containsKey(macro);
|
||||
}
|
||||
}
|
||||
|
||||
private interface IIncludeFileTester<T> {
|
||||
T checkFile(String path, boolean isHeuristicMatch, IncludeSearchPathElement onPath);
|
||||
|
@ -100,7 +142,13 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
|
||||
final private IIncludeFileTester<InternalFileContent> createCodeReaderTester= new IIncludeFileTester<InternalFileContent>() {
|
||||
public InternalFileContent checkFile(String path, boolean isHeuristicMatch, IncludeSearchPathElement onPath) {
|
||||
final InternalFileContent fc= fFileContentProvider.getContentForInclusion(path);
|
||||
final InternalFileContent fc;
|
||||
IFileNomination once= fFileContentProvider.isIncludedWithPragmaOnceSemantics(path);
|
||||
if (once != null) {
|
||||
fc= new InternalFileContent(path, InclusionKind.SKIP_FILE);
|
||||
} else {
|
||||
fc= fFileContentProvider.getContentForInclusion(path, fMacroDictionaryFacade);
|
||||
}
|
||||
if (fc != null) {
|
||||
fc.setFoundByHeuristics(isHeuristicMatch);
|
||||
fc.setFoundOnPath(onPath);
|
||||
|
@ -162,7 +210,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
TokenSequence fInputToMacroExpansion= new TokenSequence(false);
|
||||
TokenSequence fLineInputToMacroExpansion= new TokenSequence(true);
|
||||
|
||||
final private IParserLogService fLog;
|
||||
final private AbstractParserLogService fLog;
|
||||
final private InternalFileContentProvider fFileContentProvider;
|
||||
|
||||
private IIncludeFileResolutionHeuristics fIncludeFileResolutionHeuristics;
|
||||
|
@ -184,10 +232,9 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
|
||||
// state information
|
||||
private final CharArrayMap<PreprocessorMacro> fMacroDictionary = new CharArrayMap<PreprocessorMacro>(512);
|
||||
private final IMacroDictionary fMacroDictionaryFacade = new MacroDictionary();
|
||||
private final LocationMap fLocationMap;
|
||||
|
||||
/** Set of already included files */
|
||||
private final HashSet<String> fAllIncludedFiles= new HashSet<String>();
|
||||
private CharArraySet fPreventInclusion= new CharArraySet(0);
|
||||
|
||||
private final Lexer fRootLexer;
|
||||
private final ScannerContext fRootContext;
|
||||
|
@ -200,6 +247,12 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
private Token fLastToken;
|
||||
|
||||
private InternalFileContent fRootContent;
|
||||
private boolean fHandledEndOfTranslationUnit;
|
||||
|
||||
// Detection of include guards used around an include directive
|
||||
private char[] fExternIncludeGuard;
|
||||
private Set<String> fTracedGuards;
|
||||
|
||||
|
||||
public CPreprocessor(FileContent fileContent, IScannerInfo info, ParserLanguage language,
|
||||
IParserLogService log, IScannerExtensionConfiguration configuration,
|
||||
|
@ -217,7 +270,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
throw new IllegalArgumentException("Illegal file content object"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
fLog = log;
|
||||
fLog = AbstractParserLogService.convert(log);
|
||||
fAdditionalNumericLiteralSuffixes= nonNull(configuration.supportAdditionalNumericLiteralSuffixes());
|
||||
fLexOptions.fSupportDollarInIdentifiers= configuration.support$InIdentifiers();
|
||||
fLexOptions.fSupportAtSignInIdentifiers= configuration.supportAtSignInIdentifiers();
|
||||
|
@ -239,17 +292,38 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
setupMacroDictionary(configuration, info, language);
|
||||
|
||||
ILocationCtx ctx= fLocationMap.pushTranslationUnit(filePath, fRootContent.getSource());
|
||||
fAllIncludedFiles.add(filePath);
|
||||
fFileContentProvider.reportTranslationUnitFile(filePath);
|
||||
fRootLexer= new Lexer(fRootContent.getSource(), fLexOptions, this, this);
|
||||
fRootContext= fCurrentContext= new ScannerContext(ctx, null, fRootLexer);
|
||||
if (info instanceof IExtendedScannerInfo) {
|
||||
final IExtendedScannerInfo einfo= (IExtendedScannerInfo) info;
|
||||
fPreIncludedFiles= new String[][] {einfo.getMacroFiles(), einfo.getIncludeFiles()};
|
||||
fPreIncludedFiles= new String[][] { einfo.getMacroFiles(), einfo.getIncludeFiles() };
|
||||
}
|
||||
fFileContentProvider.resetForTranslationUnit();
|
||||
}
|
||||
|
||||
private char[] detectIncludeGuard(String filePath, AbstractCharArray source, ScannerContext ctx) {
|
||||
final char[] guard = IncludeGuardDetection.detectIncludeGuard(source, fLexOptions, fPPKeywords);
|
||||
if (guard != null) {
|
||||
IFileNomination nom= fLocationMap.reportPragmaOnceSemantics(ctx.getLocationCtx());
|
||||
fFileContentProvider.reportPragmaOnceSemantics(filePath, nom);
|
||||
ctx.internalModification(guard);
|
||||
ctx.setPragmaOnce(true);
|
||||
return guard;
|
||||
} else {
|
||||
ctx.trackSignificantMacros();
|
||||
}
|
||||
if (ctx != fRootContext) {
|
||||
if (fLog.isTracing(TRACE_NO_GUARD)) {
|
||||
if (fTracedGuards == null)
|
||||
fTracedGuards= new HashSet<String>();
|
||||
if (fTracedGuards.add(filePath))
|
||||
fLog.traceLog(TRACE_NO_GUARD, "No include guard in " + filePath); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setSplitShiftROperator(boolean val) {
|
||||
public void setSplitShiftROperator(boolean val) {
|
||||
fSplitShiftRightOperator= val;
|
||||
}
|
||||
|
||||
|
@ -371,15 +445,19 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
|
||||
private void beforeFirstFetchToken() {
|
||||
if (fPreIncludedFiles != null) {
|
||||
handlePreIncludedFiles();
|
||||
}
|
||||
final String location = fLocationMap.getTranslationUnitPath();
|
||||
InternalFileContent content= fFileContentProvider.getContentForContextToHeaderGap(location);
|
||||
if (content != null && content.getKind() == InclusionKind.FOUND_IN_INDEX) {
|
||||
processInclusionFromIndex(0, location, content);
|
||||
handlePreIncludedFiles();
|
||||
fPreIncludedFiles= null;
|
||||
}
|
||||
fLocationMap.replacingFile(fFileContentProvider, fRootContent);
|
||||
fRootContent= null;
|
||||
final String location = fLocationMap.getTranslationUnitPath();
|
||||
InternalFileContent content= fFileContentProvider.getContentForContextToHeaderGap(location,
|
||||
fMacroDictionaryFacade);
|
||||
if (content != null && content.getKind() == InclusionKind.FOUND_IN_INDEX) {
|
||||
processInclusionFromIndex(0, location, content, false);
|
||||
}
|
||||
|
||||
detectIncludeGuard(location, fRootContent.getSource(), fRootContext);
|
||||
fLocationMap.parsingFile(fFileContentProvider, fRootContent);
|
||||
fRootContent= null;
|
||||
}
|
||||
|
||||
private void handlePreIncludedFiles() {
|
||||
|
@ -726,11 +804,23 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
|
||||
case IToken.tEND_OF_INPUT:
|
||||
if (fCurrentContext == uptoEndOfCtx || uptoEndOfCtx == null) {
|
||||
if (fCurrentContext == fRootContext && !fHandledEndOfTranslationUnit
|
||||
&& (options & STOP_AT_NL) == 0) {
|
||||
fHandledEndOfTranslationUnit= true;
|
||||
fLocationMap.endTranslationUnit(ppToken.getEndOffset(), fCurrentContext.getSignificantMacros());
|
||||
}
|
||||
return ppToken;
|
||||
}
|
||||
final ILocationCtx locationCtx = fCurrentContext.getLocationCtx();
|
||||
|
||||
final ILocationCtx locationCtx = fCurrentContext.getLocationCtx();
|
||||
ASTInclusionStatement inc = locationCtx.getInclusionStatement();
|
||||
if (inc != null) {
|
||||
completeInclusion(inc);
|
||||
}
|
||||
fLocationMap.popContext(locationCtx);
|
||||
fCurrentContext= fCurrentContext.getParent();
|
||||
|
||||
fCurrentContext.propagateSignificantMacros();
|
||||
fCurrentContext= fCurrentContext.getParent();
|
||||
assert fCurrentContext != null;
|
||||
|
||||
ppToken= fCurrentContext.currentLexerToken();
|
||||
|
@ -781,7 +871,21 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
}
|
||||
}
|
||||
|
||||
private void checkNumber(Token number, final boolean isFloat) {
|
||||
private void completeInclusion(ASTInclusionStatement inc) {
|
||||
final ISignificantMacros sig;
|
||||
CharArrayObjectMap<char[]> sigMacros= fCurrentContext.getSignificantMacros();
|
||||
if (sigMacros == null || sigMacros.isEmpty()) {
|
||||
sig = ISignificantMacros.NONE;
|
||||
} else {
|
||||
sig = new SignificantMacros(sigMacros);
|
||||
}
|
||||
inc.setSignificantMacros(sig);
|
||||
if (!inc.hasPragmaOnceSemantics()) {
|
||||
fFileContentProvider.addLoadedVersions(inc.getPath(), fCurrentContext.getLoadedVersionCount(), sig);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkNumber(Token number, final boolean isFloat) {
|
||||
final char[] image= number.getCharImage();
|
||||
boolean hasExponent = false;
|
||||
|
||||
|
@ -1151,7 +1255,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
}
|
||||
break;
|
||||
case IPreprocessorDirective.ppPragma:
|
||||
condOffset= lexer.nextToken().getOffset();
|
||||
Token pragmaToken= lexer.nextToken();
|
||||
condOffset= pragmaToken.getOffset();
|
||||
condEndOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
||||
// Missing argument
|
||||
if (condEndOffset < condOffset) {
|
||||
|
@ -1160,6 +1265,10 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
if (fCurrentContext.getCodeState() == CodeState.eActive) {
|
||||
int endOffset= lexer.currentToken().getEndOffset();
|
||||
fLocationMap.encounterPoundPragma(startOffset, condOffset, condEndOffset, endOffset);
|
||||
if (CharArrayUtils.equals(ONCE, pragmaToken.getCharImage())) {
|
||||
IFileNomination nom= fLocationMap.reportPragmaOnceSemantics(fCurrentContext.getLocationCtx());
|
||||
fFileContentProvider.reportPragmaOnceSemantics(getCurrentFilename(), nom);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IPreprocessorDirective.ppIgnore:
|
||||
|
@ -1175,16 +1284,12 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean hasFileBeenIncluded(String location) {
|
||||
Boolean itHas= fFileContentProvider.hasFileBeenIncludedInCurrentTranslationUnit(location);
|
||||
if (itHas != null) {
|
||||
return itHas.booleanValue();
|
||||
}
|
||||
return fAllIncludedFiles.contains(location);
|
||||
}
|
||||
|
||||
private void executeInclude(final Lexer lexer, int poundOffset, boolean include_next,
|
||||
boolean active, boolean withinExpansion) throws OffsetLimitReachedException {
|
||||
// Make sure to clear the extern include guard.
|
||||
final char[] externGuard= fExternIncludeGuard;
|
||||
fExternIncludeGuard= null;
|
||||
|
||||
if (withinExpansion) {
|
||||
final char[] name= lexer.currentToken().getCharImage();
|
||||
final int endOffset = lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
||||
|
@ -1258,71 +1363,129 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
String path= null;
|
||||
boolean reported= false;
|
||||
boolean isHeuristic= false;
|
||||
|
||||
if (active && fCurrentContext.getDepth() == MAX_INCLUSION_DEPTH || fPreventInclusion.containsKey(headerName)) {
|
||||
handleProblem(IProblem.PREPROCESSOR_EXCEEDS_MAXIMUM_INCLUSION_DEPTH,
|
||||
lexer.getInputChars(poundOffset, condEndOffset), poundOffset, condEndOffset);
|
||||
fPreventInclusion.put(headerName);
|
||||
return;
|
||||
}
|
||||
|
||||
final String includeDirective = new String(headerName);
|
||||
if (!active) {
|
||||
// test if the include is inactive just because it was included before (bug 167100)
|
||||
final IncludeResolution resolved= findInclusion(includeDirective, userInclude, include_next,
|
||||
getCurrentFilename(), createPathTester);
|
||||
if (resolved != null && hasFileBeenIncluded(resolved.fLocation)) {
|
||||
path= resolved.fLocation;
|
||||
isHeuristic= resolved.fHeuristic;
|
||||
}
|
||||
} else {
|
||||
final InternalFileContent fi= findInclusion(includeDirective, userInclude, include_next,
|
||||
getCurrentFilename(), createCodeReaderTester);
|
||||
if (fi != null) {
|
||||
path= fi.getFileLocation();
|
||||
isHeuristic= fi.isFoundByHeuristics();
|
||||
switch (fi.getKind()) {
|
||||
case FOUND_IN_INDEX:
|
||||
processInclusionFromIndex(poundOffset, path, fi);
|
||||
break;
|
||||
case USE_SOURCE:
|
||||
AbstractCharArray source= fi.getSource();
|
||||
if (source != null && !isCircularInclusion(path)) {
|
||||
reported= true;
|
||||
fAllIncludedFiles.add(path);
|
||||
ILocationCtx ctx= fLocationMap.pushInclusion(poundOffset, nameOffsets[0], nameOffsets[1],
|
||||
condEndOffset, source, path, headerName, userInclude, isHeuristic, fi.isSource());
|
||||
ScannerContext fctx= new ScannerContext(ctx, fCurrentContext,
|
||||
new Lexer(source, fLexOptions, this, this));
|
||||
fctx.setFoundOnPath(fi.getFoundOnPath(), includeDirective);
|
||||
fCurrentContext= fctx;
|
||||
// Inactive include
|
||||
String path= null;
|
||||
boolean isHeuristic= false;
|
||||
IFileNomination nominationDelegate= null;
|
||||
|
||||
if (externGuard != null) {
|
||||
// #ifndef GUARD
|
||||
// #include "file.h"
|
||||
// #endif
|
||||
// When the extern guard matches we need to resolve the inclusion. We don't actually
|
||||
// check whether the guard matches.
|
||||
final IncludeResolution resolved= findInclusion(includeDirective, userInclude, include_next,
|
||||
getCurrentFilename(), createPathTester);
|
||||
if (resolved != null) {
|
||||
nominationDelegate = fFileContentProvider.isIncludedWithPragmaOnceSemantics(resolved.fLocation);
|
||||
if (nominationDelegate != null) {
|
||||
path= resolved.fLocation;
|
||||
isHeuristic= resolved.fHeuristic;
|
||||
}
|
||||
fLocationMap.replacingFile(fFileContentProvider, fi);
|
||||
break;
|
||||
|
||||
case SKIP_FILE:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
final int len = headerName.length + 2;
|
||||
StringBuilder name= new StringBuilder(len);
|
||||
name.append(userInclude ? '"' : '<');
|
||||
name.append(headerName);
|
||||
name.append(userInclude ? '"' : '>');
|
||||
|
||||
final char[] nameChars= new char[len];
|
||||
name.getChars(0, len, nameChars, 0);
|
||||
handleProblem(IProblem.PREPROCESSOR_INCLUSION_NOT_FOUND, nameChars, poundOffset, condEndOffset);
|
||||
}
|
||||
fLocationMap.encounterPoundInclude(poundOffset, nameOffsets[0], nameOffsets[1],
|
||||
condEndOffset, headerName, path, userInclude, active, isHeuristic, nominationDelegate);
|
||||
return;
|
||||
}
|
||||
|
||||
// Active include
|
||||
final InternalFileContent fi= findInclusion(includeDirective, userInclude, include_next,
|
||||
getCurrentFilename(), createCodeReaderTester);
|
||||
if (fi == null) {
|
||||
// Unresolved active include
|
||||
final int len = headerName.length + 2;
|
||||
StringBuilder name= new StringBuilder(len);
|
||||
name.append(userInclude ? '"' : '<');
|
||||
name.append(headerName);
|
||||
name.append(userInclude ? '"' : '>');
|
||||
|
||||
final char[] nameChars= new char[len];
|
||||
name.getChars(0, len, nameChars, 0);
|
||||
handleProblem(IProblem.PREPROCESSOR_INCLUSION_NOT_FOUND, nameChars, poundOffset, condEndOffset);
|
||||
fLocationMap.encounterPoundInclude(poundOffset, nameOffsets[0], nameOffsets[1],
|
||||
condEndOffset, headerName, null, userInclude, active, false, null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!reported) {
|
||||
fLocationMap.encounterPoundInclude(poundOffset, nameOffsets[0], nameOffsets[1],
|
||||
condEndOffset, headerName, path, userInclude, active, isHeuristic);
|
||||
// Resolved active include
|
||||
final String path= fi.getFileLocation();
|
||||
final boolean isHeuristic= fi.isFoundByHeuristics();
|
||||
final boolean pragmaOnceContext= fCurrentContext.isPragmaOnce();
|
||||
|
||||
IFileNomination nominationDelegate= null;
|
||||
ASTInclusionStatement stmt= null;
|
||||
List<ISignificantMacros> loadedVerisons = null;
|
||||
switch (fi.getKind()) {
|
||||
case FOUND_IN_INDEX:
|
||||
// Pulled in from index
|
||||
nominationDelegate= fi.getFilesIncluded().get(0);
|
||||
try {
|
||||
ISignificantMacros sm = nominationDelegate.getSignificantMacros();
|
||||
fCurrentContext.addSignificantMacros(sm);
|
||||
if (pragmaOnceContext && !nominationDelegate.hasPragmaOnceSemantics())
|
||||
loadedVerisons= fFileContentProvider.getLoadedVersions(path);
|
||||
} catch (CoreException e) {
|
||||
}
|
||||
|
||||
processInclusionFromIndex(poundOffset, path, fi, true);
|
||||
break;
|
||||
case USE_SOURCE:
|
||||
// Will be parsed
|
||||
AbstractCharArray source= fi.getSource();
|
||||
if (source != null) {
|
||||
ILocationCtx ctx= fLocationMap.pushInclusion(poundOffset, nameOffsets[0], nameOffsets[1],
|
||||
condEndOffset, source, path, headerName, userInclude, isHeuristic, fi.isSource());
|
||||
ScannerContext fctx= new ScannerContext(ctx, fCurrentContext,
|
||||
new Lexer(source, fLexOptions, this, this));
|
||||
fctx.setFoundOnPath(fi.getFoundOnPath(), includeDirective);
|
||||
detectIncludeGuard(path, source, fctx);
|
||||
fCurrentContext= fctx;
|
||||
stmt= ctx.getInclusionStatement();
|
||||
stmt.setContentsHash(source.getContentsHash());
|
||||
if (!fCurrentContext.isPragmaOnce()) {
|
||||
// Track the loaded version count, even in a non-pragma-once context.
|
||||
loadedVerisons= fFileContentProvider.getLoadedVersions(path);
|
||||
fctx.setLoadedVersionCount(loadedVerisons.size());
|
||||
}
|
||||
}
|
||||
fLocationMap.parsingFile(fFileContentProvider, fi);
|
||||
break;
|
||||
|
||||
case SKIP_FILE:
|
||||
// Already included or fast parsing mode.
|
||||
break;
|
||||
}
|
||||
if (stmt == null) {
|
||||
// Found in index or skipped.
|
||||
stmt= fLocationMap.encounterPoundInclude(poundOffset, nameOffsets[0], nameOffsets[1],
|
||||
condEndOffset, headerName, path, userInclude, active, isHeuristic, nominationDelegate);
|
||||
}
|
||||
// In a pragma once context store loaded versions of this non-pragma-once include
|
||||
if (pragmaOnceContext && loadedVerisons != null && !loadedVerisons.isEmpty()) {
|
||||
stmt.setLoadedVersions(loadedVerisons.toArray(new ISignificantMacros[loadedVerisons.size()]));
|
||||
}
|
||||
}
|
||||
|
||||
private void processInclusionFromIndex(int offset, String path, InternalFileContent fi) {
|
||||
private void processInclusionFromIndex(int offset, String path, InternalFileContent fi, boolean updateContext) {
|
||||
List<IIndexMacro> mdefs= fi.getMacroDefinitions();
|
||||
for (IIndexMacro macro : mdefs) {
|
||||
addMacroDefinition(macro);
|
||||
if (updateContext)
|
||||
fCurrentContext.internalModification(macro.getNameCharArray());
|
||||
}
|
||||
for (FileVersion version : fi.getNonPragmaOnceVersions()) {
|
||||
fFileContentProvider.addLoadedVersions(version.fPath, Integer.MAX_VALUE, version.fSigMacros);
|
||||
}
|
||||
fLocationMap.skippedFile(fLocationMap.getSequenceNumberForOffset(offset), fi);
|
||||
}
|
||||
|
@ -1346,24 +1509,15 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
return headerName;
|
||||
}
|
||||
|
||||
private boolean isCircularInclusion(String filename) {
|
||||
ILocationCtx checkContext= fCurrentContext.getLocationCtx();
|
||||
while (checkContext != null) {
|
||||
if (filename.equals(checkContext.getFilePath())) {
|
||||
return true;
|
||||
}
|
||||
checkContext= checkContext.getParent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private void executeDefine(final Lexer lexer, int startOffset, boolean isActive)
|
||||
throws OffsetLimitReachedException {
|
||||
try {
|
||||
ObjectStyleMacro macrodef = fMacroDefinitionParser.parseMacroDefinition(lexer, this);
|
||||
if (isActive)
|
||||
fMacroDictionary.put(macrodef.getNameCharArray(), macrodef);
|
||||
if (isActive) {
|
||||
final char[] macroName = macrodef.getNameCharArray();
|
||||
fMacroDictionary.put(macroName, macrodef);
|
||||
fCurrentContext.internalModification(macroName);
|
||||
}
|
||||
|
||||
final Token name= fMacroDefinitionParser.getNameToken();
|
||||
fLocationMap.encounterPoundDefine(startOffset, name.getOffset(), name.getEndOffset(),
|
||||
|
@ -1393,6 +1547,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
PreprocessorMacro definition;
|
||||
if (isActive) {
|
||||
definition= fMacroDictionary.remove(namechars, 0, namechars.length);
|
||||
fCurrentContext.internalModification(namechars);
|
||||
} else {
|
||||
definition= fMacroDictionary.get(namechars);
|
||||
}
|
||||
|
@ -1422,10 +1577,18 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
handleProblem(IProblem.PREPROCESSOR_DEFINITION_NOT_FOUND, name.getCharImage(), offset, nameEndOffset);
|
||||
} else {
|
||||
final char[] namechars= name.getCharImage();
|
||||
if (isIfndef) {
|
||||
if (IncludeGuardDetection.detectIncludeEndif(lexer)) {
|
||||
fExternIncludeGuard= namechars;
|
||||
}
|
||||
}
|
||||
macro= fMacroDictionary.get(namechars);
|
||||
isTaken= (macro == null) == isIfndef;
|
||||
if (macro == null) {
|
||||
macro = new UndefinedMacro(namechars);
|
||||
fCurrentContext.significantMacroUndefined(namechars);
|
||||
} else {
|
||||
fCurrentContext.significantMacroDefined(namechars);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1442,7 +1605,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
return fCurrentContext.setBranchState(conditional, isTaken, withinExpansion, offset);
|
||||
}
|
||||
|
||||
private CodeState executeIf(Lexer lexer, int startOffset, boolean isElif,
|
||||
private CodeState executeIf(Lexer lexer, int startOffset, boolean isElif,
|
||||
boolean withinExpansion) throws OffsetLimitReachedException {
|
||||
Conditional cond= fCurrentContext.newBranch(isElif ? BranchKind.eElif : BranchKind.eIf, withinExpansion);
|
||||
if (cond == null) {
|
||||
|
@ -1458,6 +1621,11 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
int condEndOffset, endOffset;
|
||||
|
||||
if (cond.canHaveActiveBranch(withinExpansion)) {
|
||||
char[] macro= IncludeGuardDetection.detectIfNotDefinedIncludeEndif(lexer);
|
||||
if (macro != null) {
|
||||
fExternIncludeGuard= macro;
|
||||
}
|
||||
|
||||
TokenList condition= new TokenList();
|
||||
condEndOffset= getTokensWithinPPDirective(true, condition, withinExpansion);
|
||||
endOffset= lexer.currentToken().getEndOffset();
|
||||
|
@ -1469,6 +1637,14 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
fExpressionEvaluator.clearMacrosInDefinedExpression();
|
||||
isTaken= fExpressionEvaluator.evaluate(condition, fMacroDictionary, fLocationMap);
|
||||
refs = fExpressionEvaluator.clearMacrosInDefinedExpression();
|
||||
for (IASTName iastName : refs) {
|
||||
IBinding mb= iastName.getBinding();
|
||||
if (mb instanceof UndefinedMacro) {
|
||||
fCurrentContext.significantMacroUndefined(iastName.toCharArray());
|
||||
} else {
|
||||
fCurrentContext.significantMacroDefined(iastName.toCharArray());
|
||||
}
|
||||
}
|
||||
} catch (EvalException e) {
|
||||
handleProblem(e.getProblemID(), e.getProblemArg(), condOffset, endOffset);
|
||||
}
|
||||
|
@ -1531,7 +1707,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
boolean withinExpansion) throws OffsetLimitReachedException {
|
||||
final ScannerContext scannerCtx= fCurrentContext;
|
||||
scannerCtx.clearInactiveCodeMarkerToken();
|
||||
int options= STOP_AT_NL;
|
||||
int options= STOP_AT_NL | REPORT_SIGNIFICANT_MACROS;
|
||||
if (isCondition)
|
||||
options |= PROTECT_DEFINED;
|
||||
|
||||
|
@ -1545,10 +1721,9 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
case Lexer.tNEWLINE:
|
||||
break loop;
|
||||
case IToken.tIDENTIFIER:
|
||||
if (isCondition && CharArrayUtils.equals(Keywords.cDEFINED, t.getCharImage())) {
|
||||
t.setType(CPreprocessor.tDEFINED);
|
||||
options |= NO_EXPANSION;
|
||||
}
|
||||
break;
|
||||
case tDEFINED:
|
||||
options |= NO_EXPANSION;
|
||||
break;
|
||||
case IToken.tLPAREN:
|
||||
break;
|
||||
|
@ -1639,9 +1814,16 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
*/
|
||||
private boolean expandMacro(final Token identifier, Lexer lexer, int options,
|
||||
boolean withinExpansion) throws OffsetLimitReachedException {
|
||||
final boolean reportSignificant = (options & REPORT_SIGNIFICANT_MACROS) != 0;
|
||||
final char[] name= identifier.getCharImage();
|
||||
if ((options & PROTECT_DEFINED) != 0 && CharArrayUtils.equals(name, Keywords.cDEFINED)) {
|
||||
identifier.setType(tDEFINED);
|
||||
return false;
|
||||
}
|
||||
PreprocessorMacro macro= fMacroDictionary.get(name);
|
||||
if (macro == null) {
|
||||
if (reportSignificant && (options & IGNORE_UNDEFINED_SIGNIFICANT_MACROS) == 0)
|
||||
fCurrentContext.significantMacroUndefined(name);
|
||||
return false;
|
||||
}
|
||||
boolean stopAtNewline= (options & STOP_AT_NL) != 0;
|
||||
|
@ -1653,6 +1835,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
}
|
||||
}
|
||||
if (t.getType() != IToken.tLPAREN) {
|
||||
if (reportSignificant)
|
||||
fCurrentContext.significantMacro(macro);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1660,8 +1844,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
final ITokenSequence input= stopAtNewline ? fLineInputToMacroExpansion : fInputToMacroExpansion;
|
||||
final MacroExpander expander = withinExpansion ? new MacroExpander(this, fMacroDictionary,
|
||||
fLocationMap, fLexOptions) : fMacroExpander;
|
||||
TokenList replacement= expander.expand(input, (options & PROTECT_DEFINED) != 0, macro,
|
||||
identifier, contentAssist);
|
||||
TokenList replacement= expander.expand(input, options, macro, identifier, contentAssist, fCurrentContext);
|
||||
final IASTName[] expansions= expander.clearImplicitExpansions();
|
||||
final ImageLocationInfo[] ili= expander.clearImageLocationInfos();
|
||||
final Token last= replacement.last();
|
||||
|
@ -1679,5 +1862,5 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
return fMacroExpander;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -299,11 +299,13 @@ public class ExpressionEvaluator {
|
|||
if (LA() != IToken.tIDENTIFIER) {
|
||||
throw new EvalException(IProblem.SCANNER_ILLEGAL_IDENTIFIER, null);
|
||||
}
|
||||
PreprocessorMacro macro= fDictionary.get(fTokens.getCharImage());
|
||||
if (macro != null) {
|
||||
fMacrosInDefinedExpressions.add(fLocationMap.encounterDefinedExpression(macro, fTokens.getOffset(), fTokens.getEndOffset()));
|
||||
}
|
||||
final char[] macroName = fTokens.getCharImage();
|
||||
PreprocessorMacro macro= fDictionary.get(macroName);
|
||||
int result= macro != null ? 1 : 0;
|
||||
if (macro == null)
|
||||
macro= new UndefinedMacro(macroName);
|
||||
|
||||
fMacrosInDefinedExpressions.add(fLocationMap.encounterDefinedExpression(macro, fTokens.getOffset(), fTokens.getEndOffset()));
|
||||
consume();
|
||||
if (parenthesis) {
|
||||
if (LA() != IToken.tRPAREN) {
|
||||
|
|
|
@ -30,4 +30,8 @@ public interface ILocationCtx {
|
|||
*/
|
||||
ILocationCtx getParent();
|
||||
|
||||
/**
|
||||
* Returns inclusion statement that created this context, or <code>null</code>.
|
||||
*/
|
||||
ASTInclusionStatement getInclusionStatement();
|
||||
}
|
||||
|
|
|
@ -28,5 +28,5 @@ public interface ISkippedIndexedFilesListener {
|
|||
/**
|
||||
* Notifies the listeners that a file is being parsed.
|
||||
*/
|
||||
void replacingFile(InternalFileContentProvider fileContentProvider, InternalFileContent fileContent);
|
||||
void parsingFile(InternalFileContentProvider fileContentProvider, InternalFileContent fileContent);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011 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.scanner;
|
||||
|
||||
import static org.eclipse.cdt.core.parser.OffsetLimitReachedException.ORIGIN_PREPROCESSOR_DIRECTIVE;
|
||||
|
||||
import org.eclipse.cdt.core.parser.IPreprocessorDirective;
|
||||
import org.eclipse.cdt.core.parser.IToken;
|
||||
import org.eclipse.cdt.core.parser.Keywords;
|
||||
import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayIntMap;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
|
||||
/**
|
||||
* Helper class for detecting include guards
|
||||
*/
|
||||
public class IncludeGuardDetection {
|
||||
public static char[] detectIncludeGuard(AbstractCharArray content, Lexer.LexerOptions lexOptions, CharArrayIntMap ppKeywords) {
|
||||
Lexer l= new Lexer(content, lexOptions, ILexerLog.NULL, null);
|
||||
char[] guard= findIncludeGuard(l, ppKeywords);
|
||||
if (guard != null && currentIfSpansFile(l, ppKeywords)) {
|
||||
return guard;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static char[] findIncludeGuard(Lexer l, CharArrayIntMap ppKeywords) {
|
||||
try {
|
||||
if (skipAll(l, Lexer.tNEWLINE).getType() == IToken.tPOUND) {
|
||||
Token t = l.nextToken();
|
||||
if (t.getType() == IToken.tIDENTIFIER) {
|
||||
char[] guard= null;
|
||||
switch(ppKeywords.get(t.getCharImage())) {
|
||||
case IPreprocessorDirective.ppIfndef:
|
||||
// #ifndef GUARD
|
||||
t= l.nextToken();
|
||||
if (t.getType() == IToken.tIDENTIFIER) {
|
||||
guard= t.getCharImage();
|
||||
}
|
||||
break;
|
||||
case IPreprocessorDirective.ppIf:
|
||||
// #if !defined GUARD
|
||||
// #if ((!((defined (GUARD)))))
|
||||
guard = findNotDefined(l);
|
||||
break;
|
||||
}
|
||||
if (guard != null) {
|
||||
// #define GUARD
|
||||
l.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
||||
if (skipAll(l, Lexer.tNEWLINE).getType() == IToken.tPOUND
|
||||
&& checkToken(l.nextToken(), Keywords.cDEFINE)
|
||||
&& checkToken(l.nextToken(), guard)) {
|
||||
l.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
||||
return guard;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (OffsetLimitReachedException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static char[] findNotDefined(Lexer l) throws OffsetLimitReachedException {
|
||||
Token t;
|
||||
if (skipAll(l, IToken.tLPAREN).getType() == IToken.tNOT
|
||||
&& checkToken(skipAll(l, IToken.tLPAREN), Keywords.cDEFINED)) {
|
||||
t= l.nextToken(); // only a single parenthesis is allowed
|
||||
if (t.getType() == IToken.tLPAREN)
|
||||
t= l.nextToken();
|
||||
if (t.getType() == IToken.tIDENTIFIER) {
|
||||
char[] guard= t.getCharImage();
|
||||
if (skipAll(l, IToken.tRPAREN).getType() == Lexer.tNEWLINE)
|
||||
return guard;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean checkToken(Token t, char[] image) throws OffsetLimitReachedException {
|
||||
return CharArrayUtils.equals(t.getCharImage(), image);
|
||||
}
|
||||
|
||||
private static boolean currentIfSpansFile(Lexer l, CharArrayIntMap ppKeywords) {
|
||||
// Check if the #ifndef spans the entire file
|
||||
try {
|
||||
int nesting= 1;
|
||||
while (nesting > 0) {
|
||||
Token t= l.nextDirective();
|
||||
if (t.getType() == IToken.tEND_OF_INPUT)
|
||||
return true;
|
||||
switch(ppKeywords.get(l.nextToken().getCharImage())) {
|
||||
case IPreprocessorDirective.ppIf:
|
||||
case IPreprocessorDirective.ppIfdef:
|
||||
case IPreprocessorDirective.ppIfndef:
|
||||
nesting++;
|
||||
break;
|
||||
case IPreprocessorDirective.ppEndif:
|
||||
nesting--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
l.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
||||
return skipAll(l, Lexer.tNEWLINE).getType() == IToken.tEND_OF_INPUT;
|
||||
} catch (OffsetLimitReachedException e) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Token skipAll(Lexer l, int kind) throws OffsetLimitReachedException {
|
||||
// Skip empty lines
|
||||
Token t= l.nextToken();
|
||||
while (t.getType() == kind)
|
||||
t= l.nextToken();
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
public static boolean detectIncludeEndif(Lexer l) {
|
||||
l.saveState();
|
||||
try {
|
||||
return findIncludeEndif(l);
|
||||
} catch (OffsetLimitReachedException e) {
|
||||
} finally {
|
||||
l.restoreState();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean findIncludeEndif(Lexer l) throws OffsetLimitReachedException {
|
||||
if (skipAll(l, Lexer.tNEWLINE).getType() != IToken.tPOUND)
|
||||
return false;
|
||||
if (!checkToken(l.nextToken(), Keywords.cINCLUDE))
|
||||
return false;
|
||||
l.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
||||
if (skipAll(l, Lexer.tNEWLINE).getType() != IToken.tPOUND)
|
||||
return false;
|
||||
if (!checkToken(l.nextToken(), Keywords.cENDIF))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static char[] detectIfNotDefinedIncludeEndif(Lexer l) {
|
||||
l.saveState();
|
||||
try {
|
||||
char[] guard= findNotDefined(l);
|
||||
if (guard != null && findIncludeEndif(l))
|
||||
return guard;
|
||||
} catch (OffsetLimitReachedException e) {
|
||||
} finally {
|
||||
l.restoreState();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
|
|||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
import org.eclipse.cdt.core.index.IIndexMacro;
|
||||
import org.eclipse.cdt.core.parser.FileContent;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
|
||||
/**
|
||||
* Instructs the preprocessor on how to handle a file-inclusion.
|
||||
|
@ -38,11 +39,21 @@ public class InternalFileContent extends FileContent {
|
|||
USE_SOURCE
|
||||
}
|
||||
|
||||
public static class FileVersion {
|
||||
public final String fPath;
|
||||
public final ISignificantMacros fSigMacros;
|
||||
public FileVersion(String path, ISignificantMacros sig) {
|
||||
fPath= path;
|
||||
fSigMacros= sig;
|
||||
}
|
||||
}
|
||||
|
||||
private final InclusionKind fKind;
|
||||
private final AbstractCharArray fSource;
|
||||
private final List<IIndexMacro> fMacroDefinitions;
|
||||
private final List<ICPPUsingDirective> fUsingDirectives;
|
||||
private final String fFileLocation;
|
||||
private final List<FileVersion> fNonPragmaOnceFiles;
|
||||
private boolean fHeuristic;
|
||||
private boolean fIsSource= false;
|
||||
private List<IIndexFile> fFiles;
|
||||
|
@ -64,6 +75,7 @@ public class InternalFileContent extends FileContent {
|
|||
fMacroDefinitions= null;
|
||||
fUsingDirectives= null;
|
||||
fSource= null;
|
||||
fNonPragmaOnceFiles= null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -79,6 +91,7 @@ public class InternalFileContent extends FileContent {
|
|||
fSource= content;
|
||||
fMacroDefinitions= null;
|
||||
fUsingDirectives= null;
|
||||
fNonPragmaOnceFiles= null;
|
||||
if (fFileLocation == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
@ -92,13 +105,14 @@ public class InternalFileContent extends FileContent {
|
|||
* @throws IllegalArgumentException in case the fileLocation or the macroDefinitions are <code>null</code>.
|
||||
*/
|
||||
public InternalFileContent(String fileLocation, List<IIndexMacro> macroDefinitions, List<ICPPUsingDirective> usingDirectives,
|
||||
List<IIndexFile> files) {
|
||||
List<IIndexFile> files, List<FileVersion> nonPragmaOnceVersions) {
|
||||
fKind= InclusionKind.FOUND_IN_INDEX;
|
||||
fFileLocation= fileLocation;
|
||||
fSource= null;
|
||||
fUsingDirectives= usingDirectives;
|
||||
fMacroDefinitions= macroDefinitions;
|
||||
fFiles= files;
|
||||
fNonPragmaOnceFiles= nonPragmaOnceVersions;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -155,6 +169,10 @@ public class InternalFileContent extends FileContent {
|
|||
public List<IIndexFile> getFilesIncluded() {
|
||||
return fFiles;
|
||||
}
|
||||
|
||||
public List<FileVersion> getNonPragmaOnceVersions() {
|
||||
return fNonPragmaOnceFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this inclusion was found by a heuristics.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2009 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2009, 2011 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
|
||||
|
@ -7,14 +7,25 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IFileNomination;
|
||||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.core.parser.IncludeFileContentProvider;
|
||||
import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics;
|
||||
import org.eclipse.cdt.internal.core.parser.IMacroDictionary;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContent.InclusionKind;
|
||||
|
||||
/**
|
||||
|
@ -22,20 +33,25 @@ import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContent.Inclusio
|
|||
*/
|
||||
public abstract class InternalFileContentProvider extends IncludeFileContentProvider {
|
||||
private IIncludeFileResolutionHeuristics fIncludeResolutionHeuristics;
|
||||
private final Map<String, IFileNomination> fPragmaOnce= new HashMap<String, IFileNomination>();
|
||||
private final Map<String, List<ISignificantMacros>> fLoadedVersions= new HashMap<String, List<ISignificantMacros>>();
|
||||
|
||||
/**
|
||||
* Check whether the specified inclusion exists.
|
||||
* Checks whether the specified inclusion exists.
|
||||
*/
|
||||
public boolean getInclusionExists(String path) {
|
||||
return new File(path).exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an InclusionContent object for the given location.
|
||||
* return an inclusion content or <code>null</code> if the location does not exist.
|
||||
* Creates an InclusionContent object for the given location.
|
||||
* @param filePath the absolute location of the file.
|
||||
* @param macroDictionary macros defined at the inclusion point.
|
||||
* @return Returns an inclusion content, or <code>null</code> if the location does not exist.
|
||||
* @see InternalFileContent
|
||||
*/
|
||||
public abstract InternalFileContent getContentForInclusion(String path);
|
||||
public abstract InternalFileContent getContentForInclusion(String filePath,
|
||||
IMacroDictionary macroDictionary);
|
||||
|
||||
/**
|
||||
* Called only when used as a delegate of the index file content provider.
|
||||
|
@ -46,28 +62,38 @@ public abstract class InternalFileContentProvider extends IncludeFileContentProv
|
|||
* Returns a file-content object of kind {@link InclusionKind#FOUND_IN_INDEX}, representing
|
||||
* the content from the context of the given file up to where the file actually gets included,
|
||||
* or <code>null</code> if this cannot be done.
|
||||
* @param filePath the absolute location of the file.
|
||||
* @param macroDictionary macros defined at the inclusion point.
|
||||
*/
|
||||
public InternalFileContent getContentForContextToHeaderGap(String location) {
|
||||
public InternalFileContent getContentForContextToHeaderGap(String filePath,
|
||||
IMacroDictionary macroDictionary) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports the path of the translation unit, such that it is known as included.
|
||||
*/
|
||||
public void reportTranslationUnitFile(String filePath) {
|
||||
public void resetForTranslationUnit() {
|
||||
fPragmaOnce.clear();
|
||||
fLoadedVersions.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the file has been included, or <code>null</code> if the content provider
|
||||
* does not track that.
|
||||
|
||||
/**
|
||||
* Reports detection of pragma once semantics.
|
||||
*/
|
||||
public Boolean hasFileBeenIncludedInCurrentTranslationUnit(String location) {
|
||||
return null;
|
||||
public void reportPragmaOnceSemantics(String file, IFileNomination nomination) {
|
||||
fPragmaOnce.put(file, nomination);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a strategy for heuristically resolving includes, or <code>null</code> if this shall not
|
||||
* be done.
|
||||
* Returns {@link IASTPreprocessorIncludeStatement} or {@link IIndexFile}, in
|
||||
* case the file has been included using pragma once semantics,
|
||||
* or <code>null</code> otherwise.
|
||||
*/
|
||||
public IFileNomination isIncludedWithPragmaOnceSemantics(String filePath) {
|
||||
return fPragmaOnce.get(filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a strategy for heuristically resolving includes, or <code>null</code> if this shall
|
||||
* not be done.
|
||||
*/
|
||||
public final IIncludeFileResolutionHeuristics getIncludeHeuristics() {
|
||||
return fIncludeResolutionHeuristics;
|
||||
|
@ -76,4 +102,26 @@ public abstract class InternalFileContentProvider extends IncludeFileContentProv
|
|||
public final void setIncludeResolutionHeuristics(IIncludeFileResolutionHeuristics heuristics) {
|
||||
fIncludeResolutionHeuristics= heuristics;
|
||||
}
|
||||
|
||||
public List<ISignificantMacros> getLoadedVersions(String path) {
|
||||
List<ISignificantMacros> result = fLoadedVersions.get(path);
|
||||
return result == null ? Collections.<ISignificantMacros>emptyList() : result;
|
||||
}
|
||||
|
||||
public void addLoadedVersions(String path, int reduceVersions, ISignificantMacros sig) {
|
||||
List<ISignificantMacros> list= fLoadedVersions.get(path);
|
||||
if (list == null || reduceVersions == 0) {
|
||||
fLoadedVersions.put(path, Collections.singletonList(sig));
|
||||
} else if (!list.contains(sig)) {
|
||||
if (list.size() == 1) {
|
||||
ISignificantMacros first = list.get(0);
|
||||
list= new ArrayList<ISignificantMacros>(2);
|
||||
list.add(first);
|
||||
fLoadedVersions.put(path, list);
|
||||
} else if (reduceVersions > 0 && reduceVersions < list.size()) {
|
||||
list.subList(reduceVersions, list.size()).clear();
|
||||
}
|
||||
list.add(sig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,10 +85,14 @@ final public class Lexer implements ITokenSequence {
|
|||
private Token fToken;
|
||||
private Token fLastToken;
|
||||
|
||||
// for the few cases where we have to lookahead more than one character
|
||||
// For the few cases where we have to lookahead more than one character
|
||||
private int fMarkOffset;
|
||||
private int fMarkEndOffset;
|
||||
private int fMarkPrefetchedChar;
|
||||
// To store the entire state.
|
||||
private boolean fMarkInsideIncludeDirective;
|
||||
private Token fMarkToken;
|
||||
private Token fMarkLastToken;
|
||||
|
||||
public Lexer(char[] input, LexerOptions options, ILexerLog log, Object source) {
|
||||
this(new CharArray(input), 0, input.length, options, log, source);
|
||||
|
@ -1256,4 +1260,22 @@ final public class Lexer implements ITokenSequence {
|
|||
restorePhase3();
|
||||
return result;
|
||||
}
|
||||
|
||||
public void saveState() {
|
||||
fMarkOffset= fOffset;
|
||||
fMarkEndOffset= fEndOffset;
|
||||
fMarkPrefetchedChar= fCharPhase3;
|
||||
fMarkInsideIncludeDirective= fInsideIncludeDirective;
|
||||
fMarkToken= fToken;
|
||||
fMarkLastToken= fLastToken;
|
||||
}
|
||||
|
||||
public void restoreState() {
|
||||
fOffset= fMarkOffset;
|
||||
fEndOffset= fMarkEndOffset;
|
||||
fCharPhase3= fMarkPrefetchedChar;
|
||||
fInsideIncludeDirective= fMarkInsideIncludeDirective;
|
||||
fToken= fMarkToken;
|
||||
fLastToken= fMarkLastToken;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -259,4 +259,9 @@ class LocationCtxContainer extends LocationCtx {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "<synthetic>"; //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,4 +131,9 @@ class LocationCtxFile extends LocationCtxContainer {
|
|||
public boolean isSourceFile() {
|
||||
return fIsSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return fFilename;
|
||||
}
|
||||
}
|
|
@ -105,4 +105,9 @@ class LocationCtxMacroExpansion extends LocationCtx {
|
|||
public ASTPreprocessorName[] getNestedMacroReferences() {
|
||||
return fLocationMap.getNestedMacroReferences((ASTMacroExpansion) fExpansionName.getParent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Expansion of " + fExpansionName.toString(); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2007, 2011 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
|
||||
|
@ -30,8 +30,12 @@ import org.eclipse.cdt.core.dom.ast.IASTProblem;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IFileNomination;
|
||||
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeSpecification;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTProblem;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
|
||||
|
@ -130,7 +134,7 @@ public class LocationMap implements ILocationResolver {
|
|||
int nameEndNumber= getSequenceNumberForOffset(nameEndOffset);
|
||||
int endNumber= getSequenceNumberForOffset(endOffset);
|
||||
final ASTInclusionStatement inclusionStatement=
|
||||
new ASTInclusionStatement(fTranslationUnit, startNumber, nameNumber, nameEndNumber, endNumber, name, filename, userInclude, true, heuristic);
|
||||
new ASTInclusionStatement(fTranslationUnit, startNumber, nameNumber, nameEndNumber, endNumber, name, filename, userInclude, true, heuristic, null);
|
||||
fDirectives.add(inclusionStatement);
|
||||
fCurrentContext= new LocationCtxFile((LocationCtxContainer) fCurrentContext, filename, buffer, startOffset, endOffset, endNumber, inclusionStatement, isSource);
|
||||
fLastChildInsertionOffset= 0;
|
||||
|
@ -226,14 +230,17 @@ public class LocationMap implements ILocationResolver {
|
|||
* @param userInclude <code>true</code> when specified with double-quotes.
|
||||
* @param active <code>true</code> when include appears in active code.
|
||||
*/
|
||||
public void encounterPoundInclude(int startOffset, int nameOffset, int nameEndOffset, int endOffset,
|
||||
char[] name, String filename, boolean userInclude, boolean active, boolean heuristic) {
|
||||
public ASTInclusionStatement encounterPoundInclude(int startOffset, int nameOffset, int nameEndOffset, int endOffset,
|
||||
char[] name, String filename, boolean userInclude, boolean active, boolean heuristic,
|
||||
IFileNomination nominationDelegate) {
|
||||
startOffset= getSequenceNumberForOffset(startOffset);
|
||||
nameOffset= getSequenceNumberForOffset(nameOffset);
|
||||
nameEndOffset= getSequenceNumberForOffset(nameEndOffset);
|
||||
endOffset= getSequenceNumberForOffset(endOffset);
|
||||
fDirectives.add(new ASTInclusionStatement(fTranslationUnit, startOffset, nameOffset,
|
||||
nameEndOffset, endOffset, name, filename, userInclude, active, heuristic));
|
||||
final ASTInclusionStatement inc = new ASTInclusionStatement(fTranslationUnit, startOffset, nameOffset,
|
||||
nameEndOffset, endOffset, name, filename, userInclude, active, heuristic, nominationDelegate);
|
||||
fDirectives.add(inc);
|
||||
return inc;
|
||||
}
|
||||
|
||||
public void encounteredComment(int offset, int endOffset, boolean isBlockComment) {
|
||||
|
@ -743,10 +750,39 @@ public class LocationMap implements ILocationResolver {
|
|||
}
|
||||
}
|
||||
|
||||
public void replacingFile(InternalFileContentProvider fileContentProvider,
|
||||
public void parsingFile(InternalFileContentProvider fileContentProvider,
|
||||
InternalFileContent fileContent) {
|
||||
for (ISkippedIndexedFilesListener l : fSkippedFilesListeners) {
|
||||
l.replacingFile(fileContentProvider, fileContent);
|
||||
l.parsingFile(fileContentProvider, fileContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IFileNomination reportPragmaOnceSemantics(ILocationCtx locationCtx) {
|
||||
if (locationCtx == fRootContext) {
|
||||
if (fTranslationUnit != null) {
|
||||
fTranslationUnit.setPragmaOnceSemantics(true);
|
||||
}
|
||||
return fTranslationUnit;
|
||||
} else if (locationCtx instanceof LocationCtxFile) {
|
||||
ASTInclusionStatement stmt = ((LocationCtxFile) locationCtx).getInclusionStatement();
|
||||
if (stmt != null) {
|
||||
stmt.setPragamOnceSemantics(true);
|
||||
}
|
||||
return stmt;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void endTranslationUnit(int endOffset, CharArrayObjectMap<char[]> sigMacros) {
|
||||
if (fTranslationUnit != null) {
|
||||
int offset= getSequenceNumberForOffset(endOffset);
|
||||
((ASTNode) fTranslationUnit).setLength(offset);
|
||||
|
||||
if (sigMacros != null) {
|
||||
ISignificantMacros sig = sigMacros.isEmpty() ? ISignificantMacros.NONE
|
||||
: new SignificantMacros(sigMacros);
|
||||
fTranslationUnit.setSignificantMacros(sig);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -136,6 +136,8 @@ public class MacroExpander {
|
|||
private String fFixedCurrentFilename;
|
||||
private int fFixedLineNumber;
|
||||
private char[] fFixedInput;
|
||||
private ScannerContext fReportMacros;
|
||||
private boolean fReportUndefined;
|
||||
|
||||
public MacroExpander(ILexerLog log, CharArrayMap<PreprocessorMacro> macroDictionary, LocationMap locationMap, LexerOptions lexOptions) {
|
||||
fDictionary= macroDictionary;
|
||||
|
@ -147,8 +149,19 @@ public class MacroExpander {
|
|||
|
||||
/**
|
||||
* Expects that the identifier has been consumed, stores the result in the list provided.
|
||||
* @param scannerContext
|
||||
*/
|
||||
public TokenList expand(ITokenSequence lexer, final boolean isPPCondition, PreprocessorMacro macro, Token identifier, boolean completionMode) throws OffsetLimitReachedException {
|
||||
public TokenList expand(ITokenSequence lexer, final int ppOptions,
|
||||
PreprocessorMacro macro, Token identifier, boolean completionMode,
|
||||
ScannerContext scannerContext) throws OffsetLimitReachedException {
|
||||
final boolean protectDefined= (ppOptions & CPreprocessor.PROTECT_DEFINED) != 0;
|
||||
if ((ppOptions & CPreprocessor.REPORT_SIGNIFICANT_MACROS) != 0) {
|
||||
fReportMacros= scannerContext;
|
||||
fReportUndefined= (ppOptions & CPreprocessor.IGNORE_UNDEFINED_SIGNIFICANT_MACROS) == 0;
|
||||
} else {
|
||||
fReportMacros= null;
|
||||
}
|
||||
|
||||
fImplicitMacroExpansions.clear();
|
||||
fImageLocationInfos.clear();
|
||||
|
||||
|
@ -170,7 +183,7 @@ public class MacroExpander {
|
|||
|
||||
input.prepend(firstExpansion);
|
||||
|
||||
result= expandAll(input, forbidden, isPPCondition, null);
|
||||
result= expandAll(input, forbidden, protectDefined, null);
|
||||
} catch (CompletionInMacroExpansionException e) {
|
||||
// for content assist in macro expansions, we return the list of tokens of the
|
||||
// parameter at the current cursor position and hope that they make sense if
|
||||
|
@ -180,6 +193,7 @@ public class MacroExpander {
|
|||
result= e.getParameterTokens().cloneTokens();
|
||||
}
|
||||
postProcessTokens(result);
|
||||
fReportMacros= null;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -193,6 +207,7 @@ public class MacroExpander {
|
|||
fFixedInput= beforeExpansion.toCharArray();
|
||||
fFixedCurrentFilename= filePath;
|
||||
fFixedLineNumber= lineNumber;
|
||||
fReportMacros= null;
|
||||
Lexer lexer= new Lexer(fFixedInput, fLexOptions, fLog, this);
|
||||
|
||||
try {
|
||||
|
@ -240,6 +255,9 @@ public class MacroExpander {
|
|||
IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden, TokenSource input, TokenList result,
|
||||
MacroExpansionTracker tracker)
|
||||
throws OffsetLimitReachedException {
|
||||
if (fReportMacros != null)
|
||||
fReportMacros.significantMacro(macro);
|
||||
|
||||
if (macro.isFunctionStyle()) {
|
||||
final int paramCount = macro.getParameterPlaceholderList().length;
|
||||
final TokenSource[] argInputs= new TokenSource[paramCount];
|
||||
|
@ -351,6 +369,13 @@ public class MacroExpander {
|
|||
protect= true;
|
||||
} else if (macro == null || (macro.isFunctionStyle() && !input.findLParenthesis())) {
|
||||
// Tricky: Don't mark function-style macros if you don't find the left parenthesis
|
||||
if (fReportMacros != null) {
|
||||
if (macro != null) {
|
||||
fReportMacros.significantMacro(macro);
|
||||
} else if (fReportUndefined){
|
||||
fReportMacros.significantMacroUndefined(image);
|
||||
}
|
||||
}
|
||||
result.append(t);
|
||||
} else if (forbidden.containsKey(macro)) {
|
||||
t.setType(CPreprocessor.tEXPANDED_IDENTIFIER); // prevent any further expansion
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorElifStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
|
@ -48,13 +49,14 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer {
|
|||
fOffset= offset;
|
||||
fLength= length;
|
||||
}
|
||||
public int getNodeOffset() {return fOffset;}
|
||||
public int getNodeLength() {return fLength;}
|
||||
public String getFileName() {return fFilePath;}
|
||||
public int getNodeOffset() { return fOffset; }
|
||||
public int getNodeLength() { return fLength; }
|
||||
public String getFileName() { return fFilePath; }
|
||||
|
||||
public int getStartingLineNumber() {return 0;}
|
||||
public int getEndingLineNumber() {return 0;}
|
||||
public IASTFileLocation asFileLocation() {return this;}
|
||||
public int getStartingLineNumber() { return 0; }
|
||||
public int getEndingLineNumber() { return 0; }
|
||||
public IASTFileLocation asFileLocation() { return this; }
|
||||
public IASTPreprocessorIncludeStatement getContextInclusionStatement() { return null; }
|
||||
}
|
||||
|
||||
private final char[] fSource;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007, 2009 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2007, 2011 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
|
||||
|
@ -12,8 +12,12 @@ package org.eclipse.cdt.internal.core.parser.scanner;
|
|||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.core.parser.IToken;
|
||||
import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
|
||||
import org.eclipse.cdt.core.parser.util.CharArraySet;
|
||||
|
||||
/**
|
||||
* Represents part of the input to the preprocessor. This may be a file or the result of a macro expansion.
|
||||
|
@ -43,6 +47,7 @@ final class ScannerContext {
|
|||
}
|
||||
|
||||
private CodeState fInactiveState= CodeState.eSkipInactive;
|
||||
private final int fDepth;
|
||||
private final ILocationCtx fLocationCtx;
|
||||
private final ScannerContext fParent;
|
||||
private final Lexer fLexer;
|
||||
|
@ -51,6 +56,11 @@ final class ScannerContext {
|
|||
private CodeState fCurrentState= CodeState.eActive;
|
||||
private IncludeSearchPathElement fFoundOnPath;
|
||||
private String fFoundViaDirective;
|
||||
private CharArraySet fInternalModifications;
|
||||
private CharArrayObjectMap<char[]> fSignificantMacros;
|
||||
private boolean fPragmaOnce;
|
||||
private int fLoadedVersionCount;
|
||||
|
||||
|
||||
/**
|
||||
* @param ctx
|
||||
|
@ -60,6 +70,7 @@ final class ScannerContext {
|
|||
fLocationCtx= ctx;
|
||||
fParent= parent;
|
||||
fLexer= lexer;
|
||||
fDepth = parent == null ? 0 : parent.fDepth+1;
|
||||
}
|
||||
|
||||
public ScannerContext(ILocationCtx ctx, ScannerContext parent, TokenList tokens) {
|
||||
|
@ -87,6 +98,13 @@ final class ScannerContext {
|
|||
return fParent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the depth of this context, equals the number of parents of this context.
|
||||
*/
|
||||
public final int getDepth() {
|
||||
return fDepth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lexer for this context.
|
||||
*/
|
||||
|
@ -297,4 +315,123 @@ final class ScannerContext {
|
|||
fFoundOnPath= foundOnPath;
|
||||
fFoundViaDirective= viaDirective;
|
||||
}
|
||||
|
||||
public void trackSignificantMacros() {
|
||||
fInternalModifications= new CharArraySet(5);
|
||||
fSignificantMacros= new CharArrayObjectMap<char[]>(5);
|
||||
}
|
||||
|
||||
public void setPragmaOnce(boolean val) {
|
||||
fPragmaOnce= val;
|
||||
}
|
||||
|
||||
public boolean isPragmaOnce() {
|
||||
return fPragmaOnce;
|
||||
}
|
||||
|
||||
public void internalModification(char[] macroName) {
|
||||
if (fInternalModifications != null)
|
||||
fInternalModifications.put(macroName);
|
||||
}
|
||||
|
||||
public void significantMacro(IMacroBinding macro) {
|
||||
final char[] macroName= macro.getNameCharArray();
|
||||
if (fInternalModifications != null && !fInternalModifications.containsKey(macroName)) {
|
||||
fSignificantMacros.put(macroName, macro.getExpansion());
|
||||
}
|
||||
}
|
||||
|
||||
public void significantMacroDefined(char[] macroName) {
|
||||
if (fInternalModifications != null && !fInternalModifications.containsKey(macroName)) {
|
||||
addSignificantMacroDefined(macroName);
|
||||
}
|
||||
}
|
||||
|
||||
private void addSignificantMacroDefined(char[] macroName) {
|
||||
char[] old= fSignificantMacros.put(macroName, SignificantMacros.DEFINED);
|
||||
if (old != null && old != SignificantMacros.DEFINED) {
|
||||
// Put back more detailed condition
|
||||
fSignificantMacros.put(macroName, old);
|
||||
}
|
||||
}
|
||||
|
||||
public void significantMacroUndefined(char[] macroName) {
|
||||
if (fInternalModifications != null && !fInternalModifications.containsKey(macroName)) {
|
||||
fSignificantMacros.put(macroName, SignificantMacros.UNDEFINED);
|
||||
}
|
||||
}
|
||||
|
||||
public CharArrayObjectMap<char[]> getSignificantMacros() {
|
||||
return fSignificantMacros;
|
||||
}
|
||||
|
||||
public void propagateSignificantMacros() {
|
||||
if (fInternalModifications == null)
|
||||
return;
|
||||
|
||||
if (fParent != null) {
|
||||
final CharArraySet local = fParent.fInternalModifications;
|
||||
if (local != null) {
|
||||
final CharArrayObjectMap<char[]> significant = fParent.fSignificantMacros;
|
||||
for (int i=0; i<fSignificantMacros.size(); i++) {
|
||||
final char[] name = fSignificantMacros.keyAt(i);
|
||||
if (!local.containsKey(name)) {
|
||||
final char[] value= fSignificantMacros.getAt(i);
|
||||
if (value == SignificantMacros.DEFINED) {
|
||||
if (!local.containsKey(name)) {
|
||||
fParent.addSignificantMacroDefined(name);
|
||||
}
|
||||
} else {
|
||||
significant.put(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
local.addAll(fInternalModifications);
|
||||
}
|
||||
}
|
||||
fInternalModifications= null;
|
||||
fSignificantMacros= null;
|
||||
}
|
||||
|
||||
public void addSignificantMacros(ISignificantMacros sm) {
|
||||
if (fInternalModifications == null)
|
||||
return;
|
||||
|
||||
sm.accept(new ISignificantMacros.IVisitor() {
|
||||
public boolean visitValue(char[] macro, char[] value) {
|
||||
if (!fInternalModifications.containsKey(macro)) {
|
||||
fSignificantMacros.put(macro, value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public boolean visitUndefined(char[] macro) {
|
||||
if (!fInternalModifications.containsKey(macro)) {
|
||||
fSignificantMacros.put(macro, SignificantMacros.UNDEFINED);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public boolean visitDefined(char[] macro) {
|
||||
if (!fInternalModifications.containsKey(macro)) {
|
||||
fSignificantMacros.put(macro, SignificantMacros.DEFINED);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public int getLoadedVersionCount() {
|
||||
return fLoadedVersionCount;
|
||||
}
|
||||
|
||||
public void setLoadedVersionCount(int count) {
|
||||
fLoadedVersionCount= count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (fParent == null)
|
||||
return fLocationCtx.toString();
|
||||
|
||||
return fParent.toString() + "\n" + fLocationCtx.toString(); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011 Google, 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:
|
||||
* Sergey Prigogin (Google) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
|
||||
/**
|
||||
* A set of static methods to encode Map<String, String> as an array of characters and to decode
|
||||
* it back.
|
||||
*
|
||||
* The map is encoded as:
|
||||
* <code><number_of_entries>,<key1><value1>...<keyN><valueN></code>.
|
||||
* <p>
|
||||
* Each string is encoded as: <code><number_of_characters>,<characters></code>.
|
||||
* A <code>null</code> string is encoded as a single comma.
|
||||
*/
|
||||
public class SignificantMacros implements ISignificantMacros {
|
||||
public static final char[] UNDEFINED = {};
|
||||
public static final char[] DEFINED = {};
|
||||
private static final int ENCODED_UNDEFINED = Character.MAX_VALUE;
|
||||
private static final int ENCODED_DEFINED = Character.MAX_VALUE-1;
|
||||
private static final Comparator<Object> SORTER = new Comparator<Object>() {
|
||||
public int compare(Object o1, Object o2) {
|
||||
return CharArrayUtils.compare((char[])o1, (char[])o2);
|
||||
}
|
||||
};
|
||||
|
||||
private final char[] fEncoded;
|
||||
private int fHash;
|
||||
|
||||
public SignificantMacros(char[] encoded) {
|
||||
assert encoded != null;
|
||||
fEncoded= encoded;
|
||||
}
|
||||
|
||||
public SignificantMacros(CharArrayObjectMap<char[]> sigMacros) {
|
||||
fEncoded= encode(sigMacros);
|
||||
}
|
||||
|
||||
private char[] encode(CharArrayObjectMap<char[]> sigMacros) {
|
||||
StringBuilder buffer= new StringBuilder();
|
||||
Object[] keys= sigMacros.keyArray();
|
||||
Arrays.sort(keys, SORTER);
|
||||
for (Object key : keys) {
|
||||
char[] name= (char[]) key;
|
||||
char[] value= sigMacros.get(name);
|
||||
buffer.append((char) name.length).append(name);
|
||||
if (value == DEFINED) {
|
||||
buffer.append((char) ENCODED_DEFINED);
|
||||
} else if (value == UNDEFINED) {
|
||||
buffer.append((char) ENCODED_UNDEFINED);
|
||||
} else {
|
||||
buffer.append((char) value.length).append(value);
|
||||
}
|
||||
}
|
||||
int len= buffer.length();
|
||||
char[] result= new char[len];
|
||||
buffer.getChars(0, len, result, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int h = fHash;
|
||||
if (h == 0) {
|
||||
char val[] = fEncoded;
|
||||
int len = fEncoded.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
h = 31*h + val[i];
|
||||
}
|
||||
fHash = h;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof SignificantMacros
|
||||
&& hashCode() == obj.hashCode()
|
||||
&& CharArrayUtils.equals(fEncoded, ((SignificantMacros) obj).fEncoded);
|
||||
}
|
||||
|
||||
public boolean accept(IVisitor visitor) {
|
||||
final char[] encoded = fEncoded;
|
||||
final int len = encoded.length;
|
||||
int i= 0;
|
||||
while (i < len) {
|
||||
final int len1 = encoded[i++];
|
||||
int v= i + len1;
|
||||
if (v >= len)
|
||||
break;
|
||||
|
||||
char[] macro= extract(encoded, i, len1);
|
||||
final int len2 = encoded[v++];
|
||||
switch(len2) {
|
||||
case ENCODED_UNDEFINED:
|
||||
i= v;
|
||||
if (!visitor.visitUndefined(macro))
|
||||
return false;
|
||||
break;
|
||||
case ENCODED_DEFINED:
|
||||
i= v;
|
||||
if (!visitor.visitDefined(macro))
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
i= v+len2;
|
||||
if (i > len)
|
||||
break;
|
||||
if (!visitor.visitValue(macro, extract(encoded, v, len2)))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public char[] extract(final char[] source, int from, final int length) {
|
||||
char[] value= new char[length];
|
||||
System.arraycopy(source, from, value, 0, length);
|
||||
return value;
|
||||
}
|
||||
|
||||
public char[] encode() {
|
||||
return fEncoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* For debugging purposes.
|
||||
*/
|
||||
@SuppressWarnings("nls")
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder buf= new StringBuilder();
|
||||
buf.append('{');
|
||||
accept(new IVisitor() {
|
||||
public boolean visitValue(char[] macro, char[] value) {
|
||||
buf.append(macro).append('=').append(value).append(',');
|
||||
return true;
|
||||
}
|
||||
public boolean visitUndefined(char[] macro) {
|
||||
buf.append(macro).append('=').append("null,");
|
||||
return true;
|
||||
}
|
||||
public boolean visitDefined(char[] macro) {
|
||||
buf.append(macro).append('=').append("*,");
|
||||
return true;
|
||||
}
|
||||
});
|
||||
int buflen = buf.length();
|
||||
if (buflen > 1)
|
||||
buf.setLength(buflen-1);
|
||||
buf.append('}');
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -56,6 +56,7 @@ import org.eclipse.cdt.core.index.IIndexLocationConverter;
|
|||
import org.eclipse.cdt.core.index.IIndexMacro;
|
||||
import org.eclipse.cdt.core.index.IIndexMacroContainer;
|
||||
import org.eclipse.cdt.core.index.IndexFilter;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
import org.eclipse.cdt.internal.core.dom.Linkage;
|
||||
|
@ -210,10 +211,11 @@ public class PDOM extends PlatformObject implements IPDOM {
|
|||
* CDT 8.1 development (versions not supported on teh 8.0.x branch)
|
||||
* 120.0 - Enumerators in global index, bug 356235
|
||||
* 120.1 - Specializations of using declarations, bug 357293.
|
||||
* 121.0 - Multiple variants of included header file, bug 197989.
|
||||
*/
|
||||
private static final int MIN_SUPPORTED_VERSION= version(120, 0);
|
||||
private static final int MAX_SUPPORTED_VERSION= version(120, Short.MAX_VALUE);
|
||||
private static final int DEFAULT_VERSION = version(120, 1);
|
||||
private static final int MIN_SUPPORTED_VERSION= version(121, 0);
|
||||
private static final int MAX_SUPPORTED_VERSION= version(121, Short.MAX_VALUE);
|
||||
private static final int DEFAULT_VERSION = version(121, 0);
|
||||
|
||||
private static int version(int major, int minor) {
|
||||
return (major << 16) + minor;
|
||||
|
@ -419,6 +421,7 @@ public class PDOM extends PlatformObject implements IPDOM {
|
|||
return fileIndex;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public PDOMFile getFile(int linkageID, IIndexFileLocation location) throws CoreException {
|
||||
PDOMLinkage linkage= getLinkage(linkageID);
|
||||
if (linkage == null)
|
||||
|
@ -426,8 +429,25 @@ public class PDOM extends PlatformObject implements IPDOM {
|
|||
return PDOMFile.findFile(linkage, getFileIndex(), location, locationConverter);
|
||||
}
|
||||
|
||||
public PDOMFile getFile(PDOMLinkage linkage, IIndexFileLocation location) throws CoreException {
|
||||
return PDOMFile.findFile(linkage, getFileIndex(), location, locationConverter);
|
||||
public PDOMFile getFile(int linkageID, IIndexFileLocation location,
|
||||
ISignificantMacros macroDictionary) throws CoreException {
|
||||
PDOMLinkage linkage= getLinkage(linkageID);
|
||||
if (linkage == null)
|
||||
return null;
|
||||
return PDOMFile.findFile(linkage, getFileIndex(), location, locationConverter,
|
||||
macroDictionary);
|
||||
}
|
||||
|
||||
public PDOMFile getFile(PDOMLinkage linkage, IIndexFileLocation location,
|
||||
ISignificantMacros macroDictionary) throws CoreException {
|
||||
return PDOMFile.findFile(linkage, getFileIndex(), location, locationConverter, macroDictionary);
|
||||
}
|
||||
|
||||
public IIndexFragmentFile[] getFiles(int linkageID, IIndexFileLocation location) throws CoreException {
|
||||
PDOMLinkage linkage= getLinkage(linkageID);
|
||||
if (linkage == null)
|
||||
return IIndexFragmentFile.EMPTY_ARRAY;
|
||||
return PDOMFile.findFiles(linkage, getFileIndex(), location, locationConverter);
|
||||
}
|
||||
|
||||
public IIndexFragmentFile[] getFiles(IIndexFileLocation location) throws CoreException {
|
||||
|
@ -436,7 +456,7 @@ public class PDOM extends PlatformObject implements IPDOM {
|
|||
|
||||
public IIndexFragmentFile[] getAllFiles() throws CoreException {
|
||||
final List<PDOMFile> locations = new ArrayList<PDOMFile>();
|
||||
getFileIndex().accept(new IBTreeVisitor(){
|
||||
getFileIndex().accept(new IBTreeVisitor() {
|
||||
public int compare(long record) throws CoreException {
|
||||
return 0;
|
||||
}
|
||||
|
@ -449,11 +469,12 @@ public class PDOM extends PlatformObject implements IPDOM {
|
|||
return locations.toArray(new IIndexFragmentFile[locations.size()]);
|
||||
}
|
||||
|
||||
protected IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location) throws CoreException {
|
||||
protected IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location,
|
||||
ISignificantMacros sigMacros) throws CoreException {
|
||||
PDOMLinkage linkage= createLinkage(linkageID);
|
||||
IIndexFragmentFile file = getFile(linkage, location);
|
||||
IIndexFragmentFile file = getFile(linkage, location, sigMacros);
|
||||
if (file == null) {
|
||||
PDOMFile pdomFile = new PDOMFile(linkage, location, linkageID);
|
||||
PDOMFile pdomFile = new PDOMFile(linkage, location, linkageID, sigMacros);
|
||||
getFileIndex().insert(pdomFile.getRecord());
|
||||
file= pdomFile;
|
||||
fEvent.setHasNewFiles();
|
||||
|
@ -1077,7 +1098,7 @@ public class PDOM extends PlatformObject implements IPDOM {
|
|||
return (PDOMFile) file;
|
||||
}
|
||||
|
||||
return getFile(file.getLinkageID(), file.getLocation());
|
||||
return getFile(file.getLinkageID(), file.getLocation(), file.getSignificantMacros());
|
||||
}
|
||||
|
||||
public File getPath() {
|
||||
|
|
|
@ -28,6 +28,11 @@ public class PDOMFileSet implements IIndexFragmentFileSet {
|
|||
fFileIDs.add(pdomFile.getRecord());
|
||||
}
|
||||
|
||||
public void remove(IIndexFragmentFile fragFile) {
|
||||
PDOMFile pdomFile= (PDOMFile) fragFile;
|
||||
fFileIDs.remove(pdomFile.getRecord());
|
||||
}
|
||||
|
||||
public boolean containsFileOfLocalBinding(IIndexFragmentBinding fb) throws CoreException {
|
||||
PDOMBinding pdomBinding= (PDOMBinding) fb;
|
||||
return fFileIDs.contains(pdomBinding.getLocalToFileRec());
|
||||
|
|
|
@ -1091,12 +1091,14 @@ public class PDOMManager implements IWritableIndexManager, IListener {
|
|||
assert monitor != null;
|
||||
Thread th= null;
|
||||
if (waitMaxMillis != FOREVER) {
|
||||
final Thread callingThread= Thread.currentThread();
|
||||
th= new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(waitMaxMillis);
|
||||
monitor.setCanceled(true);
|
||||
callingThread.interrupt();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.eclipse.cdt.core.index.IIndexFileLocation;
|
|||
import org.eclipse.cdt.core.index.IIndexLinkage;
|
||||
import org.eclipse.cdt.core.index.IIndexMacro;
|
||||
import org.eclipse.cdt.core.index.IndexFilter;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexFragmentFileSet;
|
||||
|
@ -53,6 +54,7 @@ public class PDOMProxy implements IPDOM {
|
|||
fLockDebugging= new HashMap<Thread, DebugLockInfo>();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void acquireReadLock() throws InterruptedException {
|
||||
if (fDelegate != null) {
|
||||
fDelegate.acquireReadLock();
|
||||
|
@ -152,6 +154,7 @@ public class PDOMProxy implements IPDOM {
|
|||
return 0;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public synchronized IIndexFragmentFile getFile(int linkageID, IIndexFileLocation location) throws CoreException {
|
||||
if (fDelegate != null)
|
||||
return fDelegate.getFile(linkageID, location);
|
||||
|
@ -159,6 +162,22 @@ public class PDOMProxy implements IPDOM {
|
|||
return null;
|
||||
}
|
||||
|
||||
public IIndexFragmentFile getFile(int linkageID, IIndexFileLocation location,
|
||||
ISignificantMacros sigMacros) throws CoreException {
|
||||
if (fDelegate != null)
|
||||
return fDelegate.getFile(linkageID, location, sigMacros);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public IIndexFragmentFile[] getFiles(int linkageID, IIndexFileLocation location)
|
||||
throws CoreException {
|
||||
if (fDelegate != null)
|
||||
return fDelegate.getFiles(linkageID, location);
|
||||
|
||||
return IIndexFragmentFile.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
public synchronized IIndexFragmentFile[] getFiles(IIndexFileLocation location) throws CoreException {
|
||||
if (fDelegate != null)
|
||||
return fDelegate.getFiles(location);
|
||||
|
@ -289,10 +308,12 @@ public class PDOMProxy implements IPDOM {
|
|||
public Object putCachedResult(Object key, Object value, boolean replace) {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void clearResultCache() {
|
||||
if (fDelegate != null)
|
||||
fDelegate.clearResultCache();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.index.IIndexFragment#getInlineNamespaces()
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2007, 2011 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
|
||||
|
@ -13,8 +13,6 @@
|
|||
package org.eclipse.cdt.internal.core.pdom;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
@ -47,11 +45,14 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
|
||||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||
import org.eclipse.cdt.core.index.IIndexInclude;
|
||||
import org.eclipse.cdt.core.parser.IProblem;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
||||
import org.eclipse.cdt.internal.core.index.FileContentKey;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
|
||||
import org.eclipse.cdt.internal.core.index.IWritableIndex;
|
||||
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
|
||||
|
@ -70,6 +71,36 @@ import org.eclipse.osgi.util.NLS;
|
|||
* @since 4.0
|
||||
*/
|
||||
abstract public class PDOMWriter {
|
||||
public static class FileInAST {
|
||||
final IASTPreprocessorIncludeStatement fIncludeStatement;
|
||||
final FileContentKey fFileContentKey;
|
||||
final long fContentsHash;
|
||||
|
||||
public FileInAST(IASTPreprocessorIncludeStatement includeStmt, FileContentKey key, long contentsHash) {
|
||||
fIncludeStatement= includeStmt;
|
||||
fFileContentKey= key;
|
||||
fContentsHash= contentsHash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return fFileContentKey.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class FileContext {
|
||||
final IIndexFragmentFile fContext;
|
||||
final IIndexFragmentFile fOldFile;
|
||||
IIndexFragmentFile fNewFile;
|
||||
public boolean fLostPragmaOnceSemantics;
|
||||
|
||||
public FileContext(IIndexFragmentFile context, IIndexFragmentFile oldFile) {
|
||||
fContext= context;
|
||||
fOldFile= oldFile;
|
||||
fNewFile= null;
|
||||
}
|
||||
}
|
||||
|
||||
public static int SKIP_ALL_REFERENCES= -1;
|
||||
public static int SKIP_TYPE_REFERENCES= 1;
|
||||
public static int SKIP_MACRO_REFERENCES= 2;
|
||||
|
@ -77,9 +108,24 @@ abstract public class PDOMWriter {
|
|||
public static int SKIP_NO_REFERENCES= 0;
|
||||
|
||||
private static class Symbols {
|
||||
ArrayList<IASTName[]> fNames= new ArrayList<IASTName[]>();
|
||||
ArrayList<IASTPreprocessorStatement> fMacros= new ArrayList<IASTPreprocessorStatement>();
|
||||
ArrayList<IASTPreprocessorIncludeStatement> fIncludes= new ArrayList<IASTPreprocessorIncludeStatement>();
|
||||
final ArrayList<IASTName[]> fNames= new ArrayList<IASTName[]>();
|
||||
final ArrayList<IASTPreprocessorStatement> fMacros= new ArrayList<IASTPreprocessorStatement>();
|
||||
final ArrayList<IASTPreprocessorIncludeStatement> fIncludes= new ArrayList<IASTPreprocessorIncludeStatement>();
|
||||
}
|
||||
|
||||
private static class Data {
|
||||
final IASTTranslationUnit fAST;
|
||||
final FileInAST[] fSelectedFiles;
|
||||
final IWritableIndex fIndex;
|
||||
final Map<IASTPreprocessorIncludeStatement, Symbols> fSymbolMap = new HashMap<IASTPreprocessorIncludeStatement, Symbols>();
|
||||
final Set<IASTPreprocessorIncludeStatement> fContextIncludes = new HashSet<IASTPreprocessorIncludeStatement>();
|
||||
final List<IStatus> fStati= new ArrayList<IStatus>();
|
||||
|
||||
public Data(IASTTranslationUnit ast, FileInAST[] selectedFiles, IWritableIndex index) {
|
||||
fAST= ast;
|
||||
fSelectedFiles= selectedFiles;
|
||||
fIndex= index;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean fShowProblems;
|
||||
|
@ -90,7 +136,6 @@ abstract public class PDOMWriter {
|
|||
protected final IndexerStatistics fStatistics;
|
||||
protected final IndexerInputAdapter fResolver;
|
||||
|
||||
private IndexerProgress fInfo= new IndexerProgress();
|
||||
private int fSkipReferences= SKIP_NO_REFERENCES;
|
||||
|
||||
public PDOMWriter(IndexerInputAdapter resolver) {
|
||||
|
@ -140,39 +185,45 @@ abstract public class PDOMWriter {
|
|||
*
|
||||
* When flushIndex is set to <code>false</code>, you must make sure to flush
|
||||
* the index after your last write operation.
|
||||
* @since 4.0
|
||||
*/
|
||||
public void addSymbols(IASTTranslationUnit ast, IIndexFileLocation[] ifls, IWritableIndex index,
|
||||
int readlockCount, boolean flushIndex, long fileContentsHash, int configHash,
|
||||
ITodoTaskUpdater taskUpdater, IProgressMonitor pm) throws InterruptedException, CoreException {
|
||||
final protected void addSymbols(IASTTranslationUnit ast, FileInAST[] selectedFiles,
|
||||
IWritableIndex index, boolean flushIndex, FileContext ctx,
|
||||
ITodoTaskUpdater taskUpdater, IProgressMonitor pm) throws InterruptedException,
|
||||
CoreException {
|
||||
if (fShowProblems) {
|
||||
fShowInclusionProblems= true;
|
||||
fShowScannerProblems= true;
|
||||
fShowSyntaxProblems= true;
|
||||
}
|
||||
final Map<IIndexFileLocation, Symbols> symbolMap= new HashMap<IIndexFileLocation, Symbols>();
|
||||
for (IIndexFileLocation ifl : ifls) {
|
||||
prepareInMap(symbolMap, ifl);
|
||||
|
||||
Data data= new Data(ast, selectedFiles, index);
|
||||
for (FileInAST file : selectedFiles) {
|
||||
data.fSymbolMap.put(file.fIncludeStatement, new Symbols());
|
||||
}
|
||||
ArrayList<IStatus> stati= new ArrayList<IStatus>();
|
||||
|
||||
|
||||
HashSet<IASTPreprocessorIncludeStatement> contextIncludes= new HashSet<IASTPreprocessorIncludeStatement>();
|
||||
extractSymbols(ast, symbolMap, contextIncludes);
|
||||
// Extract symbols from AST
|
||||
extractSymbols(data);
|
||||
|
||||
// name resolution
|
||||
resolveNames(symbolMap, ifls, stati, pm);
|
||||
// Name resolution
|
||||
resolveNames(data, pm);
|
||||
|
||||
// index update
|
||||
storeSymbolsInIndex(symbolMap, ifls, ast.getLinkage().getLinkageID(), fileContentsHash,
|
||||
configHash, contextIncludes, index, readlockCount, flushIndex, stati, pm);
|
||||
// Index update
|
||||
storeSymbolsInIndex(data, ctx, flushIndex, pm);
|
||||
|
||||
// Tasks update
|
||||
if (taskUpdater != null) {
|
||||
taskUpdater.updateTasks(ast.getComments(), ifls);
|
||||
Set<IIndexFileLocation> locations= new HashSet<IIndexFileLocation>();
|
||||
for (FileInAST file : selectedFiles) {
|
||||
locations.add(file.fFileContentKey.getLocation());
|
||||
}
|
||||
taskUpdater.updateTasks(ast.getComments(), locations.toArray(new IIndexFileLocation[locations.size()]));
|
||||
}
|
||||
if (!stati.isEmpty()) {
|
||||
if (!data.fStati.isEmpty()) {
|
||||
List<IStatus> stati = data.fStati;
|
||||
String path= null;
|
||||
if (ifls.length > 0) {
|
||||
path= ifls[ifls.length - 1].getURI().getPath();
|
||||
if (selectedFiles.length > 0) {
|
||||
path= selectedFiles[selectedFiles.length - 1].fFileContentKey.getLocation().getURI().getPath();
|
||||
} else {
|
||||
path= ast.getFilePath().toString();
|
||||
}
|
||||
|
@ -190,60 +241,73 @@ abstract public class PDOMWriter {
|
|||
}
|
||||
}
|
||||
|
||||
private void storeSymbolsInIndex(final Map<IIndexFileLocation, Symbols> symbolMap, IIndexFileLocation[] ifls,
|
||||
int linkageID, long fileContentsHash, int configHash,
|
||||
HashSet<IASTPreprocessorIncludeStatement> contextIncludes, IWritableIndex index, int readlockCount,
|
||||
boolean flushIndex, ArrayList<IStatus> stati, IProgressMonitor pm)
|
||||
private void storeSymbolsInIndex(final Data data, FileContext ctx, boolean flushIndex, IProgressMonitor pm)
|
||||
throws InterruptedException, CoreException {
|
||||
for (int i= 0; i < ifls.length; i++) {
|
||||
final IIndexFragmentFile newFile= ctx == null ? null : ctx.fNewFile;
|
||||
final int linkageID= data.fAST.getLinkage().getLinkageID();
|
||||
for (int i= 0; i < data.fSelectedFiles.length; i++) {
|
||||
if (pm.isCanceled())
|
||||
return;
|
||||
|
||||
final IIndexFileLocation ifl= ifls[i];
|
||||
if (ifl != null) {
|
||||
final FileInAST fileInAST= data.fSelectedFiles[i];
|
||||
if (fileInAST != null) {
|
||||
if (fShowActivity) {
|
||||
trace("Indexer: adding " + ifl.getURI()); //$NON-NLS-1$
|
||||
trace("Indexer: adding " + fileInAST.fFileContentKey.getLocation().getURI()); //$NON-NLS-1$
|
||||
}
|
||||
Throwable th= null;
|
||||
YieldableIndexLock lock = new YieldableIndexLock(index, readlockCount, flushIndex);
|
||||
YieldableIndexLock lock = new YieldableIndexLock(data.fIndex, flushIndex);
|
||||
lock.acquire();
|
||||
try {
|
||||
storeFileInIndex(index, ifl, symbolMap, linkageID, fileContentsHash, configHash,
|
||||
contextIncludes, lock);
|
||||
} catch (RuntimeException e) {
|
||||
final boolean isReplacement= ctx != null && fileInAST.fIncludeStatement == null;
|
||||
IIndexFragmentFile ifile= null;
|
||||
if (!isReplacement || newFile == null) {
|
||||
ifile= storeFileInIndex(data, fileInAST, linkageID, lock);
|
||||
reportFileWrittenToIndex(fileInAST, ifile);
|
||||
}
|
||||
|
||||
if (isReplacement) {
|
||||
if (ifile == null)
|
||||
ifile= newFile;
|
||||
if (ctx != null && !ctx.fOldFile.equals(ifile) && ifile != null) {
|
||||
if (ctx.fOldFile.hasPragmaOnceSemantics() &&
|
||||
!ifile.hasPragmaOnceSemantics()) {
|
||||
data.fIndex.transferContext(ctx.fOldFile, ifile);
|
||||
ctx.fLostPragmaOnceSemantics= true;
|
||||
} else {
|
||||
data.fIndex.transferIncluders(ctx.fOldFile, ifile);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
th= e;
|
||||
} catch (StackOverflowError e) {
|
||||
th= e;
|
||||
} catch (AssertionError e) {
|
||||
th= e;
|
||||
} finally {
|
||||
// When the caller holds a read-lock, the result cache of the index is never cleared.
|
||||
// Because the caller holds a read-lock, the result cache of the index is never cleared.
|
||||
// ==> Before releasing the lock for the last time in this ast, we clear the result cache.
|
||||
if (readlockCount > 0 && i == ifls.length-1) {
|
||||
index.clearResultCache();
|
||||
if (i == data.fSelectedFiles.length-1) {
|
||||
data.fIndex.clearResultCache();
|
||||
}
|
||||
lock.release();
|
||||
}
|
||||
if (th != null) {
|
||||
stati.add(createStatus(NLS.bind(Messages.PDOMWriter_errorWhileParsing,
|
||||
ifl.getURI().getPath()), th));
|
||||
}
|
||||
if (i < ifls.length - 1) {
|
||||
updateFileCount(0, 0, 1); // update header count
|
||||
data.fStati.add(createStatus(NLS.bind(Messages.PDOMWriter_errorWhileParsing,
|
||||
fileInAST.fFileContentKey.getLocation().getURI().getPath()), th));
|
||||
}
|
||||
fStatistics.fAddToIndexTime += lock.getCumulativeLockTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void resolveNames(final Map<IIndexFileLocation, Symbols> symbolMap, IIndexFileLocation[] ifls,
|
||||
ArrayList<IStatus> stati, IProgressMonitor pm) {
|
||||
private void resolveNames(Data data, IProgressMonitor pm) {
|
||||
long start= System.currentTimeMillis();
|
||||
for (IIndexFileLocation path : ifls) {
|
||||
for (FileInAST file : data.fSelectedFiles) {
|
||||
if (pm.isCanceled()) {
|
||||
return;
|
||||
}
|
||||
Symbols symbols= symbolMap.get(path);
|
||||
Symbols symbols= data.fSymbolMap.get(file.fIncludeStatement);
|
||||
|
||||
final ArrayList<IASTName[]> names= symbols.fNames;
|
||||
boolean reported= false;
|
||||
|
@ -286,8 +350,8 @@ abstract public class PDOMWriter {
|
|||
}
|
||||
if (th != null) {
|
||||
if (!reported) {
|
||||
stati.add(CCorePlugin.createStatus(NLS.bind(Messages.PDOMWriter_errorResolvingName,
|
||||
name.toString(), path.getURI().getPath()), th));
|
||||
data.fStati.add(CCorePlugin.createStatus(NLS.bind(Messages.PDOMWriter_errorResolvingName,
|
||||
name.toString(), file.fFileContentKey.getLocation().getURI().getPath()), th));
|
||||
}
|
||||
reported= true;
|
||||
j.remove();
|
||||
|
@ -298,45 +362,44 @@ abstract public class PDOMWriter {
|
|||
fStatistics.fResolutionTime += System.currentTimeMillis()-start;
|
||||
}
|
||||
|
||||
private void extractSymbols(IASTTranslationUnit ast, final Map<IIndexFileLocation, Symbols> symbolMap,
|
||||
Collection<IASTPreprocessorIncludeStatement> contextIncludes) throws CoreException {
|
||||
final HashSet<IIndexFileLocation> contextIFLs= new HashSet<IIndexFileLocation>();
|
||||
final IIndexFileLocation astIFL = fResolver.resolveASTPath(ast.getFilePath());
|
||||
|
||||
private void extractSymbols(Data data) throws CoreException {
|
||||
int unresolvedIncludes= 0;
|
||||
final IASTTranslationUnit ast = data.fAST;
|
||||
final Map<IASTPreprocessorIncludeStatement, Symbols> symbolMap = data.fSymbolMap;
|
||||
|
||||
IASTPreprocessorStatement[] stmts = ast.getAllPreprocessorStatements();
|
||||
for (final IASTPreprocessorStatement stmt : stmts) {
|
||||
// includes
|
||||
// Includes.
|
||||
if (stmt instanceof IASTPreprocessorIncludeStatement) {
|
||||
IASTPreprocessorIncludeStatement include= (IASTPreprocessorIncludeStatement) stmt;
|
||||
|
||||
final IASTFileLocation astLoc= include.getFileLocation();
|
||||
final IIndexFileLocation sourceIFL= astLoc != null ? fResolver.resolveASTPath(astLoc.getFileName()) : astIFL; // command-line includes
|
||||
final boolean updateSource= symbolMap.containsKey(sourceIFL);
|
||||
IASTPreprocessorIncludeStatement owner = astLoc.getContextInclusionStatement();
|
||||
final boolean updateSource= symbolMap.containsKey(owner);
|
||||
if (updateSource) {
|
||||
addToMap(symbolMap, sourceIFL, include);
|
||||
addToMap(symbolMap, owner, include);
|
||||
}
|
||||
if (include.isActive()) {
|
||||
if (!include.isResolved()) {
|
||||
unresolvedIncludes++;
|
||||
} else if (updateSource) {
|
||||
// the include was parsed, check if we want to update the included file in the index
|
||||
final IIndexFileLocation targetIFL= fResolver.resolveASTPath(include.getPath());
|
||||
if (symbolMap.containsKey(targetIFL) && contextIFLs.add(targetIFL)) {
|
||||
contextIncludes.add(include);
|
||||
// The include was parsed, check if we want to update the included file in the index.
|
||||
if (symbolMap.containsKey(include)) {
|
||||
data.fContextIncludes.add(include);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (stmt.isActive() && (stmt instanceof IASTPreprocessorUndefStatement || stmt instanceof IASTPreprocessorMacroDefinition)) {
|
||||
} else if (stmt.isActive() &&
|
||||
(stmt instanceof IASTPreprocessorUndefStatement || stmt instanceof IASTPreprocessorMacroDefinition)) {
|
||||
IASTFileLocation sourceLoc = stmt.getFileLocation();
|
||||
if (sourceLoc != null) { // skip built-ins and command line macros
|
||||
IIndexFileLocation path2 = fResolver.resolveASTPath(sourceLoc.getFileName());
|
||||
addToMap(symbolMap, path2, stmt);
|
||||
IASTPreprocessorIncludeStatement owner = sourceLoc.getContextInclusionStatement();
|
||||
addToMap(symbolMap, owner, stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// names
|
||||
// Names.
|
||||
final IndexerASTVisitor visitor = new IndexerASTVisitor((fSkipReferences & SKIP_IMPLICIT_REFERENCES) == 0) {
|
||||
@Override
|
||||
public void visit(IASTName name, IASTName caller) {
|
||||
|
@ -348,13 +411,13 @@ abstract public class PDOMWriter {
|
|||
}
|
||||
}
|
||||
|
||||
// assign a location to anonymous types.
|
||||
// Assign a location to anonymous types.
|
||||
name= PDOMASTAdapter.getAdapterIfAnonymous(name);
|
||||
if (name != null) {
|
||||
IASTFileLocation nameLoc = name.getFileLocation();
|
||||
if (nameLoc != null) {
|
||||
IIndexFileLocation location = fResolver.resolveASTPath(nameLoc.getFileName());
|
||||
addToMap(symbolMap, location, new IASTName[]{name, caller});
|
||||
IASTPreprocessorIncludeStatement owner= nameLoc.getContextInclusionStatement();
|
||||
addToMap(symbolMap, owner, new IASTName[] { name, caller });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -368,8 +431,8 @@ abstract public class PDOMWriter {
|
|||
for (IASTName name : refs) {
|
||||
IASTFileLocation nameLoc = name.getFileLocation();
|
||||
if (nameLoc != null) {
|
||||
IIndexFileLocation location = fResolver.resolveASTPath(nameLoc.getFileName());
|
||||
addToMap(symbolMap, location, new IASTName[]{name, null});
|
||||
IASTPreprocessorIncludeStatement owner= nameLoc.getContextInclusionStatement();
|
||||
addToMap(symbolMap, owner, new IASTName[] { name, null });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -426,57 +489,45 @@ abstract public class PDOMWriter {
|
|||
return false;
|
||||
}
|
||||
|
||||
private void addToMap(Map<IIndexFileLocation, Symbols> map, IIndexFileLocation location, IASTName[] thing) {
|
||||
Symbols lists= map.get(location);
|
||||
private void addToMap(Map<IASTPreprocessorIncludeStatement, Symbols> symbolMap, IASTPreprocessorIncludeStatement owner, IASTName[] thing) {
|
||||
Symbols lists= symbolMap.get(owner);
|
||||
if (lists != null)
|
||||
lists.fNames.add(thing);
|
||||
}
|
||||
|
||||
private void addToMap(Map<IIndexFileLocation, Symbols> map, IIndexFileLocation location,
|
||||
IASTPreprocessorIncludeStatement thing) {
|
||||
Symbols lists= map.get(location);
|
||||
private void addToMap(Map<IASTPreprocessorIncludeStatement, Symbols> symbolMap, IASTPreprocessorIncludeStatement owner, IASTPreprocessorIncludeStatement thing) {
|
||||
Symbols lists= symbolMap.get(owner);
|
||||
if (lists != null)
|
||||
lists.fIncludes.add(thing);
|
||||
}
|
||||
|
||||
private void addToMap(Map<IIndexFileLocation, Symbols> map, IIndexFileLocation location,
|
||||
IASTPreprocessorStatement thing) {
|
||||
Symbols lists= map.get(location);
|
||||
private void addToMap(Map<IASTPreprocessorIncludeStatement, Symbols> symbolMap,
|
||||
IASTPreprocessorIncludeStatement owner, IASTPreprocessorStatement thing) {
|
||||
Symbols lists= symbolMap.get(owner);
|
||||
if (lists != null)
|
||||
lists.fMacros.add(thing);
|
||||
}
|
||||
|
||||
private boolean prepareInMap(Map<IIndexFileLocation, Symbols> map, IIndexFileLocation location) {
|
||||
if (map.get(location) == null) {
|
||||
map.put(location, new Symbols());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private IIndexFragmentFile storeFileInIndex(IWritableIndex index, IIndexFileLocation location,
|
||||
Map<IIndexFileLocation, Symbols> symbolMap, int linkageID, long fileContentsHash,
|
||||
int configHash, Set<IASTPreprocessorIncludeStatement> contextIncludes,
|
||||
private IIndexFragmentFile storeFileInIndex(Data data, FileInAST astFile, int linkageID,
|
||||
YieldableIndexLock lock) throws CoreException, InterruptedException {
|
||||
Set<IIndexFileLocation> clearedContexts= Collections.emptySet();
|
||||
final IWritableIndex index = data.fIndex;
|
||||
IIndexFragmentFile file;
|
||||
// We create a temporary PDOMFile with zero timestamp, add names to it, then replace contents
|
||||
// of the old file from the temporary one, then delete the temporary file. The write lock on
|
||||
// the index can be yielded between adding names to the temporary file, if another thread
|
||||
// is waiting for a read lock.
|
||||
IIndexFragmentFile oldFile = index.getWritableFile(linkageID, location);
|
||||
if (oldFile != null) {
|
||||
IIndexInclude[] includedBy = index.findIncludedBy(oldFile);
|
||||
if (includedBy.length > 0) {
|
||||
clearedContexts= new HashSet<IIndexFileLocation>();
|
||||
for (IIndexInclude include : includedBy) {
|
||||
clearedContexts.add(include.getIncludedByLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
file= index.addUncommittedFile(linkageID, location);
|
||||
// We create a temporary PDOMFile with zero timestamp, add names to it, then replace
|
||||
// contents of the old file from the temporary one, then delete the temporary file.
|
||||
// The write lock on the index can be yielded between adding names to the temporary file,
|
||||
// if another thread is waiting for a read lock.
|
||||
final FileContentKey fileKey = astFile.fFileContentKey;
|
||||
final IASTPreprocessorIncludeStatement owner= astFile.fIncludeStatement;
|
||||
|
||||
IIndexFileLocation location = fileKey.getLocation();
|
||||
ISignificantMacros significantMacros = fileKey.getSignificantMacros();
|
||||
IIndexFragmentFile oldFile = index.getWritableFile(linkageID, location, significantMacros);
|
||||
file= index.addUncommittedFile(linkageID, location, significantMacros);
|
||||
try {
|
||||
file.setScannerConfigurationHashcode(configHash);
|
||||
Symbols lists= symbolMap.get(location);
|
||||
boolean pragmaOnce= owner != null ? owner.hasPragmaOnceSemantics() : data.fAST.hasPragmaOnceSemantics();
|
||||
file.setPragmaOnceSemantics(pragmaOnce);
|
||||
|
||||
Symbols lists= data.fSymbolMap.get(owner);
|
||||
if (lists != null) {
|
||||
IASTPreprocessorStatement[] macros= lists.fMacros.toArray(new IASTPreprocessorStatement[lists.fMacros.size()]);
|
||||
IASTName[][] names= lists.fNames.toArray(new IASTName[lists.fNames.size()][]);
|
||||
|
@ -487,22 +538,30 @@ abstract public class PDOMWriter {
|
|||
}
|
||||
}
|
||||
|
||||
IncludeInformation[] includeInfos= new IncludeInformation[lists.fIncludes.size()];
|
||||
List<IncludeInformation> includeInfos= new ArrayList<IncludeInformation>();
|
||||
for (int i= 0; i < lists.fIncludes.size(); i++) {
|
||||
final IASTPreprocessorIncludeStatement include = lists.fIncludes.get(i);
|
||||
final IncludeInformation info= includeInfos[i]= new IncludeInformation();
|
||||
info.fStatement= include;
|
||||
if (include.isResolved()) {
|
||||
info.fLocation= fResolver.resolveASTPath(include.getPath());
|
||||
info.fIsContext= include.isActive() &&
|
||||
(contextIncludes.contains(include) || clearedContexts.contains(info.fLocation));
|
||||
final IASTPreprocessorIncludeStatement stmt = lists.fIncludes.get(i);
|
||||
if (!stmt.isResolved()) {
|
||||
includeInfos.add(new IncludeInformation(stmt, null, ISignificantMacros.NONE, false));
|
||||
} else {
|
||||
IIndexFileLocation targetLoc = fResolver.resolveASTPath(stmt.getPath());
|
||||
ISignificantMacros mainSig= stmt.getSignificantMacros();
|
||||
for (ISignificantMacros sig : stmt.getLoadedVersions()) {
|
||||
if (!sig.equals(mainSig)) {
|
||||
includeInfos.add(new IncludeInformation(stmt, targetLoc, sig, false));
|
||||
}
|
||||
}
|
||||
final boolean isContext = stmt.isActive() && stmt.isResolved() &&
|
||||
(data.fContextIncludes.contains(stmt) || isContextFor(oldFile, stmt));
|
||||
includeInfos.add(new IncludeInformation(stmt, targetLoc, mainSig, isContext));
|
||||
}
|
||||
}
|
||||
index.setFileContent(file, linkageID, includeInfos, macros, names, fResolver, lock);
|
||||
IncludeInformation[] includeInfoArray= includeInfos.toArray(new IncludeInformation[includeInfos.size()]);
|
||||
index.setFileContent(file, linkageID, includeInfoArray, macros, names, fResolver, lock);
|
||||
}
|
||||
file.setTimestamp(fResolver.getLastModified(location));
|
||||
file.setEncodingHashcode(fResolver.getEncoding(location).hashCode());
|
||||
file.setContentsHash(fileContentsHash);
|
||||
file.setContentsHash(astFile.fContentsHash);
|
||||
file = index.commitUncommittedFile();
|
||||
} finally {
|
||||
index.clearUncommittedFile();
|
||||
|
@ -510,35 +569,21 @@ abstract public class PDOMWriter {
|
|||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a copy of the current progress information and returns it.
|
||||
* @since 4.0
|
||||
*/
|
||||
public IndexerProgress getProgressInformation() {
|
||||
synchronized (fInfo) {
|
||||
return new IndexerProgress(fInfo);
|
||||
private boolean isContextFor(IIndexFragmentFile oldFile, IASTPreprocessorIncludeStatement stmt)
|
||||
throws CoreException {
|
||||
IIndexFile target= stmt.getImportedIndexFile();
|
||||
if (oldFile != null && target != null) {
|
||||
IIndexInclude ctxInclude = target.getParsedInContext();
|
||||
if (ctxInclude != null && oldFile.equals(ctxInclude.getIncludedBy()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates current progress information with the provided delta.
|
||||
* Informs the subclass that a file has been stored in the index.
|
||||
*/
|
||||
protected final void updateFileCount(int sources, int primaryHeader, int header) {
|
||||
synchronized (fInfo) {
|
||||
fInfo.fCompletedSources += sources;
|
||||
fInfo.fPrimaryHeaderCount += primaryHeader;
|
||||
fInfo.fCompletedHeaders += header;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates current progress information with the provided delta.
|
||||
*/
|
||||
protected final void incrementRequestedFilesCount(int delta) {
|
||||
synchronized (fInfo) {
|
||||
fInfo.fRequestedFilesCount += delta;
|
||||
}
|
||||
}
|
||||
protected abstract void reportFileWrittenToIndex(FileInAST file, IIndexFragmentFile iFile) throws CoreException;
|
||||
|
||||
private String getLocationInfo(String filename, int lineNumber) {
|
||||
return " at " + filename + "(" + lineNumber + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
|
|
|
@ -264,7 +264,7 @@ public class TeamPDOMImportOperation implements IWorkspaceRunnable {
|
|||
for (IIndexFragmentFile ifile : filesToDelete) {
|
||||
if (ifile != null) {
|
||||
checkMonitor(monitor);
|
||||
pdom.clearFile(ifile, null);
|
||||
pdom.clearFile(ifile);
|
||||
}
|
||||
}
|
||||
for (FileAndChecksum fc : updateTimestamps) {
|
||||
|
@ -275,7 +275,6 @@ public class TeamPDOMImportOperation implements IWorkspaceRunnable {
|
|||
IResource r= fc.fFile.getResource();
|
||||
if (r != null) {
|
||||
file.setTimestamp(r.getLocalTimeStamp());
|
||||
file.setScannerConfigurationHashcode(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,32 +1,36 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2010 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2006, 2011 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
|
||||
* Andrew Ferguson (Symbian)
|
||||
* Sergey Prigogin (Google)
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Andrew Ferguson (Symbian)
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.pdom;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||
import org.eclipse.cdt.core.index.IIndexLocationConverter;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.internal.core.index.FileContentKey;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexFragment;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
|
||||
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
|
||||
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.BTree;
|
||||
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.ChunkCache;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.DBProperties;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
|
||||
|
@ -45,7 +49,7 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
|||
private ASTFilePathResolver fPathResolver;
|
||||
private PDOMFile fileBeingUpdated;
|
||||
private PDOMFile uncommittedFile;
|
||||
private IIndexFileLocation uncommittedLocation;
|
||||
private FileContentKey uncommittedKey;
|
||||
|
||||
public WritablePDOM(File dbPath, IIndexLocationConverter locationConverter,
|
||||
Map<String, IPDOMLinkageFactory> linkageFactoryMappings) throws CoreException {
|
||||
|
@ -62,50 +66,50 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location) throws CoreException {
|
||||
if (uncommittedLocation != null && uncommittedLocation.equals(location)) {
|
||||
public IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location, ISignificantMacros sigMacros) throws CoreException {
|
||||
if (uncommittedKey != null && uncommittedKey.equals(new FileContentKey(linkageID, location, sigMacros)))
|
||||
return uncommittedFile;
|
||||
}
|
||||
return super.addFile(linkageID, location);
|
||||
|
||||
return super.addFile(linkageID, location, sigMacros);
|
||||
}
|
||||
|
||||
public IIndexFragmentFile addUncommittedFile(int linkageID, IIndexFileLocation location) throws CoreException {
|
||||
uncommittedLocation = location;
|
||||
fileBeingUpdated = getFile(linkageID, uncommittedLocation);
|
||||
public IIndexFragmentFile addUncommittedFile(int linkageID, IIndexFileLocation location,
|
||||
ISignificantMacros significantMacros) throws CoreException {
|
||||
uncommittedKey = new FileContentKey(linkageID, location, significantMacros);
|
||||
fileBeingUpdated = getFile(linkageID, location, significantMacros);
|
||||
PDOMLinkage linkage= createLinkage(linkageID);
|
||||
uncommittedFile = new PDOMFile(linkage, location, linkageID);
|
||||
uncommittedFile = new PDOMFile(linkage, location, linkageID, significantMacros);
|
||||
return uncommittedFile;
|
||||
}
|
||||
|
||||
public IIndexFragmentFile commitUncommittedFile() throws CoreException {
|
||||
if (uncommittedFile == null)
|
||||
return null;
|
||||
IIndexFragmentFile file;
|
||||
PDOMFile file;
|
||||
if (fileBeingUpdated == null) {
|
||||
// New file.
|
||||
BTree fileIndex = getFileIndex();
|
||||
fileIndex.insert(uncommittedFile.getRecord());
|
||||
// New file, insert it into the index.
|
||||
file = uncommittedFile;
|
||||
getFileIndex().insert(file.getRecord());
|
||||
} else {
|
||||
// Existing file.
|
||||
fileBeingUpdated.replaceContentsFrom(uncommittedFile);
|
||||
file = fileBeingUpdated;
|
||||
fileBeingUpdated = null;
|
||||
}
|
||||
fEvent.fFilesWritten.add(uncommittedLocation);
|
||||
fEvent.fFilesWritten.add(uncommittedKey.getLocation());
|
||||
uncommittedFile = null;
|
||||
uncommittedLocation = null;
|
||||
uncommittedKey = null;
|
||||
return file;
|
||||
}
|
||||
|
||||
public void clearUncommittedFile() throws CoreException {
|
||||
if (uncommittedFile != null) {
|
||||
try {
|
||||
uncommittedFile.clear(null);
|
||||
uncommittedFile.clear();
|
||||
uncommittedFile.delete();
|
||||
} finally {
|
||||
uncommittedFile = null;
|
||||
uncommittedLocation = null;
|
||||
uncommittedKey = null;
|
||||
fileBeingUpdated = null;
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +121,6 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
|||
assert sourceFile.getIndexFragment() == this;
|
||||
|
||||
PDOMFile pdomFile = (PDOMFile) sourceFile;
|
||||
pdomFile.addIncludesTo(includes);
|
||||
pdomFile.addMacros(macros);
|
||||
final ASTFilePathResolver origResolver= fPathResolver;
|
||||
fPathResolver= pathResolver;
|
||||
|
@ -126,6 +129,8 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
|||
} finally {
|
||||
fPathResolver= origResolver;
|
||||
}
|
||||
// Includes expose the temporary file in the index, we must not yield the lock beyond this point.
|
||||
pdomFile.addIncludesTo(includes);
|
||||
|
||||
final IIndexFileLocation location = pdomFile.getLocation();
|
||||
if (location != null) {
|
||||
|
@ -134,12 +139,13 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
|||
}
|
||||
}
|
||||
|
||||
public void clearFile(IIndexFragmentFile file, Collection<IIndexFileLocation> contextsRemoved)
|
||||
throws CoreException {
|
||||
public void clearFile(IIndexFragmentFile file) throws CoreException {
|
||||
assert file.getIndexFragment() == this;
|
||||
((PDOMFile) file).clear(contextsRemoved);
|
||||
|
||||
fEvent.fClearedFiles.add(file.getLocation());
|
||||
IIndexFileLocation location = file.getLocation();
|
||||
PDOMFile pdomFile = (PDOMFile) file;
|
||||
pdomFile.clear();
|
||||
|
||||
fEvent.fClearedFiles.add(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -165,9 +171,9 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
|||
}
|
||||
|
||||
/**
|
||||
* Use the specified location converter to update each internal representation of a file location.
|
||||
* The file index is rebuilt with the new representations. Individual PDOMFile records are unmoved so
|
||||
* as to maintain referential integrity with other PDOM records.
|
||||
* Uses the specified location converter to update each internal representation of a file
|
||||
* location. The file index is rebuilt with the new representations. Individual PDOMFile records
|
||||
* are unmoved so as to maintain referential integrity with other PDOM records.
|
||||
*
|
||||
* <b>A write-lock must be obtained before calling this method</b>
|
||||
*
|
||||
|
@ -202,7 +208,7 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
|||
// remove content where converter returns null
|
||||
for (PDOMFile file : notConverted) {
|
||||
file.convertIncludersToUnresolved();
|
||||
file.clear(null);
|
||||
file.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,16 +233,34 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
|
|||
return false;
|
||||
}
|
||||
|
||||
public PDOMFile getFileForASTPath(int linkageID, String astPath) throws CoreException {
|
||||
if (fPathResolver != null && astPath != null) {
|
||||
IIndexFileLocation location = fPathResolver.resolveASTPath(astPath);
|
||||
if (location.equals(uncommittedLocation))
|
||||
return fileBeingUpdated != null ? fileBeingUpdated : uncommittedFile;
|
||||
return getFile(linkageID, location);
|
||||
public PDOMFile getFileForASTNode(int linkageID, IASTNode node) throws CoreException {
|
||||
if (fPathResolver != null && node != null) {
|
||||
IASTFileLocation loc= node.getFileLocation();
|
||||
if (loc != null) {
|
||||
ISignificantMacros sigMacros= getSignificantMacros(node, loc);
|
||||
if (sigMacros != null) {
|
||||
IIndexFileLocation location = fPathResolver.resolveASTPath(loc.getFileName());
|
||||
if (uncommittedKey != null && uncommittedKey.equals(new FileContentKey(linkageID, location, sigMacros)))
|
||||
return fileBeingUpdated != null ? fileBeingUpdated : uncommittedFile;
|
||||
return getFile(linkageID, location, sigMacros);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private ISignificantMacros getSignificantMacros(IASTNode node, IASTFileLocation loc) throws CoreException {
|
||||
IASTPreprocessorIncludeStatement owner= loc.getContextInclusionStatement();
|
||||
if (owner != null)
|
||||
return owner.getSignificantMacros();
|
||||
|
||||
IASTTranslationUnit tu = node.getTranslationUnit();
|
||||
if (tu != null)
|
||||
return tu.getSignificantMacros();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLastingDefinition(PDOMBinding binding) throws CoreException {
|
||||
if (fileBeingUpdated == null) {
|
||||
|
|
|
@ -19,14 +19,12 @@ import org.eclipse.cdt.internal.core.index.IWritableIndex;
|
|||
*/
|
||||
public class YieldableIndexLock {
|
||||
private final IWritableIndex index;
|
||||
private final int readlockCount;
|
||||
private final boolean flushIndex;
|
||||
private long lastLockTime;
|
||||
private long cumulativeLockTime;
|
||||
|
||||
public YieldableIndexLock(IWritableIndex index, int readlockCount, boolean flushIndex) {
|
||||
public YieldableIndexLock(IWritableIndex index, boolean flushIndex) {
|
||||
this.index = index;
|
||||
this.readlockCount = readlockCount;
|
||||
this.flushIndex = flushIndex;
|
||||
}
|
||||
|
||||
|
@ -36,7 +34,7 @@ public class YieldableIndexLock {
|
|||
* @throws InterruptedException
|
||||
*/
|
||||
public void acquire() throws InterruptedException {
|
||||
index.acquireWriteLock(readlockCount);
|
||||
index.acquireWriteLock();
|
||||
lastLockTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
|
@ -45,7 +43,7 @@ public class YieldableIndexLock {
|
|||
*/
|
||||
public void release() {
|
||||
if (lastLockTime != 0) {
|
||||
index.releaseWriteLock(readlockCount, flushIndex);
|
||||
index.releaseWriteLock(flushIndex);
|
||||
cumulativeLockTime += System.currentTimeMillis() - lastLockTime;
|
||||
lastLockTime = 0;
|
||||
}
|
||||
|
@ -58,7 +56,7 @@ public class YieldableIndexLock {
|
|||
*/
|
||||
public void yield() throws InterruptedException {
|
||||
if (index.hasWaitingReaders()) {
|
||||
index.releaseWriteLock(readlockCount, false);
|
||||
index.releaseWriteLock(false);
|
||||
cumulativeLockTime += System.currentTimeMillis() - lastLockTime;
|
||||
lastLockTime = 0;
|
||||
acquire();
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.ICompositeType;
|
||||
|
@ -73,6 +74,10 @@ public class PDOMASTAdapter {
|
|||
public int getNodeOffset() {
|
||||
return loc.getNodeOffset();
|
||||
}
|
||||
|
||||
public IASTPreprocessorIncludeStatement getContextInclusionStatement() {
|
||||
return loc.getContextInclusionStatement();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2010 QNX Software Systems and others.
|
||||
* Copyright (c) 2005, 2011 QNX Software Systems 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
|
||||
|
@ -16,7 +16,6 @@ package org.eclipse.cdt.internal.core.pdom.dom;
|
|||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
@ -31,18 +30,19 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
|
|||
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
|
||||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||
import org.eclipse.cdt.core.index.IIndexInclude;
|
||||
import org.eclipse.cdt.core.index.IIndexLocationConverter;
|
||||
import org.eclipse.cdt.core.index.IIndexMacro;
|
||||
import org.eclipse.cdt.core.index.IIndexName;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexFragment;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexFragmentName;
|
||||
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
|
||||
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
|
||||
import org.eclipse.cdt.internal.core.index.IndexFileLocation;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.SignificantMacros;
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
||||
import org.eclipse.cdt.internal.core.pdom.YieldableIndexLock;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.BTree;
|
||||
|
@ -56,28 +56,31 @@ import org.eclipse.core.runtime.Status;
|
|||
|
||||
/**
|
||||
* Represents a file containing names.
|
||||
*
|
||||
*
|
||||
* @author Doug Schaefer
|
||||
*/
|
||||
public class PDOMFile implements IIndexFragmentFile {
|
||||
private final PDOMLinkage fLinkage;
|
||||
private final long record;
|
||||
private IIndexFileLocation location; // No need to make volatile, all fields of IIndexFileLocation are final.
|
||||
private IIndexFileLocation location; // No need to make volatile, all fields of IndexFileLocation are final.
|
||||
private ISignificantMacros sigMacros; // No need to make volatile, all fields of SignificantMacros are either final or atomically updated.
|
||||
|
||||
private static final int FIRST_NAME = 0;
|
||||
private static final int FIRST_INCLUDE = 4;
|
||||
private static final int FIRST_INCLUDED_BY = 8;
|
||||
private static final int FIRST_MACRO = 12;
|
||||
private static final int LOCATION_REPRESENTATION = 16;
|
||||
private static final int LINKAGE_ID= 20;
|
||||
private static final int TIME_STAMP = 24;
|
||||
private static final int CONTENT_HASH= 32;
|
||||
private static final int SCANNER_CONFIG_HASH= 40;
|
||||
private static final int ENCODING_HASH= 44;
|
||||
private static final int LAST_USING_DIRECTIVE= 48;
|
||||
private static final int FIRST_MACRO_REFERENCE= 52;
|
||||
private static final int FIRST_INCLUDE = FIRST_NAME + Database.PTR_SIZE;
|
||||
private static final int FIRST_INCLUDED_BY = FIRST_INCLUDE + Database.PTR_SIZE;
|
||||
private static final int FIRST_MACRO = FIRST_INCLUDED_BY + Database.PTR_SIZE;
|
||||
private static final int LOCATION_REPRESENTATION = FIRST_MACRO + Database.PTR_SIZE;
|
||||
private static final int LINKAGE_ID= LOCATION_REPRESENTATION + Database.PTR_SIZE; // size 3
|
||||
private static final int FLAGS= LINKAGE_ID + 3; // size 1
|
||||
private static final int TIME_STAMP = FLAGS + 1; // long
|
||||
private static final int CONTENT_HASH= TIME_STAMP + 8; // long
|
||||
private static final int ENCODING_HASH= CONTENT_HASH + 8;
|
||||
private static final int LAST_USING_DIRECTIVE= ENCODING_HASH + 4;
|
||||
private static final int FIRST_MACRO_REFERENCE= LAST_USING_DIRECTIVE + Database.PTR_SIZE;
|
||||
private static final int SIGNIFICANT_MACROS= FIRST_MACRO_REFERENCE + Database.PTR_SIZE;
|
||||
private static final int RECORD_SIZE= SIGNIFICANT_MACROS + Database.PTR_SIZE; // 8*PTR_SIZE + 3+1+8+8+4 = 56
|
||||
|
||||
private static final int RECORD_SIZE= 56;
|
||||
private static final int FLAG_PRAGMA_ONCE_SEMANTICS = 0x01;
|
||||
|
||||
public static class Comparator implements IBTreeComparator {
|
||||
private Database db;
|
||||
|
@ -91,10 +94,26 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
IString name2 = db.getString(db.getRecPtr(record2 + LOCATION_REPRESENTATION));
|
||||
int cmp= name1.compare(name2, true);
|
||||
if (cmp == 0) {
|
||||
cmp= db.getInt(record1 + LINKAGE_ID) - db.getInt(record2 + LINKAGE_ID);
|
||||
cmp= db.get3ByteUnsignedInt(record1 + LINKAGE_ID) - db.get3ByteUnsignedInt(record2 + LINKAGE_ID);
|
||||
if (cmp == 0) {
|
||||
IString sm1= getString(record1 + SIGNIFICANT_MACROS);
|
||||
IString sm2= getString(record2 + SIGNIFICANT_MACROS);
|
||||
if (sm1 == null) {
|
||||
cmp= sm2 == null ? 0 : -1;
|
||||
} else if (sm2 == null) {
|
||||
cmp= 1;
|
||||
} else {
|
||||
cmp= sm1.compare(sm2, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
return cmp;
|
||||
}
|
||||
|
||||
private IString getString(long offset) throws CoreException {
|
||||
long rec = db.getRecPtr(offset);
|
||||
return rec != 0 ? db.getString(rec) : null;
|
||||
}
|
||||
}
|
||||
|
||||
public PDOMFile(PDOMLinkage linkage, long record) {
|
||||
|
@ -102,7 +121,7 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
this.record = record;
|
||||
}
|
||||
|
||||
public PDOMFile(PDOMLinkage linkage, IIndexFileLocation location, int linkageID) throws CoreException {
|
||||
public PDOMFile(PDOMLinkage linkage, IIndexFileLocation location, int linkageID, ISignificantMacros macros) throws CoreException {
|
||||
fLinkage = linkage;
|
||||
this.location= location;
|
||||
Database db = fLinkage.getDB();
|
||||
|
@ -112,7 +131,8 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
throw new CoreException(CCorePlugin.createStatus(Messages.getString("PDOMFile.toInternalProblem") + location.getURI())); //$NON-NLS-1$
|
||||
IString locationDBString = db.newString(locationString);
|
||||
db.putRecPtr(record + LOCATION_REPRESENTATION, locationDBString.getRecord());
|
||||
db.putInt(record + LINKAGE_ID, linkageID);
|
||||
db.put3ByteUnsignedInt(record + LINKAGE_ID, linkageID);
|
||||
db.putRecPtr(record + SIGNIFICANT_MACROS, db.newString(macros.encode()).getRecord());
|
||||
setTimestamp(-1);
|
||||
}
|
||||
|
||||
|
@ -123,7 +143,7 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
public PDOM getPDOM() {
|
||||
return fLinkage.getPDOM();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this)
|
||||
|
@ -139,86 +159,45 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
public final int hashCode() {
|
||||
return System.identityHashCode(fLinkage.getPDOM()) + (int) (41 * record);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Transfers names, macros and includes from another file to this one and deletes the other file.
|
||||
* @param sourceFile the file to transfer the local bindings from.
|
||||
* @throws CoreException
|
||||
*/
|
||||
public void replaceContentsFrom(PDOMFile sourceFile) throws CoreException {
|
||||
ICPPUsingDirective[] directives= getUsingDirectives();
|
||||
for (ICPPUsingDirective ud : directives) {
|
||||
if (ud instanceof IPDOMNode) {
|
||||
((IPDOMNode) ud).delete(null);
|
||||
}
|
||||
}
|
||||
setFirstUsingDirectiveRec(sourceFile.getLastUsingDirectiveRec());
|
||||
// Delete current content
|
||||
clear();
|
||||
|
||||
// Replace the includes
|
||||
PDOMInclude include = getFirstInclude();
|
||||
while (include != null) {
|
||||
PDOMInclude nextInclude = include.getNextInIncludes();
|
||||
IIndexFile includedBy = include.getIncludedBy();
|
||||
if (this.equals(includedBy)) {
|
||||
include.delete();
|
||||
}
|
||||
include = nextInclude;
|
||||
}
|
||||
include = sourceFile.getFirstInclude();
|
||||
// Link in the using directives
|
||||
setLastUsingDirective(sourceFile.getLastUsingDirectiveRec());
|
||||
|
||||
// Link in the includes, replace the owner.
|
||||
PDOMInclude include = sourceFile.getFirstInclude();
|
||||
setFirstInclude(include);
|
||||
while (include != null) {
|
||||
IIndexFile includedBy = include.getIncludedBy();
|
||||
if (sourceFile.equals(includedBy)) {
|
||||
include.setIncludedBy(this);
|
||||
if (sourceFile.equals(include.getIncludes())) {
|
||||
include.setIncludes(this);
|
||||
}
|
||||
}
|
||||
include = include.getNextInIncludes();
|
||||
for (; include != null; include= include.getNextInIncludes()) {
|
||||
include.setIncludedBy(this);
|
||||
}
|
||||
|
||||
// Replace all the macros in this file.
|
||||
PDOMLinkage linkage= getLinkage();
|
||||
PDOMMacro macro = getFirstMacro();
|
||||
while (macro != null) {
|
||||
PDOMMacro nextMacro = macro.getNextMacro();
|
||||
macro.delete(linkage);
|
||||
macro = nextMacro;
|
||||
}
|
||||
macro = sourceFile.getFirstMacro();
|
||||
// In the unexpected case that there is an included by relation, append it.
|
||||
transferIncluders(sourceFile);
|
||||
|
||||
// Link in the macros.
|
||||
PDOMMacro macro = sourceFile.getFirstMacro();
|
||||
setFirstMacro(macro);
|
||||
for (; macro != null; macro = macro.getNextMacro()) {
|
||||
macro.setFile(this);
|
||||
}
|
||||
|
||||
// Replace all macro references
|
||||
ArrayList<PDOMMacroReferenceName> mrefs= new ArrayList<PDOMMacroReferenceName>();
|
||||
PDOMMacroReferenceName mref = getFirstMacroReference();
|
||||
while (mref != null) {
|
||||
mrefs.add(mref);
|
||||
mref= mref.getNextInFile();
|
||||
}
|
||||
for (PDOMMacroReferenceName m : mrefs) {
|
||||
m.delete();
|
||||
}
|
||||
mref = sourceFile.getFirstMacroReference();
|
||||
// Link in macro references
|
||||
PDOMMacroReferenceName mref = sourceFile.getFirstMacroReference();
|
||||
setFirstMacroReference(mref);
|
||||
for (; mref != null; mref = mref.getNextInFile()) {
|
||||
mref.setFile(this);
|
||||
}
|
||||
|
||||
// Replace all the names in this file
|
||||
ArrayList<PDOMName> names= new ArrayList<PDOMName>();
|
||||
PDOMName name = getFirstName();
|
||||
for (; name != null; name= name.getNextInFile()) {
|
||||
names.add(name);
|
||||
linkage.onDeleteName(name);
|
||||
}
|
||||
for (Iterator<PDOMName> iterator = names.iterator(); iterator.hasNext();) {
|
||||
name = iterator.next();
|
||||
name.delete();
|
||||
}
|
||||
name = sourceFile.getFirstName();
|
||||
PDOMName name = sourceFile.getFirstName();
|
||||
setFirstName(name);
|
||||
for (; name != null; name= name.getNextInFile()) {
|
||||
name.setFile(this);
|
||||
|
@ -227,11 +206,58 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
setTimestamp(sourceFile.getTimestamp());
|
||||
setEncodingHashcode(sourceFile.getEncodingHashcode());
|
||||
setContentsHash(sourceFile.getContentsHash());
|
||||
setScannerConfigurationHashcode(sourceFile.getScannerConfigurationHashcode());
|
||||
|
||||
// Transfer the flags.
|
||||
Database db= fLinkage.getDB();
|
||||
db.putByte(record + FLAGS, db.getByte(sourceFile.record + FLAGS));
|
||||
|
||||
// Delete the source file
|
||||
sourceFile.delete();
|
||||
}
|
||||
|
||||
public void transferIncluders(IIndexFragmentFile sourceFile) throws CoreException {
|
||||
PDOMFile source= (PDOMFile) sourceFile;
|
||||
PDOMInclude include = source.getFirstIncludedBy();
|
||||
if (include != null) {
|
||||
// Detach the includes
|
||||
source.setFirstIncludedBy(null);
|
||||
// Adjust the includes
|
||||
for (PDOMInclude i= include; i != null; i= i.getNextInIncludedBy()) {
|
||||
i.setIncludes(this);
|
||||
}
|
||||
// Append the includes
|
||||
PDOMInclude last= getFirstIncludedBy();
|
||||
if (last == null) {
|
||||
setFirstIncludedBy(include);
|
||||
} else {
|
||||
for (PDOMInclude i= last; i != null; i= i.getNextInIncludedBy()) {
|
||||
last= i;
|
||||
}
|
||||
last.setNextInIncludedBy(include);
|
||||
include.setPrevInIncludedBy(last);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void transferContext(IIndexFragmentFile sourceFile) throws CoreException {
|
||||
PDOMFile source= (PDOMFile) sourceFile;
|
||||
PDOMInclude include = source.getFirstIncludedBy();
|
||||
if (include != null) {
|
||||
// Detach the include
|
||||
final PDOMInclude next = include.getNextInIncludedBy();
|
||||
include.setNextInIncludedBy(null);
|
||||
source.setFirstIncludedBy(next);
|
||||
if (next != null)
|
||||
next.setPrevInIncludedBy(null);
|
||||
|
||||
// Adjust the include
|
||||
include.setIncludes(this);
|
||||
|
||||
// Insert the include
|
||||
addIncludedBy(include, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should not be called on PDOMFile objects that are referenced by the file index.
|
||||
* @param location a new location
|
||||
|
@ -239,9 +265,10 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
*/
|
||||
public void setLocation(IIndexFileLocation location) throws CoreException {
|
||||
String locationString = fLinkage.getPDOM().getLocationConverter().toInternalFormat(location);
|
||||
if (locationString == null)
|
||||
if (locationString == null) {
|
||||
throw new CoreException(CCorePlugin.createStatus(Messages.getString("PDOMFile.toInternalProblem") + //$NON-NLS-1$
|
||||
location.getURI()));
|
||||
}
|
||||
setInternalLocation(locationString);
|
||||
}
|
||||
|
||||
|
@ -260,10 +287,10 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
db.putRecPtr(record + LOCATION_REPRESENTATION, db.newString(internalLocation).getRecord());
|
||||
location= null;
|
||||
}
|
||||
|
||||
|
||||
public int getLinkageID() throws CoreException {
|
||||
Database db = fLinkage.getDB();
|
||||
return db.getInt(record + LINKAGE_ID);
|
||||
return db.get3ByteUnsignedInt(record + LINKAGE_ID);
|
||||
}
|
||||
|
||||
public long getTimestamp() throws CoreException {
|
||||
|
@ -287,13 +314,7 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
}
|
||||
|
||||
public int getScannerConfigurationHashcode() throws CoreException {
|
||||
Database db = fLinkage.getDB();
|
||||
return db.getInt(record + SCANNER_CONFIG_HASH);
|
||||
}
|
||||
|
||||
public void setScannerConfigurationHashcode(int hashcode) throws CoreException {
|
||||
Database db= fLinkage.getDB();
|
||||
db.putInt(record + SCANNER_CONFIG_HASH, hashcode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getEncodingHashcode() throws CoreException {
|
||||
|
@ -306,6 +327,21 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
db.putInt(record + ENCODING_HASH, hashcode);
|
||||
}
|
||||
|
||||
public boolean hasPragmaOnceSemantics() throws CoreException {
|
||||
return (fLinkage.getDB().getByte(record + FLAGS) & FLAG_PRAGMA_ONCE_SEMANTICS) != 0;
|
||||
}
|
||||
|
||||
public void setPragmaOnceSemantics(boolean value) throws CoreException {
|
||||
Database db = fLinkage.getDB();
|
||||
byte flags = db.getByte(record + FLAGS);
|
||||
if (value) {
|
||||
flags |= FLAG_PRAGMA_ONCE_SEMANTICS;
|
||||
} else {
|
||||
flags &= ~FLAG_PRAGMA_ONCE_SEMANTICS;
|
||||
}
|
||||
db.putByte(record + FLAGS, flags);
|
||||
}
|
||||
|
||||
private PDOMName getFirstName() throws CoreException {
|
||||
long namerec = fLinkage.getDB().getRecPtr(record + FIRST_NAME);
|
||||
return namerec != 0 ? new PDOMName(fLinkage, namerec) : null;
|
||||
|
@ -340,7 +376,7 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
long rec = fLinkage.getDB().getRecPtr(record + FIRST_INCLUDED_BY);
|
||||
return rec != 0 ? new PDOMInclude(fLinkage, rec) : null;
|
||||
}
|
||||
|
||||
|
||||
public IIndexInclude getParsedInContext() throws CoreException {
|
||||
return getFirstIncludedBy();
|
||||
}
|
||||
|
@ -459,22 +495,22 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
return new PDOMMacroReferenceName(fLinkage, name, this, cont);
|
||||
}
|
||||
|
||||
public void clear(Collection<IIndexFileLocation> contextsRemoved) throws CoreException {
|
||||
public void clear() throws CoreException {
|
||||
ICPPUsingDirective[] directives= getUsingDirectives();
|
||||
for (ICPPUsingDirective ud : directives) {
|
||||
if (ud instanceof IPDOMNode) {
|
||||
((IPDOMNode) ud).delete(null);
|
||||
}
|
||||
}
|
||||
setFirstUsingDirectiveRec(0);
|
||||
setLastUsingDirective(0);
|
||||
|
||||
// Remove the includes
|
||||
PDOMInclude include = getFirstInclude();
|
||||
while (include != null) {
|
||||
PDOMInclude nextInclude = include.getNextInIncludes();
|
||||
if (contextsRemoved != null && include.getPrevInIncludedByRecord() == 0) {
|
||||
contextsRemoved.add(include.getIncludesLocation());
|
||||
}
|
||||
// if (contextsRemoved != null && include.getPrevInIncludedByRecord() == 0) {
|
||||
// contextsRemoved.add(include.getIncludesLocation());
|
||||
// }
|
||||
include.delete();
|
||||
include = nextInclude;
|
||||
}
|
||||
|
@ -515,7 +551,6 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
m.delete();
|
||||
}
|
||||
setFirstMacroReference(null);
|
||||
|
||||
setTimestamp(-1);
|
||||
}
|
||||
|
||||
|
@ -527,6 +562,9 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
public void delete() throws CoreException {
|
||||
Database db = fLinkage.getDB();
|
||||
long locRecord = db.getRecPtr(record + LOCATION_REPRESENTATION);
|
||||
if (locRecord != 0)
|
||||
db.getString(locRecord).delete();
|
||||
locRecord = db.getRecPtr(record + SIGNIFICANT_MACROS);
|
||||
if (locRecord != 0)
|
||||
db.getString(locRecord).delete();
|
||||
|
||||
|
@ -539,7 +577,7 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
PDOMInclude lastInclude= null;
|
||||
for (final IncludeInformation info : includeInfos) {
|
||||
final PDOMFile targetFile= (PDOMFile) info.fTargetFile;
|
||||
|
||||
|
||||
PDOMInclude pdomInclude = new PDOMInclude(fLinkage, info.fStatement, this, targetFile);
|
||||
assert targetFile == null || targetFile.getIndexFragment() instanceof IWritableIndexFragment;
|
||||
if (targetFile != null) {
|
||||
|
@ -560,7 +598,7 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
if (isContext) {
|
||||
setFirstIncludedBy(include);
|
||||
include.setNextInIncludedBy(firstIncludedBy);
|
||||
firstIncludedBy.setPrevInIncludedBy(include);
|
||||
firstIncludedBy.setPrevInIncludedBy(include);
|
||||
} else {
|
||||
PDOMInclude secondIncludedBy= firstIncludedBy.getNextInIncludedBy();
|
||||
if (secondIncludedBy != null) {
|
||||
|
@ -606,13 +644,12 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
if (nameOffset >= offset) {
|
||||
if (nameOffset + name.getNodeLength() <= offset + length) {
|
||||
result.add(name);
|
||||
} else if (name.isReference()) {
|
||||
} else if (name.isReference()) {
|
||||
// Names are ordered, but callers are inserted before
|
||||
// their references.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for (PDOMMacro macro= getFirstMacro(); macro != null; macro= macro.getNextMacro()) {
|
||||
int nameOffset= macro.getNodeOffset();
|
||||
|
@ -622,7 +659,7 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
if (name != null) {
|
||||
result.add(name);
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -632,7 +669,7 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
if (nameOffset >= offset) {
|
||||
if (nameOffset + name.getNodeLength() <= offset + length) {
|
||||
result.add(name);
|
||||
} else {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -640,11 +677,53 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
return result.toArray(new IIndexName[result.size()]);
|
||||
}
|
||||
|
||||
public static PDOMFile findFile(PDOMLinkage linkage, BTree btree, IIndexFileLocation location,
|
||||
public static IIndexFragmentFile[] findFiles(PDOMLinkage linkage, BTree btree, IIndexFileLocation location,
|
||||
IIndexLocationConverter strategy) throws CoreException {
|
||||
String internalRepresentation= strategy.toInternalFormat(location);
|
||||
if (internalRepresentation != null) {
|
||||
Finder finder = new Finder(linkage.getDB(), internalRepresentation, linkage.getLinkageID());
|
||||
Finder finder = new Finder(linkage.getDB(), internalRepresentation, linkage.getLinkageID(), null);
|
||||
btree.accept(finder);
|
||||
long[] records= finder.getRecords();
|
||||
IIndexFragmentFile[] result= new IIndexFragmentFile[records.length];
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i]= new PDOMFile(linkage, records[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return IIndexFragmentFile.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
/**
|
||||
* When a header file is stored in the index in multiple variants for different sets of macro
|
||||
* definitions this method will return an arbitrary one of these variants.
|
||||
*
|
||||
* @deprecated Use
|
||||
* {@link #findFile(PDOMLinkage, BTree, IIndexFileLocation, IIndexLocationConverter, ISignificantMacros)}
|
||||
* or {@link #findFiles(PDOMLinkage, BTree, IIndexFileLocation, IIndexLocationConverter)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static PDOMFile findFile(PDOMLinkage linkage, BTree btree, IIndexFileLocation location,
|
||||
IIndexLocationConverter strategy) throws CoreException {
|
||||
return findFile(linkage, btree, location, strategy, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the file in index.
|
||||
*
|
||||
* @param linkage The linkage of the file.
|
||||
* @param btree The file index.
|
||||
* @param location The location of the file.
|
||||
* @param strategy The index location converter.
|
||||
* @param macroDictionary The names and definitions of the macros used to disambiguate between
|
||||
* variants of the file contents corresponding to different inclusion points.
|
||||
* @return The found file, or <code>null</code> if the matching file was not found.
|
||||
*/
|
||||
public static PDOMFile findFile(PDOMLinkage linkage, BTree btree, IIndexFileLocation location,
|
||||
IIndexLocationConverter strategy, ISignificantMacros macroDictionary) throws CoreException {
|
||||
String internalRepresentation= strategy.toInternalFormat(location);
|
||||
if (internalRepresentation != null) {
|
||||
Finder finder = new Finder(linkage.getDB(), internalRepresentation, linkage.getLinkageID(),
|
||||
macroDictionary);
|
||||
btree.accept(finder);
|
||||
long record= finder.getRecord();
|
||||
if (record != 0) {
|
||||
|
@ -658,7 +737,7 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
IIndexLocationConverter strategy) throws CoreException {
|
||||
String internalRepresentation= strategy.toInternalFormat(location);
|
||||
if (internalRepresentation != null) {
|
||||
Finder finder = new Finder(pdom.getDB(), internalRepresentation, -1);
|
||||
Finder finder = new Finder(pdom.getDB(), internalRepresentation, -1, null);
|
||||
btree.accept(finder);
|
||||
long[] records= finder.getRecords();
|
||||
PDOMFile[] result= new PDOMFile[records.length];
|
||||
|
@ -672,12 +751,11 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
|
||||
public static PDOMFile recreateFile(PDOM pdom, final long record) throws CoreException {
|
||||
final Database db= pdom.getDB();
|
||||
final int linkageID= db.getInt(record + PDOMFile.LINKAGE_ID);
|
||||
final int linkageID= db.get3ByteUnsignedInt(record + LINKAGE_ID);
|
||||
PDOMLinkage linkage= pdom.getLinkage(linkageID);
|
||||
if (linkage == null)
|
||||
throw new CoreException(createStatus("Invalid linkage ID in database")); //$NON-NLS-1$
|
||||
PDOMFile file= new PDOMFile(linkage, record);
|
||||
return file;
|
||||
return new PDOMFile(linkage, record);
|
||||
}
|
||||
|
||||
private static class Finder implements IBTreeVisitor {
|
||||
|
@ -687,14 +765,17 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
private long record;
|
||||
private long[] records;
|
||||
private final int linkageID;
|
||||
private char[] rawSignificantMacros;
|
||||
|
||||
/**
|
||||
* Searches for a file with the given linkage id.
|
||||
*/
|
||||
public Finder(Database db, String internalRepresentation, int linkageID) {
|
||||
public Finder(Database db, String internalRepresentation, int linkageID, ISignificantMacros sigMacros) {
|
||||
this.db = db;
|
||||
this.rawKey = internalRepresentation;
|
||||
this.linkageID= linkageID;
|
||||
this.rawSignificantMacros = sigMacros == null ? null : sigMacros.encode();
|
||||
assert linkageID >= 0 || rawSignificantMacros == null;
|
||||
}
|
||||
|
||||
public long[] getRecords() {
|
||||
|
@ -706,32 +787,48 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
}
|
||||
return records;
|
||||
}
|
||||
|
||||
|
||||
public int compare(long record) throws CoreException {
|
||||
IString name = db.getString(db.getRecPtr(record + PDOMFile.LOCATION_REPRESENTATION));
|
||||
int cmp= name.compare(rawKey, true);
|
||||
if (cmp == 0 && linkageID >= 0) {
|
||||
cmp= db.getInt(record + PDOMFile.LINKAGE_ID) - linkageID;
|
||||
cmp= db.get3ByteUnsignedInt(record + PDOMFile.LINKAGE_ID) - linkageID;
|
||||
if (cmp == 0 && rawSignificantMacros != null) {
|
||||
IString significantMacrosStr = getString(record + SIGNIFICANT_MACROS);
|
||||
if (significantMacrosStr != null) {
|
||||
cmp = significantMacrosStr.compare(rawSignificantMacros, true);
|
||||
} else {
|
||||
cmp = rawSignificantMacros.length > 0 ? -1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cmp;
|
||||
}
|
||||
|
||||
|
||||
private IString getString(long offset) throws CoreException {
|
||||
long rec = db.getRecPtr(offset);
|
||||
return rec != 0 ? db.getString(rec) : null;
|
||||
}
|
||||
|
||||
public boolean visit(long record) throws CoreException {
|
||||
if (linkageID >= 0) {
|
||||
if (rawSignificantMacros != null) {
|
||||
this.record = record;
|
||||
return false;
|
||||
return false;
|
||||
// Stop searching.
|
||||
}
|
||||
|
||||
if (this.record == 0) {
|
||||
this.record= record;
|
||||
} else if (this.records == null) {
|
||||
this.records= new long[] {this.record, record};
|
||||
this.records= new long[] { this.record, record };
|
||||
} else {
|
||||
long[] cpy= new long[this.records.length + 1];
|
||||
System.arraycopy(this.records, 0, cpy, 0, this.records.length);
|
||||
cpy[cpy.length - 1]= record;
|
||||
this.records= cpy;
|
||||
}
|
||||
return linkageID < 0;
|
||||
// Continue search.
|
||||
return true;
|
||||
}
|
||||
|
||||
public long getRecord() {
|
||||
|
@ -757,7 +854,17 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
|
||||
public ISignificantMacros getSignificantMacros() throws CoreException {
|
||||
if (sigMacros == null) {
|
||||
Database db= fLinkage.getDB();
|
||||
final IString encoded = db.getString(db.getRecPtr(record + SIGNIFICANT_MACROS));
|
||||
sigMacros= encoded == null ? ISignificantMacros.NONE : new SignificantMacros(encoded.getChars());
|
||||
}
|
||||
return sigMacros;
|
||||
}
|
||||
|
||||
public boolean hasContent() throws CoreException {
|
||||
return getTimestamp() != -1;
|
||||
}
|
||||
|
@ -779,7 +886,7 @@ public class PDOMFile implements IIndexFragmentFile {
|
|||
return fLinkage.getDB().getRecPtr(record + LAST_USING_DIRECTIVE);
|
||||
}
|
||||
|
||||
public void setFirstUsingDirectiveRec(long rec) throws CoreException {
|
||||
public void setLastUsingDirective(long rec) throws CoreException {
|
||||
fLinkage.getDB().putRecPtr(record + LAST_USING_DIRECTIVE, rec);
|
||||
}
|
||||
|
||||
|
|
|
@ -256,9 +256,9 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
|
|||
}
|
||||
|
||||
if (checkIfInSourceOnly) {
|
||||
String path= ASTInternal.getDeclaredInSourceFileOnly(binding, requireDefinition, glob);
|
||||
if (path != null) {
|
||||
return wpdom.getFileForASTPath(getLinkageID(), path);
|
||||
IASTNode node= ASTInternal.getDeclaredInSourceFileOnly(binding, requireDefinition, glob);
|
||||
if (node != null) {
|
||||
return wpdom.getFileForASTNode(getLinkageID(), node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.eclipse.cdt.core.CCorePlugin;
|
|||
import org.eclipse.cdt.core.dom.IPDOMVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorUndefStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||
|
@ -278,10 +279,6 @@ public class PDOMMacro implements IIndexMacro, IPDOMBinding, IASTFileLocation {
|
|||
fLinkage.getDB().putRecPtr(fRecord + FILE, file != null ? file.getRecord() : 0);
|
||||
}
|
||||
|
||||
public int getEndingLineNumber() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
try {
|
||||
IIndexFile file = getFile();
|
||||
|
@ -303,6 +300,14 @@ public class PDOMMacro implements IIndexMacro, IPDOMBinding, IASTFileLocation {
|
|||
return 0;
|
||||
}
|
||||
|
||||
public int getEndingLineNumber() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public IASTPreprocessorIncludeStatement getContextInclusionStatement() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public IASTFileLocation asFileLocation() {
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ package org.eclipse.cdt.internal.core.pdom.dom;
|
|||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
|
||||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
import org.eclipse.cdt.core.index.IIndexName;
|
||||
import org.eclipse.cdt.core.index.IndexLocationFactory;
|
||||
|
@ -216,6 +217,10 @@ public final class PDOMMacroReferenceName implements IIndexFragmentName, IASTFil
|
|||
return 0;
|
||||
}
|
||||
|
||||
public IASTPreprocessorIncludeStatement getContextInclusionStatement() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public IASTFileLocation asFileLocation() {
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Doug Schaefer (QNX) - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* Sergey Prigogin (Google)
|
||||
* Doug Schaefer (QNX) - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.pdom.dom;
|
||||
|
||||
|
@ -17,6 +17,7 @@ import java.util.ArrayList;
|
|||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
|
||||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
import org.eclipse.cdt.core.index.IIndexName;
|
||||
import org.eclipse.cdt.core.index.IndexLocationFactory;
|
||||
|
@ -323,6 +324,10 @@ public final class PDOMName implements IIndexFragmentName, IASTFileLocation {
|
|||
return 0;
|
||||
}
|
||||
|
||||
public IASTPreprocessorIncludeStatement getContextInclusionStatement() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public IASTFileLocation asFileLocation() {
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -890,7 +890,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
|
|||
long rec= file.getLastUsingDirectiveRec();
|
||||
PDOMCPPUsingDirective ud= new PDOMCPPUsingDirective(this, rec, containerNS,
|
||||
pdomName.getBinding(), pdomName.getFileLocation().getNodeOffset());
|
||||
file.setFirstUsingDirectiveRec(ud.getRecord());
|
||||
file.setLastUsingDirective(ud.getRecord());
|
||||
}
|
||||
} else if (parentNode instanceof ICPPASTElaboratedTypeSpecifier) {
|
||||
ICPPASTElaboratedTypeSpecifier elaboratedSpecifier = (ICPPASTElaboratedTypeSpecifier)parentNode;
|
||||
|
@ -983,23 +983,23 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
|
|||
final WritablePDOM wpdom= (WritablePDOM) pdom;
|
||||
PDOMFile file= null;
|
||||
if (binding instanceof ICPPUsingDeclaration) {
|
||||
String path= ASTInternal.getDeclaredInOneFileOnly(binding);
|
||||
if (path != null) {
|
||||
file= wpdom.getFileForASTPath(getLinkageID(), path);
|
||||
IASTNode node= ASTInternal.getDeclaredInOneFileOnly(binding);
|
||||
if (node != null) {
|
||||
file= wpdom.getFileForASTNode(getLinkageID(), node);
|
||||
}
|
||||
} else if (binding instanceof ICPPNamespaceAlias) {
|
||||
String path= ASTInternal.getDeclaredInSourceFileOnly(binding, false, glob);
|
||||
if (path != null) {
|
||||
file= wpdom.getFileForASTPath(getLinkageID(), path);
|
||||
IASTNode node= ASTInternal.getDeclaredInSourceFileOnly(binding, false, glob);
|
||||
if (node != null) {
|
||||
file= wpdom.getFileForASTNode(getLinkageID(), node);
|
||||
}
|
||||
}
|
||||
if (file == null && !(binding instanceof IIndexBinding)) {
|
||||
IBinding owner= binding.getOwner();
|
||||
if (owner instanceof ICPPNamespace) {
|
||||
if (owner.getNameCharArray().length == 0) {
|
||||
String path= ASTInternal.getDeclaredInSourceFileOnly(owner, false, glob);
|
||||
if (path != null) {
|
||||
file= wpdom.getFileForASTPath(getLinkageID(), path);
|
||||
IASTNode node= ASTInternal.getDeclaredInSourceFileOnly(owner, false, glob);
|
||||
if (node != null) {
|
||||
file= wpdom.getFileForASTNode(getLinkageID(), node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,9 @@ import org.eclipse.cdt.core.model.ICProject;
|
|||
* Abstract base class for all indexers.
|
||||
*/
|
||||
public abstract class AbstractPDOMIndexer implements IPDOMIndexer {
|
||||
// For testing purposes
|
||||
public static boolean noFilesUpFront= false;
|
||||
|
||||
protected ICProject project;
|
||||
protected Properties fProperties= new Properties();
|
||||
|
||||
|
@ -82,11 +85,13 @@ public abstract class AbstractPDOMIndexer implements IPDOMIndexer {
|
|||
}
|
||||
|
||||
public String[] getFilesToParseUpFront() {
|
||||
String prefSetting= getProperty(IndexerPreferences.KEY_FILES_TO_PARSE_UP_FRONT);
|
||||
if (prefSetting != null) {
|
||||
prefSetting= prefSetting.trim();
|
||||
if (prefSetting.length() > 0) {
|
||||
return prefSetting.split(","); //$NON-NLS-1$
|
||||
if (!noFilesUpFront) {
|
||||
String prefSetting= getProperty(IndexerPreferences.KEY_FILES_TO_PARSE_UP_FRONT);
|
||||
if (prefSetting != null) {
|
||||
prefSetting= prefSetting.trim();
|
||||
if (prefSetting.length() > 0) {
|
||||
return prefSetting.split(","); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
}
|
||||
return new String[0];
|
||||
|
|
|
@ -15,37 +15,25 @@ import java.util.Arrays;
|
|||
import java.util.Calendar;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.ILinkage;
|
||||
import org.eclipse.cdt.core.dom.IPDOMIndexer;
|
||||
import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
|
||||
import org.eclipse.cdt.core.index.IIndexManager;
|
||||
import org.eclipse.cdt.core.model.AbstractLanguage;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.core.model.ILanguage;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.model.LanguageManager;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfoProvider;
|
||||
import org.eclipse.cdt.core.parser.ScannerInfo;
|
||||
import org.eclipse.cdt.internal.core.index.IWritableIndex;
|
||||
import org.eclipse.cdt.internal.core.index.IWritableIndexManager;
|
||||
import org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask;
|
||||
import org.eclipse.cdt.internal.core.pdom.ITodoTaskUpdater;
|
||||
import org.eclipse.cdt.internal.core.pdom.IndexerProgress;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.ChunkCache;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.content.IContentType;
|
||||
import org.eclipse.osgi.util.NLS;
|
||||
|
||||
import com.ibm.icu.text.NumberFormat;
|
||||
|
@ -177,59 +165,6 @@ public abstract class PDOMIndexerTask extends AbstractIndexerTask implements IPD
|
|||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getASTPathForParsingUpFront() {
|
||||
final IProject project = getProject().getProject();
|
||||
final IPath prjLocation= project.getLocation();
|
||||
if (prjLocation == null) {
|
||||
return null;
|
||||
}
|
||||
return prjLocation.append(super.getASTPathForParsingUpFront()).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractLanguage[] getLanguages(String filename) {
|
||||
IProject project = getProject().getProject();
|
||||
IContentType ct= CCorePlugin.getContentType(project, filename);
|
||||
if (ct != null) {
|
||||
ILanguage l = LanguageManager.getInstance().getLanguage(ct, project);
|
||||
if (l instanceof AbstractLanguage) {
|
||||
if (filename.indexOf('.') >= 0 && ct.getId().equals(CCorePlugin.CONTENT_TYPE_CXXHEADER) &&
|
||||
l.getLinkageID() == ILinkage.CPP_LINKAGE_ID) {
|
||||
ILanguage l2= LanguageManager.getInstance().getLanguageForContentTypeID(CCorePlugin.CONTENT_TYPE_CHEADER);
|
||||
if (l2 instanceof AbstractLanguage) {
|
||||
return new AbstractLanguage[] {(AbstractLanguage) l, (AbstractLanguage) l2};
|
||||
}
|
||||
}
|
||||
return new AbstractLanguage[] {(AbstractLanguage) l};
|
||||
}
|
||||
}
|
||||
return new AbstractLanguage[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IScannerInfo createDefaultScannerConfig(int linkageID) {
|
||||
IProject project= getProject().getProject();
|
||||
IScannerInfoProvider provider= CCorePlugin.getDefault().getScannerInfoProvider(project);
|
||||
IScannerInfo scanInfo;
|
||||
if (provider != null) {
|
||||
String filename= linkageID == ILinkage.C_LINKAGE_ID ? "__cdt__.c" : "__cdt__.cpp"; //$NON-NLS-1$//$NON-NLS-2$
|
||||
IFile file= project.getFile(filename);
|
||||
scanInfo= provider.getScannerInformation(file);
|
||||
if (scanInfo == null || scanInfo.getDefinedSymbols().isEmpty()) {
|
||||
scanInfo= provider.getScannerInformation(project);
|
||||
}
|
||||
if (linkageID == ILinkage.C_LINKAGE_ID) {
|
||||
final Map<String, String> definedSymbols = scanInfo.getDefinedSymbols();
|
||||
definedSymbols.remove("__cplusplus__"); //$NON-NLS-1$
|
||||
definedSymbols.remove("__cplusplus"); //$NON-NLS-1$
|
||||
}
|
||||
} else {
|
||||
scanInfo= new ScannerInfo();
|
||||
}
|
||||
return scanInfo;
|
||||
}
|
||||
|
||||
private ICProject getProject() {
|
||||
return getIndexer().getProject();
|
||||
}
|
||||
|
@ -406,4 +341,4 @@ public abstract class PDOMIndexerTask extends AbstractIndexerTask implements IPD
|
|||
}
|
||||
return super.acceptUrgentTask(urgentTask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ public class PDOMRebuildTask implements IPDOMIndexerTask {
|
|||
|
||||
private void clearIndex(ICProject project, IWritableIndex index) throws CoreException, InterruptedException {
|
||||
// First clear the pdom
|
||||
index.acquireWriteLock(0);
|
||||
index.acquireWriteLock();
|
||||
try {
|
||||
index.clear();
|
||||
IWritableIndexFragment wf= index.getWritableFragment();
|
||||
|
@ -96,7 +96,7 @@ public class PDOMRebuildTask implements IPDOMIndexerTask {
|
|||
PDOMManager.writeProjectPDOMProperties((WritablePDOM) wf, project.getProject());
|
||||
}
|
||||
} finally {
|
||||
index.releaseWriteLock(0);
|
||||
index.releaseWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ public class ProjectIndexerInputAdapter extends IndexerInputAdapter {
|
|||
public String getASTPath(IIndexFileLocation ifl) {
|
||||
IPath path= IndexLocationFactory.getAbsolutePath(ifl);
|
||||
if (path != null) {
|
||||
return path.toString();
|
||||
return path.toOSString();
|
||||
}
|
||||
return ifl.getURI().getPath();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2002, 2008 IBM Corporation and others.
|
||||
* Copyright (c) 2002, 2011 IBM Corporation 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
|
||||
|
@ -19,6 +19,7 @@ import org.eclipse.cdt.internal.core.model.DebugLogConstants;
|
|||
import org.eclipse.cdt.internal.core.model.Util;
|
||||
import org.eclipse.cdt.internal.core.util.ICancelable;
|
||||
import org.eclipse.cdt.internal.core.util.ICanceler;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
|
@ -53,6 +54,16 @@ public class ParserLogService extends AbstractParserLogService implements ICance
|
|||
Util.debugLog( message, topic );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTracing(String option) {
|
||||
return "true".equals(Platform.getDebugOption(option)); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
@Override
|
||||
public void traceLog(String option, String message) {
|
||||
if (isTracing(option))
|
||||
System.out.println(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void errorLog(String message) {
|
||||
|
|
|
@ -16,6 +16,7 @@ import junit.framework.Test;
|
|||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.swt.widgets.Tree;
|
||||
import org.eclipse.swt.widgets.TreeItem;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.IPDOMManager;
|
||||
|
@ -37,6 +38,7 @@ public class BasicIncludeBrowserTest extends IncludeBrowserBaseTest {
|
|||
// // source
|
||||
// #include "user.h"
|
||||
// #include <system.h>
|
||||
// #include "user.h"
|
||||
|
||||
public void testSimpleInclusion() throws Exception {
|
||||
TestScannerProvider.sIncludes= new String[] { getProject().getProject().getLocation().toOSString() };
|
||||
|
@ -50,9 +52,10 @@ public class BasicIncludeBrowserTest extends IncludeBrowserBaseTest {
|
|||
|
||||
openIncludeBrowser(source);
|
||||
Tree tree = getIBTree();
|
||||
checkTreeNode(tree, 0, "source.cpp");
|
||||
TreeItem node = checkTreeNode(tree, 0, "source.cpp");
|
||||
checkTreeNode(tree, 0, 0, "user.h");
|
||||
checkTreeNode(tree, 0, 1, "system.h");
|
||||
assertEquals(2, node.getItemCount());
|
||||
|
||||
// The tree has to be reversed
|
||||
openIncludeBrowser(user, true);
|
||||
|
|
|
@ -15,11 +15,13 @@ import java.io.IOException;
|
|||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeMap;
|
||||
|
@ -42,6 +44,7 @@ import org.eclipse.ui.IWorkbenchPart;
|
|||
import org.eclipse.ui.IWorkbenchPartSite;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.ILinkage;
|
||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
|
||||
|
@ -55,12 +58,14 @@ import org.eclipse.cdt.core.index.IIndex;
|
|||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||
import org.eclipse.cdt.core.index.IIndexInclude;
|
||||
import org.eclipse.cdt.core.index.IndexLocationFactory;
|
||||
import org.eclipse.cdt.core.model.CModelException;
|
||||
import org.eclipse.cdt.core.model.CoreModelUtil;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.core.model.ILanguage;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.parser.ExtendedScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfoProvider;
|
||||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
||||
import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager;
|
||||
|
@ -76,6 +81,7 @@ import org.eclipse.cdt.internal.ui.editor.ASTProvider;
|
|||
|
||||
@SuppressWarnings("nls")
|
||||
public class CreateParserLogAction implements IObjectActionDelegate {
|
||||
private static final String INDENT = " ";
|
||||
|
||||
private static final class MyVisitor extends ASTVisitor {
|
||||
List<IASTProblem> fProblems= new ArrayList<IASTProblem>();
|
||||
|
@ -118,6 +124,8 @@ public class CreateParserLogAction implements IObjectActionDelegate {
|
|||
|
||||
private ISelection fSelection;
|
||||
private IWorkbenchPartSite fSite;
|
||||
|
||||
private boolean fWroteUnresolvedTitle;
|
||||
|
||||
public void setActivePart(IAction action, IWorkbenchPart targetPart) {
|
||||
fSite= targetPart.getSite();
|
||||
|
@ -209,81 +217,90 @@ public class CreateParserLogAction implements IObjectActionDelegate {
|
|||
IStatus status = Status.OK_STATUS;
|
||||
final ICProject cproject = tu.getCProject();
|
||||
final String projectName= cproject == null ? null : cproject.getElementName();
|
||||
String scannerInfoProvider= "null";
|
||||
if (cproject != null) {
|
||||
IScannerInfoProvider provider = CCorePlugin.getDefault().getScannerInfoProvider(cproject.getProject());
|
||||
if (provider != null) {
|
||||
scannerInfoProvider= provider.getClass().getName();
|
||||
}
|
||||
}
|
||||
|
||||
ITranslationUnit ctx= tu;
|
||||
final IIndex index = ast.getIndex();
|
||||
|
||||
ITranslationUnit configureWith = tu;
|
||||
int ctxLinkage= 0;
|
||||
ISignificantMacros ctxSigMacros= null;
|
||||
if (tu instanceof TranslationUnit) {
|
||||
TranslationUnit itu= (TranslationUnit) tu;
|
||||
ctx= itu.getSourceContextTU(ast.getIndex(), ITranslationUnit.AST_CONFIGURE_USING_SOURCE_CONTEXT);
|
||||
IIndexFile[] ctxToHeader = itu.getContextToHeader(index, ITranslationUnit.AST_CONFIGURE_USING_SOURCE_CONTEXT);
|
||||
if (ctxToHeader != null) {
|
||||
try {
|
||||
final IIndexFile ctxFile = ctxToHeader[0];
|
||||
ctxLinkage= ctxToHeader[0].getLinkageID();
|
||||
ctxSigMacros= ctxFile.getSignificantMacros();
|
||||
configureWith = CoreModelUtil.findTranslationUnitForLocation(ctxFile.getLocation(), cproject);
|
||||
} catch (CoreException e) {
|
||||
}
|
||||
if (configureWith == null) {
|
||||
configureWith= tu;
|
||||
ctxToHeader= null;
|
||||
}
|
||||
}
|
||||
}
|
||||
final ExtendedScannerInfo scfg= new ExtendedScannerInfo(ctx.getScannerInfo(true));
|
||||
final String indent= " ";
|
||||
|
||||
final ExtendedScannerInfo scfg= new ExtendedScannerInfo(configureWith.getScannerInfo(true));
|
||||
final MyVisitor visitor= new MyVisitor();
|
||||
ast.accept(visitor);
|
||||
|
||||
out.println("Project: " + projectName);
|
||||
out.println("File: " + tu.getLocationURI());
|
||||
out.println("Language: " + lang.getName());
|
||||
out.println("Index Version: " + PDOM.versionString(PDOM.getDefaultVersion()));
|
||||
out.println("Scanner Info Provider: " + scannerInfoProvider);
|
||||
out.println("Build Configuration: " + getBuildConfig(cproject));
|
||||
out.println("File: " + tu.getLocationURI());
|
||||
out.println("Context: " + ctx.getLocationURI());
|
||||
out.println("Language: " + lang.getName());
|
||||
out.println();
|
||||
out.println("Include Search Path (option -I):");
|
||||
output(out, indent, scfg.getIncludePaths());
|
||||
out.println();
|
||||
out.println("Local Include Search Path (option -iquote):");
|
||||
output(out, indent, scfg.getLocalIncludePath());
|
||||
out.println();
|
||||
out.println("Preincluded files (option -include):");
|
||||
output(out, indent, scfg.getIncludeFiles());
|
||||
out.println();
|
||||
out.println("Preincluded macro files (option -imacros):");
|
||||
output(out, indent, scfg.getMacroFiles());
|
||||
out.println();
|
||||
out.println("Macro definitions (option -D):");
|
||||
HashSet<String> reported= new HashSet<String>();
|
||||
output(out, indent, scfg.getDefinedSymbols(), reported);
|
||||
out.println();
|
||||
out.println("Macro definitions (from configuration + headers in index):");
|
||||
output(out, indent, ast.getBuiltinMacroDefinitions(), reported);
|
||||
out.println();
|
||||
out.println("Macro definitions (from files actually parsed):");
|
||||
output(out, indent, ast.getMacroDefinitions(), reported);
|
||||
|
||||
out.println();
|
||||
out.println("Unresolved includes (from headers in index):");
|
||||
if (configureWith == tu) {
|
||||
out.println("Context: none");
|
||||
} else {
|
||||
out.println("Context: " + configureWith.getLocationURI());
|
||||
out.println(INDENT + getLinkageName(ctxLinkage) + ", " + ctxSigMacros);
|
||||
}
|
||||
|
||||
try {
|
||||
outputUnresolvedIncludes(cproject, ast.getIndex(), out, indent, ast.getIncludeDirectives(), ast.getLinkage().getLinkageID());
|
||||
IIndexFile[] versions= index.getFiles(IndexLocationFactory.getIFL(tu));
|
||||
out.println("Versions in Index: " + versions.length);
|
||||
for (IIndexFile f : versions) {
|
||||
out.println(INDENT + getLinkageName(f.getLinkageID()) + ": " + f.getSignificantMacros());
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
status= e.getStatus();
|
||||
}
|
||||
out.println();
|
||||
|
||||
output(out, "Include Search Path (option -I):", scfg.getIncludePaths());
|
||||
output(out, "Local Include Search Path (option -iquote):", scfg.getLocalIncludePath());
|
||||
output(out, "Preincluded files (option -include):", scfg.getIncludeFiles());
|
||||
output(out, "Preincluded macro files (option -imacros):", scfg.getMacroFiles());
|
||||
|
||||
out.println();
|
||||
out.println("Scanner problems:");
|
||||
output(out, indent, ast.getPreprocessorProblems());
|
||||
|
||||
out.println();
|
||||
out.println("Parser problems:");
|
||||
output(out, indent, visitor.fProblems.toArray(new IASTProblem[visitor.fProblems.size()]));
|
||||
|
||||
out.println();
|
||||
out.println("Unresolved names:");
|
||||
output(out, indent, visitor.fProblemBindings);
|
||||
|
||||
out.println();
|
||||
out.println("Exceptions in name resolution:");
|
||||
output(out, visitor.fExceptions);
|
||||
HashSet<String> reported= new HashSet<String>();
|
||||
output(out, "Macro definitions (option -D):", scfg.getDefinedSymbols(), reported);
|
||||
output(out, "Macro definitions (from language + headers in index):", ast.getBuiltinMacroDefinitions(), reported);
|
||||
output(out, "Macro definitions (from files actually parsed):", ast.getMacroDefinitions(), reported);
|
||||
|
||||
try {
|
||||
outputUnresolvedIncludes(cproject, ast.getIndex(), out, ast.getIncludeDirectives(), ast.getLinkage().getLinkageID());
|
||||
} catch (CoreException e) {
|
||||
status= e.getStatus();
|
||||
}
|
||||
output(out, "Scanner problems:", ast.getPreprocessorProblems());
|
||||
output(out, "Parser problems:", visitor.fProblems.toArray(new IASTProblem[0]));
|
||||
output(out, "Unresolved names:", visitor.fProblemBindings.toArray(new IProblemBinding[0]));
|
||||
output(out, "Exceptions in name resolution:", visitor.fExceptions);
|
||||
out.println("Written on " + new Date().toString());
|
||||
return status;
|
||||
}
|
||||
|
||||
private String getLinkageName(int linkageID) {
|
||||
switch(linkageID) {
|
||||
case ILinkage.NO_LINKAGE_ID: return ILinkage.NO_LINKAGE_NAME;
|
||||
case ILinkage.C_LINKAGE_ID: return ILinkage.C_LINKAGE_NAME;
|
||||
case ILinkage.CPP_LINKAGE_ID: return ILinkage.CPP_LINKAGE_NAME;
|
||||
case ILinkage.FORTRAN_LINKAGE_ID: return ILinkage.FORTRAN_LINKAGE_NAME;
|
||||
case ILinkage.OBJC_LINKAGE_ID: return ILinkage.OBJC_LINKAGE_NAME;
|
||||
}
|
||||
return String.valueOf(linkageID);
|
||||
}
|
||||
|
||||
private String getBuildConfig(ICProject cproject) {
|
||||
ICProjectDescriptionManager prjDescMgr= CCorePlugin.getDefault().getProjectDescriptionManager();
|
||||
ICProjectDescription prefs= prjDescMgr.getProjectDescription(cproject.getProject(), false);
|
||||
|
@ -295,35 +312,37 @@ public class CreateParserLogAction implements IObjectActionDelegate {
|
|||
return "unknown";
|
||||
}
|
||||
|
||||
private void outputUnresolvedIncludes(ICProject prj, IIndex index, PrintStream out, String indent,
|
||||
private void outputUnresolvedIncludes(ICProject prj, IIndex index, PrintStream out,
|
||||
IASTPreprocessorIncludeStatement[] includeDirectives, int linkageID) throws CoreException {
|
||||
fWroteUnresolvedTitle= false;
|
||||
ASTFilePathResolver resolver= new ProjectIndexerInputAdapter(prj);
|
||||
HashSet<IIndexFileLocation> handled= new HashSet<IIndexFileLocation>();
|
||||
HashSet<IIndexFile> handled= new HashSet<IIndexFile>();
|
||||
for (IASTPreprocessorIncludeStatement include : includeDirectives) {
|
||||
if (include.isActive() && include.isResolved()) {
|
||||
outputUnresolvedIncludes(index, out, indent, resolver.resolveASTPath(include.getPath()), linkageID, handled);
|
||||
if (include.isResolved()) {
|
||||
IIndexFileLocation ifl = resolver.resolveASTPath(include.getPath());
|
||||
IIndexFile ifile= index.getFile(linkageID, ifl, include.getSignificantMacros());
|
||||
outputUnresolvedIncludes(index, out, ifl, ifile, handled);
|
||||
}
|
||||
}
|
||||
if (fWroteUnresolvedTitle)
|
||||
out.println();
|
||||
}
|
||||
|
||||
private void outputUnresolvedIncludes(IIndex index, PrintStream out, String indent,
|
||||
IIndexFileLocation ifl, int linkageID, HashSet<IIndexFileLocation> handled) throws CoreException {
|
||||
if (!handled.add(ifl)) {
|
||||
return;
|
||||
}
|
||||
IIndexFile ifile= index.getFile(linkageID, ifl);
|
||||
private void outputUnresolvedIncludes(IIndex index, PrintStream out,
|
||||
IIndexFileLocation ifl, IIndexFile ifile, Set<IIndexFile> handled) throws CoreException {
|
||||
if (ifile == null) {
|
||||
out.println(indent + ifl.getURI() + " is not indexed");
|
||||
}
|
||||
else {
|
||||
writeUnresolvedTitle(out);
|
||||
out.println(INDENT + ifl.getURI() + " is not indexed");
|
||||
} else if (handled.add(ifile)) {
|
||||
IIndexInclude[] includes = ifile.getIncludes();
|
||||
for (IIndexInclude inc : includes) {
|
||||
if (inc.isActive()) {
|
||||
if (inc.isResolved()) {
|
||||
outputUnresolvedIncludes(index, out, indent, inc.getIncludesLocation(), linkageID, handled);
|
||||
}
|
||||
else {
|
||||
out.println(indent + "Unresolved inclusion: " + inc.getFullName() + " in file " +
|
||||
IIndexFile next = index.resolveInclude(inc);
|
||||
outputUnresolvedIncludes(index, out, inc.getIncludesLocation(), next, handled);
|
||||
} else {
|
||||
writeUnresolvedTitle(out);
|
||||
out.println(INDENT + "Unresolved inclusion: " + inc.getFullName() + " in file " +
|
||||
inc.getIncludedByLocation().getURI());
|
||||
}
|
||||
}
|
||||
|
@ -331,53 +350,85 @@ public class CreateParserLogAction implements IObjectActionDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
private void output(PrintStream out, String indent, String[] list) {
|
||||
for (String line : list) {
|
||||
out.println(indent + line);
|
||||
public void writeUnresolvedTitle(PrintStream out) {
|
||||
if (!fWroteUnresolvedTitle) {
|
||||
fWroteUnresolvedTitle= true;
|
||||
out.println("Unresolved includes (from headers in index):");
|
||||
}
|
||||
}
|
||||
|
||||
private void output(PrintStream out, String indent, Map<String, String> definedSymbols, HashSet<String> reported) {
|
||||
SortedMap<String, String> sorted= new TreeMap<String, String>(COMP_INSENSITIVE);
|
||||
sorted.putAll(definedSymbols);
|
||||
for (Entry<String, String> entry : sorted.entrySet()) {
|
||||
final String macro = entry.getKey() + '=' + entry.getValue();
|
||||
if (reported.add(macro)) {
|
||||
out.println(indent + macro);
|
||||
private void output(PrintStream out, String label, String[] list) {
|
||||
if (list.length > 0) {
|
||||
out.println(label);
|
||||
for (String line : list) {
|
||||
out.println(INDENT + line);
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
|
||||
private void output(PrintStream out, String label, Map<String, String> definedSymbols, HashSet<String> reported) {
|
||||
if (!definedSymbols.isEmpty()) {
|
||||
out.println(label);
|
||||
|
||||
SortedMap<String, String> sorted= new TreeMap<String, String>(COMP_INSENSITIVE);
|
||||
sorted.putAll(definedSymbols);
|
||||
for (Entry<String, String> entry : sorted.entrySet()) {
|
||||
final String macro = entry.getKey() + '=' + entry.getValue();
|
||||
if (reported.add(macro)) {
|
||||
out.println(INDENT + macro);
|
||||
}
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
|
||||
private void output(PrintStream out, String indent, IASTPreprocessorMacroDefinition[] defs, HashSet<String> reported) {
|
||||
SortedSet<String> macros= new TreeSet<String>(COMP_INSENSITIVE);
|
||||
for (IASTPreprocessorMacroDefinition def : defs) {
|
||||
macros.add(def.toString());
|
||||
private void output(PrintStream out, String label, IASTPreprocessorMacroDefinition[] defs, HashSet<String> reported) {
|
||||
if (defs.length > 0) {
|
||||
out.println(label);
|
||||
SortedSet<String> macros= new TreeSet<String>(COMP_INSENSITIVE);
|
||||
for (IASTPreprocessorMacroDefinition def : defs) {
|
||||
macros.add(def.toString());
|
||||
}
|
||||
|
||||
for (String macro : macros) {
|
||||
if (reported.add(macro)) {
|
||||
out.println(INDENT + macro);
|
||||
}
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
|
||||
private void output(PrintStream out, String label, IASTProblem[] preprocessorProblems) {
|
||||
if (preprocessorProblems.length > 0) {
|
||||
out.println(label);
|
||||
for (IASTProblem problem : preprocessorProblems) {
|
||||
out.println(INDENT + problem.getMessageWithLocation());
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
|
||||
for (String macro : macros) {
|
||||
if (reported.add(macro)) {
|
||||
out.println(indent + macro);
|
||||
private void output(PrintStream out, String label, IProblemBinding[] list) {
|
||||
if (list.length > 0) {
|
||||
out.println(label);
|
||||
for (IProblemBinding problem : list) {
|
||||
String file= problem.getFileName();
|
||||
int line = problem.getLineNumber();
|
||||
out.println(INDENT + problem.getMessage() + " in file " + file + ':' + line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void output(PrintStream out, String indent, IASTProblem[] preprocessorProblems) {
|
||||
for (IASTProblem problem : preprocessorProblems) {
|
||||
out.println(indent + problem.getMessageWithLocation());
|
||||
}
|
||||
}
|
||||
|
||||
private void output(PrintStream out, String indent, List<IProblemBinding> list) {
|
||||
for (IProblemBinding problem : list) {
|
||||
String file= problem.getFileName();
|
||||
int line = problem.getLineNumber();
|
||||
out.println(indent + problem.getMessage() + " in file " + file + ':' + line);
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
|
||||
private void output(PrintStream out, List<Exception> list) {
|
||||
for (Exception problem : list) {
|
||||
problem.printStackTrace(out);
|
||||
private void output(PrintStream out, String label, List<Exception> list) {
|
||||
if (!list.isEmpty()) {
|
||||
out.println(label);
|
||||
for (Exception problem : list) {
|
||||
problem.printStackTrace(out);
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ package org.eclipse.cdt.internal.ui.includebrowser;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
@ -102,7 +104,7 @@ public class IBContentProvider extends AsyncTreeContentProvider {
|
|||
directiveFile= node.getRepresentedFile();
|
||||
}
|
||||
if (includes.length > 0) {
|
||||
ArrayList<IBNode> result= new ArrayList<IBNode>(includes.length);
|
||||
Set<IBNode> result= new LinkedHashSet<IBNode>(includes.length);
|
||||
for (int i = 0; i < includes.length; i++) {
|
||||
IIndexInclude include = includes[i];
|
||||
try {
|
||||
|
@ -122,7 +124,8 @@ public class IBContentProvider extends AsyncTreeContentProvider {
|
|||
include.getIncludedBy().getTimestamp());
|
||||
newnode.setIsActiveCode(include.isActive());
|
||||
newnode.setIsSystemInclude(include.isSystemInclude());
|
||||
result.add(newnode);
|
||||
if (!result.contains(newnode) || newnode.isActiveCode())
|
||||
result.add(newnode);
|
||||
} catch (CoreException e) {
|
||||
CUIPlugin.log(e);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue