1
0
Fork 0
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:
Doug Schaefer 2006-07-19 03:44:26 +00:00
parent 2662f5edfb
commit 4321e9a476
7 changed files with 258 additions and 9 deletions

View file

@ -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());
}
}

View file

@ -0,0 +1,13 @@
class A {
public:
void f() {
}
};
class B : public A {
};
int main() {
B b;
b.f();
}

View file

@ -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;
}
}
}

View file

@ -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;

View file

@ -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;
}
}
}

View file

@ -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 {

View file

@ -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;
}