diff options
author | Andrew Ferguson | 2008-04-08 12:36:26 +0000 |
---|---|---|
committer | Andrew Ferguson | 2008-04-08 12:36:26 +0000 |
commit | 61cc1a811f9960c35ade853400a83885e7174d9b (patch) | |
tree | 3764277a4b8f6800fec6a182a2eadd89eab81961 | |
parent | c56222f3e5a2c3d7b3eb046032bc7c33ea82a3c3 (diff) | |
download | org.eclipse.cdt-61cc1a811f9960c35ade853400a83885e7174d9b.tar.gz org.eclipse.cdt-61cc1a811f9960c35ade853400a83885e7174d9b.tar.xz org.eclipse.cdt-61cc1a811f9960c35ade853400a83885e7174d9b.zip |
224364: apply fix
27 files changed, 478 insertions, 291 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index e71a891fc9b..f2c689e9c7f 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -2291,7 +2291,7 @@ public class AST2TemplateTests extends AST2BaseTest { // D<A> d; // foo(d); // } - public void _testUserDefinedConversions_224364() throws Exception { + public void testUserDefinedConversions_224364() throws Exception { BindingAssertionHelper bh= new BindingAssertionHelper(getContents(1)[0].toString(), true); ICPPFunction fn= bh.assertNonProblem("foo(d)", 3, ICPPFunction.class); } @@ -2311,7 +2311,7 @@ public class AST2TemplateTests extends AST2BaseTest { // D<B> d; // foo(d); // } - public void _testUserDefinedConversions_224364_2() throws Exception { + public void testUserDefinedConversions_224364_2() throws Exception { BindingAssertionHelper bh= new BindingAssertionHelper(getContents(1)[0].toString(), true); ICPPFunction fn= bh.assertNonProblem("foo(d)", 3, ICPPFunction.class); } @@ -2334,7 +2334,7 @@ public class AST2TemplateTests extends AST2BaseTest { // Z foo(Z z) {return z;} // // Z z= foo(*new E<Z>()); - public void _testUserDefinedConversions_224364_3() throws Exception { + public void testUserDefinedConversions_224364_3() throws Exception { BindingAssertionHelper bh= new BindingAssertionHelper(getContents(1)[0].toString(), true); ICPPFunction fn= bh.assertNonProblem("foo(*new", 3, ICPPFunction.class); } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java index 8e46c95e9a7..b65b44a07d9 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java @@ -1291,7 +1291,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti // E e; // foo(e); // } - public void _testUserDefinedConversionOperator_224364() throws Exception { + public void testUserDefinedConversionOperator_224364() throws Exception { IBinding ca= getBindingFromASTName("C c;", 1); assertInstance(ca, ICPPClassType.class); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java index e1c72b73d0d..832150fc030 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java @@ -922,8 +922,7 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa assertEquals("A", ((ICPPClassType) type).getName()); } - // class A {}; - // class B {}; + // class A {}; class B {}; class X {}; // template<typename T> // class C { // public: @@ -934,6 +933,12 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa // class D : public C<T> {}; // class E : public C<A> {}; // void foo(B b) {} + // template<> + // class C<X> { + // public: + // X t; + // operator B() {B b; return b;} + // }; // class F : public C<A> {}; // void refs() { @@ -945,8 +950,10 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa // foo(e); // F f; // foo(f); + // C<X> cx; + // foo(cx); // } - public void _testUserDefinedConversionOperator_224364() throws Exception { + public void testUserDefinedConversionOperator_224364() throws Exception { IBinding ca= getBindingFromASTName("C<A>", 4); assertInstance(ca, ICPPClassType.class); assertInstance(ca, ICPPTemplateInstance.class); @@ -959,5 +966,9 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa IBinding foo2= getBindingFromASTName("foo(d)", 3); IBinding foo3= getBindingFromASTName("foo(e)", 3); + IBinding foo4= getBindingFromASTName("foo(cx)", 3); + + assertEquals(foo1, foo2); assertEquals(foo2, foo3); + assertEquals(foo3, foo4); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java index f7b8ef9434b..1473bd05d56 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2007 IBM Corporation and others. + * Copyright (c) 2004, 2008 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 @@ -8,11 +8,8 @@ * Contributors: * IBM Corporation - initial API and implementation * Markus Schorn (Wind River Systems) + * Andrew Ferguson (Symbian) *******************************************************************************/ - -/* - * Created on Feb 16, 2005 - */ package org.eclipse.cdt.core.parser.util; import java.lang.reflect.Array; @@ -21,11 +18,7 @@ import java.lang.reflect.Array; * @author aniefer */ public class ArrayUtil { - public static final class ArrayWrapper { - public Object [] array = null; - } - - public static final int DEFAULT_LENGTH = 2; + private static final int DEFAULT_LENGTH = 2; /** * Assumes that array contains nulls at the end, only. @@ -365,6 +358,24 @@ public class ArrayUtil { return array; } - + /** + * Stores the specified array contents in a new array of specified + * runtime type. + * @param target the runtime type of the new array + * @param source the source array + * @return the current array stored in a new array with the + * specified runtime type, or null if source is null. + */ + @SuppressWarnings("unchecked") + public static <S,T> T[] convert(Class<T> target, S[] source) { + T[] result= null; + if(source != null) { + result= (T[]) Array.newInstance(target, source.length); + for(int i=0; i<source.length; i++) { + result[i]= (T) source[i]; + } + } + return result; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharTable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharTable.java index 325441df6d2..ac041b4ce18 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharTable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharTable.java @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Markus Schorn (Wind River Systems) + * Andrew Ferguson (Symbian) *******************************************************************************/ package org.eclipse.cdt.core.parser.util; @@ -39,6 +40,7 @@ public class CharTable extends HashTable { for( int i = 0; i < capacity(); i++ ) keyTable[i] = null; } + public Object clone(){ CharTable newTable = (CharTable) super.clone(); @@ -48,9 +50,11 @@ public class CharTable extends HashTable { return newTable; } + protected final int hash(char[] source, int start, int length) { return CharArrayUtils.hash(source, start, length) & ((keyTable.length * 2) - 1); } + protected final int hash( int pos ){ return hash(keyTable[pos], 0, keyTable[pos].length); } @@ -62,6 +66,7 @@ public class CharTable extends HashTable { protected final int addIndex(char[] buffer ) { return addIndex(buffer, 0, buffer.length); } + public final int addIndex(char[] buffer, int start, int len) { if (hashTable != null) { @@ -120,23 +125,29 @@ public class CharTable extends HashTable { return list; } - final public char[] keyAt( int i ){ + public final char[] keyAt( int i ){ if( i < 0 || i > currEntry ) return null; return keyTable[ i ]; } - final public boolean containsKey( char[] key ){ - return lookup( key ) != -1; + public final boolean containsKey(char[] key, int start, int len) { + return lookup(key, start, len) != -1; } - final public char[] findKey( char[] buffer, int start, int len ){ + + public final boolean containsKey(char[] key){ + return lookup(key) != -1; + } + + public final char[] findKey( char[] buffer, int start, int len ){ int idx = lookup( buffer, start, len ); if( idx == -1 ) return null; return keyTable[ idx ]; } + public int lookup(char[] buffer ){ return lookup(buffer, 0, buffer.length); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java index c27731c1ed8..1cb82293225 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java @@ -31,14 +31,13 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ObjectMap; -import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.index.IIndexType; /** * @author aniefer */ -public class CPPClassInstance extends CPPInstance implements ICPPClassType, ICPPInternalClassType { +public class CPPClassInstance extends CPPInstance implements ICPPClassType, ICPPInternalBinding { private CPPClassSpecializationScope instanceScope; /** @@ -114,7 +113,10 @@ public class CPPClassInstance extends CPPInstance implements ICPPClassType, ICPP * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getDeclaredMethods() */ public ICPPMethod[] getDeclaredMethods() throws DOMException { - return null; + CPPClassSpecializationScope scope = (CPPClassSpecializationScope) getCompositeScope(); + if (scope.isFullyCached()) + return scope.getDeclaredMethods(); + return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; } /* (non-Javadoc) @@ -196,15 +198,6 @@ public class CPPClassInstance extends CPPInstance implements ICPPClassType, ICPP return ICPPClassType.EMPTY_CLASS_ARRAY; } - public ICPPMethod[] getConversionOperators() throws DOMException { - IScope scope = getCompositeScope(); - if (scope instanceof CPPClassSpecializationScope) { - if (ASTInternal.isFullyCached(scope)) - return ((CPPClassSpecializationScope)scope).getConversionOperators(); - } - return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; - } - @Override public boolean equals(Object obj) { return obj instanceof ICPPClassType && isSameType((ICPPClassType) obj); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java index a972200536d..ffca78ec97c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java @@ -24,8 +24,8 @@ import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; @@ -33,6 +33,7 @@ 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.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ObjectMap; @@ -47,7 +48,7 @@ import org.eclipse.cdt.internal.core.index.IIndexType; * */ public class CPPClassSpecialization extends CPPSpecialization implements - ICPPClassType, ICPPInternalClassType { + ICPPClassType, ICPPInternalBinding { private IScope specScope; @@ -156,8 +157,46 @@ public class CPPClassSpecialization extends CPPSpecialization implements * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getDeclaredMethods() */ public ICPPMethod[] getDeclaredMethods() throws DOMException { - // TODO Auto-generated method stub - return null; + CPPClassSpecializationScope scope = (CPPClassSpecializationScope) getCompositeScope(); + if (scope.isFullyCached()) + return scope.getDeclaredMethods(); + IBinding binding = null; + ICPPMethod [] result = null; + + IASTDeclaration [] decls = getCompositeTypeSpecifier().getMembers(); + for ( int i = 0; i < decls.length; i++ ) { + IASTDeclaration decl = decls[i]; + while( decl instanceof ICPPASTTemplateDeclaration ) + decl = ((ICPPASTTemplateDeclaration)decl).getDeclaration(); + if( decl instanceof IASTSimpleDeclaration ){ + IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decl).getDeclarators(); + for ( int j = 0; j < dtors.length; j++ ) { + binding = dtors[j].getName().resolveBinding(); + if( binding instanceof ICPPMethod) + result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, binding ); + } + } else if( decl instanceof IASTFunctionDefinition ){ + IASTDeclarator dtor = ((IASTFunctionDefinition)decl).getDeclarator(); + dtor = CPPVisitor.getMostNestedDeclarator( dtor ); + binding = dtor.getName().resolveBinding(); + if( binding instanceof ICPPMethod ){ + result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, binding ); + } + } else if( decl instanceof ICPPASTUsingDeclaration ){ + IASTName n = ((ICPPASTUsingDeclaration)decl).getName(); + binding = n.resolveBinding(); + if( binding instanceof ICPPUsingDeclaration ){ + IBinding [] bs = ((ICPPUsingDeclaration)binding).getDelegates(); + for ( int j = 0; j < bs.length; j++ ) { + if( bs[j] instanceof ICPPMethod ) + result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, bs[j] ); + } + } else if( binding instanceof ICPPMethod ) { + result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, binding ); + } + } + } + return (ICPPMethod[]) ArrayUtil.trim( ICPPMethod.class, result ); } /* (non-Javadoc) @@ -249,63 +288,6 @@ public class CPPClassSpecialization extends CPPSpecialization implements return this; } - public ICPPMethod[] getConversionOperators() { - try { - ICPPMethod [] result = null; - - IScope scope = getCompositeScope(); - if (scope instanceof CPPClassSpecializationScope) { - if (ASTInternal.isFullyCached(scope)) - result = ((CPPClassSpecializationScope)scope).getConversionOperators(); - } else { - IBinding binding = null; - - IASTDeclaration [] decls = getCompositeTypeSpecifier().getMembers(); - IASTName name = null; - for ( int i = 0; i < decls.length; i++ ) { - if( decls[i] instanceof IASTSimpleDeclaration ){ - IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decls[i]).getDeclarators(); - for ( int j = 0; j < dtors.length; j++ ) { - name = CPPVisitor.getMostNestedDeclarator( dtors[j] ).getName(); - if( name instanceof ICPPASTConversionName ){ - binding = name.resolveBinding(); - if( binding instanceof ICPPMethod) - result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, binding ); - } - } - } else if( decls[i] instanceof IASTFunctionDefinition ){ - IASTDeclarator dtor = ((IASTFunctionDefinition)decls[i]).getDeclarator(); - name = CPPVisitor.getMostNestedDeclarator( dtor ).getName(); - if( name instanceof ICPPASTConversionName ){ - binding = name.resolveBinding(); - if( binding instanceof ICPPMethod ){ - result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, binding ); - } - } - } - } - } - - ICPPBase [] bases = getBases(); - for ( int i = 0; i < bases.length; i++ ) { - ICPPClassType cls = null; - try { - IBinding b = bases[i].getBaseClass(); - if( b instanceof ICPPClassType ) - cls = (ICPPClassType) b; - } catch (DOMException e) { - continue; - } - if( cls instanceof ICPPInternalClassType ) - result = (ICPPMethod[]) ArrayUtil.addAll( ICPPMethod.class, result, ((ICPPInternalClassType)cls).getConversionOperators() ); - } - - return (ICPPMethod[]) ArrayUtil.trim( ICPPMethod.class, result ); - } catch (DOMException e) { - return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; - } - } - public ICPPClassType[] getNestedClasses() throws DOMException { return ICPPClassType.EMPTY_CLASS_ARRAY; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecializationScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecializationScope.java index 45bb481154e..6632148b0cb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecializationScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecializationScope.java @@ -9,6 +9,7 @@ * IBM - Initial API and implementation * Markus Schorn (Wind River Systems) * Bryan Wilkinson (QNX) + * Andrew Ferguson (Symbian) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -159,18 +160,13 @@ public class CPPClassSpecializationScope implements ICPPClassScope, IASTInternal return (ICPPConstructor[]) ArrayUtil.trim(ICPPConstructor.class, specs); } - protected ICPPMethod[] getConversionOperators() throws DOMException { + protected ICPPMethod[] getDeclaredMethods() throws DOMException { ICPPClassType specialized = (ICPPClassType) specialization.getSpecializedBinding(); - - if (!(specialized instanceof ICPPInternalClassType)) { - return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; - } - - ICPPMethod[] bindings = ((ICPPInternalClassType)specialized).getConversionOperators(); + ICPPMethod[] bindings = specialized.getDeclaredMethods(); if (bindings == null) return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; - ICPPMethod[] specs = new ICPPMethod[0]; + ICPPMethod[] specs = new ICPPMethod[0]; for (int i = 0; i < bindings.length; i++) { specs = (ICPPMethod[]) ArrayUtil.append(ICPPMethod.class, specs, getInstance(bindings[i])); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java index 62b86fc44c1..ce661a52814 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java @@ -51,7 +51,7 @@ import org.eclipse.cdt.internal.core.index.IIndexType; * @author aniefer */ public class CPPClassTemplate extends CPPTemplateDefinition implements - ICPPClassTemplate, ICPPClassType, ICPPInternalClassType, ICPPInternalClassTemplate, + ICPPClassTemplate, ICPPClassType, ICPPInternalBinding, ICPPInternalClassTemplate, ICPPInternalClassTypeMixinHost { private class FindDefinitionAction extends CPPASTVisitor { @@ -221,10 +221,6 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements return mixin.getDeclaredFields(); } - public ICPPMethod[] getConversionOperators() throws DOMException { - return mixin.getConversionOperators(); - } - public ICPPMethod[] getMethods() throws DOMException { return mixin.getMethods(); } 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 9ed679f7903..f73dd9277dc 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 @@ -10,6 +10,7 @@ * Markus Schorn (Wind River Systems) * Bryan Wilkinson (QNX) * Sergey Prigogin (Google) + * Andrew Ferguson (Symbian) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -57,7 +58,7 @@ import org.eclipse.core.runtime.PlatformObject; * * @author aniefer */ -public class CPPClassType extends PlatformObject implements ICPPInternalClassTypeMixinHost, ICPPClassType, ICPPInternalClassType { +public class CPPClassType extends PlatformObject implements ICPPInternalClassTypeMixinHost { public static class CPPClassTypeProblem extends ProblemBinding implements ICPPClassType{ public CPPClassTypeProblem( IASTNode node, int id, char[] arg ) { super( node, id, arg ); @@ -84,6 +85,9 @@ public class CPPClassType extends PlatformObject implements ICPPInternalClassTyp public ICPPConstructor[] getConstructors() throws DOMException { throw new DOMException( this ); } + public ICPPMethod[] getDeclaredConversionOperators() throws DOMException { + throw new DOMException( this ); + } public int getKey() throws DOMException { throw new DOMException( this ); } @@ -385,10 +389,6 @@ public class CPPClassType extends PlatformObject implements ICPPInternalClassTyp return mixin.getDeclaredFields(); } - public ICPPMethod[] getConversionOperators() throws DOMException { - return mixin.getConversionOperators(); - } - public ICPPMethod[] getMethods() throws DOMException { return mixin.getMethods(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java index 13c7d5ac08a..b716d61c5e7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java @@ -40,7 +40,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; * @author aniefer */ public class CPPTemplateTemplateParameter extends CPPTemplateParameter implements - ICPPTemplateTemplateParameter, ICPPClassType, ICPPInternalTemplate, ICPPInternalUnknown { + ICPPTemplateTemplateParameter, ICPPClassType, ICPPInternalBinding, ICPPInternalTemplate, ICPPInternalUnknown { private ICPPTemplateParameter[] templateParameters = null; private ObjectMap instances = null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeMixin.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeMixin.java index 44bfacb7d87..1c3333b90a6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeMixin.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeMixin.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2007 IBM Corporation and others. + * Copyright (c) 2004, 2008 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 @@ -26,7 +26,6 @@ import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; @@ -104,59 +103,6 @@ class ClassTypeMixin { return resultSet.keyArray(IBinding.class); } - public ICPPMethod[] getConversionOperators() throws DOMException { - if( host.getDefinition() == null ){ - host.checkForDefinition(); - if( host.getDefinition() == null ){ - IASTNode[] declarations= host.getDeclarations(); - IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; - return new ICPPMethod[] { new CPPMethod.CPPMethodProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, host.getNameCharArray() ) }; - } - } - IBinding binding = null; - ICPPMethod [] result = null; - - IASTDeclaration [] decls = host.getCompositeTypeSpecifier().getMembers(); - IASTName name = null; - for ( int i = 0; i < decls.length; i++ ) { - if( decls[i] instanceof IASTSimpleDeclaration ){ - IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decls[i]).getDeclarators(); - for ( int j = 0; j < dtors.length; j++ ) { - name = CPPVisitor.getMostNestedDeclarator( dtors[j] ).getName(); - if( name instanceof ICPPASTConversionName ){ - binding = name.resolveBinding(); - if( binding instanceof ICPPMethod) - result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, binding ); - } - } - } else if( decls[i] instanceof IASTFunctionDefinition ){ - IASTDeclarator dtor = ((IASTFunctionDefinition)decls[i]).getDeclarator(); - name = CPPVisitor.getMostNestedDeclarator( dtor ).getName(); - if( name instanceof ICPPASTConversionName ){ - binding = name.resolveBinding(); - if( binding instanceof ICPPMethod ){ - result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, binding ); - } - } - } - } - - ICPPBase [] bases = getBases(); - for ( int i = 0; i < bases.length; i++ ) { - ICPPClassType cls = null; - try { - IBinding b = bases[i].getBaseClass(); - if( b instanceof ICPPClassType ) - cls = (ICPPClassType) b; - } catch (DOMException e) { - continue; - } - if( cls instanceof ICPPInternalClassType ) - result = (ICPPMethod[]) ArrayUtil.addAll( ICPPMethod.class, result, ((ICPPInternalClassType)cls).getConversionOperators() ); - } - return (ICPPMethod[]) ArrayUtil.trim( ICPPMethod.class, result ); - } - public ICPPBase [] getBases() { if( host.getDefinition() == null ){ host.checkForDefinition(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalClassType.java deleted file mode 100644 index 78a55126e75..00000000000 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalClassType.java +++ /dev/null @@ -1,24 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005 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 - *******************************************************************************/ -/* - * Created on Apr 12, 2005 - */ -package org.eclipse.cdt.internal.core.dom.parser.cpp; - -import org.eclipse.cdt.core.dom.ast.DOMException; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; - -/** - * @author aniefer - */ -public interface ICPPInternalClassType extends ICPPInternalBinding { - public ICPPMethod [] getConversionOperators() throws DOMException; -} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalClassTypeMixinHost.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalClassTypeMixinHost.java index cd205ac0eed..4c7cefcdd00 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalClassTypeMixinHost.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalClassTypeMixinHost.java @@ -1,3 +1,13 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Symbian 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: + * Andrew Ferguson (Symbian) - Initial implementation + *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; @@ -6,7 +16,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; /** * Internal interface for exposing internal methods to ClassTypeMixin */ -interface ICPPInternalClassTypeMixinHost extends ICPPInternalClassType, ICPPClassType { +interface ICPPInternalClassTypeMixinHost extends ICPPClassType, ICPPInternalBinding { /** * @return the composite type specifier for the class type */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index fabfe3e14e9..aa09a2bc772 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -143,7 +143,11 @@ import org.eclipse.cdt.internal.core.index.IIndexScope; * @author aniefer */ public class CPPSemantics { - + /** + * The maximum depth to search ancestors before assuming infinite looping. + */ + public static final int MAX_INHERITANCE_DEPTH= 10; + public static final ASTNodeProperty STRING_LOOKUP_PROPERTY = new ASTNodeProperty("CPPSemantics.STRING_LOOKUP_PROPERTY - STRING_LOOKUP"); //$NON-NLS-1$ public static final char[] EMPTY_NAME_ARRAY = new char[0]; public static final String EMPTY_NAME = ""; //$NON-NLS-1$ @@ -728,7 +732,7 @@ public class CPPSemantics { data.inheritanceChain.put( lookIn ); // workaround to fix 185828 - if(data.inheritanceChain.size() > 20) { + if(data.inheritanceChain.size() > CPPSemantics.MAX_INHERITANCE_DEPTH) { return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java index 4b4022b96de..66c5a161b50 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java @@ -43,7 +43,6 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding; -import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalClassType; /** * Routines for calculating the cost of conversions @@ -149,8 +148,8 @@ class Conversions { } //conversion operators - if( s instanceof ICPPInternalClassType ){ - ICPPMethod [] ops = ((ICPPInternalClassType)s).getConversionOperators(); + if( s instanceof ICPPClassType ){ + ICPPMethod [] ops = SemanticUtil.getConversionOperators((ICPPClassType)s); if( ops.length > 0 && !(ops[0] instanceof IProblemBinding) ){ Cost [] costs = null; for (int i = 0; i < ops.length; i++) { @@ -209,27 +208,29 @@ class Conversions { * no inheritance relation * @throws DOMException */ - private static int calculateInheritanceDepth(ICPPClassType clazz, ICPPClassType ancestorToFind) throws DOMException { + private static int calculateInheritanceDepth(int maxdepth, ICPPClassType clazz, ICPPClassType ancestorToFind) throws DOMException { if(clazz == ancestorToFind || clazz.isSameType(ancestorToFind)) return 0; - ICPPBase [] bases = clazz.getBases(); - for(int i=0; i<bases.length; i++) { - IBinding base = bases[i].getBaseClass(); - if(base instanceof IType) { - IType tbase= (IType) base; - if( tbase.isSameType(ancestorToFind) || - (ancestorToFind instanceof ICPPSpecialization && /*allow some flexibility with templates*/ - ((IType)((ICPPSpecialization)ancestorToFind).getSpecializedBinding()).isSameType(tbase) ) ) - { - return 1; - } + if(maxdepth>0) { + ICPPBase [] bases = clazz.getBases(); + for(int i=0; i<bases.length; i++) { + IBinding base = bases[i].getBaseClass(); + if(base instanceof IType) { + IType tbase= (IType) base; + if( tbase.isSameType(ancestorToFind) || + (ancestorToFind instanceof ICPPSpecialization && /*allow some flexibility with templates*/ + ((IType)((ICPPSpecialization)ancestorToFind).getSpecializedBinding()).isSameType(tbase) ) ) + { + return 1; + } - tbase= getUltimateTypeViaTypedefs(tbase); - if(tbase instanceof ICPPClassType) { - int n= calculateInheritanceDepth((ICPPClassType) tbase, ancestorToFind ); - if(n>0) - return n+1; + tbase= getUltimateTypeViaTypedefs(tbase); + if(tbase instanceof ICPPClassType) { + int n= calculateInheritanceDepth(maxdepth-1, (ICPPClassType) tbase, ancestorToFind ); + if(n>0) + return n+1; + } } } } @@ -277,7 +278,7 @@ class Conversions { //4.10-3 An rvalue of type "pointer to cv D", where D is a class type can be converted //to an rvalue of type "pointer to cv B", where B is a base class of D. else if( s instanceof ICPPClassType && tPrev instanceof IPointerType && t instanceof ICPPClassType ){ - int depth= calculateInheritanceDepth( (ICPPClassType)s, (ICPPClassType) t ); + int depth= calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, (ICPPClassType)s, (ICPPClassType) t ); cost.rank= ( depth > -1 ) ? Cost.CONVERSION_RANK : Cost.NO_MATCH_RANK; cost.conversion= ( depth > -1 ) ? depth : 0; cost.detail= 1; @@ -307,7 +308,7 @@ class Conversions { IType st = spm.getType(); IType tt = tpm.getType(); if( st != null && tt != null && st.isSameType( tt ) ){ - int depth= calculateInheritanceDepth( tpm.getMemberOfClass(), spm.getMemberOfClass() ); + int depth= calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, tpm.getMemberOfClass(), spm.getMemberOfClass()); cost.rank= ( depth > -1 ) ? Cost.CONVERSION_RANK : Cost.NO_MATCH_RANK; cost.conversion= ( depth > -1 ) ? depth : 0; cost.detail= 1; @@ -320,7 +321,7 @@ class Conversions { IType t = getUltimateType( cost.target, true ); if( cost.targetHadReference && s instanceof ICPPClassType && t instanceof ICPPClassType ){ - int depth= calculateInheritanceDepth( (ICPPClassType) s, (ICPPClassType) t ); + int depth= calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, (ICPPClassType) s, (ICPPClassType) t); if(depth > -1){ cost.rank= Cost.DERIVED_TO_BASE_CONVERSION; cost.conversion= depth; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java index 9351265d5bd..6ccaf050417 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java @@ -14,21 +14,148 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IPointerType; +import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; +import org.eclipse.cdt.core.parser.Keywords; +import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.core.parser.util.CharArraySet; +import org.eclipse.cdt.core.parser.util.ObjectSet; +import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator; /** * */ public class SemanticUtil { + /** + * Cache of overloadable operator names for fast lookup. Used by isConversionOperator. + */ + private static final CharArraySet cas= new CharArraySet(OverloadableOperator.values().length); + + static { + for(OverloadableOperator op : OverloadableOperator.values()) { + cas.put(op.toCharArray()); + } + } + + /** + * Returns a list of ICPPMethod objects representing all conversion operators + * declared by the specified class. It does not include inherited methods. Conversion + * operators can not be implicit. + * @param clazz + * @return List of ICPPMethod + */ + public static final ICPPMethod[] getDeclaredConversionOperators(ICPPClassType clazz) throws DOMException { + ICPPMethod[] methods= new ICPPMethod[0]; + ICPPMethod[] decs= clazz.getDeclaredMethods(); + if(decs != null) { + for(ICPPMethod method : decs) { + if(isConversionOperator(method)) { + methods= (ICPPMethod[]) ArrayUtil.append(ICPPMethod.class, methods, method); + } + } + } + return methods; + } + + /** + * Returns a list of ICPPMethod objects representing all conversion operators + * declared by the specified class and its ancestors. It does not include inherited + * methods. Conversion operators can not be implicit. + * @param clazz + * @return List of ICPPMethod + */ + public static ICPPMethod[] getConversionOperators(ICPPClassType clazz) throws DOMException { + ICPPMethod[] methods= new ICPPMethod[0]; + ObjectSet<ICPPClassType> ancestry= inheritanceClosure(clazz); + for(int i=0; i<ancestry.size(); i++) { + methods= (ICPPMethod[]) ArrayUtil.addAll(ICPPMethod.class, methods, getDeclaredConversionOperators(ancestry.keyAt(i))); + } + return methods; + } + + /** + * @param root the class to start at + * @return the root and all its ancestor classes + * @throws DOMException + */ + public static ObjectSet<ICPPClassType> inheritanceClosure(ICPPClassType root) throws DOMException { + ObjectSet<ICPPClassType> done= new ObjectSet<ICPPClassType>(2); + ObjectSet<ICPPClassType> current= new ObjectSet<ICPPClassType>(2); + current.put(root); + + for(int count=0; count < CPPSemantics.MAX_INHERITANCE_DEPTH && !current.isEmpty(); count++) { + ObjectSet<ICPPClassType> next= new ObjectSet<ICPPClassType>(2); + + for(int i=0; i<current.size(); i++) { + ICPPClassType clazz= current.keyAt(i); + done.put(clazz); + + for(ICPPBase base : clazz.getBases()) { + IBinding binding= base.getBaseClass(); + if(binding instanceof ICPPClassType && !(binding instanceof IProblemBinding)) { + ICPPClassType ct= (ICPPClassType) binding; + if(!done.containsKey(ct)) + next.put(ct); + } + } + } + + current= next; + } + + return done; + } + + /** + * @param method + * @return true is the specified method is a conversion operator + */ + private static final boolean isConversionOperator(ICPPMethod method) { + boolean result= false; + if(!method.isImplicit()) { + char[] name= method.getNameCharArray(); + char[] expected= Keywords.OPERATOR.toCharArray(); + if(name.length > expected.length + 1) { + for(int i=0; i<expected.length; i++) { + if(name[i] != expected[i]) + return false; + } + if(name[expected.length]!=' ') + return false; + result= !cas.containsKey(name, expected.length+1, name.length - (expected.length+1)); + } + } + return result; + } + + /** + * Descends into type containers, stopping at pointer-to-member types if + * specified. + * @param type the root type + * @param stopAtPointerToMember if true, do not descend into ICPPPointerToMember types + * @return the deepest type in a type container sequence + */ public static IType getUltimateType(IType type, boolean stopAtPointerToMember) { return getUltimateType(type, null, stopAtPointerToMember); } - + + /** + * Descends into type containers, stopping at pointer-to-member types if + * specified. + * @param type the root type + * @param lastPointerType if non-null, the deepest pointer type encounter is stored in element zero + * @param stopAtPointerToMember if true, do not descend into ICPPPointerToMember types + * @return the deepest type in a type container sequence + */ static IType getUltimateType(IType type, IType[] lastPointerType, boolean stopAtPointerToMember) { try { while( true ){ @@ -78,7 +205,7 @@ public class SemanticUtil { } /** - * Unravels a type by following purely typedefs + * Descends into a typedef sequence. * @param type * @return */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/DeclaredBindingsFilter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/DeclaredBindingsFilter.java index 829b7e4a31f..4680b46f09b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/DeclaredBindingsFilter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/DeclaredBindingsFilter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007 Wind River Systems, Inc. and others. + * Copyright (c) 2007, 2008 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,6 +7,7 @@ * * Contributors: * Markus Schorn - initial API and implementation + * Andrew Ferguson (Symbian) *******************************************************************************/ package org.eclipse.cdt.internal.core.index; @@ -14,20 +15,27 @@ package org.eclipse.cdt.internal.core.index; import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.core.runtime.CoreException; public class DeclaredBindingsFilter extends IndexFilter { final private int fLinkageID; final private boolean fAcceptImplicit; + final private boolean fAcceptSpecializations; public DeclaredBindingsFilter() { this(-1, false); } public DeclaredBindingsFilter(int linkageID, boolean acceptImplicit) { + this(linkageID, acceptImplicit, acceptImplicit /* assume specializations should behave like implicit bindings*/); + } + + public DeclaredBindingsFilter(int linkageID, boolean acceptImplicit, boolean acceptSpecializations) { fLinkageID= linkageID; fAcceptImplicit= acceptImplicit; + fAcceptSpecializations= acceptSpecializations; } public boolean acceptLinkage(ILinkage linkage) { @@ -36,8 +44,9 @@ public class DeclaredBindingsFilter extends IndexFilter { public boolean acceptBinding(IBinding binding) throws CoreException { if (binding instanceof IIndexFragmentBinding) { - return ((IIndexFragmentBinding) binding).hasDeclaration() || - (fAcceptImplicit && isImplicit(binding)); + return ((IIndexFragmentBinding) binding).hasDeclaration() + || (fAcceptImplicit && isImplicit(binding)) + || (fAcceptSpecializations && binding instanceof ICPPSpecialization); } // composite bindings don't support that kind of check. return fAcceptImplicit || !isImplicit(binding); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/AbstractCompositeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/AbstractCompositeFactory.java index 197e1cb1311..56f2b8d2196 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/AbstractCompositeFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/AbstractCompositeFactory.java @@ -73,24 +73,28 @@ public abstract class AbstractCompositeFactory implements ICompositesFactory { } /** - * Convenience method for finding a binding with a definition in the specified index - * context, which is equivalent to the specified binding, or null if no definitions were - * found. + * Convenience method for finding a binding with a definition (in the specified index + * context) which is equivalent to the specified binding. If no definition is found, + * a declaration is returned if <code>allowDeclaration</code> is set, otherwise an + * arbitrary binding is returned if available. * @param index * @param binding * @return */ - protected IIndexFragmentBinding findOneDefinition(IBinding binding) { + protected IIndexFragmentBinding findOneBinding(IBinding binding, boolean allowDeclaration) { try{ - CIndex cindex = (CIndex) index; - IIndexFragmentBinding[] ibs = cindex.findEquivalentBindings(binding); - IBinding def = ibs.length>0 ? ibs[0] : null; + CIndex cindex= (CIndex) index; + IIndexFragmentBinding[] ibs= cindex.findEquivalentBindings(binding); + IBinding def= null; + IBinding dec= ibs.length>0 ? ibs[0] : null; for(int i=0; i<ibs.length; i++) { if(ibs[i].hasDefinition()) { - def = ibs[i]; + def= ibs[i]; + } else if(allowDeclaration && ibs[i].hasDeclaration()) { + dec= ibs[i]; } } - return (IIndexFragmentBinding) def; + return (IIndexFragmentBinding) (def == null ? dec : def); } catch(CoreException ce) { CCorePlugin.log(ce); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CCompositesFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CCompositesFactory.java index 5211c6b4c2b..9be1886074f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CCompositesFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CCompositesFactory.java @@ -113,9 +113,9 @@ public class CCompositesFactory extends AbstractCompositeFactory implements ICom } else if(rbinding instanceof IVariable) { result = new CompositeCVariable(this, rbinding); } else if(rbinding instanceof ICompositeType) { - result = new CompositeCStructure(this, findOneDefinition(rbinding)); + result = new CompositeCStructure(this, findOneBinding(rbinding, false)); } else if(rbinding instanceof IEnumeration) { - result = new CompositeCEnumeration(this, findOneDefinition(rbinding)); + result = new CompositeCEnumeration(this, findOneBinding(rbinding, false)); } else if(rbinding instanceof IFunction) { result = new CompositeCFunction(this, rbinding); } else if(rbinding instanceof IEnumerator) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java index 2c6a9bbce69..468387561fd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java @@ -80,7 +80,7 @@ public class CPPCompositesFactory extends AbstractCompositeFactory implements IC } else if(rscope instanceof ICPPClassScope) { ICPPClassScope classScope = (ICPPClassScope) rscope; result = new CompositeCPPClassScope(this, - findOneDefinition(classScope.getClassType())); + findOneBinding(classScope.getClassType())); } else if(rscope instanceof ICPPNamespaceScope) { ICPPNamespace[] namespaces; if(rscope instanceof CompositeCPPNamespace) { @@ -156,9 +156,13 @@ public class CPPCompositesFactory extends AbstractCompositeFactory implements IC return index; } + protected IIndexFragmentBinding findOneBinding(IBinding binding) { + return super.findOneBinding(binding, false); + } + @Override - protected IIndexFragmentBinding findOneDefinition(IBinding binding) { - return super.findOneDefinition(binding); + protected IIndexFragmentBinding findOneBinding(IBinding binding, boolean allowDeclaration) { + return super.findOneBinding(binding, allowDeclaration); } /* (non-Javadoc) @@ -174,7 +178,7 @@ public class CPPCompositesFactory extends AbstractCompositeFactory implements IC if(binding instanceof ICPPTemplateInstance) { if(binding instanceof ICPPDeferredTemplateInstance) { if(binding instanceof ICPPClassType) { - return new CompositeCPPDeferredClassInstance(this, (ICPPClassType) findOneDefinition(binding)); + return new CompositeCPPDeferredClassInstance(this, (ICPPClassType) findOneBinding(binding)); } else if(binding instanceof ICPPFunction) { return new CompositeCPPDeferredFunctionInstance(this, (ICPPFunction) binding); } else { @@ -182,7 +186,7 @@ public class CPPCompositesFactory extends AbstractCompositeFactory implements IC } } else { if(binding instanceof ICPPClassType) { - return new CompositeCPPClassInstance(this, (ICPPClassType) findOneDefinition(binding)); + return new CompositeCPPClassInstance(this, (ICPPClassType) findOneBinding(binding)); } else if(binding instanceof ICPPConstructor) { return new CompositeCPPConstructorInstance(this, (ICPPConstructor) binding); } else if(binding instanceof ICPPMethod) { @@ -209,13 +213,13 @@ public class CPPCompositesFactory extends AbstractCompositeFactory implements IC } } else { if(binding instanceof ICPPClassType) { - return new CompositeCPPClassSpecialization(this, (ICPPClassType) findOneDefinition(binding)); + return new CompositeCPPClassSpecialization(this, (ICPPClassType) findOneBinding(binding)); } if(binding instanceof ICPPConstructor) { - return new CompositeCPPConstructorSpecialization(this, (ICPPConstructor) binding); + return new CompositeCPPConstructorSpecialization(this, (ICPPConstructor) findOneBinding(binding, true)); } if(binding instanceof ICPPMethod) { - return new CompositeCPPMethodSpecialization(this, (ICPPMethod) binding); + return new CompositeCPPMethodSpecialization(this, (ICPPMethod) findOneBinding(binding, true)); } if(binding instanceof ICPPFunction) { - return new CompositeCPPFunctionSpecialization(this, (ICPPFunction) binding); + return new CompositeCPPFunctionSpecialization(this, (ICPPFunction) findOneBinding(binding, true)); } if(binding instanceof ICPPField) { return new CompositeCPPField(this, (ICPPField) binding); } if(binding instanceof ICPPParameter) { @@ -228,7 +232,8 @@ public class CPPCompositesFactory extends AbstractCompositeFactory implements IC } } else if (binding instanceof ICPPTemplateDefinition) { if(binding instanceof ICPPClassTemplate) { - return new CompositeCPPClassTemplate(this, (ICPPClassType) findOneDefinition(binding)); + ICPPClassType def= (ICPPClassType) findOneBinding(binding); + return new CompositeCPPClassTemplate(this, def); } else if (binding instanceof ICPPConstructor) { return new CompositeCPPConstructorTemplate(this, (ICPPConstructor) binding); } else if (binding instanceof ICPPMethod) { @@ -245,7 +250,7 @@ public class CPPCompositesFactory extends AbstractCompositeFactory implements IC } else if(binding instanceof ICPPVariable) { result = new CompositeCPPVariable(this, (ICPPVariable) binding); } else if(binding instanceof ICPPClassType) { - ICPPClassType def = (ICPPClassType) findOneDefinition(binding); + ICPPClassType def = (ICPPClassType) findOneBinding(binding); result = def == null ? null : new CompositeCPPClassType(this, def); } else if(binding instanceof ICPPConstructor) { result = new CompositeCPPConstructor(this, (ICPPConstructor) binding); @@ -259,7 +264,7 @@ public class CPPCompositesFactory extends AbstractCompositeFactory implements IC } else if (binding instanceof ICPPUsingDeclaration) { result = new CompositeCPPUsingDeclaration(this, (ICPPUsingDeclaration) binding); } else if(binding instanceof IEnumeration) { - IEnumeration def = (IEnumeration) findOneDefinition(binding); + IEnumeration def = (IEnumeration) findOneBinding(binding); result = def == null ? null : new CompositeCPPEnumeration(this, def); } else if(binding instanceof ICPPFunction) { result = new CompositeCPPFunction(this, (ICPPFunction) binding); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassInstance.java index a71e8b510d0..73b699e43bc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassInstance.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007 Symbian Software Systems and others. + * Copyright (c) 2007, 2008 Symbian 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 @@ -15,9 +15,12 @@ import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; +import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.index.IIndexType; @@ -30,6 +33,16 @@ ICPPClassType, IIndexType, ICPPTemplateInstance, ICPPSpecialization { super(cf, rbinding); } + @Override + public ICPPMethod[] getDeclaredMethods() throws DOMException { + ICPPClassType specialized = (ICPPClassType) getSpecializedBinding(); + ICPPMethod[] bindings = specialized.getDeclaredMethods(); + for(int i=0; i<bindings.length; i++) { + bindings[i]= (ICPPMethod) CPPTemplates.createSpecialization((ICPPScope)getScope(), (IIndexBinding) bindings[i], getArgumentMap()); + } + return bindings; + } + public ObjectMap getArgumentMap() { return TemplateInstanceUtil.getArgumentMap(cf, rbinding); } public IBinding getSpecializedBinding() { return TemplateInstanceUtil.getSpecializedBinding(cf, rbinding); } public IType[] getArguments() { return TemplateInstanceUtil.getArguments(cf, (ICPPTemplateInstance) rbinding); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/TemplateInstanceUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/TemplateInstanceUtil.java index 9a3edac1b7d..8029dd1c3da 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/TemplateInstanceUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/TemplateInstanceUtil.java @@ -31,7 +31,7 @@ import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; public class TemplateInstanceUtil { public static ObjectMap getArgumentMap(ICompositesFactory cf, IIndexBinding rbinding) { ICPPSpecialization specn= (ICPPSpecialization) rbinding; - IBinding specd= ((CPPCompositesFactory)cf).findOneDefinition(specn.getSpecializedBinding()); + IBinding specd= ((CPPCompositesFactory)cf).findOneBinding(specn.getSpecializedBinding()); if(specd == null) specd= specn.getSpecializedBinding(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassInstance.java index f502726e3db..73a76424692 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassInstance.java @@ -150,11 +150,23 @@ class PDOMCPPClassInstance extends PDOMCPPInstance implements return false; } + public ICPPMethod[] getDeclaredMethods() throws DOMException { + ICPPClassType specialized = (ICPPClassType) getSpecializedBinding(); + ICPPMethod[] bindings = specialized.getDeclaredMethods(); + SpecializationFinder visitor= new SpecializationFinder(bindings); + try { + accept(visitor); + return ArrayUtil.convert(ICPPMethod.class, visitor.getSpecializations()); + } catch (CoreException e) { + CCorePlugin.log(e); + } + return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; + } + //ICPPClassType unimplemented public IField findField(String name) throws DOMException { fail(); return null; } public ICPPMethod[] getAllDeclaredMethods() throws DOMException { fail(); return null; } public ICPPField[] getDeclaredFields() throws DOMException { fail(); return null; } - public ICPPMethod[] getDeclaredMethods() throws DOMException { fail(); return null; } public IField[] getFields() throws DOMException { fail(); return null; } public IBinding[] getFriends() throws DOMException { fail(); return null; } public ICPPMethod[] getMethods() throws DOMException { fail(); return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java index 7705991e870..bb36efce05b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java @@ -194,7 +194,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType, public ICPPMethod[] getMethods() throws DOMException { try { PDOMClassUtil.MethodCollector methods = new PDOMClassUtil.MethodCollector(true); - acceptInHierarchy(new HashSet<PDOMCPPClassType>(), methods); + acceptInHierarchy(this, new HashSet<IPDOMMemberOwner>(), methods); return methods.getMethods(); } catch (CoreException e) { CCorePlugin.log(e); @@ -212,30 +212,36 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType, } } - private void acceptInHierarchy(Set<PDOMCPPClassType> visited, IPDOMVisitor visitor) throws CoreException { - if (visited.contains(this)) + static void acceptInHierarchy(IPDOMMemberOwner current, Set<IPDOMMemberOwner> visited, IPDOMVisitor visitor) throws CoreException { + if (visited.contains(current)) return; - visited.add(this); + visited.add(current); // Class is in its own scope - visitor.visit(this); + visitor.visit((IPDOMNode) current); // Get my members - accept(visitor); + current.accept(visitor); // Visit my base classes - for (PDOMCPPBase base = getFirstBase(); base != null; base = base.getNextBase()) { - IBinding baseClass = base.getBaseClass(); - if (baseClass != null && baseClass instanceof PDOMCPPClassType) - ((PDOMCPPClassType)baseClass).acceptInHierarchy(visited, visitor); + if(current instanceof ICPPClassType) { + try { + ICPPBase[] bases= ((ICPPClassType) current).getBases(); + for(ICPPBase base : bases) { + IBinding baseClass = base.getBaseClass(); + if (baseClass != null && baseClass instanceof IPDOMMemberOwner) + acceptInHierarchy((IPDOMMemberOwner)baseClass, visited, visitor); + } + } catch(DOMException de) { + CCorePlugin.log(Util.createStatus(de)); + } } } public ICPPMethod[] getAllDeclaredMethods() throws DOMException { PDOMClassUtil.MethodCollector myMethods = new PDOMClassUtil.MethodCollector(false, true); - Set<PDOMCPPClassType> visited = new HashSet<PDOMCPPClassType>(); try { - acceptInHierarchy(visited, myMethods); + acceptInHierarchy(this, new HashSet<IPDOMMemberOwner>(), myMethods); return myMethods.getMethods(); } catch (CoreException e) { CCorePlugin.log(e); @@ -246,7 +252,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType, public IField[] getFields() throws DOMException { try { PDOMClassUtil.FieldCollector visitor = new PDOMClassUtil.FieldCollector(); - acceptInHierarchy(new HashSet<PDOMCPPClassType>(), visitor); + acceptInHierarchy(this, new HashSet<IPDOMMemberOwner>(), visitor); return visitor.getFields(); } catch (CoreException e) { CCorePlugin.log(e); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPDeferredClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPDeferredClassInstance.java index c971cf0069a..c232a6561a5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPDeferredClassInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPDeferredClassInstance.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.cpp; +import org.eclipse.cdt.core.dom.IPDOMVisitor; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IField; @@ -30,6 +31,8 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.index.IIndexType; import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.core.pdom.db.PDOMNodeLinkedList; +import org.eclipse.cdt.internal.core.pdom.dom.IPDOMMemberOwner; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.core.runtime.CoreException; @@ -39,13 +42,15 @@ import org.eclipse.core.runtime.CoreException; * */ class PDOMCPPDeferredClassInstance extends PDOMCPPInstance implements - ICPPClassType, IIndexType, ICPPDeferredTemplateInstance, ICPPInternalDeferredClassInstance { + ICPPClassType, IPDOMMemberOwner, IIndexType, ICPPDeferredTemplateInstance, ICPPInternalDeferredClassInstance { + private static final int MEMBERLIST = PDOMCPPInstance.RECORD_SIZE + 0; + /** * The size in bytes of a PDOMCPPDeferredClassInstance record in the database. */ @SuppressWarnings("hiding") - protected static final int RECORD_SIZE = PDOMCPPInstance.RECORD_SIZE + 0; + protected static final int RECORD_SIZE = PDOMCPPInstance.RECORD_SIZE + 4; public PDOMCPPDeferredClassInstance(PDOM pdom, PDOMNode parent, ICPPClassType classType, PDOMBinding instantiated) throws CoreException { @@ -102,17 +107,6 @@ class PDOMCPPDeferredClassInstance extends PDOMCPPInstance implements return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY; } - //Unimplemented - public IField findField(String name) throws DOMException { fail(); return null; } - public ICPPMethod[] getAllDeclaredMethods() throws DOMException { fail(); return null; } - public ICPPField[] getDeclaredFields() throws DOMException { fail(); return null; } - public ICPPMethod[] getDeclaredMethods() throws DOMException { fail(); return null; } - public IField[] getFields() throws DOMException { fail(); return null; } - public IBinding[] getFriends() throws DOMException { fail(); return null; } - public ICPPMethod[] getMethods() throws DOMException { fail(); return null; } - public ICPPClassType[] getNestedClasses() throws DOMException { fail(); return null; } - public Object clone() {fail();return null;} - /** * @param argMap * @return @@ -128,4 +122,41 @@ class PDOMCPPDeferredClassInstance extends PDOMCPPInstance implements return (IType) ((ICPPInternalTemplateInstantiator)getTemplateDefinition()).instantiate( newArgs ); } + + public void addMember(PDOMNode member) throws CoreException { + PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + MEMBERLIST, getLinkageImpl()); + list.addMember(member); + } + + @Override + public void accept(IPDOMVisitor visitor) throws CoreException { + super.accept(visitor); + PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + MEMBERLIST, getLinkageImpl()); + list.accept(visitor); + } + + @Override + public void addChild(PDOMNode member) throws CoreException { + addMember(member); + } + + public ICPPMethod[] getDeclaredMethods() throws DOMException { + try { + PDOMClassUtil.MethodCollector methods = new PDOMClassUtil.MethodCollector(false); + accept(methods); + return methods.getMethods(); + } catch (CoreException e) { + return new ICPPMethod[0]; + } + } + + //Unimplemented + public IField findField(String name) throws DOMException { fail(); return null; } + public ICPPMethod[] getAllDeclaredMethods() throws DOMException { fail(); return null; } + public ICPPField[] getDeclaredFields() throws DOMException { fail(); return null; } + public IField[] getFields() throws DOMException { fail(); return null; } + public IBinding[] getFriends() throws DOMException { fail(); return null; } + public ICPPMethod[] getMethods() throws DOMException { fail(); return null; } + public ICPPClassType[] getNestedClasses() throws DOMException { fail(); return null; } + public Object clone() {fail();return null;} } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java index 65b1fe67d73..432a245bf64 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java @@ -34,7 +34,36 @@ import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; -import org.eclipse.cdt.core.dom.ast.cpp.*; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeferredTemplateInstance; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; +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.ICPPNamespace; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; +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.ICPPTemplateScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPBasicType; import org.eclipse.cdt.core.index.IIndexBinding; @@ -44,6 +73,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBlockScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalUnknownClassType; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.index.IIndexScope; import org.eclipse.cdt.internal.core.index.composite.CompositeScope; @@ -220,10 +250,23 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { PDOMNode parent = getAdaptedParent(binding, true); if (parent == null) return null; - pdomBinding = addBinding(parent, binding); - if (pdomBinding instanceof PDOMCPPClassInstance && binding instanceof ICPPClassType) { - // Add instantiated constructors to the index (bug 201174). - addConstructors(pdomBinding, (ICPPClassType) binding); + + if(binding instanceof ICPPSpecialization) { + IBinding specialized= ((ICPPSpecialization)binding).getSpecializedBinding(); + PDOMBinding pdomSpecialized= adaptBinding(specialized); + if(pdomSpecialized == null) { + addBinding(specialized, null); + } + } + + pdomBinding = adaptBinding(binding); + if(pdomBinding == null) { + pdomBinding = addBinding(parent, binding); + if ((pdomBinding instanceof PDOMCPPClassInstance || pdomBinding instanceof PDOMCPPDeferredClassInstance) && binding instanceof ICPPClassType) { + // Add instantiated constructors to the index (bug 201174). + addConstructors(pdomBinding, (ICPPClassType) binding); + addConversionOperators(pdomBinding, (ICPPClassType) binding); + } } } catch (DOMException e) { throw new CoreException(Util.createStatus(e)); @@ -234,12 +277,14 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { private void addConstructors(PDOMBinding pdomBinding, ICPPClassType binding) throws DOMException, CoreException { - ICPPConstructor[] constructors = binding.getConstructors(); - for (int i = 0; i < constructors.length; i++) { - if (adaptBinding(constructors[i]) == null) { - addBinding(pdomBinding, constructors[i]); - } - } + for(ICPPConstructor ctr : binding.getConstructors()) + addBinding(ctr, null); + } + + private void addConversionOperators(PDOMBinding pdomBinding, ICPPClassType binding) + throws DOMException, CoreException { + for(ICPPMethod conv : SemanticUtil.getDeclaredConversionOperators(binding)) + addBinding(conv, null); } private boolean shouldUpdate(PDOMBinding pdomBinding, IASTName fromName) throws CoreException { @@ -270,11 +315,9 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { if (binding instanceof ICPPSpecialization) { IBinding specialized = ((ICPPSpecialization)binding).getSpecializedBinding(); - if (specialized == null || specialized instanceof ProblemBinding) return null; - PDOMBinding pdomSpecialized = addBinding(specialized, null); - if (pdomSpecialized == null) + PDOMBinding pdomSpecialized= adaptBinding(specialized); + if(pdomSpecialized == null) return null; - if (binding instanceof ICPPDeferredTemplateInstance) { if (binding instanceof ICPPFunction && pdomSpecialized instanceof ICPPFunctionTemplate) { pdomBinding = new PDOMCPPDeferredFunctionInstance(pdom, |