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

Type Hierarchy: support for typedefs

This commit is contained in:
Markus Schorn 2007-01-23 15:14:35 +00:00
parent 57102e1bd4
commit 98261e8d92
8 changed files with 160 additions and 80 deletions

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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -15,10 +15,12 @@ import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.c.ICCompositeTypeScope; import org.eclipse.cdt.core.dom.ast.c.ICCompositeTypeScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
@ -61,6 +63,9 @@ public class CElementHandleFactory {
else if (binding instanceof IVariable) { else if (binding instanceof IVariable) {
element= new VariableHandle(parentElement, (IVariable) binding); element= new VariableHandle(parentElement, (IVariable) binding);
} }
else if (binding instanceof IEnumeration) {
element= new EnumerationHandle(parentElement, (IEnumeration) binding);
}
else if (binding instanceof IEnumerator) { else if (binding instanceof IEnumerator) {
element= new EnumeratorHandle(parentElement, (IEnumerator) binding); element= new EnumeratorHandle(parentElement, (IEnumerator) binding);
} }
@ -69,7 +74,10 @@ public class CElementHandleFactory {
} }
else if (binding instanceof ICPPNamespace) { else if (binding instanceof ICPPNamespace) {
element= new NamespaceHandle(parentElement, (ICPPNamespace) binding); element= new NamespaceHandle(parentElement, (ICPPNamespace) binding);
} }
else if (binding instanceof ITypedef) {
element= new TypedefHandle(parentElement, (ITypedef) binding);
}
if (element != null && region != null) { if (element != null && region != null) {
element.setRangeOfID(region, timestamp); element.setRangeOfID(region, timestamp);
} }

View file

@ -0,0 +1,22 @@
/*******************************************************************************
* Copyright (c) 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.model.ext;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.model.ICElement;
public class TypedefHandle extends CElementHandle implements org.eclipse.cdt.core.model.ITypeDef {
public TypedefHandle(ICElement parent, ITypedef typedef) {
super(parent, ICElement.C_TYPEDEF, typedef.getName());
}
}

View file

@ -166,7 +166,7 @@ ICPPClassScope, IPDOMMemberOwner, IIndexType {
public ICPPMethod[] getMethods() throws DOMException { public ICPPMethod[] getMethods() throws DOMException {
try { try {
MethodCollector methods = new MethodCollector(true); MethodCollector methods = new MethodCollector(true);
accept(methods); acceptInHierarchy(new HashSet(), methods);
return methods.getMethods(); return methods.getMethods();
} catch (CoreException e) { } catch (CoreException e) {
return new ICPPMethod[0]; return new ICPPMethod[0];

View file

@ -15,6 +15,7 @@ package org.eclipse.cdt.internal.core.pdom.dom.cpp;
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.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
@ -365,6 +366,12 @@ class PDOMCPPLinkage extends PDOMLinkage {
pdomName.setIsBaseSpecifier(true); pdomName.setIsBaseSpecifier(true);
} }
} }
else if (parentNode instanceof IASTDeclSpecifier) {
IASTDeclSpecifier ds= (IASTDeclSpecifier) parentNode;
if (ds.getStorageClass() == IASTDeclSpecifier.sc_typedef) {
pdomName.setIsBaseSpecifier(true);
}
}
} }
} }

View file

@ -11,6 +11,8 @@
package org.eclipse.cdt.internal.core.pdom.indexer; package org.eclipse.cdt.internal.core.pdom.indexer;
import java.util.ArrayList;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
@ -19,12 +21,14 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; 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.ICPPASTQualifiedName;
abstract public class IndexerASTVisitor extends ASTVisitor { abstract public class IndexerASTVisitor extends ASTVisitor {
private IASTName fDefinitionName; private IASTName fDefinitionName;
private IASTNode fDefinitionNode; private IASTNode fDefinitionNode;
private ArrayList fStack= new ArrayList();
public IndexerASTVisitor() { public IndexerASTVisitor() {
shouldVisitNames= true; shouldVisitNames= true;
@ -37,12 +41,6 @@ abstract public class IndexerASTVisitor extends ASTVisitor {
final public int visit(IASTName name) { final public int visit(IASTName name) {
if (!(name instanceof ICPPASTQualifiedName)) { if (!(name instanceof ICPPASTQualifiedName)) {
if (fDefinitionNode != null) {
if (!fDefinitionNode.contains(name)) {
fDefinitionNode= null;
fDefinitionName= null;
}
}
if (name != fDefinitionName) { if (name != fDefinitionName) {
visit(name, fDefinitionName); visit(name, fDefinitionName);
} }
@ -50,69 +48,91 @@ abstract public class IndexerASTVisitor extends ASTVisitor {
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
private void push(IASTName name, IASTNode node) {
if (fDefinitionName != null) {
fStack.add(new Object[] {fDefinitionName, fDefinitionNode});
}
if (name instanceof ICPPASTQualifiedName) {
name= ((ICPPASTQualifiedName) name).getLastName();
}
fDefinitionName= name;
fDefinitionNode= node;
}
private void pop(IASTNode node) {
if (node == fDefinitionNode) {
if (fStack.isEmpty()) {
fDefinitionName= null;
fDefinitionNode= null;
}
else {
Object[] old= (Object[]) fStack.remove(fStack.size()-1);
fDefinitionName= (IASTName) old[0];
fDefinitionNode= (IASTNode) old[1];
}
}
}
// functions and methods
public int visit(IASTDeclaration decl) { public int visit(IASTDeclaration decl) {
if (decl instanceof IASTFunctionDefinition) { if (decl instanceof IASTFunctionDefinition) {
IASTFunctionDefinition fdef= (IASTFunctionDefinition) decl; IASTFunctionDefinition fdef= (IASTFunctionDefinition) decl;
fDefinitionNode= decl; IASTName name = fdef.getDeclarator().getName();
fDefinitionName= fdef.getDeclarator().getName(); visit(name, fDefinitionName);
if (fDefinitionName instanceof ICPPASTQualifiedName) { push(name, decl);
fDefinitionName= ((ICPPASTQualifiedName) fDefinitionName).getLastName(); }
else if (decl instanceof IASTSimpleDeclaration) {
IASTSimpleDeclaration sdecl= (IASTSimpleDeclaration) decl;
if (sdecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef) {
IASTDeclarator[] declarators= sdecl.getDeclarators();
for (int i = 0; i < declarators.length; i++) {
IASTDeclarator declarator = declarators[i];
if (declarator.getPointerOperators().length == 0 &&
declarator.getNestedDeclarator() == null) {
IASTName name= declarator.getName();
visit(name, fDefinitionName);
push(name, decl);
}
}
} }
visit(fDefinitionName, null);
} }
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
// leave methods don't get called correctly: bug 152846 public int leave(IASTDeclaration decl) {
// public int leave(IASTDeclaration decl) { pop(decl);
// if (decl == fDefinitionNode) { return PROCESS_CONTINUE;
// fDefinitionNode= null; }
// fDefinitionName= null;
// }
// return PROCESS_CONTINUE;
// }
// class definitions, typedefs
public int visit(IASTDeclSpecifier declspec) { public int visit(IASTDeclSpecifier declspec) {
if (declspec instanceof ICPPASTCompositeTypeSpecifier) { if (declspec instanceof ICPPASTCompositeTypeSpecifier) {
if (fDefinitionNode == null || !fDefinitionNode.contains(declspec)) { ICPPASTCompositeTypeSpecifier cts= (ICPPASTCompositeTypeSpecifier) declspec;
ICPPASTCompositeTypeSpecifier cts= (ICPPASTCompositeTypeSpecifier) declspec; IASTName name = cts.getName();
fDefinitionNode= declspec; visit(name, fDefinitionName);
fDefinitionName= cts.getName(); push(name, declspec);
if (fDefinitionName instanceof ICPPASTQualifiedName) {
fDefinitionName= ((ICPPASTQualifiedName) fDefinitionName).getLastName();
}
visit(fDefinitionName, null);
}
} }
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
// leave methods don't get called correctly: bug 152846 public int leave(IASTDeclSpecifier declspec) {
// public int leave(IASTDeclSpecifier declspec) { pop(declspec);
// if (declspec == fDefinitionNode) { return PROCESS_CONTINUE;
// fDefinitionNode= null; }
// fDefinitionName= null;
// }
// return PROCESS_CONTINUE;
// }
// variable and field initializers
public int visit(IASTInitializer initializer) { public int visit(IASTInitializer initializer) {
if (fDefinitionNode == null) { if (!(fDefinitionNode instanceof IASTFunctionDefinition)) {
IASTNode cand= initializer.getParent(); IASTNode cand= initializer.getParent();
if (cand instanceof IASTDeclarator) { if (cand instanceof IASTDeclarator) {
fDefinitionNode= cand; push(((IASTDeclarator) cand).getName(), initializer);
fDefinitionName= ((IASTDeclarator) cand).getName();
} }
} }
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
// leave methods don't get called correctly: bug 152846 public int leave(IASTInitializer initializer) {
// public int leave(IASTInitializer initializer) { pop(initializer);
// if (fDefinitionNode == initializer) { return PROCESS_CONTINUE;
// fDefinitionNode= null; }
// fDefinitionName= null;
// }
// return PROCESS_CONTINUE;
// }
} }

View file

@ -25,6 +25,8 @@ import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndex;
@ -117,14 +119,12 @@ class THGraph {
} }
else if (input != null) { else if (input != null) {
try { try {
ICElement inputHandle= null;
IIndexName name= IndexUI.elementToName(index, input); IIndexName name= IndexUI.elementToName(index, input);
if (name != null) { if (name != null) {
ICElementHandle inputHandle= IndexUI.getCElementForName(input.getCProject(), index, name); inputHandle= IndexUI.getCElementForName(input.getCProject(), index, name);
fInputNode= addNode(inputHandle);
} }
else { fInputNode= addNode(inputHandle == null ? input : inputHandle);
fInputNode= addNode(input);
}
} catch (CoreException e) { } catch (CoreException e) {
CUIPlugin.getDefault().log(e); CUIPlugin.getDefault().log(e);
} catch (DOMException e) { } catch (DOMException e) {
@ -149,9 +149,11 @@ class THGraph {
THGraphNode graphNode= addNode(elem); THGraphNode graphNode= addNode(elem);
try { try {
IBinding binding = IndexUI.elementToBinding(index, elem); IBinding binding = IndexUI.elementToBinding(index, elem);
if (binding != null) {
addMembers(index, graphNode, binding);
}
if (binding instanceof ICPPClassType) { if (binding instanceof ICPPClassType) {
ICPPClassType ct= (ICPPClassType) binding; ICPPClassType ct= (ICPPClassType) binding;
addMembers(index, graphNode, ct);
ICPPBase[] bases= ct.getBases(); ICPPBase[] bases= ct.getBases();
for (int i = 0; i < bases.length; i++) { for (int i = 0; i < bases.length; i++) {
if (monitor.isCanceled()) { if (monitor.isCanceled()) {
@ -171,6 +173,23 @@ class THGraph {
} }
} }
} }
else if (binding instanceof ITypedef) {
ITypedef ct= (ITypedef) binding;
IType type= ct.getType();
if (type instanceof IBinding) {
IBinding basecl= (IBinding) type;
ICElementHandle[] baseElems= IndexUI.findRepresentative(index, basecl);
if (baseElems.length > 0) {
ICElementHandle baseElem= baseElems[0];
THGraphNode baseGraphNode= addNode(baseElem);
addMembers(index, baseGraphNode, basecl);
addEdge(graphNode, baseGraphNode);
if (handled.add(baseElem)) {
stack.add(baseElem);
}
}
}
}
} catch (DOMException e) { } catch (DOMException e) {
CUIPlugin.getDefault().log(e); CUIPlugin.getDefault().log(e);
} catch (CoreException e) { } catch (CoreException e) {
@ -196,26 +215,24 @@ class THGraph {
THGraphNode graphNode= addNode(elem); THGraphNode graphNode= addNode(elem);
try { try {
IBinding binding = IndexUI.elementToBinding(index, elem); IBinding binding = IndexUI.elementToBinding(index, elem);
if (binding instanceof ICPPClassType) { IIndexName[] names= index.findNames(binding, IIndex.FIND_REFERENCES | IIndex.FIND_DEFINITIONS);
IIndexName[] names= index.findNames(binding, IIndex.FIND_REFERENCES); for (int i = 0; i < names.length; i++) {
for (int i = 0; i < names.length; i++) { if (monitor.isCanceled()) {
if (monitor.isCanceled()) { return;
return; }
} IIndexName indexName = names[i];
IIndexName indexName = names[i]; if (indexName.isBaseSpecifier()) {
if (indexName.isBaseSpecifier()) { IIndexName subClassDef= indexName.getEnclosingDefinition();
IIndexName subClassDef= indexName.getEnclosingDefinition(); if (subClassDef != null) {
if (subClassDef != null) { IBinding subClass= index.findBinding(subClassDef);
IBinding subClass= index.findBinding(subClassDef); ICElementHandle[] subClassElems= IndexUI.findRepresentative(index, subClass);
ICElementHandle[] subClassElems= IndexUI.findRepresentative(index, subClass); if (subClassElems.length > 0) {
if (subClassElems.length > 0) { ICElementHandle subClassElem= subClassElems[0];
ICElementHandle subClassElem= subClassElems[0]; THGraphNode subGraphNode= addNode(subClassElem);
THGraphNode subGraphNode= addNode(subClassElem); addMembers(index, subGraphNode, subClass);
addMembers(index, subGraphNode, subClass); addEdge(subGraphNode, graphNode);
addEdge(subGraphNode, graphNode); if (handled.add(subClassElem)) {
if (handled.add(subClassElem)) { stack.add(subClassElem);
stack.add(subClassElem);
}
} }
} }
} }

View file

@ -78,7 +78,9 @@ class THGraphNode {
private void collectMembers(HashSet visited, List list) { private void collectMembers(HashSet visited, List list) {
if (visited.add(this)) { if (visited.add(this)) {
list.addAll(Arrays.asList(fMembers)); if (fMembers != null) {
list.addAll(Arrays.asList(fMembers));
}
List bases= getOutgoing(); List bases= getOutgoing();
for (Iterator iterator = bases.iterator(); iterator.hasNext();) { for (Iterator iterator = bases.iterator(); iterator.hasNext();) {
THGraphEdge edge = (THGraphEdge) iterator.next(); THGraphEdge edge = (THGraphEdge) iterator.next();

View file

@ -28,6 +28,8 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexManager; import org.eclipse.cdt.core.index.IIndexManager;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
@ -185,8 +187,9 @@ public class TypeHierarchyUI {
} }
public static boolean isValidInput(IBinding binding) { public static boolean isValidInput(IBinding binding) {
if (binding instanceof ICompositeType) { if (binding instanceof ICompositeType
// || binding instanceof ITypedef || || binding instanceof IEnumeration
|| binding instanceof ITypedef) {
// binding instanceof IField || binding instanceof ICPPMethod) { // binding instanceof IField || binding instanceof ICPPMethod) {
return true; return true;
} }
@ -204,7 +207,8 @@ public class TypeHierarchyUI {
case ICElement.C_CLASS_DECLARATION: case ICElement.C_CLASS_DECLARATION:
case ICElement.C_STRUCT_DECLARATION: case ICElement.C_STRUCT_DECLARATION:
case ICElement.C_UNION_DECLARATION: case ICElement.C_UNION_DECLARATION:
// case ICElement.C_TYPEDEF: case ICElement.C_ENUMERATION:
case ICElement.C_TYPEDEF:
// case ICElement.C_FIELD: // case ICElement.C_FIELD:
// case ICElement.C_METHOD: // case ICElement.C_METHOD:
// case ICElement.C_METHOD_DECLARATION: // case ICElement.C_METHOD_DECLARATION: