diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBindingResolutionTestBase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBindingResolutionTestBase.java index 9adcb3f5d6b..7f7240bb309 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBindingResolutionTestBase.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBindingResolutionTestBase.java @@ -39,6 +39,7 @@ import org.eclipse.cdt.core.model.LanguageManager; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.testplugin.CProjectHelper; import org.eclipse.cdt.core.testplugin.CTestPlugin; +import org.eclipse.cdt.core.testplugin.TestScannerProvider; import org.eclipse.cdt.core.testplugin.util.BaseTestCase; import org.eclipse.cdt.core.testplugin.util.TestSourceReader; import org.eclipse.cdt.internal.core.CCoreInternals; @@ -337,6 +338,7 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase { testData= TestSourceReader.getContentsForTest(b, "parser", IndexBindingResolutionTestBase.this.getClass(), getName(), 2); referenced = createReferencedContent(); + TestScannerProvider.sIncludes= new String[] {referenced.getProject().getLocation().toOSString()}; IFile references= TestSourceReader.createFile(cproject.getProject(), new Path("refs.c" + (cpp ? "pp" : "")), testData[1].toString()); IProject[] refs = new IProject[] {referenced.getProject()}; diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionBugs.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionBugs.java index d56d3d89b12..75310fda1e9 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionBugs.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionBugs.java @@ -11,6 +11,8 @@ *******************************************************************************/ package org.eclipse.cdt.internal.index.tests; +import java.util.regex.Pattern; + import junit.framework.TestSuite; import org.eclipse.cdt.core.dom.ast.DOMException; @@ -35,9 +37,13 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable; +import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexBinding; +import org.eclipse.cdt.core.index.IIndexMacro; +import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalTemplateInstantiator; +import org.eclipse.core.runtime.CoreException; /** * For testing PDOM binding resolution @@ -65,6 +71,56 @@ public class IndexCPPBindingResolutionBugs extends IndexBindingResolutionTestBas setStrategy(new SinglePDOMTestStrategy(true)); } + // #define OBJ void foo() + // #define FUNC() void bar() + // #define FUNC2(A) void baz() + + // #include "header.h" + // + // OBJ {} + // FUNC() {} + // FUNC2(1) {} + public void testBug208558() throws CoreException { + IIndex index= getIndex(); + + IIndexMacro[] macrosA= index.findMacros("OBJ".toCharArray(), IndexFilter.ALL, NPM); + IIndexMacro[] macrosB= index.findMacros("FUNC".toCharArray(), IndexFilter.ALL, NPM); + IIndexMacro[] macrosC= index.findMacros("FUNC2".toCharArray(), IndexFilter.ALL, NPM); + + assertEquals(1, macrosA.length); + assertEquals(1, macrosB.length); + assertEquals(1, macrosC.length); + IIndexMacro obj= macrosA[0]; + IIndexMacro func= macrosB[0]; + IIndexMacro func2= macrosC[0]; + + assertEquals("OBJ", new String(obj.getName())); + assertEquals("FUNC", new String(func.getName())); + assertEquals("FUNC2", new String(func2.getName())); + + assertEquals("void foo()", new String(obj.getExpansion())); + assertEquals("void bar()", new String(func.getExpansion())); + assertEquals("void baz()", new String(func2.getExpansion())); + + assertEquals("OBJ", new String(obj.getSignature())); + assertEquals("FUNC()", new String(func.getSignature())); + assertEquals("FUNC2(A)", new String(func2.getSignature())); + + IIndexBinding[] bindings= index.findBindings(Pattern.compile(".*"), false, IndexFilter.ALL, NPM); + assertEquals(3, bindings.length); + + IIndexBinding foo= index.findBindings("foo".toCharArray(), IndexFilter.ALL, NPM)[0]; + IIndexBinding bar= index.findBindings("bar".toCharArray(), IndexFilter.ALL, NPM)[0]; + IIndexBinding baz= index.findBindings("baz".toCharArray(), IndexFilter.ALL, NPM)[0]; + + assertEquals("foo", foo.getName()); + assertEquals("bar", bar.getName()); + assertEquals("baz", baz.getName()); + assertInstance(foo, ICPPFunction.class); + assertInstance(bar, ICPPFunction.class); + assertInstance(baz, ICPPFunction.class); + } + // template // inline void testTemplate(T& aRef); // diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/FunctionStyleMacro.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/FunctionStyleMacro.java index 1fd16dc4e01..809c570ef2c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/FunctionStyleMacro.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/FunctionStyleMacro.java @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial implementation * Markus Schorn (Wind River Systems) + * Andrew Ferguson (Symbian) *******************************************************************************/ package org.eclipse.cdt.internal.core.parser.scanner2; @@ -34,7 +35,7 @@ public class FunctionStyleMacro extends ObjectStyleMacro { this.arglist = arglist; // determine if there's an argument with "..." - if (arglist != null && arglist[0]!= null && arglist.length > 0) { + if (arglist != null && arglist.length > 0 && arglist[0]!= null) { int last = -1; // if the last element in the list is null then binary search for the last non-null element diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index dc90c237ee2..ee1565998d6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -81,10 +81,20 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { */ public static final String FRAGMENT_PROPERTY_VALUE_FORMAT_ID= "org.eclipse.cdt.internal.core.pdom.PDOM"; //$NON-NLS-1$ - public static final int CURRENT_VERSION = 38; + public static final int CURRENT_VERSION = 39; public static final int MIN_SUPPORTED_VERSION= 36; - public static final int MIN_VERSION_TO_WRITE_NESTED_BINDINGS_INDEX= 37; // to be removed in 4.1 - public static final int MIN_VERSION_TO_WRITE_MACROS_INDEX= 38; // to be removed in 4.1 + public static final int MIN_VERSION_TO_WRITE_NESTED_BINDINGS_INDEX= 37; // to be removed in 5.0 + public static final int MIN_VERSION_TO_WRITE_MACROS_INDEX= 38; // to be removed in 5.0 + + /** + * The earliest PDOM version that the CURRENT_VERSION can be read as. For example, + * versions 37,38 and 39 may be safely read by code from the version of CDT (4.0.0) + * released at PDOM version 36. + *

+ * Ideally this would always be CURRENT_VERSION on the basis that CURRENT_VERSION is + * not incrementing. + */ + public static final int EARLIEST_FORWARD_COMPATIBLE_VERSION= 36; /* * PDOM internal format history @@ -110,18 +120,18 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { * 16 - have PDOMCPPField store type information, and PDOMCPPNamespaceAlias store what it is aliasing * 17 - use single linked list for names in file, adds a link to enclosing definition name. * 18 - distinction between c-unions and c-structs. - * 19 - alter representation of paths in the pdom (162172) + * 19 - alter representation of paths in the PDOM (162172) * 20 - add pointer to member types, array types, return types for functions - * 21 - change representation of paths in the pdom (167549) + * 21 - change representation of paths in the PDOM (167549) * 22 - fix inheritance relations (167396) * 23 - types on c-variables, return types on c-functions * 24 - file local scopes (161216) * 25 - change ordering of bindings (175275) * 26 - add properties storage * 27 - templates: classes, functions, limited nesting support, only template type parameters - * 28 - templates: class instance/specialization base classes - * 29 - includes: fixed modeling of unresolved includes (180159) - * 30 - templates: method/constructor templates, typedef specializations + * 28 - templates: class instance/specialisation base classes + * 29 - includes: fixed modelling of unresolved includes (180159) + * 30 - templates: method/constructor templates, typedef specialisations * 31 - macros: added file locations * 32 - support stand-alone function types (181936) * 33 - templates: constructor instances @@ -129,7 +139,8 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { * 35 - add scanner configuration hash-code (62366) * #36#- changed chunk size back to 4K (184892) - <> * #37#- added index for nested bindings (189811), compatible with version 36 - <> - * #38#- added btree for macros (193056), compatible with version 36 and 37 - <> + * 38 - added b-tree for macros (193056), compatible with version 36 and 37 + * #39#- added flag for function-style macros (208558), compatible with version 36,37,38 - <> */ public static final int LINKAGES = Database.DATA_AREA; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java index 976830b49cb..6b08789c642 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java @@ -8,6 +8,7 @@ * Contributors: * QNX - Initial API and implementation * Markus Schorn (Wind River Systems) + * Andrew Ferguson (Symbian) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom; @@ -43,6 +44,10 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation { private final int record; private IMacro macro; + private static final byte MACROSTYLE_UNKNOWN = 0; // for reading versions of PDOM <39 + private static final byte MACROSTYLE_OBJECT = 1; + private static final byte MACROSTYLE_FUNCTION= 2; + private static final int NAME = 0; private static final int FILE = 4; private static final int NAME_OFFSET = 8; @@ -50,8 +55,9 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation { private static final int FIRST_PARAMETER = 14; private static final int EXPANSION = 18; private static final int NEXT_MACRO = 22; + private static final int MACRO_STYLE = 26; // byte - private static final int RECORD_SIZE = 26; + private static final int RECORD_SIZE = 27; public PDOMMacro(PDOM pdom, int record) { this.pdom = pdom; @@ -72,8 +78,10 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation { db.putInt(record + EXPANSION, db.newString(macro.getExpansion()).getRecord()); setNextMacro(0); + byte macroStyle= MACROSTYLE_OBJECT; PDOMMacroParameter last = null; if (macro instanceof IASTPreprocessorFunctionStyleMacroDefinition) { + macroStyle= MACROSTYLE_FUNCTION; IASTPreprocessorFunctionStyleMacroDefinition func = (IASTPreprocessorFunctionStyleMacroDefinition)macro; IASTFunctionStyleMacroParameter[] params = func.getParameters(); for (int i = params.length - 1; i >= 0; --i) { @@ -85,6 +93,7 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation { } } db.putInt(record + FIRST_PARAMETER, last != null ? last.getRecord() : 0); + db.putByte(record + MACRO_STYLE, macroStyle); } public int getRecord() { @@ -106,7 +115,7 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation { return db.getString(rec); } - public IString getExpansionInDB() throws CoreException { + private IString getExpansionInDB() throws CoreException { Database db = pdom.getDB(); int rec = db.getInt(record + EXPANSION); return db.getString(rec); @@ -121,11 +130,11 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation { setNextMacro(macro != null ? macro.getRecord() : 0); } - public void setNextMacro(int rec) throws CoreException { + private void setNextMacro(int rec) throws CoreException { pdom.getDB().putInt(record + NEXT_MACRO, rec); } - public PDOMMacroParameter getFirstParameter() throws CoreException { + private PDOMMacroParameter getFirstParameter() throws CoreException { int rec = pdom.getDB().getInt(record + FIRST_PARAMETER); return rec != 0 ? new PDOMMacroParameter(pdom, rec) : null; } @@ -188,8 +197,19 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation { private void rebuildMacro() throws CoreException { char[] name = getNameInDB(pdom, record).getChars(); - PDOMMacroParameter param = getFirstParameter(); - if (param != null) { + PDOMMacroParameter param= getFirstParameter(); + + byte style= pdom.getDB().getByte(record + MACRO_STYLE); + if(style == MACROSTYLE_UNKNOWN) { + /* PDOM formats < 39 do not store MACRO_STYLE (208558) */ + style= param != null ? MACROSTYLE_FUNCTION : MACROSTYLE_OBJECT; + } + + switch(style) { + case MACROSTYLE_OBJECT: + macro= new ObjectStylePDOMMacro(name); + break; + case MACROSTYLE_FUNCTION: List paramList = new ArrayList(); while (param != null) { paramList.add(param.getName().getChars()); @@ -197,8 +217,10 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation { } char[][] params = (char[][])paramList.toArray(new char[paramList.size()][]); macro= new FunctionStylePDOMMacro(name, params); - } else - macro= new ObjectStylePDOMMacro(name); + break; + default: + throw new PDOMNotImplementedError(); + } } public char[] getSignature() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOM.java index df5e2811f87..ad6f6ebb6f1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOM.java @@ -80,11 +80,9 @@ public class GeneratePDOM implements ISafeRunnable { exportedPDOM.setProperty((String) entry.getKey(), (String) entry.getValue()); } } - // fake version of pdom, such that it works with CDT 4.0.0 and CDT 4.0.1, also. - // can be removed in CDT 5.0 - if (PDOM.CURRENT_VERSION == PDOM.MIN_VERSION_TO_WRITE_MACROS_INDEX) { - exportedPDOM.getDB().setVersion(PDOM.CURRENT_VERSION-2); - } + // fake PDOM-version to that which can be safely read by the CDT-version + // (and following CDT-versions) released at that PDOM-version. + exportedPDOM.getDB().setVersion(PDOM.EARLIEST_FORWARD_COMPATIBLE_VERSION); exportedPDOM.close(); } finally {