diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBaseClause.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBaseClause.java index 88682a894ad..156d9b7e45f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBaseClause.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBaseClause.java @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Bryan Wilkinson (QNX) *******************************************************************************/ /* @@ -30,8 +31,8 @@ import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; /** * @author aniefer */ -public class CPPBaseClause implements ICPPBase { - static public class CPPBaseProblem extends ProblemBinding implements ICPPBase { +public class CPPBaseClause implements ICPPBase, ICPPInternalBase { + static public class CPPBaseProblem extends ProblemBinding implements ICPPBase, ICPPInternalBase { private ICPPClassType classProblem = null; public CPPBaseProblem( IASTNode node, int id, char[] arg ) { super( node, id, arg ); @@ -53,6 +54,9 @@ public class CPPBaseClause implements ICPPBase { public IName getBaseClassSpecifierName() { return (IName) node; } + public void setBaseClass(IBinding binding) throws DOMException { + throw new DOMException( this ); + } } private ICPPASTBaseSpecifier base = null; private IBinding baseClass = null; @@ -107,7 +111,7 @@ public class CPPBaseClause implements ICPPBase { return base.isVirtual(); } - public void setBaseClass(ICPPClassType cls) { + public void setBaseClass(IBinding cls) { baseClass = cls; } @@ -115,4 +119,13 @@ public class CPPBaseClause implements ICPPBase { return base.getName(); } + public Object clone(){ + ICPPBase t = null; + try { + t = (ICPPBase) super.clone(); + } catch ( CloneNotSupportedException e ) { + //not going to happen + } + return t; + } } 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 f1d30276bb8..b5b1d1b1de4 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 @@ -30,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; +import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.internal.core.index.IIndexType; @@ -54,18 +55,21 @@ public class CPPClassInstance extends CPPInstance implements ICPPClassType, ICPP public ICPPBase[] getBases() throws DOMException { ICPPClassType cls = (ICPPClassType) getSpecializedBinding(); if( cls != null ){ + ICPPBase[] result = null; 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 (bindings[i] instanceof CPPBaseClause && base instanceof IType) { + if (base instanceof IType) { IType specBase = CPPTemplates.instantiateType((IType) base, argumentMap); specBase = CPPSemantics.getUltimateType(specBase, false); - if (specBase instanceof ICPPClassType) { - ((CPPBaseClause)bindings[i]).setBaseClass((ICPPClassType)specBase); + if (specBase instanceof IBinding) { + ((ICPPInternalBase)specBinding).setBaseClass((IBinding)specBase); } + result = (ICPPBase[]) ArrayUtil.append(ICPPBase.class, result, specBinding); } } - return bindings; + return (ICPPBase[]) ArrayUtil.trim(ICPPBase.class, result); } return ICPPBase.EMPTY_BASE_ARRAY; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java index 8d85ecde54d..68f0a69495e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java @@ -75,18 +75,21 @@ public class CPPClassSpecialization extends CPPSpecialization implements */ public ICPPBase[] getBases() throws DOMException { if( getDefinition() == null ){ + ICPPBase[] result = null; ICPPBase[] bindings = ((ICPPClassType)getSpecializedBinding()).getBases(); for (int i = 0; i < bindings.length; i++) { + ICPPBase specBinding = (ICPPBase) ((ICPPInternalBase)bindings[i]).clone(); IBinding base = bindings[i].getBaseClass(); - if (bindings[i] instanceof CPPBaseClause && base instanceof IType) { + if (base instanceof IType) { IType specBase = CPPTemplates.instantiateType((IType) base, argumentMap); specBase = CPPSemantics.getUltimateType(specBase, false); - if (specBase instanceof ICPPClassType) { - ((CPPBaseClause)bindings[i]).setBaseClass((ICPPClassType)specBase); + if (specBase instanceof IBinding) { + ((ICPPInternalBase)specBinding).setBaseClass((IBinding)specBase); } + result = (ICPPBase[]) ArrayUtil.append(ICPPBase.class, result, specBinding); } } - return bindings; + return (ICPPBase[]) ArrayUtil.trim(ICPPBase.class, result); } ICPPASTBaseSpecifier[] bases = getCompositeTypeSpecifier().getBaseSpecifiers(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalBase.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalBase.java new file mode 100644 index 00000000000..9bd43eccc73 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalBase.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2007 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IBinding; + +/** + * @author Bryan Wilkinson + * + */ +public interface ICPPInternalBase extends Cloneable { + public Object clone(); + + /** + * Set the base class. + */ + public void setBaseClass(IBinding binding) throws DOMException; +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassType.java index ce64fee9f38..57b8f9dce9f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassType.java @@ -21,6 +21,7 @@ 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.internal.core.dom.parser.cpp.ICPPInternalBase; import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; import org.eclipse.cdt.internal.core.index.IIndexType; import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; @@ -47,28 +48,43 @@ class CompositeCPPClassType extends CompositeCPPBinding implements ICPPClassType return result; } + private class CPPBaseDelegate implements ICPPBase, ICPPInternalBase { + private ICPPBase base; + + CPPBaseDelegate(ICPPBase b) { + this.base = b; + } + + public IBinding getBaseClass() throws DOMException { + return cf.getCompositeBinding((IIndexFragmentBinding)base.getBaseClass()); + } + + public IName getBaseClassSpecifierName() { + return base.getBaseClassSpecifierName(); + } + + public int getVisibility() throws DOMException { + return base.getVisibility(); + } + + public boolean isVirtual() throws DOMException { + return base.isVirtual(); + } + + public void setBaseClass(IBinding binding) throws DOMException { + ((ICPPInternalBase)base).setBaseClass(binding); + } + + public Object clone(){ + return ((ICPPInternalBase)base).clone(); + } + } + public ICPPBase[] getBases() throws DOMException { final ICPPBase[] preresult = ((ICPPClassType)rbinding).getBases(); ICPPBase[] result = new ICPPBase[preresult.length]; for(int i=0; i