1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 08:55:25 +02:00

Complete implementation of ICPPClassType, bug 98171.

This commit is contained in:
Markus Schorn 2008-08-06 14:19:12 +00:00
parent c9129857f9
commit 03b82b0928
34 changed files with 1057 additions and 739 deletions

View file

@ -136,6 +136,7 @@ public class EmptyIndexFragment implements IIndexFragment {
return null;
}
public void putCachedResult(Object key, Object newMap) {
public Object putCachedResult(Object key, Object value, boolean replace) {
return value;
}
}

View file

@ -113,8 +113,15 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
/*
* @see IndexBindingResolutionTestBase#getBindingFromASTName(Class, String, int)
*/
protected IBinding getBindingFromASTName(String section, int len) {
return getBindingFromASTName(section, len, IBinding.class);
protected <T extends IBinding> T getBindingFromASTName(String section, int len) {
IASTName name= findName(section, len);
assertNotNull("name not found for \""+section+"\"", name);
assertEquals(section.substring(0, len), name.getRawSignature());
IBinding binding = name.resolveBinding();
assertNotNull("No binding for "+name.getRawSignature(), binding);
assertFalse("Binding is a ProblemBinding for name "+name.getRawSignature(), IProblemBinding.class.isAssignableFrom(name.resolveBinding().getClass()));
return (T) binding;
}
/**

View file

@ -36,14 +36,16 @@ public class IndexCBindingResolutionBugs extends IndexBindingResolutionTestBase
public static class SingleProject extends IndexCBindingResolutionBugs {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
public static class ProjectWithDepProj extends IndexCBindingResolutionBugs {
public ProjectWithDepProj() {setStrategy(new ReferencedProject(false));}
public static TestSuite suite() {return suite(ProjectWithDepProj.class);}
}
public static void addTests(TestSuite suite) {
suite.addTest(suite(SingleProject.class));
suite.addTest(suite(ProjectWithDepProj.class));
suite.addTest(SingleProject.suite());
suite.addTest(ProjectWithDepProj.suite());
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007 Symbian Software Systems and others.
* Copyright (c) 2007, 2008 Symbian Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -37,14 +37,16 @@ public class IndexCBindingResolutionTest extends IndexBindingResolutionTestBase
public static class SingleProject extends IndexCBindingResolutionTest {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(false));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
public static class ProjectWithDepProj extends IndexCBindingResolutionTest {
public ProjectWithDepProj() {setStrategy(new ReferencedProject(false));}
public static TestSuite suite() {return suite(ProjectWithDepProj.class);}
}
public static void addTests(TestSuite suite) {
suite.addTest(suite(SingleProject.class));
suite.addTest(suite(ProjectWithDepProj.class));
suite.addTest(SingleProject.suite());
suite.addTest(ProjectWithDepProj.suite());
}
public IndexCBindingResolutionTest() {

View file

@ -11,6 +11,7 @@
*******************************************************************************/
package org.eclipse.cdt.internal.index.tests;
import java.util.Arrays;
import java.util.regex.Pattern;
import junit.framework.TestSuite;
@ -30,6 +31,7 @@ import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IVariable;
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.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
@ -58,15 +60,17 @@ public class IndexCPPBindingResolutionBugs extends IndexBindingResolutionTestBas
public static class SingleProject extends IndexCPPBindingResolutionBugs {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
public static class ProjectWithDepProj extends IndexCPPBindingResolutionBugs {
public ProjectWithDepProj() {setStrategy(new ReferencedProject(true));}
public static TestSuite suite() {return suite(ProjectWithDepProj.class);}
}
public static void addTests(TestSuite suite) {
suite.addTest(suite(SingleProject.class));
suite.addTest(suite(ProjectWithDepProj.class));
suite.addTest(SingleProject.suite());
suite.addTest(ProjectWithDepProj.suite());
}
public static TestSuite suite() {
@ -870,4 +874,198 @@ public class IndexCPPBindingResolutionBugs extends IndexBindingResolutionTestBas
getBindingFromASTName("test2(x)", 5, ICPPFunction.class);
getBindingFromASTName("test3(x)", 5, ICPPFunction.class);
}
// class A {
// A();
// void l();
// void e;
// class M {};
// };
// class B {
// B();
// void m();
// void f;
// class N {};
// };
// class C : B {
// C();
// void n();
// int g;
// class O {};
// };
// template<typename T> class CT : B {
// CT();
// void n();
// T g;
// class O {};
// };
// template<> class CT<char> : A {
// CT(); CT(int);
// void o();
// int h;
// class P {};
// };
// template<typename S> class Container {
// class C : B {
// C();
// void n();
// int g;
// class O {};
// };
// template<typename T> class CT : B {
// CT();
// void n();
// T g;
// class O {};
// };
// };
// template<> class Container<char>::C : A {
// C(); C(int);
// void o();
// int h;
// class P {};
// };
// template<> template<typename T> class Container<char>::CT : A {
// CT(); CT(int);
// void o();
// int h;
// class P {};
// };
// C c;
// CT<int> ct;
// CT<char> ctinst;
// Container<int>::C spec;
// Container<int>::CT<int> spect;
// Container<char>::C espec;
// Container<char>::CT<int> espect;
public void testClassTypes_Bug98171() throws Exception {
// regular class
ICPPClassType ct= getBindingFromASTName("C", 1);
assertBindings(new String[] {"B"}, ct.getBases());
assertBindings(new String[] {"n", "m", "B", "C"}, ct.getAllDeclaredMethods());
assertBindings(new String[] {"C", "C"}, ct.getConstructors());
assertBindings(new String[] {"g"}, ct.getDeclaredFields());
assertBindings(new String[] {"n", "C"}, ct.getDeclaredMethods());
assertBindings(new String[] {"f", "g"}, ct.getFields());
assertBindings(new String[] {"m", "n", "C", "C", "~C", "B", "B", "~B", "operator =", "operator ="}, ct.getMethods());
assertBindings(new String[] {"O"}, ct.getNestedClasses());
// class template
ct= getBindingFromASTName("CT<int>", 2);
assertInstance(ct, ICPPClassTemplate.class);
assertBindings(new String[] {"B"}, ct.getBases());
assertBindings(new String[] {"n", "m", "B", "CT"}, ct.getAllDeclaredMethods());
assertBindings(new String[] {"CT", "CT"}, ct.getConstructors());
assertBindings(new String[] {"g"}, ct.getDeclaredFields());
assertBindings(new String[] {"n", "CT"}, ct.getDeclaredMethods());
assertBindings(new String[] {"f", "g"}, ct.getFields());
assertBindings(new String[] {"m", "n", "CT", "CT", "~CT", "B", "B", "~B", "operator =", "operator ="}, ct.getMethods());
assertBindings(new String[] {"O"}, ct.getNestedClasses());
// class template instance
ct= getBindingFromASTName("CT<int>", 7);
assertInstance(ct, ICPPTemplateInstance.class);
assertBindings(new String[] {"B"}, ct.getBases());
assertBindings(new String[] {"n", "m", "B", "CT"}, ct.getAllDeclaredMethods());
assertBindings(new String[] {"CT", "CT"}, ct.getConstructors());
assertBindings(new String[] {"g"}, ct.getDeclaredFields());
assertBindings(new String[] {"n", "CT"}, ct.getDeclaredMethods());
assertBindings(new String[] {"f", "g"}, ct.getFields());
assertBindings(new String[] {"m", "n", "CT", "CT", "~CT", "B", "B", "~B", "operator =", "operator ="}, ct.getMethods());
assertBindings(new String[] {"O"}, ct.getNestedClasses());
// explicit class template instance
ct= getBindingFromASTName("CT<char>", 8);
assertInstance(ct, ICPPTemplateInstance.class);
assertBindings(new String[] {"A"}, ct.getBases());
assertBindings(new String[] {"o", "l", "A", "CT", "CT"}, ct.getAllDeclaredMethods());
assertBindings(new String[] {"CT", "CT", "CT"}, ct.getConstructors());
assertBindings(new String[] {"h"}, ct.getDeclaredFields());
assertBindings(new String[] {"o", "CT", "CT"}, ct.getDeclaredMethods());
assertBindings(new String[] {"e", "h"}, ct.getFields());
assertBindings(new String[] {"l", "o", "CT", "CT", "CT", "~CT", "A", "A", "~A", "operator =", "operator ="}, ct.getMethods());
assertBindings(new String[] {"P"}, ct.getNestedClasses());
// class specialization
ct= getBindingFromASTName("C spec", 1);
assertInstance(ct, ICPPClassSpecialization.class);
assertBindings(new String[] {"B"}, ct.getBases());
assertBindings(new String[] {"n", "m", "B", "C"}, ct.getAllDeclaredMethods());
assertBindings(new String[] {"C", "C"}, ct.getConstructors());
assertBindings(new String[] {"g"}, ct.getDeclaredFields());
assertBindings(new String[] {"n", "C"}, ct.getDeclaredMethods());
assertBindings(new String[] {"f", "g"}, ct.getFields());
assertBindings(new String[] {"m", "n", "C", "C", "~C", "B", "B", "~B", "operator =", "operator ="}, ct.getMethods());
assertBindings(new String[] {"O"}, ct.getNestedClasses());
// class template specialization
ct= getBindingFromASTName("CT<int> spect", 2);
assertInstance(ct, ICPPClassTemplate.class, ICPPClassSpecialization.class);
assertBindings(new String[] {"B"}, ct.getBases());
assertBindings(new String[] {"n", "m", "B", "CT"}, ct.getAllDeclaredMethods());
assertBindings(new String[] {"CT", "CT"}, ct.getConstructors());
assertBindings(new String[] {"g"}, ct.getDeclaredFields());
assertBindings(new String[] {"n", "CT"}, ct.getDeclaredMethods());
assertBindings(new String[] {"f", "g"}, ct.getFields());
assertBindings(new String[] {"m", "n", "CT", "CT", "~CT", "B", "B", "~B", "operator =", "operator ="}, ct.getMethods());
assertBindings(new String[] {"O"}, ct.getNestedClasses());
// explicit class specialization
ct= getBindingFromASTName("C espec", 1);
assertInstance(ct, ICPPClassSpecialization.class);
assertBindings(new String[] {"A"}, ct.getBases());
assertBindings(new String[] {"o", "l", "A", "C", "C"}, ct.getAllDeclaredMethods());
assertBindings(new String[] {"C", "C", "C"}, ct.getConstructors());
assertBindings(new String[] {"h"}, ct.getDeclaredFields());
assertBindings(new String[] {"o", "C", "C"}, ct.getDeclaredMethods());
assertBindings(new String[] {"e", "h"}, ct.getFields());
assertBindings(new String[] {"l", "o", "C", "C", "C", "~C", "A", "A", "~A", "operator =", "operator ="}, ct.getMethods());
assertBindings(new String[] {"P"}, ct.getNestedClasses());
// explicit class template specialization
ct= getBindingFromASTName("CT<int> espect", 7);
assertInstance(ct, ICPPTemplateInstance.class);
assertBindings(new String[] {"A"}, ct.getBases());
assertBindings(new String[] {"o", "l", "A", "CT", "CT"}, ct.getAllDeclaredMethods());
assertBindings(new String[] {"CT", "CT", "CT"}, ct.getConstructors());
assertBindings(new String[] {"h"}, ct.getDeclaredFields());
assertBindings(new String[] {"o", "CT", "CT"}, ct.getDeclaredMethods());
assertBindings(new String[] {"e", "h"}, ct.getFields());
assertBindings(new String[] {"l", "o", "CT", "CT", "CT", "~CT", "A", "A", "~A", "operator =", "operator ="}, ct.getMethods());
assertBindings(new String[] {"P"}, ct.getNestedClasses());
}
private void assertBindings(String[] expected, ICPPBase[] bases) throws DOMException {
IBinding[] bindings= new IBinding[bases.length];
for (int i = 0; i < bindings.length; i++) {
bindings[i]= bases[i].getBaseClass();
}
assertBindings(expected, bindings);
}
private void assertBindings(String[] expected, IBinding[] binding) {
String[] actual= new String[binding.length];
for (int i = 0; i < actual.length; i++) {
actual[i]= binding[i].getName();
}
Arrays.sort(actual);
Arrays.sort(expected);
assertEquals(toString(expected), toString(actual));
}
private String toString(String[] actual) {
StringBuilder buf= new StringBuilder();
buf.append('{');
boolean isFirst= true;
for (String val : actual) {
if (!isFirst) {
buf.append(',');
}
buf.append(val);
isFirst= false;
}
buf.append('}');
return buf.toString();
}
}

View file

@ -53,14 +53,16 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
public static class SingleProject extends IndexCPPBindingResolutionTest {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
public static class ProjectWithDepProj extends IndexCPPBindingResolutionTest {
public ProjectWithDepProj() {setStrategy(new ReferencedProject(true));}
public static TestSuite suite() {return suite(ProjectWithDepProj.class);}
}
public static void addTests(TestSuite suite) {
suite.addTest(suite(SingleProject.class));
suite.addTest(suite(ProjectWithDepProj.class));
suite.addTest(SingleProject.suite());
suite.addTest(ProjectWithDepProj.suite());
}
// namespace ns { class A; enum E {E1}; typedef int T; }

View file

@ -6,7 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andrew Ferguson (Symbian) - Initial implementation
* Andrew Ferguson (Symbian) - Initial implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.index.tests;
@ -62,15 +63,17 @@ import org.eclipse.core.runtime.CoreException;
public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBase {
public static class SingleProject extends IndexCPPTemplateResolutionTest {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true));}
public static TestSuite suite() {return suite(SingleProject.class);}
}
public static class ProjectWithDepProj extends IndexCPPTemplateResolutionTest {
public ProjectWithDepProj() {setStrategy(new ReferencedProject(true));}
public static TestSuite suite() {return suite(ProjectWithDepProj.class);}
}
public static void addTests(TestSuite suite) {
suite.addTest(suite(SingleProject.class));
suite.addTest(suite(ProjectWithDepProj.class));
suite.addTest(SingleProject.suite());
suite.addTest(ProjectWithDepProj.suite());
}
public IndexCPPTemplateResolutionTest() {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007 Symbian Software Systems and others.
* Copyright (c) 2007, 2008 Symbian Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -231,7 +231,7 @@ public class CPPClassTemplateTests extends PDOMTestBase {
// void bar() {
// foo->f(*new A());
// }
public void _testFunctionPointer() throws Exception {
public void testFunctionPointer() throws Exception {
IIndexFragmentBinding[] bs= pdom.findBindings(new char[][] {"foo".toCharArray()}, IndexFilter.ALL, NPM);
assertEquals(1, bs.length);
assertInstance(bs[0], ICPPVariable.class);

View file

@ -6,7 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
@ -18,16 +19,18 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBas
/**
* Represents the relationship between a class and one of its base classes.
*
* @author Doug Schaefer
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPBase {
public interface ICPPBase extends Cloneable {
public static final ICPPBase[] EMPTY_BASE_ARRAY = new ICPPBase[0];
public static final int v_private = ICPPASTBaseSpecifier.v_private;
public static final int v_protected = ICPPASTBaseSpecifier.v_protected;
public static final int v_public = ICPPASTBaseSpecifier.v_public;
/**
* The base class. Generally a ICPPClassType, but may be a ICPPTemplateParameter.
* In the case of typedefs, the binding being typedefed will be returned instead of
* the typedef itself.
*
* In the case of typedefs, the target type will be returned instead of the typedef itself.
*/
public IBinding getBaseClass() throws DOMException;
@ -43,16 +46,21 @@ public interface ICPPBase {
*/
public int getVisibility() throws DOMException;
public static final int v_private = ICPPASTBaseSpecifier.v_private;
public static final int v_protected = ICPPASTBaseSpecifier.v_protected;
public static final int v_public = ICPPASTBaseSpecifier.v_public;
/**
* Whether this is a virtual base class.
*
*/
public boolean isVirtual() throws DOMException;
/**
* @since 5.1
*/
public ICPPBase clone();
/**
* Used internally to change cloned bases.
*
* @noreference This method is not intended to be referenced by clients.
*/
public void setBaseClass(IBinding baseClass);
}

View file

@ -18,16 +18,24 @@ import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.EScopeKind;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
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.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
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.ICPPNamespace;
import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
/**
* Base class for all specialization scopes
@ -100,43 +108,77 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
public ICPPClassSpecialization getClassType() {
return specialClass;
}
public ICPPBase[] getBases() throws DOMException {
ICPPBase[] result = null;
ICPPBase[] bases = specialClass.getSpecializedBinding().getBases();
final ObjectMap argmap = specialClass.getArgumentMap();
for (ICPPBase base : bases) {
ICPPBase specBase = base.clone();
IBinding origClass = base.getBaseClass();
if (origClass instanceof IType) {
IType specClass= CPPTemplates.instantiateType((IType) origClass, argmap, specialClass);
specClass = SemanticUtil.getUltimateType(specClass, false);
if (specClass instanceof IBinding && !(specClass instanceof IProblemBinding)) {
specBase.setBaseClass((IBinding) specClass);
}
result = (ICPPBase[]) ArrayUtil.append(ICPPBase.class, result, specBase);
}
}
return (ICPPBase[]) ArrayUtil.trim(ICPPBase.class, result);
}
@SuppressWarnings("unchecked")
private <T extends IBinding> T[] specializeMembers(T[] array) {
if (array == null || array.length == 0)
return array;
T[] newArray= array.clone();
for (int i = 0; i < newArray.length; i++) {
newArray[i]= (T) specialClass.specializeMember(array[i]);
}
return newArray;
}
public ICPPField[] getDeclaredFields() throws DOMException {
ICPPField[] fields= specialClass.getSpecializedBinding().getDeclaredFields();
return specializeMembers(fields);
}
public ICPPMethod[] getImplicitMethods() {
// Implicit methods shouldn't have implicit specializations
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
try {
ICPPClassScope origClassType= (ICPPClassScope) specialClass.getSpecializedBinding().getCompositeScope();
ICPPMethod[] methods= origClassType.getImplicitMethods();
return specializeMembers(methods);
} catch (DOMException e) {
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
}
}
public IName getScopeName() {
if (specialClass instanceof ICPPInternalBinding)
return (IASTName) ((ICPPInternalBinding) specialClass).getDefinition();
//TODO: get the scope name for non-internal bindings
return null;
}
public ICPPConstructor[] getConstructors() throws DOMException {
ICPPClassType specialized = specialClass.getSpecializedBinding();
ICPPConstructor[] bindings = specialized.getConstructors();
if (bindings == null) return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY;
ICPPConstructor[] specs = new ICPPConstructor[0];
for (ICPPConstructor binding : bindings) {
specs = (ICPPConstructor[]) ArrayUtil.append(ICPPConstructor.class, specs, specialClass.specializeMember(binding));
}
return (ICPPConstructor[]) ArrayUtil.trim(ICPPConstructor.class, specs);
ICPPConstructor[] ctors= specialClass.getSpecializedBinding().getConstructors();
return specializeMembers(ctors);
}
public ICPPMethod[] getDeclaredMethods() throws DOMException {
ICPPClassType specialized = specialClass.getSpecializedBinding();
ICPPMethod[] bindings = specialized.getDeclaredMethods();
if (bindings == null) return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
ICPPMethod[] specs = new ICPPMethod[0];
for (ICPPMethod binding : bindings) {
specs = (ICPPMethod[]) ArrayUtil.append(ICPPMethod.class, specs, specialClass.specializeMember(binding));
}
return (ICPPMethod[]) ArrayUtil.trim(ICPPMethod.class, specs);
ICPPMethod[] bindings = specialClass.getSpecializedBinding().getDeclaredMethods();
return specializeMembers(bindings);
}
public ICPPClassType[] getNestedClasses() throws DOMException {
ICPPClassType[] bindings = specialClass.getSpecializedBinding().getNestedClasses();
return specializeMembers(bindings);
}
public IBinding[] getFriends() throws DOMException {
// not yet supported
return IBinding.EMPTY_BINDING_ARRAY;
}
public IScope getParent() throws DOMException {

View file

@ -6,13 +6,10 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Bryan Wilkinson (QNX)
* IBM Corporation - initial API and implementation
* Bryan Wilkinson (QNX)
* Markus Schorn (Wind River Systems)
*******************************************************************************/
/*
* Created on Dec 15, 2004
*/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.IName;
@ -58,8 +55,12 @@ public class CPPBaseClause implements ICPPBase, ICPPInternalBase {
return (IName) node;
}
public void setBaseClass(IBinding binding) throws DOMException {
throw new DOMException(this);
public void setBaseClass(IBinding binding) {
}
@Override
public ICPPBase clone() {
return this;
}
}
@ -123,7 +124,7 @@ public class CPPBaseClause implements ICPPBase, ICPPInternalBase {
}
@Override
public Object clone() {
public ICPPBase clone() {
ICPPBase t = null;
try {
t = (ICPPBase) super.clone();

View file

@ -13,46 +13,45 @@
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.IASTTranslationUnit;
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.ICPPASTQualifiedName;
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.ICPPASTTemplateId;
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.ICPPClassSpecialization;
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.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.core.index.IIndexType;
/**
* @author aniefer
*
*/
public class CPPClassSpecialization extends CPPSpecialization implements ICPPClassSpecialization {
public class CPPClassSpecialization extends CPPSpecialization
implements ICPPClassSpecialization, ICPPInternalClassTypeMixinHost {
private IScope specScope;
private CPPClassSpecializationScope specScope;
private ObjectMap specializationMap= ObjectMap.EMPTY_MAP;
private boolean checked;
public CPPClassSpecialization(ICPPClassType specialized, IBinding owner, ObjectMap argumentMap) {
super(specialized, owner, argumentMap);
@ -74,189 +73,167 @@ public class CPPClassSpecialization extends CPPSpecialization implements ICPPCla
}
return result;
}
private class FindDefinitionAction extends CPPASTVisitor {
private char [] nameArray = CPPClassSpecialization.this.getNameCharArray();
public IASTName result = null;
private ICPPASTCompositeTypeSpecifier getCompositeTypeSpecifier(){
IASTNode definition = getDefinition();
if( definition != null ){
IASTNode node = definition;
while( node instanceof IASTName )
node = node.getParent();
if( node instanceof ICPPASTCompositeTypeSpecifier )
return (ICPPASTCompositeTypeSpecifier)node;
}
return null;
{
shouldVisitNames = true;
shouldVisitDeclarations = true;
shouldVisitDeclSpecifiers = true;
shouldVisitDeclarators = true;
}
@Override
public int visit( IASTName name ){
if( name instanceof ICPPASTTemplateId )
return PROCESS_SKIP;
if( name instanceof ICPPASTQualifiedName )
return PROCESS_CONTINUE;
char [] c = name.toCharArray();
if( name.getParent() instanceof ICPPASTQualifiedName ){
IASTName [] ns = ((ICPPASTQualifiedName)name.getParent()).getNames();
if( ns[ ns.length - 1 ] != name )
return PROCESS_CONTINUE;
name = (IASTName) name.getParent();
}
if( name.getParent() instanceof ICPPASTCompositeTypeSpecifier &&
CharArrayUtils.equals( c, nameArray ) )
{
IBinding binding = name.resolveBinding();
if( binding == CPPClassSpecialization.this ){
if( name instanceof ICPPASTQualifiedName ){
IASTName [] ns = ((ICPPASTQualifiedName)name).getNames();
name = ns[ ns.length - 1 ];
}
result = name;
return PROCESS_ABORT;
}
}
return PROCESS_CONTINUE;
}
@Override
public int visit( IASTDeclaration declaration ){
if(declaration instanceof IASTSimpleDeclaration || declaration instanceof ICPPASTTemplateDeclaration)
return PROCESS_CONTINUE;
return PROCESS_SKIP;
}
@Override
public int visit( IASTDeclSpecifier declSpec ){
return (declSpec instanceof ICPPASTCompositeTypeSpecifier ) ? PROCESS_CONTINUE : PROCESS_SKIP;
}
@Override
public int visit( IASTDeclarator declarator ) { return PROCESS_SKIP; }
}
public void checkForDefinition() {
if( !checked && definition == null ) {
IBinding orig= getSpecializedBinding();
IASTTranslationUnit tu= null;
while (orig != null) {
if (orig instanceof ICPPInternalBinding) {
IASTNode node= ((ICPPInternalBinding) orig).getDefinition();
if (node != null) {
tu= node.getTranslationUnit();
if (tu != null)
break;
}
}
if (!(orig instanceof ICPPSpecialization))
break;
orig= ((ICPPSpecialization) orig).getSpecializedBinding();
}
if (tu != null) {
FindDefinitionAction action= new FindDefinitionAction();
tu.accept( action );
definition = action.result;
}
checked = true;
}
return;
}
public ICPPASTCompositeTypeSpecifier getCompositeTypeSpecifier() {
IASTNode definition= getDefinition();
if (definition != null) {
IASTNode node= definition;
while (node instanceof IASTName)
node= node.getParent();
if (node instanceof ICPPASTCompositeTypeSpecifier)
return (ICPPASTCompositeTypeSpecifier) node;
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getBases()
*/
public ICPPBase[] getBases() throws DOMException {
if( getDefinition() == null ){
ICPPBase[] result = null;
ICPPBase[] bindings = (getSpecializedBinding()).getBases();
for (ICPPBase binding : bindings) {
ICPPBase specBinding = (ICPPBase) ((ICPPInternalBase)binding).clone();
IBinding base = binding.getBaseClass();
if (base instanceof IType) {
IType specBase= specializeType((IType) base);
specBase = SemanticUtil.getUltimateType(specBase, false);
if (specBase instanceof IBinding && !(specBase instanceof IProblemBinding)) {
((ICPPInternalBase)specBinding).setBaseClass((IBinding)specBase);
}
result = (ICPPBase[]) ArrayUtil.append(ICPPBase.class, result, specBinding);
}
}
return (ICPPBase[]) ArrayUtil.trim(ICPPBase.class, result);
}
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]);
IBinding base = bindings[i].getBaseClass();
if (base instanceof IType) {
IType specBase = specializeType((IType) base);
if (specBase instanceof ICPPClassType) {
((CPPBaseClause) bindings[i]).setBaseClass((ICPPClassType) specBase);
}
}
}
return bindings;
ICPPClassSpecializationScope scope= getSpecializationScope();
if (scope == null)
return ClassTypeHelper.getBases(this);
return scope.getBases();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getFields()
*/
public IField[] getFields() throws DOMException {
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#findField(java.lang.String)
*/
public IField findField(String name) throws DOMException {
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getDeclaredFields()
*/
public ICPPField[] getDeclaredFields() throws DOMException {
// TODO Auto-generated method stub
return null;
ICPPClassSpecializationScope scope= getSpecializationScope();
if (scope == null)
return ClassTypeHelper.getDeclaredFields(this);
return scope.getDeclaredFields();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getMethods()
*/
public ICPPMethod[] getMethods() throws DOMException {
return CPPClassType.getMethods(this);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getAllDeclaredMethods()
*/
public ICPPMethod[] getAllDeclaredMethods() throws DOMException {
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getDeclaredMethods()
*/
public ICPPMethod[] getDeclaredMethods() throws DOMException {
IScope scope= getCompositeScope();
if (scope instanceof CPPClassSpecializationScope) {
CPPClassSpecializationScope sscope= (CPPClassSpecializationScope) scope;
if (sscope.isFullyCached())
return sscope.getDeclaredMethods();
}
IBinding binding = null;
ICPPMethod [] result = null;
ICPPClassSpecializationScope scope= getSpecializationScope();
if (scope == null)
return ClassTypeHelper.getDeclaredMethods(this);
IASTDeclaration [] decls = getCompositeTypeSpecifier().getMembers();
for (IASTDeclaration decl : decls) {
while( decl instanceof ICPPASTTemplateDeclaration )
decl = ((ICPPASTTemplateDeclaration)decl).getDeclaration();
if( decl instanceof IASTSimpleDeclaration ){
IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decl).getDeclarators();
for (IASTDeclarator dtor : dtors) {
binding = dtor.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.findInnermostDeclarator(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 (IBinding element : bs) {
if( element instanceof ICPPMethod )
result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, element );
}
} else if( binding instanceof ICPPMethod ) {
result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, binding );
}
}
}
return (ICPPMethod[]) ArrayUtil.trim( ICPPMethod.class, result );
return scope.getDeclaredMethods();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getConstructors()
*/
public ICPPConstructor[] getConstructors() throws DOMException {
IScope scope = getCompositeScope();
if (scope instanceof CPPClassSpecializationScope) {
if (ASTInternal.isFullyCached(scope))
return ((CPPClassSpecializationScope)scope).getConstructors();
}
if( ASTInternal.isFullyCached(scope))
return ((CPPClassScope)scope).getConstructors( true );
IASTDeclaration [] members = getCompositeTypeSpecifier().getMembers();
for (IASTDeclaration decl : members) {
if( decl instanceof ICPPASTTemplateDeclaration )
decl = ((ICPPASTTemplateDeclaration)decl).getDeclaration();
if( decl instanceof IASTSimpleDeclaration ){
IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decl).getDeclarators();
for (IASTDeclarator dtor : dtors) {
if( dtor == null ) break;
dtor= CPPVisitor.findInnermostDeclarator(dtor);
ASTInternal.addName(scope, dtor.getName() );
}
} else if( decl instanceof IASTFunctionDefinition ){
IASTDeclarator dtor = ((IASTFunctionDefinition)decl).getDeclarator();
dtor= CPPVisitor.findInnermostDeclarator(dtor);
ASTInternal.addName(scope, dtor.getName() );
}
}
return ((CPPClassScope)scope).getConstructors( true );
ICPPClassSpecializationScope scope= getSpecializationScope();
if (scope == null)
return ClassTypeHelper.getConstructors(this);
return scope.getConstructors();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getFriends()
*/
public IBinding[] getFriends() throws DOMException {
// TODO Auto-generated method stub
return IBinding.EMPTY_BINDING_ARRAY;
ICPPClassSpecializationScope scope= getSpecializationScope();
if (scope == null)
return ClassTypeHelper.getFriends(this);
return scope.getFriends();
}
public ICPPClassType[] getNestedClasses() throws DOMException {
ICPPClassSpecializationScope scope= getSpecializationScope();
if (scope == null)
return ClassTypeHelper.getNestedClasses(this);
return scope.getNestedClasses();
}
public IField[] getFields() throws DOMException {
return ClassTypeHelper.getFields(this);
}
public IField findField(String name) throws DOMException {
return ClassTypeHelper.findField(this, name);
}
public ICPPMethod[] getMethods() throws DOMException {
return ClassTypeHelper.getMethods(this);
}
public ICPPMethod[] getAllDeclaredMethods() throws DOMException {
return ClassTypeHelper.getAllDeclaredMethods(this);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.ICompositeType#getKey()
@ -272,21 +249,23 @@ public class CPPClassSpecialization extends CPPSpecialization implements ICPPCla
* @see org.eclipse.cdt.core.dom.ast.ICompositeType#getCompositeScope()
*/
public IScope getCompositeScope() throws DOMException {
final IScope specScope= getSpecializationScope();
if (specScope != null)
return specScope;
return getCompositeTypeSpecifier().getScope();
}
private ICPPClassSpecializationScope getSpecializationScope() {
checkForDefinition();
if (getDefinition() != null)
return null;
//implicit specialization: must specialize bindings in scope
if (specScope == null) {
ICPPClassScope scope = null;
if( getDefinition() != null ){
scope = (ICPPClassScope) getCompositeTypeSpecifier().getScope();
}
if (scope != null && scope.getClassType() == this) {
//explicit specialization: can use composite type specifier scope
specScope = scope;
} else {
//implicit specialization: must specialize bindings in scope
specScope = new CPPClassSpecializationScope(this);
}
specScope = new CPPClassSpecializationScope(this);
}
return specScope;
return specScope;
}
/* (non-Javadoc)
@ -306,11 +285,6 @@ public class CPPClassSpecialization extends CPPSpecialization implements ICPPCla
return this;
}
public ICPPClassType[] getNestedClasses() throws DOMException {
return ICPPClassType.EMPTY_CLASS_ARRAY;
}
public boolean isAnonymous() throws DOMException {
if (getNameCharArray().length > 0)
return false;

View file

@ -6,10 +6,10 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* Bryan Wilkinson (QNX)
* Markus Schorn (Wind River Systems)
* Andrew Ferguson (Symbian)
* IBM - Initial API and implementation
* Bryan Wilkinson (QNX)
* Markus Schorn (Wind River Systems)
* Andrew Ferguson (Symbian)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -106,11 +106,9 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements
}
private ICPPClassTemplatePartialSpecialization[] partialSpecializations = null;
private ClassTypeMixin mixin;
public CPPClassTemplate(IASTName name) {
super(name);
this.mixin= new ClassTypeMixin(this);
}
public void checkForDefinition() {
@ -197,43 +195,43 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements
}
public ICPPBase[] getBases() {
return mixin.getBases();
return ClassTypeHelper.getBases(this);
}
public IField[] getFields() throws DOMException {
return mixin.getFields();
return ClassTypeHelper.getFields(this);
}
public ICPPField[] getDeclaredFields() throws DOMException {
return mixin.getDeclaredFields();
return ClassTypeHelper.getDeclaredFields(this);
}
public ICPPMethod[] getMethods() throws DOMException {
return CPPClassType.getMethods(this);
return ClassTypeHelper.getMethods(this);
}
public ICPPMethod[] getAllDeclaredMethods() throws DOMException {
return mixin.getAllDeclaredMethods();
return ClassTypeHelper.getAllDeclaredMethods(this);
}
public ICPPMethod[] getDeclaredMethods() throws DOMException {
return mixin.getDeclaredMethods();
return ClassTypeHelper.getDeclaredMethods(this);
}
public ICPPConstructor[] getConstructors() throws DOMException {
return mixin.getConstructors();
return ClassTypeHelper.getConstructors(this);
}
public IBinding[] getFriends() {
return mixin.getFriends();
return ClassTypeHelper.getFriends(this);
}
public ICPPClassType[] getNestedClasses() {
return mixin.getNestedClasses();
return ClassTypeHelper.getNestedClasses(this);
}
public IField findField(String name) throws DOMException {
return mixin.findField(name);
return ClassTypeHelper.findField(this, name);
}
@Override

View file

@ -49,7 +49,6 @@ import org.eclipse.cdt.core.index.IIndex;
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.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
@ -63,83 +62,60 @@ import org.eclipse.core.runtime.PlatformObject;
*/
public class CPPClassType extends PlatformObject implements ICPPInternalClassTypeMixinHost {
public static ICPPMethod[] getMethods(ICPPClassType ct) throws DOMException {
ObjectSet<ICPPMethod> set = new ObjectSet<ICPPMethod>(4);
set.addAll(ct.getDeclaredMethods());
ICPPClassScope scope = (ICPPClassScope) ct.getCompositeScope();
set.addAll( scope.getImplicitMethods() );
ICPPBase [] bases = ct.getBases();
for (ICPPBase base : bases) {
IBinding b = base.getBaseClass();
if( b instanceof ICPPClassType )
set.addAll( ((ICPPClassType)b).getMethods() );
public static class CPPClassTypeProblem extends ProblemBinding implements ICPPClassType {
public CPPClassTypeProblem(IASTNode node, int id, char[] arg) {
super(node, id, arg);
}
return set.keyArray(ICPPMethod.class);
}
public static class CPPClassTypeProblem extends ProblemBinding implements ICPPClassType{
public CPPClassTypeProblem( IASTNode node, int id, char[] arg ) {
super( node, id, arg );
}
public ICPPBase[] getBases() throws DOMException {
throw new DOMException( this );
throw new DOMException(this);
}
public IField[] getFields() throws DOMException {
throw new DOMException( this );
throw new DOMException(this);
}
public ICPPField[] getDeclaredFields() throws DOMException {
throw new DOMException( this );
throw new DOMException(this);
}
public ICPPMethod[] getMethods() throws DOMException {
throw new DOMException( this );
throw new DOMException(this);
}
public ICPPMethod[] getAllDeclaredMethods() throws DOMException {
throw new DOMException( this );
throw new DOMException(this);
}
public ICPPMethod[] getDeclaredMethods() throws DOMException {
throw new DOMException( this );
throw new DOMException(this);
}
public ICPPConstructor[] getConstructors() throws DOMException {
throw new DOMException( this );
throw new DOMException(this);
}
public ICPPMethod[] getDeclaredConversionOperators() throws DOMException {
throw new DOMException( this );
throw new DOMException(this);
}
public int getKey() throws DOMException {
throw new DOMException( this );
throw new DOMException(this);
}
public IField findField(String name) throws DOMException {
throw new DOMException( this );
throw new DOMException(this);
}
public IScope getCompositeScope() throws DOMException {
throw new DOMException( this );
}
@Override
public IScope getParent() throws DOMException {
throw new DOMException( this );
}
@Override
public IBinding[] find(String name) throws DOMException {
throw new DOMException( this );
throw new DOMException(this);
}
public IBinding[] getFriends() throws DOMException {
throw new DOMException( this );
throw new DOMException(this);
}
public String[] getQualifiedName() throws DOMException {
throw new DOMException( this );
throw new DOMException(this);
}
public char[][] getQualifiedNameCharArray() throws DOMException {
throw new DOMException( this );
throw new DOMException(this);
}
public boolean isGloballyQualified() throws DOMException {
throw new DOMException( this );
throw new DOMException(this);
}
public ICPPClassType[] getNestedClasses() throws DOMException {
throw new DOMException( this );
throw new DOMException(this);
}
public boolean isAnonymous() throws DOMException {
throw new DOMException( this );
throw new DOMException(this);
}
}
@ -203,7 +179,6 @@ public class CPPClassType extends PlatformObject implements ICPPInternalClassTyp
private IASTName [] declarations;
private boolean checked = false;
private ICPPClassType typeInIndex;
private ClassTypeMixin mixin;
public CPPClassType( IASTName name, IBinding indexBinding ){
if( name instanceof ICPPASTQualifiedName ){
@ -222,7 +197,6 @@ public class CPPClassType extends PlatformObject implements ICPPInternalClassTyp
if (indexBinding instanceof ICPPClassType && indexBinding instanceof IIndexBinding) {
typeInIndex= (ICPPClassType) indexBinding;
}
mixin= new ClassTypeMixin(this);
}
public IASTNode[] getDeclarations() {
@ -406,43 +380,43 @@ public class CPPClassType extends PlatformObject implements ICPPInternalClassTyp
}
public ICPPBase [] getBases() {
return mixin.getBases();
return ClassTypeHelper.getBases(this);
}
public IField[] getFields() throws DOMException {
return mixin.getFields();
return ClassTypeHelper.getFields(this);
}
public ICPPField[] getDeclaredFields() throws DOMException {
return mixin.getDeclaredFields();
return ClassTypeHelper.getDeclaredFields(this);
}
public ICPPMethod[] getMethods() throws DOMException {
return getMethods(this);
return ClassTypeHelper.getMethods(this);
}
public ICPPMethod[] getAllDeclaredMethods() throws DOMException {
return mixin.getAllDeclaredMethods();
return ClassTypeHelper.getAllDeclaredMethods(this);
}
public ICPPMethod[] getDeclaredMethods() throws DOMException {
return mixin.getDeclaredMethods();
return ClassTypeHelper.getDeclaredMethods(this);
}
public ICPPConstructor[] getConstructors() throws DOMException {
return mixin.getConstructors();
return ClassTypeHelper.getConstructors(this);
}
public IBinding[] getFriends() {
return mixin.getFriends();
return ClassTypeHelper.getFriends(this);
}
public ICPPClassType[] getNestedClasses() {
return mixin.getNestedClasses();
return ClassTypeHelper.getNestedClasses(this);
}
public IField findField(String name) throws DOMException {
return mixin.findField(name);
return ClassTypeHelper.findField(this, name);
}
@Override

View file

@ -6,13 +6,9 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
*
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
/*
* Created on Apr 29, 2005
*/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ILinkage;
@ -41,7 +37,7 @@ public abstract class CPPSpecialization extends PlatformObject implements ICPPSp
private IBinding owner;
private IBinding specialized;
protected ObjectMap argumentMap;
private IASTNode definition;
protected IASTNode definition;
private IASTNode[] declarations;
public CPPSpecialization(IBinding specialized, IBinding owner, ObjectMap argumentMap) {
@ -50,7 +46,7 @@ public abstract class CPPSpecialization extends PlatformObject implements ICPPSp
this.argumentMap = argumentMap;
}
protected IType specializeType(IType type) throws DOMException {
public IType specializeType(IType type) throws DOMException {
if (owner instanceof ICPPClassSpecialization) {
return CPPTemplates.instantiateType(type, argumentMap, (ICPPClassSpecialization) owner);
} else {

View file

@ -121,37 +121,32 @@ public class CPPTemplateTemplateParameter extends CPPTemplateParameter implement
public ICPPBase[] getBases() {
return ICPPBase.EMPTY_BASE_ARRAY;
}
public IField[] getFields() throws DOMException {
return null;
return IField.EMPTY_FIELD_ARRAY;
}
public IField findField(String name) throws DOMException {
return null;
}
public ICPPField[] getDeclaredFields() throws DOMException {
return null;
return ICPPField.EMPTY_CPPFIELD_ARRAY;
}
public ICPPMethod[] getMethods() throws DOMException {
return null;
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
}
public ICPPMethod[] getAllDeclaredMethods() throws DOMException {
return null;
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
}
public ICPPMethod[] getDeclaredMethods() throws DOMException {
return null;
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
}
public ICPPConstructor[] getConstructors() {
return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY;
}
public IBinding[] getFriends() throws DOMException {
return null;
return IBinding.EMPTY_BINDING_ARRAY;
}
public ICPPClassType[] getNestedClasses() {
return ICPPClassType.EMPTY_CLASS_ARRAY;
}
public int getKey() throws DOMException {
@ -215,10 +210,6 @@ public class CPPTemplateTemplateParameter extends CPPTemplateParameter implement
}
return ICPPTemplateInstance.EMPTY_TEMPLATE_INSTANCE_ARRAY;
}
public ICPPClassType[] getNestedClasses() {
return ICPPClassType.EMPTY_CLASS_ARRAY;
}
public IASTName getUnknownName() {
return new CPPASTName(getNameCharArray());

View file

@ -48,20 +48,13 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
/**
* 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.
* a corresponding textual definition in the source code.
*
* @see CPPClassType
* @see CPPClassTemplate
*/
class ClassTypeMixin {
private ICPPInternalClassTypeMixinHost host;
public ClassTypeMixin(ICPPInternalClassTypeMixinHost host) {
this.host= host;
}
public IBinding[] getFriends() {
public class ClassTypeHelper {
public static IBinding[] getFriends(ICPPInternalClassTypeMixinHost host) {
if( host.getDefinition() == null ){
host.checkForDefinition();
if( host.getDefinition() == null ){
@ -103,7 +96,7 @@ class ClassTypeMixin {
return resultSet.keyArray(IBinding.class);
}
public ICPPBase [] getBases() {
public static ICPPBase[] getBases(ICPPInternalClassTypeMixinHost host) {
if( host.getDefinition() == null ){
host.checkForDefinition();
if( host.getDefinition() == null ){
@ -124,7 +117,7 @@ class ClassTypeMixin {
return bindings;
}
public ICPPField[] getDeclaredFields() throws DOMException {
public static ICPPField[] getDeclaredFields(ICPPInternalClassTypeMixinHost host) throws DOMException {
if( host.getDefinition() == null ){
host.checkForDefinition();
if( host.getDefinition() == null ){
@ -161,19 +154,10 @@ class ClassTypeMixin {
}
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();
public static ICPPMethod[] getAllDeclaredMethods(ICPPClassType ct) throws DOMException {
ICPPMethod[] methods = ct.getDeclaredMethods();
ICPPBase [] bases = ct.getBases();
for (ICPPBase base : bases) {
IBinding b = base.getBaseClass();
if( b instanceof ICPPClassType )
@ -181,8 +165,22 @@ class ClassTypeMixin {
}
return (ICPPMethod[]) ArrayUtil.trim( ICPPMethod.class, methods );
}
public ICPPMethod[] getDeclaredMethods() throws DOMException {
public static ICPPMethod[] getMethods(ICPPClassType ct) throws DOMException {
ObjectSet<ICPPMethod> set = new ObjectSet<ICPPMethod>(4);
set.addAll(ct.getDeclaredMethods());
ICPPClassScope scope = (ICPPClassScope) ct.getCompositeScope();
set.addAll(scope.getImplicitMethods());
ICPPBase[] bases = ct.getBases();
for (ICPPBase base : bases) {
IBinding b = base.getBaseClass();
if (b instanceof ICPPClassType)
set.addAll(((ICPPClassType) b).getMethods());
}
return set.keyArray(ICPPMethod.class);
}
public static ICPPMethod[] getDeclaredMethods(ICPPInternalClassTypeMixinHost host) throws DOMException {
if( host.getDefinition() == null ){
host.checkForDefinition();
if( host.getDefinition() == null ){
@ -232,7 +230,7 @@ class ClassTypeMixin {
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getConstructors()
*/
public ICPPConstructor[] getConstructors() throws DOMException {
public static ICPPConstructor[] getConstructors(ICPPInternalClassTypeMixinHost host) throws DOMException {
if( host.getDefinition() == null ){
host.checkForDefinition();
if( host.getDefinition() == null ){
@ -267,7 +265,7 @@ class ClassTypeMixin {
return ((CPPClassScope)scope).getConstructors( true );
}
public ICPPClassType[] getNestedClasses() {
public static ICPPClassType[] getNestedClasses(ICPPInternalClassTypeMixinHost host) {
if( host.getDefinition() == null ){
host.checkForDefinition();
if( host.getDefinition() == null ){
@ -300,18 +298,9 @@ class ClassTypeMixin {
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();
public static IField[] getFields(ICPPClassType ct) throws DOMException {
IField[] fields = ct.getDeclaredFields();
ICPPBase [] bases = ct.getBases();
for (ICPPBase base : bases) {
IBinding b = base.getBaseClass();
if( b instanceof ICPPClassType )
@ -320,17 +309,17 @@ class ClassTypeMixin {
return (IField[]) ArrayUtil.trim( IField.class, fields );
}
public IField findField(String name) throws DOMException {
IBinding [] bindings = CPPSemantics.findBindings( host.getCompositeScope(), name, true );
public static IField findField(ICPPClassType ct, String name) throws DOMException {
IBinding[] bindings = CPPSemantics.findBindings(ct.getCompositeScope(), name, true);
IField field = null;
for (IBinding binding : bindings) {
if( binding instanceof IField ){
if( field == null )
if (binding instanceof IField) {
if (field == null) {
field = (IField) binding;
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() );
} else {
IASTNode[] decls= ASTInternal.getDeclarationsOfBinding(ct);
IASTNode node= (decls != null && decls.length > 0) ? decls[0] : null;
return new CPPField.CPPFieldProblem(node, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, name.toCharArray());
}
}
}

View file

@ -11,10 +11,13 @@
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;
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.ICPPClassSpecialization;
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;
/**
@ -35,12 +38,32 @@ public interface ICPPClassSpecializationScope extends ICPPClassScope {
ICPPClassSpecialization getClassType();
/**
* Computes constructors off specialized class.
* Computes the bases via the original class.
*/
ICPPBase[] getBases() throws DOMException;
/**
* Computes the constructors via the original class.
*/
ICPPConstructor[] getConstructors() throws DOMException;
/**
* Computes the declared methods off the specialized class.
* Computes the methods via the original class.
*/
ICPPMethod[] getDeclaredMethods() throws DOMException;
/**
* Computes the fields via the original class.
*/
ICPPField[] getDeclaredFields() throws DOMException;
/**
* Computes the friends via the original class.
*/
IBinding[] getFriends() throws DOMException;
/**
* Computes the nested classes via the original class.
*/
ICPPClassType[] getNestedClasses() throws DOMException;
}

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andrew Ferguson (Symbian) - Initial implementation
* Andrew Ferguson (Symbian) - Initial implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -14,7 +14,7 @@ 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
* Internal interface for exposing internal methods to {@link ClassTypeHelper}
*/
interface ICPPInternalClassTypeMixinHost extends ICPPClassType, ICPPInternalBinding {
/**

View file

@ -257,9 +257,11 @@ public interface IIndexFragment {
/**
* Caches an object with the key, the cache must be cleared at latest when the fragment no
* longer holds a locks.
* longer holds a locks.
* @param replace if <code>false</code> an existing entry will not be replaced.
* @return the value that is actually stored.
*/
void putCachedResult(Object key, Object value);
Object putCachedResult(Object key, Object value, boolean replace);
/**
* Returns a previously cached object, the cache is cleared at latest when the fragment no

View file

@ -6,7 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andrew Ferguson (Symbian) - Initial implementation
* Andrew Ferguson (Symbian) - Initial implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.index.composite;
@ -57,6 +58,16 @@ public abstract class AbstractCompositeFactory implements ICompositesFactory {
public final IIndexBinding[] getCompositeBindings(IIndexFragmentBinding[][] fragmentBindings) {
return getCompositeBindings(mergeBindingArrays(fragmentBindings));
}
public final IIndexFragmentBinding[] findEquivalentBindings(IBinding binding) {
CIndex cindex= (CIndex) index;
try {
return cindex.findEquivalentBindings(binding);
} catch (CoreException e) {
CCorePlugin.log(e);
return IIndexFragmentBinding.EMPTY_INDEX_BINDING_ARRAY;
}
}
/**
* Convenience method for taking a group of binding arrays, and returning a single array
@ -84,8 +95,7 @@ public abstract class AbstractCompositeFactory implements ICompositesFactory {
*/
protected IIndexFragmentBinding findOneBinding(IBinding binding, boolean allowDeclaration) {
try{
CIndex cindex= (CIndex) index;
IIndexFragmentBinding[] ibs= cindex.findEquivalentBindings(binding);
IIndexFragmentBinding[] ibs= findEquivalentBindings(binding);
IBinding def= null;
IBinding dec= ibs.length>0 ? ibs[0] : null;
for(int i=0; i<ibs.length; i++) {

View file

@ -11,6 +11,7 @@
package org.eclipse.cdt.internal.core.index.composite;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
@ -40,4 +41,9 @@ public interface ICompositesFactory {
* Identifies common bindings, calls getCompositeBindings
*/
public IIndexBinding[] getCompositeBindings(IIndexFragmentBinding[][] bindings);
/**
* Selects all equivalent bindings from the available fragments
*/
public IIndexFragmentBinding[] findEquivalentBindings(IBinding binding);
}

View file

@ -6,18 +6,15 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andrew Ferguson (Symbian) - Initial implementation
* Andrew Ferguson (Symbian) - Initial implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.index.composite.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.index.IIndexScope;
import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
public class CompositeCPPClassInstance extends CompositeCPPClassSpecialization implements ICPPTemplateInstance {
@ -26,15 +23,11 @@ public class CompositeCPPClassInstance extends CompositeCPPClassSpecialization i
super(cf, rbinding);
}
@Override
public IScope getCompositeScope() throws DOMException {
return cf.getCompositeScope((IIndexScope) ((ICPPClassType) rbinding).getCompositeScope());
public IType[] getArguments() {
return TemplateInstanceUtil.getArguments(cf, (ICPPTemplateInstance) rbinding);
}
public ICPPTemplateDefinition getTemplateDefinition() {
return TemplateInstanceUtil.getTemplateDefinition(cf, rbinding);
}
@Override
public ObjectMap getArgumentMap() { return TemplateInstanceUtil.getArgumentMap(cf, rbinding); }
@Override
public ICPPClassType getSpecializedBinding() { return (ICPPClassType) TemplateInstanceUtil.getSpecializedBinding(cf, rbinding); }
public IType[] getArguments() { return TemplateInstanceUtil.getArguments(cf, (ICPPTemplateInstance) rbinding); }
public ICPPTemplateDefinition getTemplateDefinition() { return TemplateInstanceUtil.getTemplateDefinition(cf, rbinding); }
}

View file

@ -1,31 +1,34 @@
/*******************************************************************************
* Copyright (c) 2007 Symbian Software Systems and others.
* Copyright (c) 2007, 2008 Symbian Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andrew Ferguson (Symbian) - Initial implementation
* Andrew Ferguson (Symbian) - Initial implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.index.composite.cpp;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
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.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBase;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
import org.eclipse.cdt.internal.core.index.IIndexScope;
import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
public class CompositeCPPClassSpecialization extends CompositeCPPClassType implements ICPPClassSpecialization {
@ -36,6 +39,11 @@ public class CompositeCPPClassSpecialization extends CompositeCPPClassType imple
super(cf, rbinding);
}
@Override
public IScope getCompositeScope() throws DOMException {
return cf.getCompositeScope((IIndexScope) ((ICPPClassType) rbinding).getCompositeScope());
}
public ObjectMap getArgumentMap() {
return TemplateInstanceUtil.getArgumentMap(cf, rbinding);
}
@ -49,46 +57,56 @@ public class CompositeCPPClassSpecialization extends CompositeCPPClassType imple
final Object key= CPPCompositesFactory.createSpecializationKey(cf, rbinding);
final IIndexFragment frag= rbinding.getFragment();
Object cached= frag.getCachedResult(key);
if (cached instanceof ObjectMap) {
if (cached != null) {
specializationMap= (ObjectMap) cached;
} else {
final ObjectMap newMap= new ObjectMap(2);
frag.putCachedResult(key, newMap);
specializationMap= newMap;
try {
// in any fragment explicit specializations may be defined.
IIndexFragmentBinding[] frags= cf.findEquivalentBindings(rbinding);
for (IIndexFragmentBinding fb : frags) {
if (fb instanceof ICPPClassType) {
final ICPPClassType[] nested = ((ICPPClassType)fb).getNestedClasses();
if (nested.length > 0) {
for (ICPPClassType ct : nested) {
if (ct instanceof ICPPClassSpecialization &&
!(ct.getCompositeScope() instanceof ICPPClassSpecializationScope)) {
ICPPClassSpecialization cspec= (ICPPClassSpecialization) cf.getCompositeBinding((IIndexFragmentBinding) ct);
newMap.put(cspec.getSpecializedBinding(), cspec);
}
}
if (!newMap.isEmpty())
break;
}
}
}
} catch (DOMException e) {
CCorePlugin.log(e);
}
specializationMap= (ObjectMap) frag.putCachedResult(key, newMap, false);
}
}
IBinding result= (IBinding) specializationMap.get(original);
if (result == null) {
result= CPPTemplates.createSpecialization(this, original, getArgumentMap());
specializationMap.put(original, result);
synchronized (specializationMap) {
IBinding result= (IBinding) specializationMap.get(original);
if (result != null)
return result;
}
return result;
IBinding newSpec= CPPTemplates.createSpecialization(this, original, getArgumentMap());
synchronized (specializationMap) {
IBinding oldSpec= (IBinding) specializationMap.put(original, newSpec);
if (oldSpec != null) {
specializationMap.put(original, oldSpec);
return oldSpec;
}
}
return newSpec;
}
@Override
public ICPPBase[] getBases() throws DOMException {
IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) {
// this is an implicit specialization
final ICPPBase[] pdomBases = (getSpecializedBinding()).getBases();
if (pdomBases != null) {
ICPPBase[] result = null;
for (ICPPBase origBase : pdomBases) {
ICPPBase specBase = (ICPPBase) ((ICPPInternalBase)origBase).clone();
IBinding origClass = origBase.getBaseClass();
if (origClass instanceof IType) {
IType specClass = CPPTemplates.instantiateType((IType) origClass, getArgumentMap(), this);
specClass = SemanticUtil.getUltimateType(specClass, true);
if (specClass instanceof IBinding) {
((ICPPInternalBase)specBase).setBaseClass((IBinding) specClass);
}
result = (ICPPBase[]) ArrayUtil.append(ICPPBase.class, result, specBase);
}
}
return (ICPPBase[]) ArrayUtil.trim(ICPPBase.class, result);
}
return ICPPBase.EMPTY_BASE_ARRAY;
return ((ICPPClassSpecializationScope) scope).getBases();
}
return super.getBases();
}
@ -110,4 +128,51 @@ public class CompositeCPPClassSpecialization extends CompositeCPPClassType imple
}
return super.getDeclaredMethods();
}
@Override
public ICPPField[] getDeclaredFields() throws DOMException {
IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getDeclaredFields();
}
return super.getDeclaredFields();
}
@Override
public IBinding[] getFriends() throws DOMException {
IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getFriends();
}
return super.getFriends();
}
@Override
public ICPPClassType[] getNestedClasses() throws DOMException {
IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getNestedClasses();
}
return super.getNestedClasses();
}
@Override
public IField findField(String name) throws DOMException {
return ClassTypeHelper.findField(this, name);
}
@Override
public ICPPMethod[] getAllDeclaredMethods() throws DOMException {
return ClassTypeHelper.getAllDeclaredMethods(this);
}
@Override
public IField[] getFields() throws DOMException {
return ClassTypeHelper.getFields(this);
}
@Override
public ICPPMethod[] getMethods() throws DOMException {
return ClassTypeHelper.getMethods(this);
}
}

View file

@ -7,6 +7,7 @@
*
* Contributors:
* Andrew Ferguson (Symbian) - Initial implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.index.composite.cpp;
@ -14,9 +15,11 @@ import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.EScopeKind;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
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.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexFileSet;
@ -90,4 +93,24 @@ public class CompositeCPPClassSpecializationScope extends CompositeScope impleme
createDelegate();
return fDelegate.getDeclaredMethods();
}
public ICPPBase[] getBases() throws DOMException {
createDelegate();
return fDelegate.getBases();
}
public ICPPField[] getDeclaredFields() throws DOMException {
createDelegate();
return fDelegate.getDeclaredFields();
}
public IBinding[] getFriends() throws DOMException {
createDelegate();
return fDelegate.getFriends();
}
public ICPPClassType[] getNestedClasses() throws DOMException {
createDelegate();
return fDelegate.getNestedClasses();
}
}

View file

@ -22,7 +22,6 @@ 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;
@ -50,7 +49,7 @@ class CompositeCPPClassType extends CompositeCPPBinding implements ICPPClassType
return result;
}
private class CPPBaseDelegate implements ICPPBase, ICPPInternalBase {
private class CPPBaseDelegate implements ICPPBase {
private ICPPBase base;
private IBinding baseClass;
private boolean writable;
@ -84,16 +83,16 @@ class CompositeCPPClassType extends CompositeCPPBinding implements ICPPClassType
return base.isVirtual();
}
public void setBaseClass(IBinding binding) throws DOMException {
public void setBaseClass(IBinding binding) {
if(writable) {
baseClass= binding;
} else {
((ICPPInternalBase)base).setBaseClass(binding);
base.setBaseClass(binding);
}
}
@Override
public Object clone(){
public ICPPBase clone(){
return new CPPBaseDelegate(base, true);
}
}

View file

@ -10,15 +10,18 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.index.composite.cpp;
import java.util.ArrayList;
import java.util.HashMap;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
import org.eclipse.cdt.internal.core.index.IndexCPPSignatureUtil;
import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
import org.eclipse.core.runtime.CoreException;
public class CompositeInstanceCache {
@ -26,43 +29,38 @@ public class CompositeInstanceCache {
final IIndexFragment frag= fb.getFragment();
final Object key = CPPCompositesFactory.createInstanceCacheKey(cf, fb);
Object cache= frag.getCachedResult(key);
if (cache instanceof CompositeInstanceCache) {
if (cache != null) {
return (CompositeInstanceCache) cache;
}
CompositeInstanceCache newCache= new CompositeInstanceCache();
newCache.populate(cf, fb);
cache= frag.getCachedResult(key);
if (cache instanceof CompositeInstanceCache) {
return (CompositeInstanceCache) cache;
}
frag.putCachedResult(key, newCache);
return newCache;
return (CompositeInstanceCache) frag.putCachedResult(key, newCache, false);
}
private final ArrayList<Object> fList;
private final HashMap<String, ICPPTemplateInstance> fMap;
public CompositeInstanceCache() {
fList= new ArrayList<Object>();
fMap= new HashMap<String, ICPPTemplateInstance>();
}
synchronized public final void addInstance(IType[] arguments, ICPPTemplateInstance instance) {
fList.add(arguments);
fList.add(instance);
try {
String key= IndexCPPSignatureUtil.getTemplateArgString(arguments, true);
fMap.put(key, instance);
} catch (CoreException e) {
CCorePlugin.log(e);
} catch (DOMException e) {
}
}
synchronized public final ICPPTemplateInstance getInstance(IType[] arguments) {
loop: for (int i=0; i < fList.size(); i+=2) {
final IType[] args = (IType[]) fList.get(i);
if (args.length == arguments.length) {
for (int j=0; j < args.length; j++) {
if (!CPPTemplates.isSameTemplateArgument(args[j], arguments[j])) {
continue loop;
}
}
return (ICPPTemplateInstance) fList.get(i+1);
}
try {
String key= IndexCPPSignatureUtil.getTemplateArgString(arguments, true);
return fMap.get(key);
} catch (CoreException e) {
CCorePlugin.log(e);
} catch (DOMException e) {
}
return null;
}
@ -73,18 +71,14 @@ public class CompositeInstanceCache {
for (ICPPTemplateInstance ti : insts) {
if (ti instanceof IIndexFragmentBinding) {
ICPPTemplateInstance comp= (ICPPTemplateInstance) cf.getCompositeBinding((IIndexFragmentBinding) ti);
fList.add(comp.getArguments());
fList.add(comp);
IType[] args= comp.getArguments();
addInstance(args, comp);
}
}
}
}
synchronized public ICPPTemplateInstance[] getAllInstances() {
ICPPTemplateInstance[] result= new ICPPTemplateInstance[fList.size()/2];
for (int i=0; i < fList.size(); i+=2) {
result[i/2]= (ICPPTemplateInstance) fList.get(i+1);
}
return result;
return fMap.values().toArray(new ICPPTemplateInstance[fMap.size()]);
}
}

View file

@ -960,8 +960,17 @@ public class PDOM extends PlatformObject implements IPDOM {
}
public void putCachedResult(Object key, Object result) {
putCachedResult(key, result, true);
}
public Object putCachedResult(Object key, Object result, boolean replace) {
synchronized(fResultCache) {
fResultCache.put(key, result);
Object old= fResultCache.put(key, result);
if (old != null && !replace) {
fResultCache.put(key, old);
return old;
}
return result;
}
}

View file

@ -256,6 +256,7 @@ public class PDOMProxy implements IPDOM {
return null;
}
public void putCachedResult(Object key, Object value) {
public Object putCachedResult(Object key, Object value, boolean replace) {
return value;
}
}

View file

@ -134,7 +134,7 @@ class PDOMCPPBase implements ICPPBase, ICPPInternalBase {
}
@Override
public Object clone() {
public ICPPBase clone() {
return new PDOMCPPBaseClone(this);
}
@ -164,7 +164,7 @@ class PDOMCPPBase implements ICPPBase, ICPPInternalBase {
baseClass = binding;
}
@Override
public Object clone() {
public ICPPBase clone() {
return new PDOMCPPBaseClone(this);
}
}

View file

@ -35,14 +35,11 @@ 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.ICPPTemplateDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBase;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.index.IIndexType;
import org.eclipse.cdt.internal.core.pdom.PDOM;
@ -99,20 +96,39 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
if (specializationMap == null) {
final Integer key= record+PDOMCPPLinkage.CACHE_INSTANCE_SCOPE;
Object cached= pdom.getCachedResult(key);
if (cached instanceof ObjectMap) {
if (cached != null) {
specializationMap= (ObjectMap) cached;
} else {
final ObjectMap newMap= new ObjectMap(2);
pdom.putCachedResult(key, newMap);
specializationMap= newMap;
try {
PDOMClassUtil.NestedClassCollector visitor = new PDOMClassUtil.NestedClassCollector();
PDOMCPPClassScope.acceptViaCache(this, visitor, false);
final ICPPClassType[] nested= visitor.getNestedClasses();
for (ICPPClassType classType : nested) {
if (classType instanceof ICPPSpecialization) {
newMap.put(((ICPPSpecialization) classType).getSpecializedBinding(), classType);
}
}
} catch (CoreException e) {
CCorePlugin.log(e);
}
specializationMap= (ObjectMap) pdom.putCachedResult(key, newMap, false);
}
}
IBinding result= (IBinding) specializationMap.get(original);
if (result == null) {
result= CPPTemplates.createSpecialization(this, original, getArgumentMap());
specializationMap.put(original, result);
synchronized (specializationMap) {
IBinding result= (IBinding) specializationMap.get(original);
if (result != null)
return result;
}
return result;
IBinding newSpec= CPPTemplates.createSpecialization(this, original, getArgumentMap());
synchronized (specializationMap) {
IBinding oldSpec= (IBinding) specializationMap.put(original, newSpec);
if (oldSpec != null) {
specializationMap.put(original, oldSpec);
return oldSpec;
}
}
return newSpec;
}
public IScope getCompositeScope() throws DOMException {
@ -129,34 +145,7 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
return fScope;
}
public ICPPConstructor[] getConstructors() throws DOMException {
IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getConstructors();
}
try {
PDOMClassUtil.ConstructorCollector visitor= new PDOMClassUtil.ConstructorCollector();
PDOMCPPClassScope.acceptViaCache(this, visitor, false);
return visitor.getConstructors();
} catch (CoreException e) {
CCorePlugin.log(e);
return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY;
}
}
public ICPPMethod[] getDeclaredMethods() throws DOMException {
IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getDeclaredMethods();
}
try {
PDOMClassUtil.MethodCollector methods = new PDOMClassUtil.MethodCollector(false);
PDOMCPPClassScope.acceptViaCache(this, methods, false);
return methods.getMethods();
} catch (CoreException e) {
return new ICPPMethod[0];
}
}
public PDOMCPPBase getFirstBase() throws CoreException {
int rec = pdom.getDB().getInt(record + FIRSTBASE);
@ -197,72 +186,112 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
}
}
public IField findField(String name) throws DOMException { fail(); return null; }
public ICPPMethod[] getAllDeclaredMethods() throws DOMException { fail(); return null; }
// implementation of class type
public ICPPBase[] getBases() throws DOMException {
IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) {
// this is an implicit specialization
final ICPPBase[] pdomBases = (getSpecializedBinding()).getBases();
if (pdomBases != null) {
ICPPBase[] result = null;
for (ICPPBase origBase : pdomBases) {
ICPPBase specBase = (ICPPBase) ((ICPPInternalBase)origBase).clone();
IBinding origClass = origBase.getBaseClass();
if (origClass instanceof IType) {
IType specClass = CPPTemplates.instantiateType((IType) origClass, getArgumentMap(), this);
specClass = SemanticUtil.getUltimateType(specClass, true);
if (specClass instanceof IBinding) {
((ICPPInternalBase)specBase).setBaseClass((IBinding) specClass);
}
result = (ICPPBase[]) ArrayUtil.append(ICPPBase.class, result, specBase);
}
}
return (ICPPBase[]) ArrayUtil.trim(ICPPBase.class, result);
}
} else {
// this is an explicit specialization
Integer key= record + PDOMCPPLinkage.CACHE_BASES;
ICPPBase[] bases= (ICPPBase[]) pdom.getCachedResult(key);
if (bases != null)
return bases;
try {
List<PDOMCPPBase> list = new ArrayList<PDOMCPPBase>();
for (PDOMCPPBase base = getFirstBase(); base != null; base = base.getNextBase())
list.add(base);
Collections.reverse(list);
bases = list.toArray(new ICPPBase[list.size()]);
pdom.putCachedResult(key, bases);
return bases;
} catch (CoreException e) {
CCorePlugin.log(e);
}
}
return ((ICPPClassSpecializationScope) scope).getBases();
}
// this is an explicit specialization
Integer key= record + PDOMCPPLinkage.CACHE_BASES;
ICPPBase[] bases= (ICPPBase[]) pdom.getCachedResult(key);
if (bases != null)
return bases;
try {
List<PDOMCPPBase> list = new ArrayList<PDOMCPPBase>();
for (PDOMCPPBase base = getFirstBase(); base != null; base = base.getNextBase())
list.add(base);
Collections.reverse(list);
bases = list.toArray(new ICPPBase[list.size()]);
pdom.putCachedResult(key, bases);
return bases;
} catch (CoreException e) {
CCorePlugin.log(e);
}
return ICPPBase.EMPTY_BASE_ARRAY;
}
public ICPPConstructor[] getConstructors() throws DOMException {
IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getConstructors();
}
try {
PDOMClassUtil.ConstructorCollector visitor= new PDOMClassUtil.ConstructorCollector();
PDOMCPPClassScope.acceptViaCache(this, visitor, false);
return visitor.getConstructors();
} catch (CoreException e) {
CCorePlugin.log(e);
return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY;
}
}
public ICPPMethod[] getDeclaredMethods() throws DOMException {
IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getDeclaredMethods();
}
try {
PDOMClassUtil.MethodCollector methods = new PDOMClassUtil.MethodCollector(false);
PDOMCPPClassScope.acceptViaCache(this, methods, false);
return methods.getMethods();
} catch (CoreException e) {
CCorePlugin.log(e);
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
}
}
public ICPPField[] getDeclaredFields() throws DOMException {
IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getDeclaredFields();
}
try {
PDOMClassUtil.FieldCollector visitor = new PDOMClassUtil.FieldCollector();
accept(visitor);
PDOMCPPClassScope.acceptViaCache(this, visitor, false);
return visitor.getFields();
} catch (CoreException e) {
CCorePlugin.log(e);
return new ICPPField[0];
return ICPPField.EMPTY_CPPFIELD_ARRAY;
}
}
//ICPPClassType unimplemented
public IField[] getFields() throws DOMException { fail(); return null; }
public IBinding[] getFriends() throws DOMException { fail(); return null; }
public ICPPClassType[] getNestedClasses() throws DOMException { fail(); return null; }
public ICPPClassType[] getNestedClasses() throws DOMException {
IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getNestedClasses();
}
try {
PDOMClassUtil.NestedClassCollector visitor = new PDOMClassUtil.NestedClassCollector();
PDOMCPPClassScope.acceptViaCache(this, visitor, false);
return visitor.getNestedClasses();
} catch (CoreException e) {
CCorePlugin.log(e);
return ICPPClassType.EMPTY_CLASS_ARRAY;
}
}
public IBinding[] getFriends() throws DOMException {
// not yet supported.
return IBinding.EMPTY_BINDING_ARRAY;
}
public ICPPMethod[] getMethods() throws DOMException {
return CPPClassType.getMethods(this);
return ClassTypeHelper.getMethods(this);
}
public ICPPMethod[] getAllDeclaredMethods() throws DOMException {
return ClassTypeHelper.getAllDeclaredMethods(this);
}
public IField[] getFields() throws DOMException {
return ClassTypeHelper.getFields(this);
}
public IField findField(String name) throws DOMException {
return ClassTypeHelper.findField(this, name);
}
public int getKey() throws DOMException {
@ -316,7 +345,13 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
}
@Override
public Object clone() {fail();return null;}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
}
return null;
}
@Override
public void addChild(PDOMNode member) throws CoreException {

View file

@ -16,12 +16,9 @@ package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMNode;
import org.eclipse.cdt.core.dom.IPDOMVisitor;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException;
@ -38,7 +35,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.internal.core.Util;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.db.PDOMNodeLinkedList;
@ -80,6 +77,17 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO
super(pdom, bindingRecord);
}
@Override
protected int getRecordSize() {
return RECORD_SIZE;
}
@Override
public int getNodeType() {
return IIndexCPPBindingConstants.CPPCLASSTYPE;
}
@Override
public void update(PDOMLinkage linkage, IBinding newBinding) throws CoreException {
if (newBinding instanceof ICPPClassType) {
@ -106,23 +114,33 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO
}
}
@Override
public boolean mayHaveChildren() {
return true;
}
@Override
public void addChild(PDOMNode member) throws CoreException {
pdom.removeCachedResult(record+PDOMCPPLinkage.CACHE_MEMBERS);
PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + MEMBERLIST, getLinkageImpl());
list.addMember(member);
}
@Override
protected int getRecordSize() {
return RECORD_SIZE;
public void accept(IPDOMVisitor visitor) throws CoreException {
PDOMCPPClassScope.acceptViaCache(this, visitor, false);
}
@Override
public int getNodeType() {
return IIndexCPPBindingConstants.CPPCLASSTYPE;
/**
* Called to populate the cache for the bindings in the class scope.
*/
public void acceptUncached(IPDOMVisitor visitor) throws CoreException {
super.accept(visitor);
PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + MEMBERLIST, getLinkageImpl());
list.accept(visitor);
}
private PDOMCPPBase getFirstBase() throws CoreException {
int rec = pdom.getDB().getInt(record + FIRSTBASE);
return rec != 0 ? new PDOMCPPBase(pdom, rec) : null;
@ -165,6 +183,40 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO
}
}
public IScope getCompositeScope() throws DOMException {
if (fScope == null) {
fScope= new PDOMCPPClassScope(this);
}
return fScope;
}
public int getKey() throws DOMException {
try {
return pdom.getDB().getByte(record + KEY);
} catch (CoreException e) {
CCorePlugin.log(e);
return ICPPClassType.k_class; // or something
}
}
public boolean isAnonymous() throws DOMException {
try {
return pdom.getDB().getByte(record + ANONYMOUS) != 0;
} catch (CoreException e) {
CCorePlugin.log(e);
return false;
}
}
@Override
public boolean isGloballyQualified() throws DOMException {
try {
return getParentNode() instanceof PDOMLinkage;
} catch (CoreException e) {
return true;
}
}
public boolean isSameType(IType type) {
if (type instanceof ITypedef) {
return type.isSameType(this);
@ -212,65 +264,25 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO
}
}
public ICPPConstructor[] getConstructors() throws DOMException {
PDOMClassUtil.ConstructorCollector visitor= new PDOMClassUtil.ConstructorCollector();
try {
PDOMCPPClassScope.acceptViaCache(this, visitor, false);
return visitor.getConstructors();
} catch (CoreException e) {
CCorePlugin.log(e);
return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY;
}
}
public ICPPMethod[] getDeclaredMethods() throws DOMException {
try {
PDOMClassUtil.MethodCollector methods = new PDOMClassUtil.MethodCollector(false);
PDOMCPPClassScope.acceptViaCache(this, methods, false);
return methods.getMethods();
} catch (CoreException e) {
return new ICPPMethod[0];
}
}
public ICPPMethod[] getMethods() throws DOMException {
return CPPClassType.getMethods(this);
}
static void acceptInHierarchy(IPDOMMemberOwner current, Set<IPDOMMemberOwner> visited, IPDOMVisitor visitor) throws CoreException {
if (visited.contains(current))
return;
visited.add(current);
// Class is in its own scope
visitor.visit((IPDOMNode) current);
// Get my members
current.accept(visitor);
// Visit my base classes
if(current instanceof ICPPClassType) {
try {
ICPPBase[] bases= ((ICPPClassType) current).getBases();
for(ICPPBase base : bases) {
IBinding baseClass = base.getBaseClass();
if (baseClass != null && baseClass instanceof IPDOMMemberOwner)
acceptInHierarchy((IPDOMMemberOwner)baseClass, visited, visitor);
}
} catch(DOMException de) {
CCorePlugin.log(Util.createStatus(de));
}
}
}
public ICPPMethod[] getAllDeclaredMethods() throws DOMException {
PDOMClassUtil.MethodCollector myMethods = new PDOMClassUtil.MethodCollector(false, true);
try {
acceptInHierarchy(this, new HashSet<IPDOMMemberOwner>(), myMethods);
return myMethods.getMethods();
} catch (CoreException e) {
CCorePlugin.log(e);
return new ICPPMethod[0];
}
}
public IField[] getFields() throws DOMException {
try {
PDOMClassUtil.FieldCollector visitor = new PDOMClassUtil.FieldCollector();
acceptInHierarchy(this, new HashSet<IPDOMMemberOwner>(), visitor);
return visitor.getFields();
} catch (CoreException e) {
CCorePlugin.log(e);
return new IField[0];
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
}
}
@ -281,102 +293,49 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO
return visitor.getFields();
} catch (CoreException e) {
CCorePlugin.log(e);
return new ICPPField[0];
}
}
private static class NestedClassCollector implements IPDOMVisitor {
private List<IPDOMNode> nestedClasses = new ArrayList<IPDOMNode>();
public boolean visit(IPDOMNode node) throws CoreException {
if (node instanceof ICPPClassType)
nestedClasses.add(node);
return false;
}
public void leave(IPDOMNode node) throws CoreException {
}
public ICPPClassType[] getNestedClasses() {
return nestedClasses.toArray(new ICPPClassType[nestedClasses.size()]);
return ICPPField.EMPTY_CPPFIELD_ARRAY;
}
}
public ICPPClassType[] getNestedClasses() throws DOMException {
try {
NestedClassCollector visitor = new NestedClassCollector();
PDOMClassUtil.NestedClassCollector visitor = new PDOMClassUtil.NestedClassCollector();
PDOMCPPClassScope.acceptViaCache(this, visitor, false);
return visitor.getNestedClasses();
} catch (CoreException e) {
CCorePlugin.log(e);
return new ICPPClassType[0];
return ICPPClassType.EMPTY_CLASS_ARRAY;
}
}
public IBinding[] getFriends() throws DOMException {
// not yet supported.
return IBinding.EMPTY_BINDING_ARRAY;
}
public ICPPMethod[] getMethods() throws DOMException {
return ClassTypeHelper.getMethods(this);
}
public ICPPMethod[] getAllDeclaredMethods() throws DOMException {
return ClassTypeHelper.getAllDeclaredMethods(this);
}
public IField[] getFields() throws DOMException {
return ClassTypeHelper.getFields(this);
}
public IField findField(String name) throws DOMException {
return ClassTypeHelper.findField(this, name);
}
@Override
public void accept(IPDOMVisitor visitor) throws CoreException {
PDOMCPPClassScope.acceptViaCache(this, visitor, false);
}
/**
* Called to populate the cache for the bindings in the class scope.
*/
public void acceptUncached(IPDOMVisitor visitor) throws CoreException {
super.accept(visitor);
PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + MEMBERLIST, getLinkageImpl());
list.accept(visitor);
}
public IScope getCompositeScope() throws DOMException {
if (fScope == null) {
fScope= new PDOMCPPClassScope(this);
}
return fScope;
}
public int getKey() throws DOMException {
public Object clone() {
try {
return pdom.getDB().getByte(record + KEY);
} catch (CoreException e) {
CCorePlugin.log(e);
return ICPPClassType.k_class; // or something
return super.clone();
} catch (CloneNotSupportedException e) {
}
}
public boolean isAnonymous() throws DOMException {
try {
return pdom.getDB().getByte(record + ANONYMOUS) != 0;
} catch (CoreException e) {
CCorePlugin.log(e);
return false;
}
}
@Override
public boolean isGloballyQualified() throws DOMException {
try {
return getParentNode() instanceof PDOMLinkage;
} catch (CoreException e) {
return true;
}
}
public ICPPConstructor[] getConstructors() throws DOMException {
PDOMClassUtil.ConstructorCollector visitor= new PDOMClassUtil.ConstructorCollector();
try {
PDOMCPPClassScope.acceptViaCache(this, visitor, false);
} catch (CoreException e) {
CCorePlugin.log(e);
}
return visitor.getConstructors();
}
@Override
public Object clone() {fail();return null;}
public IField findField(String name) throws DOMException {fail();return null;}
public IBinding[] getFriends() throws DOMException {fail();return null;}
@Override
public boolean mayHaveChildren() {
return true;
return null;
}
@Override

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007 QNX Software Systems and others.
* Copyright (c) 2007, 2008 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
@ -16,6 +16,7 @@ import java.util.List;
import org.eclipse.cdt.core.dom.IPDOMNode;
import org.eclipse.cdt.core.dom.IPDOMVisitor;
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;
@ -92,4 +93,18 @@ class PDOMClassUtil {
return methods.toArray(new ICPPMethod[methods.size()]);
}
}
static class NestedClassCollector implements IPDOMVisitor {
private List<IPDOMNode> nestedClasses = new ArrayList<IPDOMNode>();
public boolean visit(IPDOMNode node) throws CoreException {
if (node instanceof ICPPClassType)
nestedClasses.add(node);
return false;
}
public void leave(IPDOMNode node) throws CoreException {
}
public ICPPClassType[] getNestedClasses() {
return nestedClasses.toArray(new ICPPClassType[nestedClasses.size()]);
}
}
}

View file

@ -42,11 +42,7 @@ public class PDOMInstanceCache {
CCorePlugin.log(e);
}
cache= pdom.getCachedResult(key);
if (cache instanceof PDOMInstanceCache) {
return (PDOMInstanceCache) cache;
}
pdom.putCachedResult(key, newCache);
newCache= (PDOMInstanceCache) pdom.putCachedResult(key, newCache, false);
return newCache;
}