mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-17 21:25:58 +02:00
Add base classes to PDOM.
This commit is contained in:
parent
2662f5edfb
commit
4321e9a476
7 changed files with 258 additions and 9 deletions
|
@ -0,0 +1,51 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2006 QNX Software Systems and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.pdom.tests;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||||
|
import org.eclipse.cdt.core.model.ICProject;
|
||||||
|
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Doug Schaefer
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ClassTests extends PDOMTestBase {
|
||||||
|
|
||||||
|
protected ICProject project;
|
||||||
|
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
project = createProject("classTests");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void test1() throws Exception {
|
||||||
|
PDOM pdom = (PDOM)CCorePlugin.getPDOMManager().getPDOM(project);
|
||||||
|
|
||||||
|
IBinding[] Bs = pdom.findBindings(Pattern.compile("B"));
|
||||||
|
assertEquals(1, Bs.length);
|
||||||
|
ICPPClassType B = (ICPPClassType)Bs[0];
|
||||||
|
ICPPMethod[] Bmethods = B.getAllDeclaredMethods();
|
||||||
|
assertEquals(1, Bmethods.length);
|
||||||
|
ICPPMethod Bf = Bmethods[0];
|
||||||
|
assertEquals("f", Bf.getName());
|
||||||
|
IASTName [] Bf_refs = pdom.getReferences(Bf);
|
||||||
|
assertEquals(1, Bf_refs.length);
|
||||||
|
IASTFileLocation loc = Bf_refs[0].getFileLocation();
|
||||||
|
assertEquals(offset(95, 84), loc.getNodeOffset());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
class A {
|
||||||
|
public:
|
||||||
|
void f() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class B : public A {
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
B b;
|
||||||
|
b.f();
|
||||||
|
}
|
|
@ -283,4 +283,13 @@ public class ArrayUtil {
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void reverse(Object [] array) {
|
||||||
|
for (int left = 0, right = array.length - 1;
|
||||||
|
left < right; ++left, --right) {
|
||||||
|
Object tmp = array[left];
|
||||||
|
array[left] = array[right];
|
||||||
|
array[right] = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class PDOM extends PlatformObject
|
||||||
|
|
||||||
private Database db;
|
private Database db;
|
||||||
|
|
||||||
public static final int VERSION = 8;
|
public static final int VERSION = 9;
|
||||||
// 0 - the beginning of it all
|
// 0 - the beginning of it all
|
||||||
// 1 - first change to kick off upgrades
|
// 1 - first change to kick off upgrades
|
||||||
// 2 - added file inclusions
|
// 2 - added file inclusions
|
||||||
|
@ -64,6 +64,7 @@ public class PDOM extends PlatformObject
|
||||||
// 6 - function style macros.
|
// 6 - function style macros.
|
||||||
// 7 - class key
|
// 7 - class key
|
||||||
// 8 - enumerators
|
// 8 - enumerators
|
||||||
|
// 9 - base classes
|
||||||
|
|
||||||
public static final int LINKAGES = Database.DATA_AREA;
|
public static final int LINKAGES = Database.DATA_AREA;
|
||||||
public static final int FILE_INDEX = Database.DATA_AREA + 4;
|
public static final int FILE_INDEX = Database.DATA_AREA + 4;
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2006 QNX Software Systems and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.pdom.dom.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.cpp.ICPPBase;
|
||||||
|
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
||||||
|
import org.eclipse.cdt.internal.core.pdom.db.Database;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Doug Schaefer
|
||||||
|
*/
|
||||||
|
public class PDOMCPPBase implements ICPPBase {
|
||||||
|
|
||||||
|
private static final int BASECLASS = 0;
|
||||||
|
private static final int NEXTBASE = 4;
|
||||||
|
private static final int FLAGS = 8;
|
||||||
|
|
||||||
|
protected static final int RECORD_SIZE = 9;
|
||||||
|
|
||||||
|
protected final PDOM pdom;
|
||||||
|
protected final int record;
|
||||||
|
|
||||||
|
public PDOMCPPBase(PDOM pdom, int record) {
|
||||||
|
this.pdom = pdom;
|
||||||
|
this.record = record;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PDOMCPPBase(PDOM pdom, PDOMCPPClassType baseClass, boolean isVirtual, int visibility) throws CoreException {
|
||||||
|
this.pdom = pdom;
|
||||||
|
Database db = pdom.getDB();
|
||||||
|
this.record = db.malloc(RECORD_SIZE);
|
||||||
|
|
||||||
|
int baserec = baseClass != null ? baseClass.getRecord() : 0;
|
||||||
|
db.putInt(record + BASECLASS, baserec);
|
||||||
|
|
||||||
|
byte flags = (byte)(visibility | (isVirtual ? 4 : 0));
|
||||||
|
db.putByte(record + FLAGS, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRecord() {
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNextBase(PDOMCPPBase nextBase) throws CoreException {
|
||||||
|
int rec = nextBase != null ? nextBase.getRecord() : 0;
|
||||||
|
pdom.getDB().putInt(record + NEXTBASE, rec);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PDOMCPPBase getNextBase() throws CoreException {
|
||||||
|
int rec = pdom.getDB().getInt(record + NEXTBASE);
|
||||||
|
return rec != 0 ? new PDOMCPPBase(pdom, rec) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getFlags() throws CoreException {
|
||||||
|
return pdom.getDB().getByte(record + FLAGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBinding getBaseClass() throws DOMException {
|
||||||
|
try {
|
||||||
|
int rec = pdom.getDB().getInt(record + BASECLASS);
|
||||||
|
return rec != 0 ? new PDOMCPPClassType(pdom, rec) : null;
|
||||||
|
} catch (CoreException e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVisibility() throws DOMException {
|
||||||
|
try {
|
||||||
|
return getFlags() & 0x3;
|
||||||
|
} catch (CoreException e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isVirtual() throws DOMException {
|
||||||
|
try {
|
||||||
|
return (getFlags() & 0x4) != 0;
|
||||||
|
} catch (CoreException e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -11,6 +11,11 @@
|
||||||
|
|
||||||
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
|
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
|
@ -25,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
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.ICPPMethod;
|
||||||
|
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||||
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
||||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
|
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
|
||||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMember;
|
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMember;
|
||||||
|
@ -40,9 +46,10 @@ import org.eclipse.core.runtime.CoreException;
|
||||||
public class PDOMCPPClassType extends PDOMMemberOwner implements ICPPClassType,
|
public class PDOMCPPClassType extends PDOMMemberOwner implements ICPPClassType,
|
||||||
ICPPClassScope {
|
ICPPClassScope {
|
||||||
|
|
||||||
private static final int KEY = PDOMMemberOwner.RECORD_SIZE + 0; // byte
|
private static final int FIRSTBASE = PDOMMemberOwner.RECORD_SIZE + 0;
|
||||||
|
private static final int KEY = PDOMMemberOwner.RECORD_SIZE + 4; // byte
|
||||||
|
|
||||||
protected static final int RECORD_SIZE = PDOMMemberOwner.RECORD_SIZE + 1;
|
protected static final int RECORD_SIZE = PDOMMemberOwner.RECORD_SIZE + 5;
|
||||||
|
|
||||||
public PDOMCPPClassType(PDOM pdom, PDOMNode parent, IASTName name)
|
public PDOMCPPClassType(PDOM pdom, PDOMNode parent, IASTName name)
|
||||||
throws CoreException {
|
throws CoreException {
|
||||||
|
@ -67,6 +74,22 @@ public class PDOMCPPClassType extends PDOMMemberOwner implements ICPPClassType,
|
||||||
return PDOMCPPLinkage.CPPCLASSTYPE;
|
return PDOMCPPLinkage.CPPCLASSTYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PDOMCPPBase getFirstBase() throws CoreException {
|
||||||
|
int rec = pdom.getDB().getInt(record + FIRSTBASE);
|
||||||
|
return rec != 0 ? new PDOMCPPBase(pdom, rec) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setFirstBase(PDOMCPPBase base) throws CoreException {
|
||||||
|
int rec = base != null ? base.getRecord() : 0;
|
||||||
|
pdom.getDB().putInt(record + FIRSTBASE, rec);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addBase(PDOMCPPBase base) throws CoreException {
|
||||||
|
PDOMCPPBase firstBase = getFirstBase();
|
||||||
|
base.setNextBase(firstBase);
|
||||||
|
setFirstBase(base);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isSameType(IType type) {
|
public boolean isSameType(IType type) {
|
||||||
if (type instanceof PDOMBinding)
|
if (type instanceof PDOMBinding)
|
||||||
return record == ((PDOMBinding)type).getRecord();
|
return record == ((PDOMBinding)type).getRecord();
|
||||||
|
@ -83,13 +106,49 @@ public class PDOMCPPClassType extends PDOMMemberOwner implements ICPPClassType,
|
||||||
throw new PDOMNotImplementedError();
|
throw new PDOMNotImplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void visitAllDeclaredMethods(Set visited, List methods) throws CoreException {
|
||||||
|
if (visited.contains(this))
|
||||||
|
return;
|
||||||
|
visited.add(this);
|
||||||
|
|
||||||
|
// Get my members
|
||||||
|
for (PDOMMember member = getFirstMember(); member != null; member = member.getNextMember()) {
|
||||||
|
if (member instanceof ICPPMethod)
|
||||||
|
methods.add(member);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Visit my base classes
|
||||||
|
for (PDOMCPPBase base = getFirstBase(); base != null; base = base.getNextBase()) {
|
||||||
|
IBinding baseClass = base.getBaseClass();
|
||||||
|
if (baseClass != null && baseClass instanceof PDOMCPPClassType)
|
||||||
|
((PDOMCPPClassType)baseClass).visitAllDeclaredMethods(visited, methods);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public ICPPMethod[] getAllDeclaredMethods() throws DOMException {
|
public ICPPMethod[] getAllDeclaredMethods() throws DOMException {
|
||||||
throw new PDOMNotImplementedError();
|
List methods = new ArrayList();
|
||||||
|
Set visited = new HashSet();
|
||||||
|
try {
|
||||||
|
visitAllDeclaredMethods(visited, methods);
|
||||||
|
return (ICPPMethod[])methods.toArray(new ICPPMethod[methods.size()]);
|
||||||
|
} catch (CoreException e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
|
return new ICPPMethod[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICPPBase[] getBases() throws DOMException {
|
public ICPPBase[] getBases() throws DOMException {
|
||||||
// TODO
|
try {
|
||||||
return new ICPPBase[0];
|
List list = new ArrayList();
|
||||||
|
for (PDOMCPPBase base = getFirstBase(); base != null; base = base.getNextBase())
|
||||||
|
list.add(base);
|
||||||
|
ICPPBase[] bases = (ICPPBase[])list.toArray(new ICPPBase[list.size()]);
|
||||||
|
ArrayUtil.reverse(bases);
|
||||||
|
return bases;
|
||||||
|
} catch (CoreException e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
|
return new ICPPBase[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICPPConstructor[] getConstructors() throws DOMException {
|
public ICPPConstructor[] getConstructors() throws DOMException {
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.eclipse.cdt.core.dom.ast.IParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
|
||||||
|
@ -36,6 +37,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
|
import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
|
||||||
import org.eclipse.cdt.core.model.ILanguage;
|
import org.eclipse.cdt.core.model.ILanguage;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBlockScope;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBlockScope;
|
||||||
|
@ -160,10 +162,25 @@ public class PDOMCPPLinkage extends PDOMLinkage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add in the name
|
// final processing
|
||||||
if (pdomBinding != null)
|
if (pdomBinding != null) {
|
||||||
|
// Add in the name
|
||||||
new PDOMName(pdom, name, file, pdomBinding);
|
new PDOMName(pdom, name, file, pdomBinding);
|
||||||
|
|
||||||
|
// Check if is a base specifier
|
||||||
|
if (pdomBinding instanceof ICPPClassType && name.getParent() instanceof ICPPASTBaseSpecifier) {
|
||||||
|
ICPPASTBaseSpecifier baseNode = (ICPPASTBaseSpecifier)name.getParent();
|
||||||
|
ICPPASTCompositeTypeSpecifier ownerNode = (ICPPASTCompositeTypeSpecifier)baseNode.getParent();
|
||||||
|
IBinding ownerBinding = adaptBinding(ownerNode.getName().resolveBinding());
|
||||||
|
if (ownerBinding != null && ownerBinding instanceof PDOMCPPClassType) {
|
||||||
|
PDOMCPPClassType ownerClass = (PDOMCPPClassType)ownerBinding;
|
||||||
|
PDOMCPPBase pdomBase = new PDOMCPPBase(pdom, (PDOMCPPClassType)pdomBinding,
|
||||||
|
baseNode.isVirtual(), baseNode.getVisibility());
|
||||||
|
ownerClass.addBase(pdomBase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return pdomBinding;
|
return pdomBinding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue