From 61cc1a811f9960c35ade853400a83885e7174d9b Mon Sep 17 00:00:00 2001 From: Andrew Ferguson Date: Tue, 8 Apr 2008 12:36:26 +0000 Subject: [PATCH] 224364: apply fix --- .../parser/tests/ast2/AST2TemplateTests.java | 6 +- .../tests/IndexCPPBindingResolutionTest.java | 2 +- .../tests/IndexCPPTemplateResolutionTest.java | 17 ++- .../cdt/core/parser/util/ArrayUtil.java | 33 +++-- .../cdt/core/parser/util/CharTable.java | 19 ++- .../core/dom/parser/cpp/CPPClassInstance.java | 17 +-- .../parser/cpp/CPPClassSpecialization.java | 104 ++++++-------- .../cpp/CPPClassSpecializationScope.java | 12 +- .../core/dom/parser/cpp/CPPClassTemplate.java | 6 +- .../core/dom/parser/cpp/CPPClassType.java | 10 +- .../cpp/CPPTemplateTemplateParameter.java | 2 +- .../core/dom/parser/cpp/ClassTypeMixin.java | 56 +------- .../dom/parser/cpp/ICPPInternalClassType.java | 24 ---- .../cpp/ICPPInternalClassTypeMixinHost.java | 12 +- .../parser/cpp/semantics/CPPSemantics.java | 8 +- .../dom/parser/cpp/semantics/Conversions.java | 47 ++++--- .../parser/cpp/semantics/SemanticUtil.java | 131 +++++++++++++++++- .../core/index/DeclaredBindingsFilter.java | 15 +- .../composite/AbstractCompositeFactory.java | 22 +-- .../index/composite/c/CCompositesFactory.java | 4 +- .../composite/cpp/CPPCompositesFactory.java | 29 ++-- .../cpp/CompositeCPPClassInstance.java | 15 +- .../composite/cpp/TemplateInstanceUtil.java | 2 +- .../pdom/dom/cpp/PDOMCPPClassInstance.java | 14 +- .../core/pdom/dom/cpp/PDOMCPPClassType.java | 32 +++-- .../dom/cpp/PDOMCPPDeferredClassInstance.java | 57 ++++++-- .../core/pdom/dom/cpp/PDOMCPPLinkage.java | 73 ++++++++-- 27 files changed, 478 insertions(+), 291 deletions(-) delete mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalClassType.java 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 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 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()); - 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 // class C { // public: @@ -934,6 +933,12 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa // class D : public C {}; // class E : public C {}; // void foo(B b) {} + // template<> + // class C { + // public: + // X t; + // operator B() {B b; return b;} + // }; // class F : public C {}; // void refs() { @@ -945,8 +950,10 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa // foo(e); // F f; // foo(f); + // C cx; + // foo(cx); // } - public void _testUserDefinedConversionOperator_224364() throws Exception { + public void testUserDefinedConversionOperator_224364() throws Exception { IBinding ca= getBindingFromASTName("C", 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 T[] convert(Class target, S[] source) { + T[] result= null; + if(source != null) { + result= (T[]) Array.newInstance(target, source.length); + for(int 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; i0) { + ICPPBase [] bases = clazz.getBases(); + for(int i=0; i0) - 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 ancestry= inheritanceClosure(clazz); + for(int i=0; i inheritanceClosure(ICPPClassType root) throws DOMException { + ObjectSet done= new ObjectSet(2); + ObjectSet current= new ObjectSet(2); + current.put(root); + + for(int count=0; count < CPPSemantics.MAX_INHERITANCE_DEPTH && !current.isEmpty(); count++) { + ObjectSet next= new ObjectSet(2); + + for(int i=0; i expected.length + 1) { + for(int i=0; iallowDeclaration 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(), methods); + acceptInHierarchy(this, new HashSet(), methods); return methods.getMethods(); } catch (CoreException e) { CCorePlugin.log(e); @@ -212,30 +212,36 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType, } } - private void acceptInHierarchy(Set visited, IPDOMVisitor visitor) throws CoreException { - if (visited.contains(this)) + static void acceptInHierarchy(IPDOMMemberOwner current, Set 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 visited = new HashSet(); try { - acceptInHierarchy(visited, myMethods); + acceptInHierarchy(this, new HashSet(), 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(), visitor); + acceptInHierarchy(this, new HashSet(), 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,