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 0ab8f999445..d37d82e5161 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 @@ -9,6 +9,7 @@ * IBM - Initial API and implementation * Markus Schorn (Wind River Systems) * Bryan Wilkinson (QNX) + * Andrew Ferguson (Symbian) *******************************************************************************/ /* * Created on Mar 11, 2005 @@ -52,6 +53,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; 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.ICPPTemplateNonTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; @@ -2142,4 +2144,42 @@ public class AST2TemplateTests extends AST2BaseTest { } } } + + // class A {}; + // + // template class C { + // public: + // inline C(T& aRef) {} + // inline operator T&() {} + // }; + // + // void foo(A a) {} + // void bar(C ca) {} + // + // void main2() { + // const A a= *new A(); + // const C ca= *new C(*new A()); + // + // foo(a); + // bar(ca); + // } + public void testBug214646() throws Exception { + BindingAssertionHelper bh= new BindingAssertionHelper(getContents(1)[0].toString(), true); + + IBinding b0= bh.assertNonProblem("foo(a)", 3); + IBinding b1= bh.assertNonProblem("bar(ca)", 3); + + assertInstance(b0, ICPPFunction.class); + assertInstance(b1, ICPPFunction.class); + + ICPPFunction f0= (ICPPFunction) b0, f1= (ICPPFunction) b1; + assertEquals(1, f0.getParameters().length); + assertEquals(1, f1.getParameters().length); + + assertInstance(f0.getParameters()[0].getType(), ICPPClassType.class); + assertFalse(f0 instanceof ICPPTemplateInstance); + assertFalse(f0 instanceof ICPPTemplateDefinition); + assertInstance(f1.getParameters()[0].getType(), ICPPClassType.class); + assertInstance(f1.getParameters()[0].getType(), ICPPTemplateInstance.class); + } } 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 b5b1d1b1de4..701fea215fd 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 @@ -8,10 +8,8 @@ * Contributors: * IBM - Initial API and implementation * Bryan Wilkinson (QNX) + * Andrew Ferguson (Symbian) *******************************************************************************/ -/* - * Created on Mar 28, 2005 - */ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.DOMException; @@ -32,14 +30,15 @@ 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.index.IIndexType; /** * @author aniefer */ -public class CPPClassInstance extends CPPInstance implements ICPPClassType, ICPPInternalBinding { +public class CPPClassInstance extends CPPInstance implements ICPPClassType, ICPPInternalClassType { private CPPClassSpecializationScope instanceScope; - + /** * @param decl * @param args @@ -59,15 +58,15 @@ public class CPPClassInstance extends CPPInstance implements ICPPClassType, ICPP ICPPBase [] bindings = cls.getBases(); for (int i = 0; i < bindings.length; i++) { ICPPBase specBinding = (ICPPBase) ((ICPPInternalBase)bindings[i]).clone(); - IBinding base = bindings[i].getBaseClass(); - if (base instanceof IType) { - IType specBase = CPPTemplates.instantiateType((IType) base, argumentMap); - specBase = CPPSemantics.getUltimateType(specBase, false); - if (specBase instanceof IBinding) { - ((ICPPInternalBase)specBinding).setBaseClass((IBinding)specBase); - } - result = (ICPPBase[]) ArrayUtil.append(ICPPBase.class, result, specBinding); - } + IBinding base = bindings[i].getBaseClass(); + if (base instanceof IType) { + IType specBase = CPPTemplates.instantiateType((IType) base, argumentMap); + specBase = CPPSemantics.getUltimateType(specBase, false); + if (specBase instanceof IBinding) { + ((ICPPInternalBase)specBinding).setBaseClass((IBinding)specBase); + } + result = (ICPPBase[]) ArrayUtil.append(ICPPBase.class, result, specBinding); + } } return (ICPPBase[]) ArrayUtil.trim(ICPPBase.class, result); } @@ -172,42 +171,51 @@ public class CPPClassInstance extends CPPInstance implements ICPPClassType, ICPP return new CPPClassType.CPPClassTypeDelegate( name, this ); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IType#isSameType(org.eclipse.cdt.core.dom.ast.IType) - */ - public boolean isSameType( IType type ) { - if( type == this ) - return true; - if( type instanceof ITypedef || type instanceof IIndexType ) - return type.isSameType( this ); - if( type instanceof ICPPDeferredTemplateInstance && type instanceof ICPPClassType ) - return type.isSameType( this ); //the CPPDeferredClassInstance has some fuzziness - - if( type instanceof ICPPTemplateInstance ){ - ICPPClassType ct1= (ICPPClassType) getSpecializedBinding(); - ICPPClassType ct2= (ICPPClassType) ((ICPPTemplateInstance)type).getTemplateDefinition(); - if(!ct1.isSameType(ct2)) - return false; - - ObjectMap m1 = getArgumentMap(), m2 = ((ICPPTemplateInstance)type).getArgumentMap(); - if( m1 == null || m2 == null || m1.size() != m2.size()) - return false; - for( int i = 0; i < m1.size(); i++ ){ - IType t1 = (IType) m1.getAt( i ); - IType t2 = (IType) m2.getAt( i ); - if( t1 == null || ! t1.isSameType( t2 ) ) - return false; - } - return true; - } + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IType#isSameType(org.eclipse.cdt.core.dom.ast.IType) + */ + public boolean isSameType( IType type ) { + if( type == this ) + return true; + if( type instanceof ITypedef || type instanceof IIndexType ) + return type.isSameType( this ); + if( type instanceof ICPPDeferredTemplateInstance && type instanceof ICPPClassType ) + return type.isSameType( this ); //the CPPDeferredClassInstance has some fuzziness - return false; - } + if( type instanceof ICPPTemplateInstance ){ + ICPPClassType ct1= (ICPPClassType) getSpecializedBinding(); + ICPPClassType ct2= (ICPPClassType) ((ICPPTemplateInstance)type).getTemplateDefinition(); + if(!ct1.isSameType(ct2)) + return false; + + ObjectMap m1 = getArgumentMap(), m2 = ((ICPPTemplateInstance)type).getArgumentMap(); + if( m1 == null || m2 == null || m1.size() != m2.size()) + return false; + for( int i = 0; i < m1.size(); i++ ){ + IType t1 = (IType) m1.getAt( i ); + IType t2 = (IType) m2.getAt( i ); + if( t1 == null || ! t1.isSameType( t2 ) ) + return false; + } + return true; + } + + return false; + } public ICPPClassType[] getNestedClasses() throws DOMException { 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; + } + public boolean equals(Object obj) { return obj instanceof ICPPClassType ? isSameType((ICPPClassType)obj) : false; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java index 088b7b23aaa..7a741a3249a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java @@ -405,7 +405,7 @@ class ImplicitsAnalysis { ICPPASTFunctionDeclarator dcltor= ctors[i]; IASTParameterDeclaration [] ps = dcltor.getParameters(); if( ps.length >= 1 ){ - if(paramHasTypeReferenceToTheAssociatedClassType(ps[0])) { + if(paramHasTypeReferenceToTheAssociatedClassType(ps[0], compSpec.getName().getRawSignature())) { // and all remaining arguments have initialisers for(int j=1; j result= new ArrayList(); IASTDeclaration [] members = compSpec.getMembers(); char [] name = compSpec.getName().toCharArray(); IASTDeclarator dcltor = null; @@ -466,13 +466,13 @@ class ImplicitsAnalysis { if(!nameEquals) continue; - result.add(dcltor); + result.add((ICPPASTFunctionDeclarator) dcltor); } - return (ICPPASTFunctionDeclarator[]) result.toArray(new ICPPASTFunctionDeclarator[result.size()]); + return result.toArray(new ICPPASTFunctionDeclarator[result.size()]); } private static ICPPASTFunctionDeclarator[] getUserDeclaredCopyAssignmentOperators( ICPPASTCompositeTypeSpecifier compSpec ) { - List result= new ArrayList(); + List result= new ArrayList(); IASTDeclaration [] members = compSpec.getMembers(); IASTDeclarator dcltor = null; for( int i = 0; i < members.length; i++ ){ @@ -491,20 +491,29 @@ class ImplicitsAnalysis { } IASTParameterDeclaration [] ps = ((ICPPASTFunctionDeclarator)dcltor).getParameters(); - if( ps.length != 1 || !paramHasTypeReferenceToTheAssociatedClassType(ps[0]) ) + if(ps.length != 1 || !paramHasTypeReferenceToTheAssociatedClassType(ps[0], null)) continue; - result.add(dcltor); + result.add((ICPPASTFunctionDeclarator)dcltor); } - return (ICPPASTFunctionDeclarator[]) result.toArray(new ICPPASTFunctionDeclarator[result.size()]); + return result.toArray(new ICPPASTFunctionDeclarator[result.size()]); } - private static boolean paramHasTypeReferenceToTheAssociatedClassType(IASTParameterDeclaration dec) { + /** + * @param compSpec the name the parameter must have in order to match, or null for any name + * @param dec + * @return whether the specified parameter is a reference to the associated class type, and + * (optionally) if it has the specified name + */ + private static boolean paramHasTypeReferenceToTheAssociatedClassType(IASTParameterDeclaration dec, String name) { boolean result= false; IASTDeclarator pdtor= dec.getDeclarator(); if(pdtor.getPointerOperators().length==1 && pdtor.getPointerOperators()[0] instanceof ICPPASTReferenceOperator) { if(dec.getDeclSpecifier() instanceof ICPPASTNamedTypeSpecifier) { - result= true; + ICPPASTNamedTypeSpecifier nts= (ICPPASTNamedTypeSpecifier) dec.getDeclSpecifier(); + if(name==null || name.equals(nts.getName().getRawSignature())) { + result= true; + } } } return result; 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 a7862020e60..be4430af21e 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 @@ -10,9 +10,6 @@ * Markus Schorn (Wind River Systems) * Bryan Wilkinson (QNX) *******************************************************************************/ -/* - * Created on Mar 28, 2005 - */ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.IName; @@ -145,7 +142,7 @@ public class CPPClassSpecializationScope implements ICPPClassScope, IASTInternal return (ICPPConstructor[]) ArrayUtil.trim(ICPPConstructor.class, specs); } - protected ICPPMethod[] getConversionOperators() { + protected ICPPMethod[] getConversionOperators() throws DOMException { ICPPClassType specialized = (ICPPClassType) specialization.getSpecializedBinding(); if (!(specialized instanceof ICPPInternalClassType)) { 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 98f32d7c83d..1adca731eeb 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 @@ -9,23 +9,19 @@ * IBM - Initial API and implementation * Bryan Wilkinson (QNX) * Markus Schorn (Wind River Systems) + * Andrew Ferguson (Symbian) *******************************************************************************/ -/* - * Created on Mar 31, 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.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; -import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; 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.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; @@ -35,9 +31,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; -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.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; @@ -47,67 +41,62 @@ 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.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; -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.CharArrayUtils; -import org.eclipse.cdt.core.parser.util.ObjectSet; -import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; -import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassType.CPPClassTypeProblem; import org.eclipse.cdt.internal.core.index.IIndexType; /** + * * @author aniefer */ public class CPPClassTemplate extends CPPTemplateDefinition implements - ICPPClassTemplate, ICPPClassType, ICPPInternalClassType, ICPPInternalClassTemplate { - - public static class CPPClassTemplateDelegate extends CPPClassType.CPPClassTypeDelegate implements ICPPClassTemplate, ICPPInternalClassTemplate { - public CPPClassTemplateDelegate( IASTName name, ICPPClassType cls ) { - super( name, cls ); - } - public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() throws DOMException { - return ((ICPPClassTemplate)getBinding()).getPartialSpecializations(); - } - public ICPPTemplateParameter[] getTemplateParameters() throws DOMException { - return ((ICPPClassTemplate)getBinding()).getTemplateParameters(); - } - public void addSpecialization( IType[] arguments, ICPPSpecialization specialization ) { - final IBinding binding = getBinding(); - if (binding instanceof ICPPInternalBinding) { - ((ICPPInternalTemplate)binding).addSpecialization( arguments, specialization ); - } - } - public IBinding instantiate( IType[] arguments ) { - return ((ICPPInternalTemplateInstantiator)getBinding()).instantiate( arguments ); - } - public ICPPSpecialization deferredInstance( IType[] arguments ) { - return ((ICPPInternalTemplateInstantiator)getBinding()).deferredInstance( arguments ); - } - public ICPPSpecialization getInstance( IType[] arguments ) { - return ((ICPPInternalTemplateInstantiator)getBinding()).getInstance( arguments ); - } - public void addPartialSpecialization( ICPPClassTemplatePartialSpecialization spec ) { - final IBinding binding = getBinding(); - if (binding instanceof ICPPInternalClassTemplate) { - ((ICPPInternalClassTemplate)getBinding()).addPartialSpecialization( spec ); - } +ICPPClassTemplate, ICPPClassType, ICPPInternalClassType, ICPPInternalClassTemplate, ICPPInternalClassTypeMixinHost { + + public static class CPPClassTemplateDelegate extends CPPClassType.CPPClassTypeDelegate implements ICPPClassTemplate, ICPPInternalClassTemplate { + public CPPClassTemplateDelegate( IASTName name, ICPPClassType cls ) { + super( name, cls ); } - } - private ICPPClassTemplatePartialSpecialization [] partialSpecializations = null; - + public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() throws DOMException { + return ((ICPPClassTemplate)getBinding()).getPartialSpecializations(); + } + public ICPPTemplateParameter[] getTemplateParameters() throws DOMException { + return ((ICPPClassTemplate)getBinding()).getTemplateParameters(); + } + public void addSpecialization( IType[] arguments, ICPPSpecialization specialization ) { + final IBinding binding = getBinding(); + if (binding instanceof ICPPInternalBinding) { + ((ICPPInternalTemplate)binding).addSpecialization( arguments, specialization ); + } + } + public IBinding instantiate( IType[] arguments ) { + return ((ICPPInternalTemplateInstantiator)getBinding()).instantiate( arguments ); + } + public ICPPSpecialization deferredInstance( IType[] arguments ) { + return ((ICPPInternalTemplateInstantiator)getBinding()).deferredInstance( arguments ); + } + public ICPPSpecialization getInstance( IType[] arguments ) { + return ((ICPPInternalTemplateInstantiator)getBinding()).getInstance( arguments ); + } + public void addPartialSpecialization( ICPPClassTemplatePartialSpecialization spec ) { + final IBinding binding = getBinding(); + if (binding instanceof ICPPInternalClassTemplate) { + ((ICPPInternalClassTemplate)getBinding()).addPartialSpecialization( spec ); + } + } + } + private class FindDefinitionAction extends CPPASTVisitor { - private char [] nameArray = CPPClassTemplate.this.getNameCharArray(); - public IASTName result = null; - - { - shouldVisitNames = true; + private char [] nameArray = CPPClassTemplate.this.getNameCharArray(); + public IASTName result = null; + + { + shouldVisitNames = true; shouldVisitDeclarations = true; shouldVisitDeclSpecifiers = true; shouldVisitDeclarators = true; - } - - public int visit( IASTName name ){ + } + + public int visit( IASTName name ){ if( name instanceof ICPPASTTemplateId || name instanceof ICPPASTQualifiedName ) return PROCESS_CONTINUE; char [] c = name.toCharArray(); @@ -119,38 +108,40 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements return PROCESS_CONTINUE; name = (IASTName) name.getParent(); } - - if( name.getParent() instanceof ICPPASTCompositeTypeSpecifier && - CharArrayUtils.equals( c, nameArray ) ) - { - IBinding binding = name.resolveBinding(); - if( binding == CPPClassTemplate.this ){ - if( name instanceof ICPPASTQualifiedName ){ - IASTName [] ns = ((ICPPASTQualifiedName)name).getNames(); - name = ns[ ns.length - 1 ]; - } - result = name; - return PROCESS_ABORT; - } - } - return PROCESS_CONTINUE; - } - + + if( name.getParent() instanceof ICPPASTCompositeTypeSpecifier && + CharArrayUtils.equals( c, nameArray ) ) + { + IBinding binding = name.resolveBinding(); + if( binding == CPPClassTemplate.this ){ + if( name instanceof ICPPASTQualifiedName ){ + IASTName [] ns = ((ICPPASTQualifiedName)name).getNames(); + name = ns[ ns.length - 1 ]; + } + result = name; + return PROCESS_ABORT; + } + } + return PROCESS_CONTINUE; + } + public int visit( IASTDeclaration declaration ){ - if(declaration instanceof IASTSimpleDeclaration || declaration instanceof ICPPASTTemplateDeclaration ) + if(declaration instanceof IASTSimpleDeclaration || declaration instanceof ICPPASTTemplateDeclaration) return PROCESS_CONTINUE; return PROCESS_SKIP; } public int visit( IASTDeclSpecifier declSpec ){ - return (declSpec instanceof ICPPASTCompositeTypeSpecifier ) ? PROCESS_CONTINUE : PROCESS_SKIP; + return (declSpec instanceof ICPPASTCompositeTypeSpecifier ) ? PROCESS_CONTINUE : PROCESS_SKIP; } public int visit( IASTDeclarator declarator ) { return PROCESS_SKIP; } } - /** - * @param decl - */ - public CPPClassTemplate(IASTName name) { + + private ICPPClassTemplatePartialSpecialization [] partialSpecializations = null; + private ClassTypeMixin mixin; + + public CPPClassTemplate(IASTName name) { super(name); + this.mixin= new ClassTypeMixin(this); } public ICPPSpecialization deferredInstance( IType [] arguments ){ @@ -161,310 +152,43 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements } return instance; } - - private void checkForDefinition(){ + + public void checkForDefinition(){ FindDefinitionAction action = new FindDefinitionAction(); IASTNode node = CPPVisitor.getContainingBlockItem( declarations[0] ).getParent(); while( node instanceof ICPPASTTemplateDeclaration ) node = node.getParent(); node.accept( action ); - definition = action.result; - + definition = action.result; + if( definition == null ){ node.getTranslationUnit().accept( action ); - definition = action.result; + definition = action.result; } - + return; } public void addPartialSpecialization( ICPPClassTemplatePartialSpecialization spec ){ partialSpecializations = (ICPPClassTemplatePartialSpecialization[]) ArrayUtil.append( ICPPClassTemplatePartialSpecialization.class, partialSpecializations, spec ); } - - private ICPPASTCompositeTypeSpecifier getCompositeTypeSpecifier(){ - if( definition != null ){ - IASTNode node = definition.getParent(); - if( node instanceof ICPPASTQualifiedName ) - node = node.getParent(); - if( node instanceof ICPPASTCompositeTypeSpecifier ) - return (ICPPASTCompositeTypeSpecifier) node; - } - return null; - } - /** - * @param templateParameter - * @return - */ - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getBases() - */ - public ICPPBase [] getBases() { - if( definition == null ){ - checkForDefinition(); - if( definition == null ){ - IASTName node = (declarations != null && declarations.length > 0) ? declarations[0] : null; - return new ICPPBase [] { new CPPBaseClause.CPPBaseProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) }; - } - } - ICPPASTBaseSpecifier [] bases = getCompositeTypeSpecifier().getBaseSpecifiers(); - if( bases.length == 0 ) - return ICPPBase.EMPTY_BASE_ARRAY; - - ICPPBase [] bindings = new ICPPBase[ bases.length ]; - for( int i = 0; i < bases.length; i++ ){ - bindings[i] = new CPPBaseClause( bases[i] ); + + public ICPPASTCompositeTypeSpecifier getCompositeTypeSpecifier(){ + if( definition != null ){ + IASTNode node = definition.getParent(); + if( node instanceof ICPPASTQualifiedName ) + node = node.getParent(); + if( node instanceof ICPPASTCompositeTypeSpecifier ) + return (ICPPASTCompositeTypeSpecifier) node; } - - return bindings; + return null; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.ICompositeType#getFields() - */ - public IField[] getFields() throws DOMException { - if( definition == null ){ - checkForDefinition(); - if( definition == null ){ - IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; - return new IField [] { new CPPField.CPPFieldProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) }; - } - } - - IField[] fields = getDeclaredFields(); - ICPPBase [] bases = getBases(); - for ( int i = 0; i < bases.length; i++ ) { - IBinding b = bases[i].getBaseClass(); - if( b instanceof ICPPClassType ) - fields = (IField[]) ArrayUtil.addAll( IField.class, fields, ((ICPPClassType)b).getFields() ); - } - return (IField[]) ArrayUtil.trim( IField.class, fields ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.ICompositeType#findField(java.lang.String) - */ - public IField findField(String name) throws DOMException { - IBinding [] bindings = CPPSemantics.findBindings( getCompositeScope(), name, true ); - IField field = null; - for ( int i = 0; i < bindings.length; i++ ) { - if( bindings[i] instanceof IField ){ - if( field == null ) - field = (IField) bindings[i]; - else { - IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; - return new CPPField.CPPFieldProblem( node, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, name.toCharArray() ); - } - } - } - return field; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getDeclaredFields() - */ - public ICPPField[] getDeclaredFields() throws DOMException { - if( definition == null ){ - checkForDefinition(); - if( definition == null ){ - IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; - return new ICPPField[] { new CPPField.CPPFieldProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) }; - } - } - IBinding binding = null; - ICPPField [] result = null; - - IASTDeclaration [] decls = getCompositeTypeSpecifier().getMembers(); - 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++ ) { - binding = dtors[j].getName().resolveBinding(); - if( binding instanceof ICPPField ) - result = (ICPPField[]) ArrayUtil.append( ICPPField.class, result, binding ); - } - } else if( decls[i] instanceof ICPPASTUsingDeclaration ){ - IASTName n = ((ICPPASTUsingDeclaration)decls[i]).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 ICPPField ) - result = (ICPPField[]) ArrayUtil.append( ICPPField.class, result, bs[j] ); - } - } else if( binding instanceof ICPPField ) { - result = (ICPPField[]) ArrayUtil.append( ICPPField.class, result, binding ); - } - } - } - return (ICPPField[]) ArrayUtil.trim( ICPPField.class, result ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getMethods() - */ - public ICPPMethod[] getMethods() throws DOMException { - ObjectSet set = new ObjectSet(4); - set.addAll( getDeclaredMethods() ); - ICPPClassScope scope = (ICPPClassScope) getCompositeScope(); - set.addAll( scope.getImplicitMethods() ); - ICPPBase [] bases = getBases(); - for ( int i = 0; i < bases.length; i++ ) { - IBinding b = bases[i].getBaseClass(); - if( b instanceof ICPPClassType ) - set.addAll( ((ICPPClassType)b).getMethods() ); - } - return (ICPPMethod[]) set.keyArray( ICPPMethod.class ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getAllDeclaredMethods() - */ - public ICPPMethod[] getAllDeclaredMethods() throws DOMException { - if( definition == null ){ - checkForDefinition(); - if( definition == null ){ - IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; - return new ICPPMethod [] { new CPPMethod.CPPMethodProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) }; - } - } - - ICPPMethod[] methods = getDeclaredMethods(); - ICPPBase [] bases = getBases(); - for ( int i = 0; i < bases.length; i++ ) { - IBinding b = bases[i].getBaseClass(); - if( b instanceof ICPPClassType ) - methods = (ICPPMethod[]) ArrayUtil.addAll( ICPPMethod.class, methods, ((ICPPClassType)b).getAllDeclaredMethods() ); - } - return (ICPPMethod[]) ArrayUtil.trim( ICPPMethod.class, methods ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getDeclaredMethods() - */ - public ICPPMethod[] getDeclaredMethods() throws DOMException { - if( definition == null ){ - checkForDefinition(); - if( definition == null ){ - IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; - return new ICPPMethod[] { new CPPMethod.CPPMethodProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) }; - } - } - 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) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getConstructors() - */ - public ICPPConstructor[] getConstructors() throws DOMException { - if( definition == null ){ - checkForDefinition(); - if( definition == null ){ - IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; - return new ICPPConstructor [] { new CPPConstructor.CPPConstructorProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) }; - } - } - - ICPPClassScope scope = (ICPPClassScope) getCompositeScope(); - if( ASTInternal.isFullyCached(scope)) - return ((CPPClassScope)scope).getConstructors( true ); - - IASTDeclaration [] members = getCompositeTypeSpecifier().getMembers(); - for( int i = 0; i < members.length; i++ ){ - IASTDeclaration decl = members[i]; - if( decl instanceof ICPPASTTemplateDeclaration ) - decl = ((ICPPASTTemplateDeclaration)decl).getDeclaration(); - if( decl instanceof IASTSimpleDeclaration ){ - IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decl).getDeclarators(); - for( int j = 0; j < dtors.length; j++ ){ - if( dtors[j] == null ) break; - ASTInternal.addName(scope, dtors[j].getName() ); - } - } else if( decl instanceof IASTFunctionDefinition ){ - IASTDeclarator dtor = ((IASTFunctionDefinition)decl).getDeclarator(); - ASTInternal.addName(scope, dtor.getName() ); - } - } - - return ((CPPClassScope)scope).getConstructors( true ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getFriends() - */ - public IBinding[] getFriends() { - //TODO - return IBinding.EMPTY_BINDING_ARRAY; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.ICompositeType#getKey() - */ - public int getKey() { - if( definition != null ) { - ICPPASTCompositeTypeSpecifier cts= getCompositeTypeSpecifier(); - if (cts != null) { - return cts.getKey(); - } - IASTNode n= definition.getParent(); - if (n instanceof ICPPASTElaboratedTypeSpecifier) { - return ((ICPPASTElaboratedTypeSpecifier)n).getKind(); - } - } - - if( declarations != null && declarations.length > 0 ){ - IASTNode n = declarations[0].getParent(); - if( n instanceof ICPPASTElaboratedTypeSpecifier ){ - return ((ICPPASTElaboratedTypeSpecifier)n).getKind(); - } - } - - return ICPPASTElaboratedTypeSpecifier.k_class; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.ICompositeType#getCompositeScope() - */ public IScope getCompositeScope() { - if( definition == null ) - checkForDefinition(); - if( definition != null ) { + if (definition == null) { + checkForDefinition(); + } + if (definition != null) { IASTNode parent = definition.getParent(); while (parent instanceof IASTName) parent = parent.getParent(); @@ -476,9 +200,93 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements return null; } - /* (non-Javadoc) - * @see java.lang.Object#clone() - */ + public int getKey() { + if( definition != null ) { + ICPPASTCompositeTypeSpecifier cts= getCompositeTypeSpecifier(); + if (cts != null) { + return cts.getKey(); + } + IASTNode n= definition.getParent(); + if (n instanceof ICPPASTElaboratedTypeSpecifier) { + return ((ICPPASTElaboratedTypeSpecifier)n).getKind(); + } + } + + if( declarations != null && declarations.length > 0 ){ + IASTNode n = declarations[0].getParent(); + if( n instanceof ICPPASTElaboratedTypeSpecifier ){ + return ((ICPPASTElaboratedTypeSpecifier)n).getKind(); + } + } + + return ICPPASTElaboratedTypeSpecifier.k_class; + } + + + + public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() { + partialSpecializations = (ICPPClassTemplatePartialSpecialization[]) ArrayUtil.trim( ICPPClassTemplatePartialSpecialization.class, partialSpecializations ); + return partialSpecializations; + } + + public ICPPDelegate createDelegate( IASTName name ) { + return new CPPClassTemplateDelegate( name, this ); + } + + /* */ + + public boolean isSameType( IType type ) { + if (type == this) + return true; + if (type instanceof ITypedef || type instanceof IIndexType || type instanceof ICPPDelegate) + return type.isSameType(this); + return false; + } + + public ICPPBase [] getBases() { + return mixin.getBases(); + } + + public IField[] getFields() throws DOMException { + return mixin.getFields(); + } + + public ICPPField[] getDeclaredFields() throws DOMException { + return mixin.getDeclaredFields(); + } + + public ICPPMethod[] getConversionOperators() throws DOMException { + return mixin.getConversionOperators(); + } + + public ICPPMethod[] getMethods() throws DOMException { + return mixin.getMethods(); + } + + public ICPPMethod[] getAllDeclaredMethods() throws DOMException { + return mixin.getAllDeclaredMethods(); + } + + public ICPPMethod[] getDeclaredMethods() throws DOMException { + return mixin.getDeclaredMethods(); + } + + public ICPPConstructor[] getConstructors() throws DOMException { + return mixin.getConstructors(); + } + + public IBinding[] getFriends() { + return mixin.getFriends(); + } + + public ICPPClassType[] getNestedClasses() { + return mixin.getNestedClasses(); + } + + public IField findField(String name) throws DOMException { + return mixin.findField(name); + } + public Object clone() { try { return super.clone(); @@ -486,66 +294,4 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements } return null; } - - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalClassType#getConversionOperators() - */ - public ICPPMethod[] getConversionOperators() { - return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IType#isSameType(org.eclipse.cdt.core.dom.ast.IType) - */ - public boolean isSameType( IType type ) { - if( type == this ) - return true; - if( type instanceof ITypedef || type instanceof IIndexType) - return type.isSameType( this ); - return false; - } - - public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() { - partialSpecializations = (ICPPClassTemplatePartialSpecialization[]) ArrayUtil.trim( ICPPClassTemplatePartialSpecialization.class, partialSpecializations ); - return partialSpecializations; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#createDelegate(org.eclipse.cdt.core.dom.ast.IASTName) - */ - public ICPPDelegate createDelegate( IASTName name ) { - return new CPPClassTemplateDelegate( name, this ); - } - - public ICPPClassType[] getNestedClasses() { - if( definition == null ){ - checkForDefinition(); - if( definition == null ){ - IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; - return new ICPPClassType[] { new CPPClassTypeProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) }; - } - } - IBinding binding = null; - ICPPClassType [] 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 ){ - IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration) decl).getDeclSpecifier(); - if( declSpec instanceof ICPPASTCompositeTypeSpecifier ){ - binding = ((ICPPASTCompositeTypeSpecifier)declSpec).getName().resolveBinding(); - } else if( declSpec instanceof ICPPASTElaboratedTypeSpecifier && - ((IASTSimpleDeclaration)decl).getDeclarators().length == 0 ) - { - binding = ((ICPPASTElaboratedTypeSpecifier)declSpec).getName().resolveBinding(); - } - if( binding instanceof ICPPClassType ) - result = (ICPPClassType[])ArrayUtil.append( ICPPClassType.class, result, binding ); - } - } - return (ICPPClassType[]) ArrayUtil.trim( ICPPClassType.class, result ); - } } 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 3a92214987e..07a6e3552a2 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 @@ -11,9 +11,6 @@ * Bryan Wilkinson (QNX) * Sergey Prigogin (Google) *******************************************************************************/ -/* - * Created on Nov 29, 2004 - */ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ILinkage; @@ -29,19 +26,15 @@ import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; 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.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.CPPASTVisitor; 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.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; -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.ICPPBlockScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; @@ -51,85 +44,82 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArrayUtils; -import org.eclipse.cdt.core.parser.util.ObjectSet; import org.eclipse.cdt.internal.core.dom.Linkage; -import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.index.IIndexType; import org.eclipse.core.runtime.PlatformObject; /** + * * @author aniefer */ -public class CPPClassType extends PlatformObject implements ICPPClassType, ICPPInternalClassType { - public static class CPPClassTypeDelegate extends CPPDelegate implements ICPPClassType, ICPPInternalClassType { - public CPPClassTypeDelegate( IASTName name, ICPPClassType cls ){ - super( name, cls ); - } - public ICPPBase[] getBases() throws DOMException { - return ((ICPPClassType)getBinding()).getBases(); - } - public IField[] getFields() throws DOMException { - return ((ICPPClassType)getBinding()).getFields(); - } - public IField findField( String name ) throws DOMException { - return ((ICPPClassType)getBinding()).findField( name ); - } - public ICPPField[] getDeclaredFields() throws DOMException { - return ((ICPPClassType)getBinding()).getDeclaredFields(); - } - public ICPPMethod[] getMethods() throws DOMException { - return ((ICPPClassType)getBinding()).getMethods(); - } - public ICPPMethod[] getAllDeclaredMethods() throws DOMException { - return ((ICPPClassType)getBinding()).getAllDeclaredMethods(); - } - public ICPPMethod[] getDeclaredMethods() throws DOMException { - return ((ICPPClassType)getBinding()).getDeclaredMethods(); - } - public ICPPConstructor[] getConstructors() throws DOMException { - return ((ICPPClassType)getBinding()).getConstructors(); - } - public IBinding[] getFriends() throws DOMException { - return ((ICPPClassType)getBinding()).getFriends(); - } - public int getKey() throws DOMException { - return ((ICPPClassType)getBinding()).getKey(); - } - public IScope getCompositeScope() throws DOMException { - return ((ICPPClassType)getBinding()).getCompositeScope(); - } - public Object clone() { - CPPClassTypeDelegate d = null; - try { - d = (CPPClassTypeDelegate) super.clone(); - } catch ( CloneNotSupportedException e ) { - } - return d; - } - public ICPPMethod[] getConversionOperators() { +public class CPPClassType extends PlatformObject implements ICPPInternalClassTypeMixinHost, ICPPClassType, ICPPInternalClassType { + public static class CPPClassTypeDelegate extends CPPDelegate implements ICPPClassType, ICPPInternalClassType { + public CPPClassTypeDelegate( IASTName name, ICPPClassType cls ){ + super( name, cls ); + } + public ICPPBase[] getBases() throws DOMException { + return ((ICPPClassType)getBinding()).getBases(); + } + public IField[] getFields() throws DOMException { + return ((ICPPClassType)getBinding()).getFields(); + } + public IField findField( String name ) throws DOMException { + return ((ICPPClassType)getBinding()).findField( name ); + } + public ICPPField[] getDeclaredFields() throws DOMException { + return ((ICPPClassType)getBinding()).getDeclaredFields(); + } + public ICPPMethod[] getMethods() throws DOMException { + return ((ICPPClassType)getBinding()).getMethods(); + } + public ICPPMethod[] getAllDeclaredMethods() throws DOMException { + return ((ICPPClassType)getBinding()).getAllDeclaredMethods(); + } + public ICPPMethod[] getDeclaredMethods() throws DOMException { + return ((ICPPClassType)getBinding()).getDeclaredMethods(); + } + public ICPPConstructor[] getConstructors() throws DOMException { + return ((ICPPClassType)getBinding()).getConstructors(); + } + public IBinding[] getFriends() throws DOMException { + return ((ICPPClassType)getBinding()).getFriends(); + } + public int getKey() throws DOMException { + return ((ICPPClassType)getBinding()).getKey(); + } + public IScope getCompositeScope() throws DOMException { + return ((ICPPClassType)getBinding()).getCompositeScope(); + } + public Object clone() { + CPPClassTypeDelegate d = null; + try { + d = (CPPClassTypeDelegate) super.clone(); + } catch ( CloneNotSupportedException e ) { + } + return d; + } + public ICPPMethod[] getConversionOperators() throws DOMException { IBinding binding = getBinding(); if( binding instanceof ICPPInternalClassType ) return ((ICPPInternalClassType)binding).getConversionOperators(); return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; } - public boolean isSameType( IType type ) { - return ((ICPPClassType)getBinding()).isSameType( type ); - } + public boolean isSameType( IType type ) { + return ((ICPPClassType)getBinding()).isSameType( type ); + } public ICPPClassType[] getNestedClasses() throws DOMException { return ((ICPPClassType)getBinding()).getNestedClasses(); } - } + } public static class CPPClassTypeProblem extends ProblemBinding implements ICPPClassType{ - public CPPClassTypeProblem( IASTNode node, int id, char[] arg ) { - super( node, id, arg ); - } + public CPPClassTypeProblem( IASTNode node, int id, char[] arg ) { + super( node, id, arg ); + } public ICPPBase[] getBases() throws DOMException { throw new DOMException( this ); @@ -167,72 +157,35 @@ public class CPPClassType extends PlatformObject implements ICPPClassType, ICPPI public IBinding[] find(String name) throws DOMException { throw new DOMException( this ); } - public IBinding[] getFriends() throws DOMException { + public IBinding[] getFriends() throws DOMException { throw new DOMException( this ); - } - public String[] getQualifiedName() throws DOMException { - throw new DOMException( this ); - } - public char[][] getQualifiedNameCharArray() throws DOMException { - throw new DOMException( this ); - } - public boolean isGloballyQualified() throws DOMException { - throw new DOMException( this ); - } + } + public String[] getQualifiedName() throws DOMException { + throw new DOMException( this ); + } + public char[][] getQualifiedNameCharArray() throws DOMException { + throw new DOMException( this ); + } + public boolean isGloballyQualified() throws DOMException { + throw new DOMException( this ); + } public ICPPClassType[] getNestedClasses() throws DOMException { throw new DOMException( this ); } - } - - private IASTName definition; - private IASTName [] declarations; - private boolean checked = false; - private ICPPClassType typeInIndex; - public CPPClassType( IASTName name, IBinding indexBinding ){ - if( name instanceof ICPPASTQualifiedName ){ - IASTName [] ns = ((ICPPASTQualifiedName)name).getNames(); - name = ns[ ns.length - 1 ]; - } - IASTNode parent = name.getParent(); - while( parent instanceof IASTName ) - parent = parent.getParent(); - - if( parent instanceof IASTCompositeTypeSpecifier ) - definition = name; - else - declarations = new IASTName[] { name }; - name.setBinding( this ); - if (indexBinding instanceof ICPPClassType && indexBinding instanceof IIndexBinding) { - typeInIndex= (ICPPClassType) indexBinding; - } } - - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPBinding#getDeclarations() - */ - public IASTNode[] getDeclarations() { - return declarations; - } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPBinding#getDefinition() - */ - public IASTNode getDefinition() { - return definition; - } - private class FindDefinitionAction extends CPPASTVisitor { - private char [] nameArray = CPPClassType.this.getNameCharArray(); - public IASTName result = null; - - { - shouldVisitNames = true; + private char [] nameArray = CPPClassType.this.getNameCharArray(); + public IASTName result = null; + + { + shouldVisitNames = true; shouldVisitDeclarations = true; shouldVisitDeclSpecifiers = true; shouldVisitDeclarators = true; - } - - public int visit( IASTName name ){ + } + + public int visit( IASTName name ){ if( name instanceof ICPPASTTemplateId ) return PROCESS_SKIP; if( name instanceof ICPPASTQualifiedName ) @@ -245,157 +198,140 @@ public class CPPClassType extends PlatformObject implements ICPPClassType, ICPPI return PROCESS_CONTINUE; name = (IASTName) name.getParent(); } - - if( name.getParent() instanceof ICPPASTCompositeTypeSpecifier && - CharArrayUtils.equals( c, nameArray ) ) - { - IBinding binding = name.resolveBinding(); - if( binding == CPPClassType.this ){ - if( name instanceof ICPPASTQualifiedName ){ - IASTName [] ns = ((ICPPASTQualifiedName)name).getNames(); - name = ns[ ns.length - 1 ]; - } - result = name; - return PROCESS_ABORT; - } - } - return PROCESS_CONTINUE; - } - + + if( name.getParent() instanceof ICPPASTCompositeTypeSpecifier && + CharArrayUtils.equals( c, nameArray ) ) + { + IBinding binding = name.resolveBinding(); + if( binding == CPPClassType.this ){ + if( name instanceof ICPPASTQualifiedName ){ + IASTName [] ns = ((ICPPASTQualifiedName)name).getNames(); + name = ns[ ns.length - 1 ]; + } + result = name; + return PROCESS_ABORT; + } + } + return PROCESS_CONTINUE; + } + public int visit( IASTDeclaration declaration ){ - if( declaration instanceof IASTSimpleDeclaration || declaration instanceof ICPPASTTemplateDeclaration ) + if(declaration instanceof IASTSimpleDeclaration || declaration instanceof ICPPASTTemplateDeclaration) return PROCESS_CONTINUE; return PROCESS_SKIP; } public int visit( IASTDeclSpecifier declSpec ){ - return (declSpec instanceof ICPPASTCompositeTypeSpecifier ) ? PROCESS_CONTINUE : PROCESS_SKIP; + return (declSpec instanceof ICPPASTCompositeTypeSpecifier ) ? PROCESS_CONTINUE : PROCESS_SKIP; } public int visit( IASTDeclarator declarator ) { return PROCESS_SKIP; } } - - private void checkForDefinition(){ + + private IASTName definition; + private IASTName [] declarations; + private boolean checked = false; + private ICPPClassType typeInIndex; + private ClassTypeMixin mixin; + + public CPPClassType( IASTName name, IBinding indexBinding ){ + if( name instanceof ICPPASTQualifiedName ){ + IASTName [] ns = ((ICPPASTQualifiedName)name).getNames(); + name = ns[ ns.length - 1 ]; + } + IASTNode parent = name.getParent(); + while( parent instanceof IASTName ) + parent = parent.getParent(); + + if( parent instanceof IASTCompositeTypeSpecifier ) + definition = name; + else + declarations = new IASTName[] { name }; + name.setBinding( this ); + if (indexBinding instanceof ICPPClassType && indexBinding instanceof IIndexBinding) { + typeInIndex= (ICPPClassType) indexBinding; + } + mixin= new ClassTypeMixin(this); + } + + public IASTNode[] getDeclarations() { + return declarations; + } + + public IASTNode getDefinition() { + return definition; + } + + public void checkForDefinition(){ if( !checked ) { FindDefinitionAction action = new FindDefinitionAction(); IASTNode node = CPPVisitor.getContainingBlockItem( getPhysicalNode() ).getParent(); - + if( node instanceof ICPPASTCompositeTypeSpecifier ) node = CPPVisitor.getContainingBlockItem( node.getParent() ); while( node instanceof ICPPASTTemplateDeclaration ) node = node.getParent(); node.accept( action ); - definition = action.result; - + definition = action.result; + if( definition == null ){ node.getTranslationUnit().accept( action ); - definition = action.result; + definition = action.result; } checked = true; } return; } + + public ICPPASTCompositeTypeSpecifier getCompositeTypeSpecifier(){ + if( definition != null ){ + IASTNode node = definition; + while( node instanceof IASTName ) + node = node.getParent(); + if( node instanceof ICPPASTCompositeTypeSpecifier ) + return (ICPPASTCompositeTypeSpecifier)node; + } + return null; + } - private ICPPASTCompositeTypeSpecifier getCompositeTypeSpecifier(){ - if( definition != null ){ - IASTNode node = definition; - while( node instanceof IASTName ) - node = node.getParent(); - if( node instanceof ICPPASTCompositeTypeSpecifier ) - return (ICPPASTCompositeTypeSpecifier)node; - } - return null; - } private ICPPASTElaboratedTypeSpecifier getElaboratedTypeSpecifier() { - if( declarations != null ){ - IASTNode node = declarations[0]; - while( node instanceof IASTName ) - node = node.getParent(); - if( node instanceof ICPPASTElaboratedTypeSpecifier ) - return (ICPPASTElaboratedTypeSpecifier)node; - } - return null; - } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.ICompositeType#getFields() - */ - public IField[] getFields() throws DOMException { - if( definition == null ){ - checkForDefinition(); - if( definition == null ){ - IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; - return new IField [] { new CPPField.CPPFieldProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) }; - } - } - - IField[] fields = getDeclaredFields(); - ICPPBase [] bases = getBases(); - for ( int i = 0; i < bases.length; i++ ) { - IBinding b = bases[i].getBaseClass(); - if( b instanceof ICPPClassType ) - fields = (IField[]) ArrayUtil.addAll( IField.class, fields, ((ICPPClassType)b).getFields() ); - } - return (IField[]) ArrayUtil.trim( IField.class, fields ); + if( declarations != null ){ + IASTNode node = declarations[0]; + while( node instanceof IASTName ) + node = node.getParent(); + if( node instanceof ICPPASTElaboratedTypeSpecifier ) + return (ICPPASTElaboratedTypeSpecifier)node; + } + return null; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.ICompositeType#findField(java.lang.String) - */ - public IField findField(String name) throws DOMException { - IBinding [] bindings = CPPSemantics.findBindings( getCompositeScope(), name, true ); - IField field = null; - for ( int i = 0; i < bindings.length; i++ ) { - if( bindings[i] instanceof IField ){ - if( field == null ) - field = (IField) bindings[i]; - else { - IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; - return new CPPField.CPPFieldProblem( node, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, name.toCharArray() ); - } - } - } - return field; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IBinding#getName() - */ public String getName() { return ( definition != null ) ? definition.toString() : declarations[0].toString(); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray() - */ public char[] getNameCharArray() { return ( definition != null ) ? definition.toCharArray() : declarations[0].toCharArray(); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() - */ public IScope getScope() { IASTName name = definition != null ? definition : declarations[0]; IScope scope = CPPVisitor.getContainingScope( name ); if( definition == null && name.getPropertyInParent() != ICPPASTQualifiedName.SEGMENT_NAME ){ - IASTNode node = declarations[0].getParent().getParent(); - if( node instanceof IASTFunctionDefinition || node instanceof IASTParameterDeclaration || - ( node instanceof IASTSimpleDeclaration && - ( ((IASTSimpleDeclaration) node).getDeclarators().length > 0 || getElaboratedTypeSpecifier().isFriend() ) ) ) - { - while( scope instanceof ICPPClassScope || scope instanceof ICPPFunctionScope ){ + IASTNode node = declarations[0].getParent().getParent(); + if( node instanceof IASTFunctionDefinition || node instanceof IASTParameterDeclaration || + ( node instanceof IASTSimpleDeclaration && + ( ((IASTSimpleDeclaration) node).getDeclarators().length > 0 || getElaboratedTypeSpecifier().isFriend() ) ) ) + { + while( scope instanceof ICPPClassScope || scope instanceof ICPPFunctionScope ){ try { scope = scope.getParent(); } catch (DOMException e1) { } } - } + } } return scope; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.ICompositeType#getCompositeScope() - */ public IScope getCompositeScope() { if (definition == null) { checkForDefinition(); @@ -413,21 +349,15 @@ public class CPPClassType extends PlatformObject implements ICPPClassType, ICPPI } return null; } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IBinding#getPhysicalNode() - */ + public IASTNode getPhysicalNode() { return (definition != null ) ? (IASTNode) definition : declarations[0]; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.ICompositeType#getKey() - */ public int getKey() { - if( definition != null ) - return getCompositeTypeSpecifier().getKey(); - + if( definition != null ) + return getCompositeTypeSpecifier().getKey(); + return getElaboratedTypeSpecifier().getKind(); } @@ -435,10 +365,11 @@ public class CPPClassType extends PlatformObject implements ICPPClassType, ICPPI if( node instanceof ICPPASTCompositeTypeSpecifier ) definition = ((ICPPASTCompositeTypeSpecifier)node).getName(); } + public void addDeclaration( IASTNode node ) { if( !(node instanceof ICPPASTElaboratedTypeSpecifier) ) return; - + IASTName name = ((ICPPASTElaboratedTypeSpecifier) node).getName(); if( declarations == null ){ @@ -453,7 +384,7 @@ public class CPPClassType extends PlatformObject implements ICPPClassType, ICPPI declarations = (IASTName[]) ArrayUtil.append( IASTName.class, declarations, name ); } } - + public void removeDeclaration(IASTNode node) { if( definition == node ){ definition = null; @@ -462,380 +393,92 @@ public class CPPClassType extends PlatformObject implements ICPPClassType, ICPPI ArrayUtil.remove(declarations, node); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getBases() - */ - public ICPPBase [] getBases() { - if( definition == null ){ - checkForDefinition(); - if( definition == null ){ - IASTName node = (declarations != null && declarations.length > 0) ? declarations[0] : null; - return new ICPPBase [] { new CPPBaseClause.CPPBaseProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) }; - } - } - ICPPASTBaseSpecifier [] bases = getCompositeTypeSpecifier().getBaseSpecifiers(); - if( bases.length == 0 ) - return ICPPBase.EMPTY_BASE_ARRAY; - - ICPPBase [] bindings = new ICPPBase[ bases.length ]; - for( int i = 0; i < bases.length; i++ ){ - bindings[i] = new CPPBaseClause( bases[i] ); + public String[] getQualifiedName() { + return CPPVisitor.getQualifiedName( this ); + } + + public char[][] getQualifiedNameCharArray() { + return CPPVisitor.getQualifiedNameCharArray( this ); + } + + public boolean isGloballyQualified() throws DOMException { + IScope scope = getScope(); + while( scope != null ){ + if( scope instanceof ICPPBlockScope ) + return false; + scope = scope.getParent(); } - - return bindings; + return true; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getDeclaredFields() - */ - public ICPPField[] getDeclaredFields() throws DOMException { - if( definition == null ){ - checkForDefinition(); - if( definition == null ){ - IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; - return new ICPPField[] { new CPPField.CPPFieldProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) }; - } - } - IBinding binding = null; - ICPPField [] result = null; - - IASTDeclaration [] decls = getCompositeTypeSpecifier().getMembers(); - 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++ ) { - binding = dtors[j].getName().resolveBinding(); - if( binding instanceof ICPPField ) - result = (ICPPField[]) ArrayUtil.append( ICPPField.class, result, binding ); - } - } else if( decls[i] instanceof ICPPASTUsingDeclaration ){ - IASTName n = ((ICPPASTUsingDeclaration)decls[i]).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 ICPPField ) - result = (ICPPField[]) ArrayUtil.append( ICPPField.class, result, bs[j] ); - } - } else if( binding instanceof ICPPField ) { - result = (ICPPField[]) ArrayUtil.append( ICPPField.class, result, binding ); - } - } - } - return (ICPPField[]) ArrayUtil.trim( ICPPField.class, result ); - } - - public ICPPMethod[] getConversionOperators() { - if( definition == null ){ - checkForDefinition(); - if( definition == null ){ - IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; - return new ICPPMethod[] { new CPPMethod.CPPMethodProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) }; - } - } - IBinding binding = null; - ICPPMethod [] result = 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 ); + public ICPPDelegate createDelegate( IASTName name ) { + return new CPPClassTypeDelegate( name, this ); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getMethods() - */ - public ICPPMethod[] getMethods() throws DOMException { - ObjectSet set = new ObjectSet(4); - ICPPMethod [] ms = getDeclaredMethods(); - set.addAll( ms ); - ICPPClassScope scope = (ICPPClassScope) getCompositeScope(); - set.addAll( scope.getImplicitMethods() ); - ICPPBase [] bases = getBases(); - for ( int i = 0; i < bases.length; i++ ) { - IBinding b = bases[i].getBaseClass(); - if( b instanceof ICPPClassType ) - set.addAll( ((ICPPClassType)b).getMethods() ); - } - return (ICPPMethod[]) set.keyArray( ICPPMethod.class ); - } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getAllDeclaredMethods() - */ - public ICPPMethod[] getAllDeclaredMethods() throws DOMException { - if( definition == null ){ - checkForDefinition(); - if( definition == null ){ - IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; - return new ICPPMethod [] { new CPPMethod.CPPMethodProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) }; - } - } - - ICPPMethod[] methods = getDeclaredMethods(); - ICPPBase [] bases = getBases(); - for ( int i = 0; i < bases.length; i++ ) { - IBinding b = bases[i].getBaseClass(); - if( b instanceof ICPPClassType ) - methods = (ICPPMethod[]) ArrayUtil.addAll( ICPPMethod.class, methods, ((ICPPClassType)b).getAllDeclaredMethods() ); - } - return (ICPPMethod[]) ArrayUtil.trim( ICPPMethod.class, methods ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getDeclaredMethods() - */ - public ICPPMethod[] getDeclaredMethods() throws DOMException { - if( definition == null ){ - checkForDefinition(); - if( definition == null ){ - IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; - return new ICPPMethod[] { new CPPMethod.CPPMethodProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) }; - } - } - 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 ); - } - - public Object clone(){ - IType t = null; - try { - t = (IType) super.clone(); - } catch ( CloneNotSupportedException e ) { - //not going to happen - } - return t; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getConstructors() - */ - public ICPPConstructor[] getConstructors() throws DOMException { - if( definition == null ){ - checkForDefinition(); - if( definition == null ){ - IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; - return new ICPPConstructor [] { new CPPConstructor.CPPConstructorProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) }; - } - } - - ICPPClassScope scope = (ICPPClassScope) getCompositeScope(); - if( ASTInternal.isFullyCached(scope) ) - return ((CPPClassScope)scope).getConstructors( true ); - - IASTDeclaration [] members = getCompositeTypeSpecifier().getMembers(); - for( int i = 0; i < members.length; i++ ){ - IASTDeclaration decl = members[i]; - if( decl instanceof ICPPASTTemplateDeclaration ) - decl = ((ICPPASTTemplateDeclaration)decl).getDeclaration(); - if( decl instanceof IASTSimpleDeclaration ){ - IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decl).getDeclarators(); - for( int j = 0; j < dtors.length; j++ ){ - if( dtors[j] == null ) break; - ASTInternal.addName(scope, dtors[j].getName() ); - } - } else if( decl instanceof IASTFunctionDefinition ){ - IASTDeclarator dtor = ((IASTFunctionDefinition)decl).getDeclarator(); - ASTInternal.addName(scope, dtor.getName() ); - } - } - - return ((CPPClassScope)scope).getConstructors( true ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getFriends() - */ - public IBinding[] getFriends() { - if( definition == null ){ - checkForDefinition(); - if( definition == null ){ - IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; - return new IBinding [] { new ProblemBinding( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) }; - } - } - ObjectSet resultSet = new ObjectSet(2); - IASTDeclaration [] members = getCompositeTypeSpecifier().getMembers(); - for( int i = 0; i < members.length; i++ ){ - IASTDeclaration decl = members[i]; - while( decl instanceof ICPPASTTemplateDeclaration ) - decl = ((ICPPASTTemplateDeclaration)decl).getDeclaration(); - - if( decl instanceof IASTSimpleDeclaration ){ - ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTSimpleDeclaration)decl).getDeclSpecifier(); - if( declSpec.isFriend() ){ - IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decl).getDeclarators(); - if( declSpec instanceof ICPPASTElaboratedTypeSpecifier && dtors.length == 0 ){ - resultSet.put( ((ICPPASTElaboratedTypeSpecifier)declSpec).getName().resolveBinding() ); - } else { - for( int j = 0; j < dtors.length; j++ ){ - if( dtors[j] == null ) break; - resultSet.put( dtors[j].getName().resolveBinding() ); - } - } - } - } else if( decl instanceof IASTFunctionDefinition ){ - ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTFunctionDefinition)decl).getDeclSpecifier(); - if( declSpec.isFriend() ){ - IASTDeclarator dtor = ((IASTFunctionDefinition)decl).getDeclarator(); - resultSet.put( dtor.getName().resolveBinding() ); - } - - } - } - - return (IBinding[]) resultSet.keyArray( IBinding.class ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding#getQualifiedName() - */ - public String[] getQualifiedName() { - return CPPVisitor.getQualifiedName( this ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding#getQualifiedNameCharArray() - */ - public char[][] getQualifiedNameCharArray() { - return CPPVisitor.getQualifiedNameCharArray( this ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding#isGloballyQualified() - */ - public boolean isGloballyQualified() throws DOMException { - IScope scope = getScope(); - while( scope != null ){ - if( scope instanceof ICPPBlockScope ) - return false; - scope = scope.getParent(); - } - return true; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#createDelegate(org.eclipse.cdt.core.dom.ast.IASTName) - */ - public ICPPDelegate createDelegate( IASTName name ) { - return new CPPClassTypeDelegate( name, this ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IType#isSameType(org.eclipse.cdt.core.dom.ast.IType) - */ - public boolean isSameType( IType type ) { - if (type == this) - return true; - if (type instanceof ITypedef || type instanceof IIndexType || type instanceof ICPPDelegate) - return type.isSameType(this); - return false; - } - - public ICPPClassType[] getNestedClasses() { - if( definition == null ){ - checkForDefinition(); - if( definition == null ){ - IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; - return new ICPPClassType[] { new CPPClassTypeProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) }; - } - } - - ICPPClassType [] 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 ){ - IBinding binding = null; - IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration) decl).getDeclSpecifier(); - if( declSpec instanceof ICPPASTCompositeTypeSpecifier ){ - binding = ((ICPPASTCompositeTypeSpecifier)declSpec).getName().resolveBinding(); - } else if( declSpec instanceof ICPPASTElaboratedTypeSpecifier && - ((IASTSimpleDeclaration)decl).getDeclarators().length == 0 ) - { - binding = ((ICPPASTElaboratedTypeSpecifier)declSpec).getName().resolveBinding(); - } - if( binding instanceof ICPPClassType ) - result = (ICPPClassType[])ArrayUtil.append( ICPPClassType.class, result, binding ); - } - } - return (ICPPClassType[]) ArrayUtil.trim( ICPPClassType.class, result ); - } - public ILinkage getLinkage() { return Linkage.CPP_LINKAGE; } + + /* */ + + public boolean isSameType( IType type ) { + if (type == this) + return true; + if (type instanceof ITypedef || type instanceof IIndexType || type instanceof ICPPDelegate) + return type.isSameType(this); + return false; + } + + public ICPPBase [] getBases() { + return mixin.getBases(); + } + + public IField[] getFields() throws DOMException { + return mixin.getFields(); + } + + public ICPPField[] getDeclaredFields() throws DOMException { + return mixin.getDeclaredFields(); + } + + public ICPPMethod[] getConversionOperators() throws DOMException { + return mixin.getConversionOperators(); + } + + public ICPPMethod[] getMethods() throws DOMException { + return mixin.getMethods(); + } + + public ICPPMethod[] getAllDeclaredMethods() throws DOMException { + return mixin.getAllDeclaredMethods(); + } + + public ICPPMethod[] getDeclaredMethods() throws DOMException { + return mixin.getDeclaredMethods(); + } + + public ICPPConstructor[] getConstructors() throws DOMException { + return mixin.getConstructors(); + } + + public IBinding[] getFriends() { + return mixin.getFriends(); + } + + public ICPPClassType[] getNestedClasses() { + return mixin.getNestedClasses(); + } + + public IField findField(String name) throws DOMException { + return mixin.findField(name); + } + + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + } + return 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 new file mode 100644 index 00000000000..9a0620827e2 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeMixin.java @@ -0,0 +1,407 @@ +/******************************************************************************* + * Copyright (c) 2004, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Markus Schorn (Wind River Systems) + * Bryan Wilkinson (QNX) + * Sergey Prigogin (Google) + * Andrew Ferguson (Symbian) + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; +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; +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; +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.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.ObjectSet; +import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; +import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassType.CPPClassTypeProblem; + +/** + * Holds common implementation of methods for ICPPClassType implementations that have + * a corresponding textual definition in the source code. This functionality is then + * accessed via a delegate. + * + * @see CPPClassType + * @see CPPClassTemplate + */ +class ClassTypeMixin { + private ICPPInternalClassTypeMixinHost host; + + public ClassTypeMixin(ICPPInternalClassTypeMixinHost host) { + this.host= host; + } + + public IBinding[] getFriends() { + 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 IBinding [] { new ProblemBinding( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, host.getNameCharArray() ) }; + } + } + ObjectSet resultSet = new ObjectSet(2); + IASTDeclaration [] members = host.getCompositeTypeSpecifier().getMembers(); + for( int i = 0; i < members.length; i++ ){ + IASTDeclaration decl = members[i]; + while( decl instanceof ICPPASTTemplateDeclaration ) + decl = ((ICPPASTTemplateDeclaration)decl).getDeclaration(); + + if( decl instanceof IASTSimpleDeclaration ){ + ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTSimpleDeclaration)decl).getDeclSpecifier(); + if( declSpec.isFriend() ){ + IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decl).getDeclarators(); + if( declSpec instanceof ICPPASTElaboratedTypeSpecifier && dtors.length == 0 ){ + resultSet.put( ((ICPPASTElaboratedTypeSpecifier)declSpec).getName().resolveBinding() ); + } else { + for( int j = 0; j < dtors.length; j++ ){ + if( dtors[j] == null ) break; + resultSet.put( dtors[j].getName().resolveBinding() ); + } + } + } + } else if( decl instanceof IASTFunctionDefinition ){ + ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTFunctionDefinition)decl).getDeclSpecifier(); + if( declSpec.isFriend() ){ + IASTDeclarator dtor = ((IASTFunctionDefinition)decl).getDeclarator(); + resultSet.put( dtor.getName().resolveBinding() ); + } + + } + } + + return (IBinding[]) 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(); + if( host.getDefinition() == null ){ + IASTNode[] declarations= host.getDeclarations(); + IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; + return new ICPPBase [] { new CPPBaseClause.CPPBaseProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, host.getNameCharArray() ) }; + } + } + ICPPASTBaseSpecifier [] bases = host.getCompositeTypeSpecifier().getBaseSpecifiers(); + if( bases.length == 0 ) + return ICPPBase.EMPTY_BASE_ARRAY; + + ICPPBase [] bindings = new ICPPBase[ bases.length ]; + for( int i = 0; i < bases.length; i++ ){ + bindings[i] = new CPPBaseClause( bases[i] ); + } + + return bindings; + } + + public ICPPMethod[] getMethods() throws DOMException { + ObjectSet set = new ObjectSet(4); + set.addAll(getDeclaredMethods()); + ICPPClassScope scope = (ICPPClassScope) host.getCompositeScope(); + set.addAll( scope.getImplicitMethods() ); + ICPPBase [] bases = getBases(); + for ( int i = 0; i < bases.length; i++ ) { + IBinding b = bases[i].getBaseClass(); + if( b instanceof ICPPClassType ) + set.addAll( ((ICPPClassType)b).getMethods() ); + } + return (ICPPMethod[]) set.keyArray( ICPPMethod.class ); + } + + + public ICPPField[] getDeclaredFields() 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 ICPPField[] { new CPPField.CPPFieldProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, host.getNameCharArray() ) }; + } + } + IBinding binding = null; + ICPPField [] result = null; + + IASTDeclaration [] decls = host.getCompositeTypeSpecifier().getMembers(); + 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++ ) { + binding = dtors[j].getName().resolveBinding(); + if( binding instanceof ICPPField ) + result = (ICPPField[]) ArrayUtil.append( ICPPField.class, result, binding ); + } + } else if( decls[i] instanceof ICPPASTUsingDeclaration ){ + IASTName n = ((ICPPASTUsingDeclaration)decls[i]).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 ICPPField ) + result = (ICPPField[]) ArrayUtil.append( ICPPField.class, result, bs[j] ); + } + } else if( binding instanceof ICPPField ) { + result = (ICPPField[]) ArrayUtil.append( ICPPField.class, result, binding ); + } + } + } + return (ICPPField[]) ArrayUtil.trim( ICPPField.class, result ); + } + + public ICPPMethod[] getAllDeclaredMethods() 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() ) }; + } + } + + ICPPMethod[] methods = getDeclaredMethods(); + ICPPBase [] bases = getBases(); + for ( int i = 0; i < bases.length; i++ ) { + IBinding b = bases[i].getBaseClass(); + if( b instanceof ICPPClassType ) + methods = (ICPPMethod[]) ArrayUtil.addAll( ICPPMethod.class, methods, ((ICPPClassType)b).getAllDeclaredMethods() ); + } + return (ICPPMethod[]) ArrayUtil.trim( ICPPMethod.class, methods ); + } + + public ICPPMethod[] getDeclaredMethods() 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(); + 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) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getConstructors() + */ + public ICPPConstructor[] getConstructors() 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 ICPPConstructor [] { new CPPConstructor.CPPConstructorProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, host.getNameCharArray() ) }; + } + } + + ICPPClassScope scope = (ICPPClassScope) host.getCompositeScope(); + if(ASTInternal.isFullyCached(scope)) + return ((CPPClassScope)scope).getConstructors( true ); + + IASTDeclaration [] members = host.getCompositeTypeSpecifier().getMembers(); + for( int i = 0; i < members.length; i++ ){ + IASTDeclaration decl = members[i]; + if( decl instanceof ICPPASTTemplateDeclaration ) + decl = ((ICPPASTTemplateDeclaration)decl).getDeclaration(); + if( decl instanceof IASTSimpleDeclaration ){ + IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decl).getDeclarators(); + for( int j = 0; j < dtors.length; j++ ){ + if( dtors[j] == null ) break; + ASTInternal.addName(scope, dtors[j].getName() ); + } + } else if( decl instanceof IASTFunctionDefinition ){ + IASTDeclarator dtor = ((IASTFunctionDefinition)decl).getDeclarator(); + ASTInternal.addName(scope, dtor.getName() ); + } + } + + return ((CPPClassScope)scope).getConstructors( true ); + } + + public ICPPClassType[] getNestedClasses() { + 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 ICPPClassType[] { new CPPClassTypeProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, host.getNameCharArray() ) }; + } + } + + ICPPClassType [] result = null; + + IASTDeclaration [] decls = host.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 ){ + IBinding binding = null; + IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration) decl).getDeclSpecifier(); + if( declSpec instanceof ICPPASTCompositeTypeSpecifier ){ + binding = ((ICPPASTCompositeTypeSpecifier)declSpec).getName().resolveBinding(); + } else if( declSpec instanceof ICPPASTElaboratedTypeSpecifier && + ((IASTSimpleDeclaration)decl).getDeclarators().length == 0 ) + { + binding = ((ICPPASTElaboratedTypeSpecifier)declSpec).getName().resolveBinding(); + } + if( binding instanceof ICPPClassType ) + result = (ICPPClassType[])ArrayUtil.append( ICPPClassType.class, result, binding ); + } + } + return (ICPPClassType[]) ArrayUtil.trim( ICPPClassType.class, result ); + } + + public IField[] getFields() 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 IField [] { new CPPField.CPPFieldProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, host.getNameCharArray() ) }; + } + } + + IField[] fields = getDeclaredFields(); + ICPPBase [] bases = getBases(); + for ( int i = 0; i < bases.length; i++ ) { + IBinding b = bases[i].getBaseClass(); + if( b instanceof ICPPClassType ) + fields = (IField[]) ArrayUtil.addAll( IField.class, fields, ((ICPPClassType)b).getFields() ); + } + return (IField[]) ArrayUtil.trim( IField.class, fields ); + } + + public IField findField(String name) throws DOMException { + IBinding [] bindings = CPPSemantics.findBindings( host.getCompositeScope(), name, true ); + IField field = null; + for ( int i = 0; i < bindings.length; i++ ) { + if( bindings[i] instanceof IField ){ + if( field == null ) + field = (IField) bindings[i]; + else { + IASTNode[] declarations= host.getDeclarations(); + IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; + return new CPPField.CPPFieldProblem( node, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, name.toCharArray() ); + } + } + } + return field; + } +} 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 index 7d8b0364081..78a55126e75 100644 --- 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 @@ -13,11 +13,12 @@ */ 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(); + 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 new file mode 100644 index 00000000000..cd205ac0eed --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalClassTypeMixinHost.java @@ -0,0 +1,20 @@ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; + +/** + * Internal interface for exposing internal methods to ClassTypeMixin + */ +interface ICPPInternalClassTypeMixinHost extends ICPPInternalClassType, ICPPClassType { + /** + * @return the composite type specifier for the class type + */ + ICPPASTCompositeTypeSpecifier getCompositeTypeSpecifier(); + + /** + * Ensures the ICPPInternalBinding definition is set, if this is possible. + * @see ICPPInternalBinding#getDefinition() + */ + void checkForDefinition(); +}