1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Fix for 167396, inheritance relations in PDOM.

This commit is contained in:
Markus Schorn 2007-01-19 12:37:42 +00:00
parent 10fedfa4d0
commit 9c3fe10028
8 changed files with 210 additions and 63 deletions

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2006 QNX Software Systems and others.
* Copyright (c) 2005, 2007 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -71,7 +71,7 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
private Database db;
public static final int VERSION = 20;
public static final int VERSION = 22;
// 0 - the beginning of it all
// 1 - first change to kick off upgrades
// 2 - added file inclusions
@ -94,6 +94,7 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
// 19 - alter representation of paths in the pdom (162172)
// 20 - add pointer to member types, array types, return types for functions
// 21 - change representation of paths in the pdom (167549)
// 22 - fix inheritance relations (167396)
public static final int LINKAGES = Database.DATA_AREA;
public static final int FILE_INDEX = Database.DATA_AREA + 4;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2006 QNX Software Systems and others.
* Copyright (c) 2005, 2007 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.pdom.dom;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import org.eclipse.cdt.core.CCorePlugin;
@ -211,6 +212,7 @@ public class PDOMFile implements IIndexFragmentFile {
PDOMBinding binding = ((WritablePDOM) pdom).addBinding(name);
if (binding != null) {
result= new PDOMName(pdom, name, this, binding, caller);
binding.getLinkageImpl().onCreateName(result, name);
}
} catch (CoreException e) {
CCorePlugin.log(e);
@ -238,11 +240,17 @@ public class PDOMFile implements IIndexFragmentFile {
setFirstMacro(null);
// Delete all the names in this file
ArrayList names= new ArrayList();
PDOMName name = getFirstName();
while (name != null) {
PDOMName nextName = name.getNextInFile();
names.add(name);
name.getPDOMBinding().getLinkageImpl().onDeleteName(name);
name= name.getNextInFile();
}
for (Iterator iterator = names.iterator(); iterator.hasNext();) {
name = (PDOMName) iterator.next();
name.delete();
name = nextName;
}
setFirstName(null);
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2006 QNX Software Systems and others.
* Copyright (c) 2005, 2007 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -226,4 +226,26 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
return visitor.getBinding();
}
/**
* Callback informing the linkage that a name has been added. This is
* used to do addtional processing, like establishing inheritance relationships.
* @param pdomName the name that was inserted into the linkage
* @param name the name that caused the insertion
* @throws CoreException
* @since 4.0
*/
public void onCreateName(PDOMName pdomName, IASTName name) throws CoreException {
}
/**
* Callback informing the linkage that a name is about to be deleted. This is
* used to do addtional processing, like removing inheritance relationships.
* @param pdomName the name that was inserted into the linkage
* @param name the name that caused the insertion
* @throws CoreException
* @since 4.0
*/
public void onDeleteName(PDOMName nextName) throws CoreException {
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2006 QNX Software Systems and others.
* Copyright (c) 2005, 2007 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -50,6 +50,9 @@ public class PDOMName implements IIndexFragmentName, IASTFileLocation {
private static final int IS_DECLARATION = 1;
private static final int IS_DEFINITION = 2;
private static final int IS_REFERENCE = 3;
private static final int DECL_DEF_REF_MASK= 3;
private static final int IS_INHERITANCE_SPEC = 4;
public PDOMName(PDOM pdom, IASTName name, PDOMFile file, PDOMBinding binding, PDOMName caller) throws CoreException {
@ -192,13 +195,26 @@ public class PDOMName implements IIndexFragmentName, IASTFileLocation {
}
}
private byte getFlags() throws CoreException {
return pdom.getDB().getByte(record + FLAGS);
private byte getFlags(int mask) throws CoreException {
return (byte) (pdom.getDB().getByte(record + FLAGS) & mask);
}
public void setIsBaseSpecifier(boolean val) throws CoreException {
byte flags= getFlags(0xff);
if (val)
flags |= IS_INHERITANCE_SPEC;
else
flags &= ~IS_INHERITANCE_SPEC;
pdom.getDB().putByte(record + FLAGS, flags);
}
public boolean isBaseSpecifier() throws CoreException {
return getFlags(IS_INHERITANCE_SPEC) == IS_INHERITANCE_SPEC;
}
public boolean isDeclaration() {
try {
byte flags = getFlags();
byte flags = getFlags(DECL_DEF_REF_MASK);
return flags == IS_DECLARATION || flags == IS_DEFINITION;
} catch (CoreException e) {
CCorePlugin.log(e);
@ -208,7 +224,7 @@ public class PDOMName implements IIndexFragmentName, IASTFileLocation {
public boolean isReference() {
try {
byte flags = getFlags();
byte flags = getFlags(DECL_DEF_REF_MASK);
return flags == IS_REFERENCE;
} catch (CoreException e) {
CCorePlugin.log(e);
@ -218,7 +234,7 @@ public class PDOMName implements IIndexFragmentName, IASTFileLocation {
public boolean isDefinition() {
try {
byte flags = getFlags();
byte flags = getFlags(DECL_DEF_REF_MASK);
return flags == IS_DEFINITION;
} catch (CoreException e) {
CCorePlugin.log(e);
@ -286,7 +302,7 @@ public class PDOMName implements IIndexFragmentName, IASTFileLocation {
if (prevName != null)
prevName.setNextInBinding(nextName);
else {
switch (getFlags()) {
switch (getFlags(DECL_DEF_REF_MASK)) {
case IS_DECLARATION:
getPDOMBinding().setFirstDeclaration(nextName);
break;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006 QNX Software Systems and others.
* Copyright (c) 2006, 2007 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -7,15 +7,16 @@
*
* Contributors:
* QNX - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
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.cdt.internal.core.pdom.dom.PDOMName;
import org.eclipse.core.runtime.CoreException;
/**
@ -23,7 +24,7 @@ import org.eclipse.core.runtime.CoreException;
*/
class PDOMCPPBase implements ICPPBase {
private static final int BASECLASS = 0;
private static final int BASECLASS_SPECIFIER = 0;
private static final int NEXTBASE = 4;
private static final int FLAGS = 8;
@ -37,13 +38,13 @@ class PDOMCPPBase implements ICPPBase {
this.record = record;
}
public PDOMCPPBase(PDOM pdom, PDOMCPPClassType baseClass, boolean isVirtual, int visibility) throws CoreException {
public PDOMCPPBase(PDOM pdom, PDOMName baseClassSpec, 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);
int baserec = baseClassSpec != null ? baseClassSpec.getRecord() : 0;
db.putInt(record + BASECLASS_SPECIFIER, baserec);
byte flags = (byte)(visibility | (isVirtual ? 4 : 0));
db.putByte(record + FLAGS, flags);
@ -66,18 +67,31 @@ class PDOMCPPBase implements ICPPBase {
private int getFlags() throws CoreException {
return pdom.getDB().getByte(record + FLAGS);
}
public IBinding getBaseClass() throws DOMException {
public PDOMName getBaseClassSpecifierImpl() {
try {
int rec = pdom.getDB().getInt(record + BASECLASS);
return rec != 0 ? new PDOMCPPClassType(pdom, rec) : null;
int rec = pdom.getDB().getInt(record + BASECLASS_SPECIFIER);
if (rec != 0) {
return new PDOMName(pdom, rec);
}
} catch (CoreException e) {
CCorePlugin.log(e);
return null;
}
return null;
}
public int getVisibility() throws DOMException {
public IBinding getBaseClass() {
try {
PDOMName name= getBaseClassSpecifierImpl();
if (name != null)
return name.getPDOMBinding();
} catch (CoreException e) {
CCorePlugin.log(e);
}
return null;
}
public int getVisibility() {
try {
return getFlags() & 0x3;
} catch (CoreException e) {
@ -87,7 +101,7 @@ class PDOMCPPBase implements ICPPBase {
}
public boolean isVirtual() throws DOMException {
public boolean isVirtual() {
try {
return (getFlags() & 0x4) != 0;
} catch (CoreException e) {
@ -96,4 +110,7 @@ class PDOMCPPBase implements ICPPBase {
}
}
public void delete() throws CoreException {
pdom.getDB().free(record);
}
}

View file

@ -44,6 +44,7 @@ import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.db.PDOMNodeLinkedList;
import org.eclipse.cdt.internal.core.pdom.dom.IPDOMMemberOwner;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNamedNode;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.core.runtime.CoreException;
@ -192,13 +193,9 @@ ICPPClassScope, IPDOMMemberOwner, IIndexType {
// Visit my base classes
for (PDOMCPPBase base = getFirstBase(); base != null; base = base.getNextBase()) {
try {
IBinding baseClass = base.getBaseClass();
if (baseClass != null && baseClass instanceof PDOMCPPClassType)
((PDOMCPPClassType)baseClass).acceptInHierarchy(visited, visitor);
} catch (DOMException e) {
throw new CoreException(Util.createStatus(e));
}
IBinding baseClass = base.getBaseClass();
if (baseClass != null && baseClass instanceof PDOMCPPClassType)
((PDOMCPPClassType)baseClass).acceptInHierarchy(visited, visitor);
}
}
@ -427,4 +424,26 @@ ICPPClassScope, IPDOMMemberOwner, IIndexType {
public boolean mayHaveChildren() {
return true;
}
public void removeBase(PDOMName pdomName) throws CoreException {
PDOMCPPBase base= getFirstBase();
PDOMCPPBase predecessor= null;
int nameRec= pdomName.getRecord();
while (base != null) {
if (base.getBaseClassSpecifierImpl().getRecord() == nameRec) {
break;
}
predecessor= base;
base= base.getNextBase();
}
if (base != null) {
if (predecessor != null) {
predecessor.setNextBase(base.getNextBase());
}
else {
setFirstBase(base.getNextBase());
}
base.delete();
}
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2006 QNX Software Systems and others.
* Copyright (c) 2005, 2007 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -25,7 +25,6 @@ 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.ICPPASTCompositeTypeSpecifier;
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.ICPPClassScope;
@ -51,6 +50,7 @@ import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator;
import org.eclipse.cdt.internal.core.pdom.dom.IPDOMMemberOwner;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.core.runtime.CoreException;
@ -123,10 +123,6 @@ class PDOMCPPLinkage extends PDOMLinkage {
PDOMBinding pdomBinding = addBinding(binding);
if (pdomBinding instanceof PDOMCPPClassType) {
PDOMCPPClassType pdomClassType= (PDOMCPPClassType) pdomBinding;
IASTNode baseNode= name.getParent();
if (baseNode instanceof ICPPASTBaseSpecifier)
addBaseClasses(pdomClassType, (ICPPASTBaseSpecifier) baseNode);
if (binding instanceof ICPPClassType && name.isDefinition()) {
addImplicitMethods(pdomClassType, (ICPPClassType) binding);
}
@ -150,17 +146,6 @@ class PDOMCPPLinkage extends PDOMLinkage {
return pdomBinding;
}
private void addBaseClasses(PDOMCPPClassType pdomBinding, ICPPASTBaseSpecifier baseNode) throws CoreException {
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, pdomBinding,
baseNode.isVirtual(), baseNode.getVisibility());
ownerClass.addBase(pdomBase);
}
}
private PDOMBinding addBinding(PDOMNode parent, IBinding binding) throws CoreException, DOMException {
PDOMBinding pdomBinding= null;
@ -363,4 +348,38 @@ class PDOMCPPLinkage extends PDOMLinkage {
public IBTreeComparator getIndexComparator() {
return new CPPFindBinding.CPPBindingBTreeComparator(pdom);
}
public void onCreateName(PDOMName pdomName, IASTName name) throws CoreException {
super.onCreateName(pdomName, name);
PDOMName derivedClassName= (PDOMName) pdomName.getEnclosingDefinition();
if (derivedClassName != null) {
IASTNode parentNode= name.getParent();
if (parentNode instanceof ICPPASTBaseSpecifier) {
ICPPASTBaseSpecifier baseNode= (ICPPASTBaseSpecifier) parentNode;
PDOMBinding derivedClassBinding= derivedClassName.getPDOMBinding();
if (derivedClassBinding instanceof PDOMCPPClassType) {
PDOMCPPClassType ownerClass = (PDOMCPPClassType)derivedClassBinding;
PDOMCPPBase pdomBase = new PDOMCPPBase(pdom, pdomName, baseNode.isVirtual(), baseNode.getVisibility());
ownerClass.addBase(pdomBase);
pdomName.setIsBaseSpecifier(true);
}
}
}
}
public void onDeleteName(PDOMName pdomName) throws CoreException {
super.onDeleteName(pdomName);
if (pdomName.isBaseSpecifier()) {
PDOMName derivedClassName= (PDOMName) pdomName.getEnclosingDefinition();
if (derivedClassName != null) {
PDOMBinding derivedClassBinding= derivedClassName.getPDOMBinding();
if (derivedClassBinding instanceof PDOMCPPClassType) {
PDOMCPPClassType ownerClass = (PDOMCPPClassType)derivedClassBinding;
ownerClass.removeBase(pdomName);
}
}
}
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006 Wind River Systems, Inc. and others.
* Copyright (c) 2006, 2007 Wind River Systems, Inc. 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
@ -12,31 +12,34 @@
package org.eclipse.cdt.internal.core.pdom.indexer;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
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.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
abstract public class IndexerASTVisitor extends ASTVisitor {
private IASTName fDefinitionName;
private IASTNode fDefinition;
private IASTNode fDefinitionNode;
public IndexerASTVisitor() {
shouldVisitNames= true;
shouldVisitDeclarations= true;
shouldVisitInitializers= true;
shouldVisitDeclSpecifiers= true;
}
abstract public void visit(IASTName name, IASTName definitionName);
final public int visit(IASTName name) {
if (!(name instanceof ICPPASTQualifiedName)) {
if (fDefinition != null) {
if (!fDefinition.contains(name)) {
fDefinition= null;
if (fDefinitionNode != null) {
if (!fDefinitionNode.contains(name)) {
fDefinitionNode= null;
fDefinitionName= null;
}
}
@ -50,7 +53,7 @@ abstract public class IndexerASTVisitor extends ASTVisitor {
public int visit(IASTDeclaration decl) {
if (decl instanceof IASTFunctionDefinition) {
IASTFunctionDefinition fdef= (IASTFunctionDefinition) decl;
fDefinition= decl;
fDefinitionNode= decl;
fDefinitionName= fdef.getDeclarator().getName();
if (fDefinitionName instanceof ICPPASTQualifiedName) {
fDefinitionName= ((ICPPASTQualifiedName) fDefinitionName).getLastName();
@ -59,15 +62,57 @@ abstract public class IndexerASTVisitor extends ASTVisitor {
}
return PROCESS_CONTINUE;
}
public int visit(IASTInitializer initializer) {
if (fDefinition == null) {
IASTNode cand= initializer.getParent();
if (cand instanceof IASTDeclarator) {
fDefinition= cand;
fDefinitionName= ((IASTDeclarator) fDefinition).getName();
// leave methods don't get called correctly: bug 152846
// public int leave(IASTDeclaration decl) {
// if (decl == fDefinitionNode) {
// fDefinitionNode= null;
// fDefinitionName= null;
// }
// return PROCESS_CONTINUE;
// }
public int visit(IASTDeclSpecifier declspec) {
if (declspec instanceof ICPPASTCompositeTypeSpecifier) {
if (fDefinitionNode == null || !fDefinitionNode.contains(declspec)) {
ICPPASTCompositeTypeSpecifier cts= (ICPPASTCompositeTypeSpecifier) declspec;
fDefinitionNode= declspec;
fDefinitionName= cts.getName();
if (fDefinitionName instanceof ICPPASTQualifiedName) {
fDefinitionName= ((ICPPASTQualifiedName) fDefinitionName).getLastName();
}
visit(fDefinitionName, null);
}
}
return PROCESS_CONTINUE;
}
// leave methods don't get called correctly: bug 152846
// public int leave(IASTDeclSpecifier declspec) {
// if (declspec == fDefinitionNode) {
// fDefinitionNode= null;
// fDefinitionName= null;
// }
// return PROCESS_CONTINUE;
// }
public int visit(IASTInitializer initializer) {
if (fDefinitionNode == null) {
IASTNode cand= initializer.getParent();
if (cand instanceof IASTDeclarator) {
fDefinitionNode= cand;
fDefinitionName= ((IASTDeclarator) cand).getName();
}
}
return PROCESS_CONTINUE;
}
// leave methods don't get called correctly: bug 152846
// public int leave(IASTInitializer initializer) {
// if (fDefinitionNode == initializer) {
// fDefinitionNode= null;
// fDefinitionName= null;
// }
// return PROCESS_CONTINUE;
// }
}