diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java index 731dcc7a4ce..b69fec2256c 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java @@ -625,7 +625,7 @@ public class IndexBugsTests extends BaseTestCase { } // typedef int T20070213; - public void _test173997() throws Exception { + public void test173997() throws Exception { waitForIndexer(); String content= getContentsForTest(1)[0].toString(); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java index 2698a4ebdfa..412f7d3d1bb 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java @@ -25,6 +25,7 @@ public class IndexTests extends TestSuite { suite.addTest(IndexLocationTest.suite()); suite.addTest(IndexSearchTest.suite()); suite.addTest(IndexIncludeTest.suite()); + suite.addTest(IndexUpdateTests.suite()); suite.addTest(IndexBugsTests.suite()); suite.addTest(EnclosingNamesTest.suite()); suite.addTest(TeamSharedIndexTest.suite()); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexUpdateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexUpdateTests.java new file mode 100644 index 00000000000..0e74f5ea931 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexUpdateTests.java @@ -0,0 +1,557 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.index.tests; + +import java.util.Arrays; + +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.IPDOMManager; +import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IFunction; +import org.eclipse.cdt.core.dom.ast.IParameter; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.IVariable; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; +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.IndexFilter; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.testplugin.CProjectHelper; +import org.eclipse.cdt.core.testplugin.util.TestSourceReader; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; + +public class IndexUpdateTests extends IndexTestBase { + + private static final String EXPLICIT = "explicit"; + private static final String VIRTUAL = "virtual"; + private static final String PROTECTED = "protected"; + private static final String PUBLIC = "public"; + private static final String PRIVATE = "private"; + private static final String CHAR = "char"; + private static final String INLINE = "inline"; + private static final String MUTABLE = "mutable"; + private static final String STATIC = "static"; + private static final String REGISTER = "register"; + private static final String AUTO = "auto"; + private static final String SHORT = "short int"; + private static final String INT = "int"; + private static final String IMPLICIT= "implicit"; + + public static TestSuite suite() { + TestSuite suite= suite(IndexUpdateTests.class, "_"); + suite.addTest(new IndexUpdateTests("deleteProject")); + return suite; + } + + private ICProject fCppProject= null; + private ICProject fCProject= null; + private IIndex fIndex= null; + private StringBuffer[] fContents; + private IFile fFile; + private int fContentUsed; + + public IndexUpdateTests(String name) { + super(name); + } + + public void setUp() throws Exception { + super.setUp(); + if (fCppProject == null) { + fCppProject= CProjectHelper.createCCProject("indexUpdateTestsCpp", null, IPDOMManager.ID_FAST_INDEXER); + } + if (fCProject == null) { + fCProject= CProjectHelper.createCProject("indexUpdateTestsC", null, IPDOMManager.ID_FAST_INDEXER); + } + fIndex= CCorePlugin.getIndexManager().getIndex(new ICProject[] {fCProject, fCppProject}); + } + + private void setupFile(int totalFileVersions, boolean cpp) throws Exception { + fContents= getContentsForTest(totalFileVersions); + IProject project= cpp ? fCppProject.getProject() : fCProject.getProject(); + fFile= TestSourceReader.createFile(project, "file" + (cpp ? ".cpp" : ".c"), fContents[0].toString()); + fContentUsed= 0; + assertTrue(CCorePlugin.getIndexManager().joinIndexer(INDEXER_WAIT_TIME, NPM)); + } + + private void updateFile() throws Exception { + fFile= TestSourceReader.createFile(fFile.getParent(), fFile.getName(), fContents[++fContentUsed].toString()); + TestSourceReader.waitUntilFileIsIndexed(fIndex, fFile, INDEXER_WAIT_TIME); + } + + public void tearDown() throws Exception { + fIndex= null; + if (fFile != null) { + fFile.delete(true, NPM); + CCorePlugin.getIndexManager().joinIndexer(INDEXER_WAIT_TIME, NPM); + } + super.tearDown(); + } + + public void deleteProject() { + if (fCProject != null) { + CProjectHelper.delete(fCProject); + fCProject= null; + } + if (fCppProject != null) { + CProjectHelper.delete(fCppProject); + fCppProject= null; + } + } + + // int globalVar; + + // short globalVar; + + // auto int globalVar; + + // register int globalVar; + public void testGlobalCVariable() throws Exception { + setupFile(4, false); + checkVariable("globalVar", INT, new String[] {}); + updateFile(); + checkVariable("globalVar", SHORT, new String[] {}); + updateFile(); + checkVariable("globalVar", INT, new String[] {AUTO}); + updateFile(); + checkVariable("globalVar", INT, new String[] {REGISTER}); + } + + private void checkVariable(String name, String type, String[] modifiers) throws Exception { + fIndex.acquireReadLock(); + try { + IVariable var = (IVariable) findBinding(name); + checkVariable(var, type, modifiers); + } finally { + fIndex.releaseReadLock(); + } + } + + private void checkVariable(IVariable var, String type, String[] modifiers) throws DOMException { + assertEquals(msg(), type, ASTTypeUtil.getType(var.getType())); + checkModifier(modifiers, AUTO, var.isAuto()); + checkModifier(modifiers, REGISTER, var.isRegister()); + checkModifier(modifiers, STATIC, var.isStatic()); + } + + private void checkModifier(String[] modifiers, String modifier, boolean actual) throws DOMException { + assertEquals(msg(modifier), hasMod(modifiers, modifier), actual); + } + + private boolean hasMod(String[] modifiers, String mod) { + return Arrays.asList(modifiers).contains(mod); + } + + private IIndexBinding findBinding(String name) throws CoreException { + String[] names= name.split("::"); + char[][] nchars= new char[names.length][]; + for (int i = 0; i < nchars.length; i++) { + nchars[i]= names[i].toCharArray(); + } + return fIndex.findBindings(nchars, IndexFilter.ALL_DECLARED, NPM)[0]; + } + + private String msg() { + return "Update #" + fContentUsed; + } + + private String msg(String modifier) { + return msg() + "; " + modifier + ":"; + } + + // int globalVar; + + // short globalVar; + + // auto int globalVar; + + // register int globalVar; + + public void testGlobalCppVariable() throws Exception { + setupFile(4, true); + checkCppVariable("globalVar", INT, new String[]{}); + updateFile(); + checkCppVariable("globalVar", SHORT, new String[]{}); + updateFile(); + checkCppVariable("globalVar", INT, new String[]{AUTO}); + updateFile(); + checkCppVariable("globalVar", INT, new String[]{REGISTER}); + } + + private void checkCppVariable(String name, String type, String[] modifiers) throws Exception { + fIndex.acquireReadLock(); + try { + ICPPVariable var = (ICPPVariable) findBinding(name); + checkCppVariable(var, type, modifiers); + } finally { + fIndex.releaseReadLock(); + } + } + + private void checkCppVariable(ICPPVariable var, String type, String[] modifiers) throws Exception { + checkVariable(var, type, modifiers); + checkModifier(modifiers, MUTABLE, var.isMutable()); + } + + // int globalFunction(int a, int b){}; + + // short globalFunction(int a, int b){}; + + // int globalFunction(char a){}; + + // inline int globalFunction(char a){}; + public void testCFunction() throws Exception { + setupFile(4, false); + checkFunction("globalFunction", new String[] {INT, INT, INT}, new String[]{}); + updateFile(); + checkFunction("globalFunction", new String[] {SHORT, INT, INT}, new String[]{}); + updateFile(); + checkFunction("globalFunction", new String[] {INT, CHAR}, new String[]{}); + updateFile(); + checkFunction("globalFunction", new String[] {INT, CHAR}, new String[]{INLINE}); + } + + private void checkFunction(String name, String[] types, String[] modifiers) throws Exception { + fIndex.acquireReadLock(); + try { + IFunction func = (IFunction) findBinding(name); + checkFunction(func, types, modifiers); + } finally { + fIndex.releaseReadLock(); + } + } + + private void checkFunction(IFunction func, String[] types, String[] modifiers) + throws DOMException { + assertEquals(msg(), types[0], ASTTypeUtil.getType(func.getType().getReturnType())); + IParameter[] params= func.getParameters(); + assertEquals(msg(), types.length-1, params.length); + for (int i = 0; i < params.length; i++) { + IParameter parameter = params[i]; + assertEquals(msg(), types[i+1], ASTTypeUtil.getType(parameter.getType())); + } + checkModifier(modifiers, INLINE, func.isInline()); + checkModifier(modifiers, STATIC, func.isStatic()); + } + + + // int globalFunction(int a, int b){}; + + // short globalFunction(int a, int b){}; + + // int globalFunction(char a){}; + + // inline int globalFunction(char a){}; + public void testCppFunction() throws Exception { + setupFile(4, true); + checkFunction("globalFunction", new String[] {INT, INT, INT}, new String[]{}); + updateFile(); + checkFunction("globalFunction", new String[] {SHORT, INT, INT}, new String[]{}); + updateFile(); + checkFunction("globalFunction", new String[] {INT, CHAR}, new String[]{}); + updateFile(); + checkFunction("globalFunction", new String[] {INT, CHAR}, new String[]{INLINE}); + } + + + // struct my_struct {int fField;}; + + // struct my_struct {short fField;}; + + public void testCField() throws Exception { + setupFile(2, false); + checkVariable("my_struct::fField", INT, new String[]{}); + updateFile(); + checkVariable("my_struct::fField", SHORT, new String[]{}); + } + + + // class MyClass {int fField;}; + + // class MyClass {short fField;}; + + // class MyClass {mutable int fField;}; + + // class MyClass {public: int fField;}; + + // class MyClass {protected: int fField;}; + + // class MyClass {private: int fField;}; + + // class MyClass {private: static int fField;}; + public void testCppField() throws Exception { + setupFile(7, true); + checkCppField("MyClass::fField", INT, new String[]{PRIVATE}); + updateFile(); + checkCppField("MyClass::fField", SHORT, new String[]{PRIVATE}); + updateFile(); + checkCppField("MyClass::fField", INT, new String[]{PRIVATE, MUTABLE}); + updateFile(); + checkCppField("MyClass::fField", INT, new String[]{PUBLIC}); + updateFile(); + checkCppField("MyClass::fField", INT, new String[]{PROTECTED}); + updateFile(); + checkCppField("MyClass::fField", INT, new String[]{PRIVATE}); + updateFile(); + checkCppField("MyClass::fField", INT, new String[]{PRIVATE, STATIC}); + } + + private void checkCppField(String name, String type, String[] modifiers) throws Exception { + fIndex.acquireReadLock(); + try { + ICPPField field = (ICPPField) findBinding(name); + checkCppVariable(field, type, modifiers); + checkCppMember(field, modifiers); + } finally { + fIndex.releaseReadLock(); + } + } + + private void checkCppMember(ICPPMember member, String[] modifiers) throws Exception { + int visibility= member.getVisibility(); + checkModifier(modifiers, PUBLIC, visibility == ICPPMember.v_public); + checkModifier(modifiers, PROTECTED, visibility == ICPPMember.v_protected); + checkModifier(modifiers, PRIVATE, visibility == ICPPMember.v_private); + } + + + // class MyClass {int method(int a, int b);}; + + // class MyClass {short method(int a, int b);}; + + // class MyClass {int method(char a);}; + + // class MyClass {inline int method(char a);}; + + // class MyClass {virtual int method(char a);}; + + // class MyClass {public: int method(char a);}; + + // class MyClass {protected: int method(char a);}; + + // class MyClass {private: int method(char a);}; + + // class MyClass {int method(char a){};}; + + public void testCppMethod() throws Exception { + setupFile(9, true); + checkCppMethod("MyClass::method", new String[] {INT, INT, INT}, new String[]{PRIVATE}); + updateFile(); + checkCppMethod("MyClass::method", new String[] {SHORT, INT, INT}, new String[]{PRIVATE}); + updateFile(); + checkCppMethod("MyClass::method", new String[] {INT, CHAR}, new String[]{PRIVATE}); + updateFile(); + checkCppMethod("MyClass::method", new String[] {INT, CHAR}, new String[]{PRIVATE, INLINE}); + updateFile(); + checkCppMethod("MyClass::method", new String[] {INT, CHAR}, new String[]{PRIVATE, VIRTUAL}); + updateFile(); + checkCppMethod("MyClass::method", new String[] {INT, CHAR}, new String[]{PUBLIC}); + updateFile(); + checkCppMethod("MyClass::method", new String[] {INT, CHAR}, new String[]{PROTECTED}); + updateFile(); + checkCppMethod("MyClass::method", new String[] {INT, CHAR}, new String[]{PRIVATE}); + updateFile(); + checkCppMethod("MyClass::method", new String[] {INT, CHAR}, new String[]{PRIVATE, INLINE}); + } + + private void checkCppMethod(String name, String[] types, String[] modifiers) throws Exception { + fIndex.acquireReadLock(); + try { + ICPPMethod method = (ICPPMethod) findBinding(name); + checkCppMethod(method, types, modifiers); + } finally { + fIndex.releaseReadLock(); + } + } + + private void checkCppMethod(ICPPMethod method, String[] types, String[] modifiers) + throws DOMException, Exception { + checkFunction(method, types, modifiers); + checkCppMember(method, modifiers); + checkModifier(modifiers, VIRTUAL, method.isVirtual()); + checkModifier(modifiers, IMPLICIT, method.isImplicit()); + } + + // class MyClass {MyClass(int a, int b);}; + + // class MyClass {MyClass(char a, int b);}; + + // class MyClass {explicit MyClass(char a, int b);}; + + // class MyClass {public: MyClass(char a, int b);}; + + // class MyClass {protected: MyClass(char a, int b);}; + + // class MyClass {private: MyClass(char a, int b);}; + + public void testCppConstructor() throws Exception { + setupFile(6, true); + checkCppConstructor("MyClass::MyClass", new String[] {"", INT, INT}, new String[]{PRIVATE}); + updateFile(); + checkCppConstructor("MyClass::MyClass", new String[] {"", CHAR, INT}, new String[]{PRIVATE}); + updateFile(); + checkCppConstructor("MyClass::MyClass", new String[] {"", CHAR, INT}, new String[]{PRIVATE,EXPLICIT}); + updateFile(); + checkCppConstructor("MyClass::MyClass", new String[] {"", CHAR, INT}, new String[]{PUBLIC}); + updateFile(); + checkCppConstructor("MyClass::MyClass", new String[] {"", CHAR, INT}, new String[]{PROTECTED}); + updateFile(); + checkCppConstructor("MyClass::MyClass", new String[] {"", CHAR, INT}, new String[]{PRIVATE}); + } + + private void checkCppConstructor(String name, String[] types, String[] modifiers) throws Exception { + fIndex.acquireReadLock(); + try { + ICPPConstructor ctor = (ICPPConstructor) findBinding(name); + checkCppConstructor(ctor, types, modifiers); + } finally { + fIndex.releaseReadLock(); + } + } + + private void checkCppConstructor(ICPPConstructor ctor, String[] types, String[] modifiers) throws Exception { + checkFunction(ctor, types, modifiers); + checkCppMember(ctor, modifiers); + checkModifier(modifiers, EXPLICIT, ctor.isExplicit()); + } + + // class MyClass {}; + + // class MyClass {protected: MyClass(void);}; + + // class MyClass {explicit MyClass(const MyClass& rhs);}; + + // class MyClass {public: MyClass& operator=(const MyClass& rhs) {}}; + + // class MyClass {}; + public void testImplicitMethods() throws Exception { + setupFile(5, true); + checkImplicitMethods("MyClass", + new String[] {IMPLICIT, PUBLIC}, + new String[] {IMPLICIT, PUBLIC}, + new String[] {IMPLICIT, PUBLIC}); + updateFile(); + checkImplicitMethods("MyClass", + new String[] {PROTECTED}, + new String[] {IMPLICIT, PUBLIC}, + new String[] {IMPLICIT, PUBLIC}); + updateFile(); + checkImplicitMethods("MyClass", + null, // no default constructor, because we declared the copy constr. + new String[] {EXPLICIT, PRIVATE}, + new String[] {IMPLICIT, PUBLIC}); + updateFile(); + checkImplicitMethods("MyClass", + new String[] {IMPLICIT, PUBLIC}, + new String[] {IMPLICIT, PUBLIC}, + new String[] {INLINE, PUBLIC}); + updateFile(); + checkImplicitMethods("MyClass", + new String[] {IMPLICIT, PUBLIC}, + new String[] {IMPLICIT, PUBLIC}, + new String[] {IMPLICIT, PUBLIC}); + } + + private void checkImplicitMethods(String name, String[] m1, String[] m2, String[] m3) throws Exception { + fIndex.acquireReadLock(); + try { + final char[] nchars = name.toCharArray(); + final String refType = name + " &"; + final String constRefType = "const " + refType; + IBinding[] ctors= fIndex.findBindings(new char[][]{nchars, nchars}, IndexFilter.ALL_DECLARED_OR_IMPLICIT, NPM); + assertEquals(m1 == null ? 1 : 2, ctors.length); + final IType[] parameterTypes = ((ICPPConstructor) ctors[0]).getType().getParameterTypes(); + if (parameterTypes.length!=1 || !(parameterTypes[0] instanceof ICPPReferenceType)) { + IBinding h= ctors[0]; ctors[0]= ctors[1]; ctors[1]= h; + } + if (m1 != null) { + checkCppConstructor((ICPPConstructor) ctors[1], new String[]{"", "void"}, m1); + } + checkCppConstructor((ICPPConstructor) ctors[0], new String[]{"", constRefType}, m2); + + IBinding assignmentOp= fIndex.findBindings(new char[][]{nchars, "operator =".toCharArray()}, IndexFilter.ALL_DECLARED_OR_IMPLICIT, NPM)[0]; + checkCppMethod((ICPPMethod) assignmentOp, new String[]{refType, constRefType}, m3); + } finally { + fIndex.releaseReadLock(); + } + } + + // typedef int myType; + + // typedef short myType; + public void testCTypedef() throws Exception { + setupFile(2, false); + checkTypedef("myType", INT); + updateFile(); + checkTypedef("myType", SHORT); + } + + private void checkTypedef(String name, String type) throws Exception { + fIndex.acquireReadLock(); + try { + ITypedef var = (ITypedef) findBinding(name); + checkTypedef(var, type); + } finally { + fIndex.releaseReadLock(); + } + } + + private void checkTypedef(ITypedef var, String type) throws DOMException { + assertEquals(msg(), type, ASTTypeUtil.getType(var.getType())); + } + + // typedef int myType; + + // typedef short myType; + public void testCppTypedef() throws Exception { + setupFile(2, true); + checkTypedef("myType", INT); + updateFile(); + checkTypedef("myType", SHORT); + } + + // namespace aNs { + // } + // namespace nsAlias= aNs; + + // namespace bNs { + // } + // namespace nsAlias= bNs; + public void testNamespaceAlias() throws Exception { + setupFile(2, true); + checkNamespaceAlias("nsAlias", "aNs"); + updateFile(); + checkNamespaceAlias("nsAlias", "bNs"); + } + + private void checkNamespaceAlias(String name, String target) throws Exception { + fIndex.acquireReadLock(); + try { + ICPPNamespaceAlias nsalias = (ICPPNamespaceAlias) findBinding(name); + assertEquals(msg(), target, nsalias.getBinding().getName()); + } finally { + fIndex.releaseReadLock(); + } + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java index ea04219567d..47bdd889421 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java @@ -52,6 +52,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; +import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.ObjectSet; @@ -185,7 +186,8 @@ public class CPPClassType extends PlatformObject implements ICPPClassType, ICPPI private IASTName definition; private IASTName [] declarations; private boolean checked = false; - public CPPClassType( IASTName name ){ + private ICPPClassType typeInIndex; + public CPPClassType( IASTName name, IBinding indexBinding ){ if( name instanceof ICPPASTQualifiedName ){ IASTName [] ns = ((ICPPASTQualifiedName)name).getNames(); name = ns[ ns.length - 1 ]; @@ -199,6 +201,9 @@ public class CPPClassType extends PlatformObject implements ICPPClassType, ICPPI else declarations = new IASTName[] { name }; name.setBinding( this ); + if (indexBinding instanceof ICPPClassType && indexBinding instanceof IIndexBinding) { + typeInIndex= (ICPPClassType) indexBinding; + } } /* (non-Javadoc) @@ -391,10 +396,21 @@ public class CPPClassType extends PlatformObject implements ICPPClassType, ICPPI * @see org.eclipse.cdt.core.dom.ast.ICompositeType#getCompositeScope() */ public IScope getCompositeScope() { - if( definition == null ){ + if (definition == null) { checkForDefinition(); } - return (definition != null ) ? getCompositeTypeSpecifier().getScope() : null; + if (definition != null) { + return getCompositeTypeSpecifier().getScope(); + } + // fwd-declarations must be backed up from the index + if (typeInIndex != null) { + try { + return typeInIndex.getCompositeScope(); + } catch (DOMException e) { + // index bindings don't throw DOMExeptions. + } + } + return null; } /* (non-Javadoc) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructor.java index b4f083f521e..f2c51847dd7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2005 IBM Corporation and others. + * Copyright (c) 2004, 2007 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 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ /* * Created on Dec 21, 2004 @@ -14,7 +15,9 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; @@ -42,8 +45,14 @@ public class CPPConstructor extends CPPMethod implements ICPPConstructor { /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor#isExplicit() */ - public boolean isExplicit() { - // TODO Auto-generated method stub + public boolean isExplicit() throws DOMException { + IASTDeclaration decl= getPrimaryDeclaration(); + if (decl != null) { + ICPPASTDeclSpecifier declspec= getDeclSpec(decl); + if (declspec != null) { + return declspec.isExplicit(); + } + } return false; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethod.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethod.java index ae6e79686e1..0d5f10757c0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethod.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethod.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2006 IBM Corporation and others. + * Copyright (c) 2004, 2007 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 @@ -243,12 +243,7 @@ public class CPPMethod extends CPPFunction implements ICPPMethod { public boolean isVirtual() throws DOMException { IASTDeclaration decl = getPrimaryDeclaration(); if( decl != null ){ - ICPPASTDeclSpecifier declSpec = null; - if( decl instanceof IASTSimpleDeclaration ) - declSpec = (ICPPASTDeclSpecifier) ((IASTSimpleDeclaration)decl).getDeclSpecifier(); - else if( decl instanceof IASTFunctionDefinition ) - declSpec = (ICPPASTDeclSpecifier) ((IASTFunctionDefinition)decl).getDeclSpecifier(); - + ICPPASTDeclSpecifier declSpec = getDeclSpec(decl); if( declSpec != null ){ return declSpec.isVirtual(); } @@ -256,6 +251,15 @@ public class CPPMethod extends CPPFunction implements ICPPMethod { return false; } + protected ICPPASTDeclSpecifier getDeclSpec(IASTDeclaration decl) { + ICPPASTDeclSpecifier declSpec = null; + if( decl instanceof IASTSimpleDeclaration ) + declSpec = (ICPPASTDeclSpecifier) ((IASTSimpleDeclaration)decl).getDeclSpecifier(); + else if( decl instanceof IASTFunctionDefinition ) + declSpec = (ICPPASTDeclSpecifier) ((IASTFunctionDefinition)decl).getDeclSpecifier(); + return declSpec; + } + /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction#isInline() */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java index 19b7bf2144c..edc17bd0e40 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java @@ -356,7 +356,7 @@ public class CPPVisitor { if( template ) binding = new CPPClassTemplate( name ); else - binding = new CPPClassType( name ); + binding = new CPPClassType( name, binding); ASTInternal.addName( scope, elabType.getName() ); } } else { @@ -396,7 +396,7 @@ public class CPPVisitor { if( template ) binding = new CPPClassTemplate( name ); else - binding = new CPPClassType( name ); + binding = new CPPClassType( name, binding ); if( scope != null ) ASTInternal.addName( scope, compType.getName() ); } else { @@ -434,7 +434,7 @@ public class CPPVisitor { IBinding binding; try{ binding = scope.getBinding( alias.getAlias(), false ); - if( binding == null ){ + if( !(binding instanceof ICPPInternalBinding) ){ IBinding namespace = alias.getMappingName().resolveBinding(); if( namespace instanceof IProblemBinding ){ IProblemBinding problem = (IProblemBinding) namespace; @@ -611,7 +611,7 @@ public class CPPVisitor { } } else if( parent instanceof IASTSimpleDeclaration ){ IType t1 = null, t2 = null; - if( binding != null && binding instanceof IVariable ){ + if( binding != null && binding instanceof IVariable && !(binding instanceof IIndexBinding)){ t1 = createType( declarator ); try { t2 = ((IVariable)binding).getType(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/ListItem.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/ListItem.java index c79242c2c3a..06598e0229c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/ListItem.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/ListItem.java @@ -1,12 +1,13 @@ /******************************************************************************* - * Copyright (c) 2006 QNX Software Systems and others. + * Copyright (c) 2006, 2007 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * QNX - Initial API and implementation + * QNX - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.db; @@ -78,5 +79,9 @@ public class ListItem { int prev = db.getInt(record + PREV); return prev != 0 ? new ListItem(db, prev) : null; } + + public void delete() throws CoreException { + db.free(record); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/PDOMNodeLinkedList.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/PDOMNodeLinkedList.java index 08a4101dbfe..fc022d0a974 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/PDOMNodeLinkedList.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/PDOMNodeLinkedList.java @@ -6,7 +6,8 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * QNX - Initial API and implementation + * QNX - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.db; @@ -106,4 +107,18 @@ public class PDOMNodeLinkedList { newMember.setNext(firstMember); } } + + public void deleteListItems() throws CoreException { + ListItem item = getFirstMemberItem(); + if (item != null) { + int firstRec= item.record; + + do { + ListItem nextItem= item.getNext(); + item.delete(); + item= nextItem; + } + while (item.record != firstRec && item.record != 0); + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMArrayType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMArrayType.java index 00345cb6b7d..c7d1b086dfa 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMArrayType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMArrayType.java @@ -60,7 +60,7 @@ public class PDOMArrayType extends PDOMNode implements IIndexType, IArrayType, I return null; } - public IType getType() throws DOMException { + public IType getType() { try { PDOMNode node = getLinkageImpl().getNode(pdom.getDB().getInt(record + TYPE)); return node instanceof IType ? (IType)node : null; @@ -96,4 +96,9 @@ public class PDOMArrayType extends PDOMNode implements IIndexType, IArrayType, I public Object clone() { return new ArrayTypeClone(this); } + + public void delete(PDOMLinkage linkage) throws CoreException { + linkage.deleteType(getType(), record); + super.delete(linkage); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java index be3760f5e65..e0a682ecaa5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java @@ -309,4 +309,15 @@ public abstract class PDOMBinding extends PDOMNamedNode implements IIndexFragmen public final int getBindingConstant() { return getNodeType(); } + + /** + * The binding is reused by a declaration or definition, we may need to update modifiers. + * @throws CoreException + */ + public void update(PDOMLinkage linkage, IBinding newBinding) throws CoreException { + } + + final public void delete(PDOMLinkage linkage) throws CoreException { + assert false; + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFileLocalScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFileLocalScope.java index b428e929a0a..6caf82c2565 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFileLocalScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFileLocalScope.java @@ -51,4 +51,9 @@ public class PDOMFileLocalScope extends PDOMNamedNode implements IPDOMMemberOwne public void addChild(PDOMNode child) throws CoreException { addMember(child); } + + public void delete(PDOMLinkage linkage) throws CoreException { + // no support for deleting bindings and their scopes. + assert false; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java index 1f7be7e8e17..ff3bfc4b1f0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java @@ -183,7 +183,7 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage public abstract PDOMBinding addBinding(IASTName name) throws CoreException; - public abstract PDOMBinding addBinding(IBinding binding) throws CoreException; + public abstract PDOMBinding addBinding(IBinding binding, IASTName fromName) throws CoreException; public abstract PDOMBinding adaptBinding(IBinding binding) throws CoreException; @@ -292,7 +292,7 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage if (scopeBinding != null && scopeBinding != binding) { PDOMBinding scopePDOMBinding = null; if (addParent) { - scopePDOMBinding = addBinding(scopeBinding); + scopePDOMBinding = addBinding(scopeBinding, null); } else { scopePDOMBinding = adaptBinding(scopeBinding); } @@ -414,4 +414,24 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage } return 0; } + + public void deleteType(IType type, int ownerRec) throws CoreException { + if (type instanceof PDOMNode) { + PDOMNode node= (PDOMNode) type; + // at this point only delete types that are actually owned by the requesting party. + if (node.getParentNodeRec() == ownerRec) { + assert ! (node instanceof IBinding); + node.delete(this); + } + } + } + + public void deleteBinding(IBinding binding) throws CoreException { + // no implementation, yet. + } + + public void delete(PDOMLinkage linkage) throws CoreException { + assert false; // no need to delete linkages. + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNamedNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNamedNode.java index 986d4ae2687..8ef77bee0bd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNamedNode.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNamedNode.java @@ -66,4 +66,13 @@ public abstract class PDOMNamedNode extends PDOMNode { public boolean hasName(char[] name) throws CoreException { return getDBName().equals(name); } + + public void delete(PDOMLinkage linkage) throws CoreException { + final Database db = pdom.getDB(); + final int namerec= db.getInt(record + NAME); + if (namerec != 0) { + db.free(namerec); + } + super.delete(linkage); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNode.java index 36a909e00eb..e60108f87df 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNode.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNode.java @@ -158,4 +158,14 @@ public abstract class PDOMNode implements IPDOMNode { int mask = 1 << offset; return (bitVector & mask) == mask; } + + /** + * Delete this PDOMNode, make sure you are actually the owner of this record! + * @param linkage + * @throws CoreException + * @throws CoreException + */ + public void delete(PDOMLinkage linkage) throws CoreException { + pdom.getDB().free(record); + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMPointerType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMPointerType.java index b1981564222..b064b1892ff 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMPointerType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMPointerType.java @@ -139,4 +139,9 @@ public class PDOMPointerType extends PDOMNode implements IPointerType, public Object clone() { return new PointerTypeClone(this); } + + public void delete(PDOMLinkage linkage) throws CoreException { + linkage.deleteType(getType(), record); + super.delete(linkage); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMQualifierType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMQualifierType.java index 998c358b962..2c436c47164 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMQualifierType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMQualifierType.java @@ -85,7 +85,7 @@ public class PDOMQualifierType extends PDOMNode implements IQualifierType, ICQua return PDOMLinkage.QUALIFIER_TYPE; } - public IType getType() throws DOMException { + public IType getType() { try { PDOMNode node = getLinkageImpl().getNode(pdom.getDB().getInt(record + TYPE)); return node instanceof IType ? (IType)node : null; @@ -153,4 +153,9 @@ public class PDOMQualifierType extends PDOMNode implements IQualifierType, ICQua public Object clone() { return new QualifierTypeClone(this); } + + public void delete(PDOMLinkage linkage) throws CoreException { + linkage.deleteType(getType(), record); + super.delete(linkage); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCFunction.java index a1d375eac6b..d00884cd4d0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCFunction.java @@ -6,15 +6,17 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * QNX - Initial API and implementation - * IBM Corporation - * Andrew Ferguson (Symbian) + * QNX - Initial API and implementation + * IBM Corporation + * Andrew Ferguson (Symbian) + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.c; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IParameter; @@ -22,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.core.runtime.CoreException; @@ -62,25 +65,66 @@ class PDOMCFunction extends PDOMBinding implements IFunction { public PDOMCFunction(PDOM pdom, PDOMNode parent, IFunction function) throws CoreException { super(pdom, parent, function.getNameCharArray()); + IFunctionType type; + IParameter[] parameters; + byte annotations; try { - IFunctionType ft= function.getType(); - - if (ft != null) { - PDOMNode typeNode = getLinkageImpl().addType(this, ft); - if (typeNode != null) { - pdom.getDB().putInt(record + FUNCTION_TYPE, typeNode.getRecord()); - } - } - - IParameter[] params = function.getParameters(); - pdom.getDB().putInt(record + NUM_PARAMS, params.length); - for (int i = 0; i < params.length; ++i) { - setFirstParameter(new PDOMCParameter(pdom, this, params[i])); - } - pdom.getDB().putByte(record + ANNOTATIONS, PDOMCAnnotation.encodeAnnotation(function)); + type = function.getType(); + parameters = function.getParameters(); + annotations = PDOMCAnnotation.encodeAnnotation(function); } catch(DOMException e) { throw new CoreException(Util.createStatus(e)); } + setType(getLinkageImpl(), type); + setParameters(parameters); + pdom.getDB().putByte(record + ANNOTATIONS, annotations); + } + + public void update(final PDOMLinkage linkage, IBinding newBinding) throws CoreException { + if (newBinding instanceof IFunction) { + IFunction func= (IFunction) newBinding; + IFunctionType newType; + IParameter[] newParams; + byte newAnnotation; + try { + newType= func.getType(); + newParams = func.getParameters(); + newAnnotation = PDOMCAnnotation.encodeAnnotation(func); + } catch (DOMException e) { + throw new CoreException(Util.createStatus(e)); + } + + IFunctionType oldType= getType(); + setType(linkage, newType); + PDOMCParameter oldParams= getFirstParameter(); + setParameters(newParams); + if (oldType != null) { + linkage.deleteType(oldType, record); + } + if (oldParams != null) { + oldParams.delete(linkage); + } + pdom.getDB().putByte(record + ANNOTATIONS, newAnnotation); + } + } + + private void setType(PDOMLinkage linkage, IFunctionType ft) throws CoreException { + int rec= 0; + if (ft != null) { + PDOMNode typeNode = linkage.addType(this, ft); + if (typeNode != null) { + rec= typeNode.getRecord(); + } + } + pdom.getDB().putInt(record + FUNCTION_TYPE, rec); + } + + private void setParameters(IParameter[] params) throws CoreException { + pdom.getDB().putInt(record + NUM_PARAMS, params.length); + pdom.getDB().putInt(record + FIRST_PARAM, 0); + for (int i = 0; i < params.length; ++i) { + setFirstParameter(new PDOMCParameter(pdom, this, params[i])); + } } public PDOMCParameter getFirstParameter() throws CoreException { @@ -107,13 +151,13 @@ class PDOMCFunction extends PDOMBinding implements IFunction { return PDOMCLinkage.CFUNCTION; } - public IFunctionType getType() throws DOMException { + public IFunctionType getType() { /* * CVisitor binding resolution assumes any IBinding which is * also an IType should be converted to a IProblemBinding in a * route through the code that triggers errors here. This means * we can't use the convenient idea of having PDOMCFunction implement - * both the IType and IBinding subinterfaces. + * both the IType and IBinding interfaces. */ try { int offset= pdom.getDB().getInt(record + FUNCTION_TYPE); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCFunctionType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCFunctionType.java index 666d2b471bd..fb7a8048a0f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCFunctionType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCFunctionType.java @@ -6,8 +6,9 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * QNX - Initial implementation - * Andrew Ferguson (Symbian) + * QNX - Initial implementation + * Andrew Ferguson (Symbian) + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.c; @@ -75,6 +76,23 @@ public class PDOMCFunctionType extends PDOMNode implements IIndexType, IFunction } } + public void delete(final PDOMLinkage linkage) throws CoreException { + linkage.deleteType(getReturnType(), record); + PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + TYPELIST, getLinkageImpl(), true); + list.accept(new IPDOMVisitor(){ + public void leave(IPDOMNode node) throws CoreException { + } + public boolean visit(IPDOMNode node) throws CoreException { + if (node instanceof IType) { + linkage.deleteType((IType) node, record); + } + return false; + } + }); + list.deleteListItems(); + super.delete(linkage); + } + public int getNodeType() { return PDOMCLinkage.CFUNCTIONTYPE; } @@ -125,7 +143,7 @@ public class PDOMCFunctionType extends PDOMNode implements IIndexType, IFunction } - public IType[] getParameterTypes() throws DOMException { + public IType[] getParameterTypes() { final List result= new ArrayList(); try { PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + TYPELIST, getLinkageImpl(), true); @@ -143,7 +161,7 @@ public class PDOMCFunctionType extends PDOMNode implements IIndexType, IFunction return (IType[]) result.toArray(new IType[result.size()]); } - public IType getReturnType() throws DOMException { + public IType getReturnType() { try { PDOMNode node = getLinkageImpl().getNode(pdom.getDB().getInt(record + RETURN_TYPE)); if (node instanceof IType) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java index 5f7fed65c59..fd5cb0d51ba 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java @@ -62,9 +62,14 @@ class PDOMCLinkage extends PDOMLinkage implements IIndexCBindingConstants { return C_LINKAGE_ID; } - public PDOMBinding addBinding(IBinding binding) throws CoreException { + public PDOMBinding addBinding(IBinding binding, IASTName fromName) throws CoreException { PDOMBinding pdomBinding = adaptBinding(binding); - if (pdomBinding == null) { + if (pdomBinding != null) { + if (shouldUpdate(pdomBinding, fromName)) { + pdomBinding.update(this, fromName.getBinding()); + } + } + else { PDOMNode parent = getAdaptedParent(binding, true, false); if (parent == null) return null; @@ -108,6 +113,19 @@ class PDOMCLinkage extends PDOMLinkage implements IIndexCBindingConstants { return pdomBinding; } + private boolean shouldUpdate(PDOMBinding pdomBinding, IASTName fromName) throws CoreException { + if (fromName != null) { + if (fromName.isDefinition()) { + return true; + } + if (fromName.isReference()) { + return false; + } + return !pdomBinding.hasDefinition(); + } + return false; + } + public PDOMBinding addBinding(IASTName name) throws CoreException { if (name == null) return null; @@ -125,7 +143,7 @@ class PDOMCLinkage extends PDOMLinkage implements IIndexCBindingConstants { // skip parameters return null; - return addBinding(binding); + return addBinding(binding, name); } public int getBindingType(IBinding binding) { @@ -224,7 +242,7 @@ class PDOMCLinkage extends PDOMLinkage implements IIndexCBindingConstants { } else if(type instanceof IFunctionType) { return new PDOMCFunctionType(pdom, parent, (IFunctionType)type); } else if (type instanceof IBinding) { - return addBinding((IBinding)type); + return addBinding((IBinding)type, null); } return super.addType(parent, type); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCParameter.java index 57563e7bd18..4050a29d22a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCParameter.java @@ -92,7 +92,7 @@ class PDOMCParameter extends PDOMNamedNode implements IParameter, IIndexFragment // TODO throw new PDOMNotImplementedError(); } - public IType getType() throws DOMException { + public IType getType() { try { PDOMLinkage linkage = getLinkageImpl(); PDOMNode node = linkage.getNode(pdom.getDB().getInt(record + TYPE)); @@ -177,4 +177,13 @@ class PDOMCParameter extends PDOMNamedNode implements IParameter, IIndexFragment public int getBindingConstant() { return getNodeType(); } + + public void delete(PDOMLinkage linkage) throws CoreException { + linkage.deleteType(getType(), record); + PDOMCParameter next= getNextParameter(); + if (next != null) { + next.delete(linkage); + } + super.delete(linkage); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCTypedef.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCTypedef.java index edea134058e..c0fc61ae150 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCTypedef.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCTypedef.java @@ -1,26 +1,29 @@ /******************************************************************************* - * Copyright (c) 2006 QNX Software Systems and others. + * Copyright (c) 2006, 2007 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * QNX - Initial API and implementation - * Markus Schorn (Wind River Systems) - * IBM Corporation + * QNX - Initial API and implementation + * Markus Schorn (Wind River Systems) + * IBM Corporation *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.c; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; +import org.eclipse.cdt.internal.core.index.IIndexCBindingConstants; import org.eclipse.cdt.internal.core.index.IIndexType; import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.core.runtime.CoreException; @@ -39,9 +42,7 @@ class PDOMCTypedef extends PDOMBinding implements ITypedef, ITypeContainer, IInd try { IType type = typedef.getType(); - PDOMNode typeNode = parent.getLinkageImpl().addType(this, type); - if (typeNode != null) - pdom.getDB().putInt(record + TYPE, typeNode.getRecord()); + setType(parent.getLinkageImpl(), type); } catch (DOMException e) { throw new CoreException(Util.createStatus(e)); } @@ -51,15 +52,36 @@ class PDOMCTypedef extends PDOMBinding implements ITypedef, ITypeContainer, IInd super(pdom, record); } + public void update(final PDOMLinkage linkage, IBinding newBinding) throws CoreException { + if (newBinding instanceof ITypedef) { + ITypedef td= (ITypedef) newBinding; + IType mytype= getType(); + try { + IType newType= td.getType(); + setType(linkage, newType); + if (mytype != null) { + linkage.deleteType(mytype, record); + } + } catch (DOMException e) { + throw new CoreException(Util.createStatus(e)); + } + } + } + + private void setType(final PDOMLinkage linkage, IType newType) throws CoreException, DOMException { + PDOMNode typeNode = linkage.addType(this, newType); + pdom.getDB().putInt(record+TYPE, typeNode != null ? typeNode.getRecord() : 0); + } + protected int getRecordSize() { return RECORD_SIZE; } public int getNodeType() { - return PDOMCLinkage.CTYPEDEF; + return IIndexCBindingConstants.CTYPEDEF; } - public IType getType() throws DOMException { + public IType getType() { try { int typeRec = pdom.getDB().getInt(record + TYPE); return (IType)getLinkageImpl().getNode(typeRec); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCVariable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCVariable.java index d0369607abc..2125129c564 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCVariable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCVariable.java @@ -6,20 +6,22 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * QNX - Initial API and implementation - * IBM Corporation + * QNX - Initial API and implementation + * IBM Corporation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.c; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.pdom.PDOM; -import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.core.runtime.CoreException; @@ -50,17 +52,34 @@ class PDOMCVariable extends PDOMBinding implements IVariable { super(pdom, parent, variable.getNameCharArray()); try { - // Find the type record - Database db = pdom.getDB(); - PDOMNode typeNode = parent.getLinkageImpl().addType(this, variable.getType()); - if (typeNode != null) - db.putInt(record + TYPE_OFFSET, typeNode.getRecord()); - + setType(parent.getLinkageImpl(), variable.getType()); pdom.getDB().putByte(record + ANNOTATIONS, PDOMCAnnotation.encodeAnnotation(variable)); } catch (DOMException e) { throw new CoreException(Util.createStatus(e)); } } + + public void update(final PDOMLinkage linkage, IBinding newBinding) throws CoreException { + if (newBinding instanceof IVariable) { + IVariable var= (IVariable) newBinding; + IType mytype= getType(); + try { + IType newType= var.getType(); + setType(linkage, newType); + if (mytype != null) { + linkage.deleteType(mytype, record); + } + pdom.getDB().putByte(record + ANNOTATIONS, PDOMCAnnotation.encodeAnnotation(var)); + } catch (DOMException e) { + throw new CoreException(Util.createStatus(e)); + } + } + } + + private void setType(final PDOMLinkage linkage, final IType type) throws CoreException { + final PDOMNode typeNode = linkage.addType(this, type); + pdom.getDB().putInt(record + TYPE_OFFSET, typeNode != null ? typeNode.getRecord() : 0); + } public PDOMCVariable(PDOM pdom, int record) { super(pdom, record); @@ -74,7 +93,7 @@ class PDOMCVariable extends PDOMBinding implements IVariable { return PDOMCLinkage.CVARIABLE; } - public IType getType() throws DOMException { + public IType getType() { try { int typeRec = pdom.getDB().getInt(record + TYPE_OFFSET); return (IType)getLinkageImpl().getNode(typeRec); @@ -99,5 +118,4 @@ class PDOMCVariable extends PDOMBinding implements IVariable { public boolean isRegister() throws DOMException { return getBit(getByte(record + ANNOTATIONS), PDOMCAnnotation.REGISTER_OFFSET); } - } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunction.java index b497cccf129..f25300f75a6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunction.java @@ -17,6 +17,8 @@ import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IScope; @@ -32,6 +34,7 @@ import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.cdt.internal.core.pdom.dom.IPDOMOverloader; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError; import org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCAnnotation; @@ -85,7 +88,7 @@ class PDOMCPPFunction extends PDOMCPPBinding implements ICPPFunction, IPDOMOverl pdom.getDB().putInt(record + SIGNATURE_MEMENTO, memento != null ? memento.intValue() : 0); if(setTypes) { - initData(function); + initData((ICPPFunctionType) function.getType(), function.getParameters()); } db.putByte(record + ANNOTATION, PDOMCPPAnnotation.encodeAnnotation(function)); } catch (DOMException e) { @@ -93,21 +96,53 @@ class PDOMCPPFunction extends PDOMCPPBinding implements ICPPFunction, IPDOMOverl } } - public void initData(ICPPFunction function) throws CoreException, DOMException { - Database db= pdom.getDB(); - - ICPPFunctionType ft= (ICPPFunctionType) function.getType(); - PDOMCPPFunctionType pft = (PDOMCPPFunctionType) getLinkageImpl().addType(this, ft); - db.putInt(record + FUNCTION_TYPE, pft.getRecord()); - - IParameter[] params= function.getParameters(); + public void initData(ICPPFunctionType ftype, IParameter[] params) throws CoreException { + PDOMCPPFunctionType pft= setType(ftype); + setParameters(pft, params); + } + + public void update(final PDOMLinkage linkage, IBinding newBinding) throws CoreException { + if (newBinding instanceof ICPPFunction) { + IFunction func= (ICPPFunction) newBinding; + ICPPFunctionType newType; + IParameter[] newParams; + byte newAnnotation; + try { + newType= (ICPPFunctionType) func.getType(); + newParams = func.getParameters(); + newAnnotation = PDOMCPPAnnotation.encodeAnnotation(func); + } catch (DOMException e) { + throw new CoreException(Util.createStatus(e)); + } + + IFunctionType oldType= getType(); + PDOMCPPParameter oldParams= getFirstParameter(); + initData(newType, newParams); + if (oldType != null) { + linkage.deleteType(oldType, record); + } + if (oldParams != null) { + oldParams.delete(linkage); + } + pdom.getDB().putByte(record + ANNOTATION, newAnnotation); + } + } + + private void setParameters(PDOMCPPFunctionType pft, IParameter[] params) throws CoreException { + final Database db= pdom.getDB(); db.putInt(record + NUM_PARAMS, params.length); - + db.putInt(record + FIRST_PARAM, 0); IType[] paramTypes= pft.getParameterTypes(); for (int i=0; i