mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-30 21:55:31 +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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
public static final int VERSION = 8;
|
||||
public static final int VERSION = 9;
|
||||
// 0 - the beginning of it all
|
||||
// 1 - first change to kick off upgrades
|
||||
// 2 - added file inclusions
|
||||
|
@ -64,6 +64,7 @@ public class PDOM extends PlatformObject
|
|||
// 6 - function style macros.
|
||||
// 7 - class key
|
||||
// 8 - enumerators
|
||||
// 9 - base classes
|
||||
|
||||
public static final int LINKAGES = Database.DATA_AREA;
|
||||
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;
|
||||
|
||||
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.dom.ast.DOMException;
|
||||
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.ICPPField;
|
||||
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.dom.PDOMBinding;
|
||||
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,
|
||||
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)
|
||||
throws CoreException {
|
||||
|
@ -67,6 +74,22 @@ public class PDOMCPPClassType extends PDOMMemberOwner implements ICPPClassType,
|
|||
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) {
|
||||
if (type instanceof PDOMBinding)
|
||||
return record == ((PDOMBinding)type).getRecord();
|
||||
|
@ -82,14 +105,50 @@ public class PDOMCPPClassType extends PDOMMemberOwner implements ICPPClassType,
|
|||
public IField findField(String name) throws DOMException {
|
||||
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 {
|
||||
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 {
|
||||
// TODO
|
||||
return new ICPPBase[0];
|
||||
try {
|
||||
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 {
|
||||
|
|
|
@ -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.IScope;
|
||||
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.ICPPASTQualifiedName;
|
||||
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.ICPPNamespaceAlias;
|
||||
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.model.ILanguage;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBlockScope;
|
||||
|
@ -160,9 +162,24 @@ public class PDOMCPPLinkage extends PDOMLinkage {
|
|||
}
|
||||
}
|
||||
|
||||
// Add in the name
|
||||
if (pdomBinding != null)
|
||||
// final processing
|
||||
if (pdomBinding != null) {
|
||||
// Add in the name
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue