1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-08 08:45:44 +02:00

patch from Devin Steffler

This commit is contained in:
Andrew Niefer 2005-03-09 19:50:55 +00:00
parent a9e1167971
commit 9b1b4fc340
9 changed files with 387 additions and 18 deletions

View file

@ -0,0 +1,342 @@
/*******************************************************************************
* Copyright (c) 2005 Rational Software Corp. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* Rational Software - initial implementation
******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
import org.eclipse.cdt.core.dom.ast.c.ICArrayType;
import org.eclipse.cdt.core.dom.ast.c.ICBasicType;
import org.eclipse.cdt.core.dom.ast.c.ICPointerType;
import org.eclipse.cdt.core.dom.ast.c.ICQualifierType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPBasicType;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPPointerType;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPQualifierType;
import org.eclipse.cdt.core.parser.GCCKeywords;
import org.eclipse.cdt.core.parser.Keywords;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTTypeId;
import org.eclipse.cdt.internal.core.dom.parser.c.CExternalFunction;
import org.eclipse.cdt.internal.core.dom.parser.c.CExternalVariable;
import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTypeId;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor;
/**
* This is a utility class to help convert AST elements to Strings.
*/
public class ASTUtil {
private static final String COMMA_SPACE = ", "; //$NON-NLS-1$
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
private static final String SPACE = " "; //$NON-NLS-1$
private static final String[] EMPTY_STRING_ARRAY = new String[0];
private static final int DEAULT_ITYPE_SIZE = 2;
public static String getParameterTypeString(IFunctionType type) {
StringBuffer result = new StringBuffer();
String[] parms = getParameterTypeStringArray(type);
result.append(Keywords.cpLPAREN);
for(int i=0; i<parms.length; i++) {
if (parms[i] != null) {
result.append(parms[i]);
if (i<parms.length-1) result.append(COMMA_SPACE);
}
}
result.append(Keywords.cpRPAREN);
return result.toString();
}
public static String[] getParameterTypeStringArray(IFunctionType type) {
IType[] parms = null;
try {
parms = type.getParameterTypes();
} catch (DOMException e) { return EMPTY_STRING_ARRAY; }
String[] result = new String[parms.length];
for(int i=0; i<parms.length; i++) {
if (parms[i] != null) {
result[i] = getType(parms[i]);
}
}
return result;
}
private static String getTypeString(IType type) {
StringBuffer result = new StringBuffer();
boolean needSpace = false;
if (type instanceof IArrayType) {
result.append(Keywords.cpLBRACKET);
if (type instanceof ICArrayType) {
try {
if (((ICArrayType)type).isConst()) { result.append(Keywords.CONST); needSpace=true; }
if (((ICArrayType)type).isRestrict()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.RESTRICT); needSpace=true; }
if (((ICArrayType)type).isStatic()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.STATIC); needSpace=true; }
if (((ICArrayType)type).isVolatile()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.VOLATILE); }
} catch (DOMException e) {}
}
result.append(Keywords.cpRBRACKET);
} else if (type instanceof IBasicType) {
try {
if (((IBasicType)type).isSigned()) { result.append(Keywords.SIGNED); needSpace = true; }
else if (((IBasicType)type).isUnsigned()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.UNSIGNED); needSpace=true; }
if (((IBasicType)type).isLong()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.LONG); needSpace = true; }
else if (((IBasicType)type).isShort()) { if (needSpace) { result.append(SPACE); needSpace=false; }result.append(Keywords.SHORT); needSpace = true; }
} catch (DOMException e) {}
if (type instanceof IGPPBasicType) {
try {
if (((IGPPBasicType)type).isLongLong()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.LONG_LONG); needSpace=true; }
switch (((IGPPBasicType)type).getType()) {
case IGPPBasicType.t_Complex:
result.append(Keywords.c_COMPLEX);
break;
case IGPPBasicType.t_Imaginary:
result.append(Keywords.c_IMAGINARY);
break;
case IGPPBasicType.t_typeof:
result.append(GCCKeywords.TYPEOF);
break;
}
} catch (DOMException e) {}
} else if (type instanceof ICPPBasicType) {
try {
switch (((ICPPBasicType)type).getType()) {
case ICPPBasicType.t_bool:
result.append(Keywords.BOOL);
break;
case ICPPBasicType.t_wchar_t:
result.append(Keywords.WCHAR_T);
break;
}
} catch (DOMException e) {}
} else if (type instanceof ICBasicType) {
try {
switch (((ICBasicType)type).getType()) {
case ICBasicType.t_Bool:
result.append(Keywords.c_BOOL);
break;
case ICBasicType.t_Complex:
result.append(Keywords.c_COMPLEX);
break;
case ICBasicType.t_Imaginary:
result.append(Keywords.c_IMAGINARY);
break;
}
} catch (DOMException e) {}
}
try {
switch (((IBasicType)type).getType()) {
case IBasicType.t_char:
result.append(Keywords.CHAR);
break;
case IBasicType.t_double:
result.append(Keywords.DOUBLE);
break;
case IBasicType.t_float:
result.append(Keywords.FLOAT);
break;
case IBasicType.t_int:
result.append(Keywords.INT);
break;
case IBasicType.t_void:
result.append(Keywords.VOID);
break;
}
} catch (DOMException e) {}
} else if (type instanceof ICompositeType) {
if (type instanceof ICPPClassType) {
try {
switch(((ICPPClassType)type).getKey()) {
case ICPPClassType.k_class:
result.append(Keywords.CLASS);
break;
}
} catch (DOMException e) {}
}
try {
switch(((ICompositeType)type).getKey()) {
case ICompositeType.k_struct:
result.append(Keywords.STRUCT);
break;
case ICompositeType.k_union:
result.append(Keywords.UNION);
break;
}
} catch (DOMException e) {}
} else if (type instanceof ICPPReferenceType) {
result.append(Keywords.cpAMPER);
} else if (type instanceof ICPPTemplateTypeParameter) {
try {
result.append(getType(((ICPPTemplateTypeParameter)type).getDefault()));
} catch (DOMException e) {}
} else if (type instanceof IEnumeration) {
result.append(Keywords.ENUM);
} else if (type instanceof IFunctionType) {
try {
String temp = getType(((IFunctionType)type).getReturnType());
if (temp != null && !temp.equals(EMPTY_STRING)) { result.append(temp); needSpace=true; }
if (needSpace) { result.append(SPACE); needSpace=false; }
temp = getParameterTypeString((IFunctionType)type);
if (temp != null && !temp.equals(EMPTY_STRING)) { result.append(temp); needSpace=false; }
} catch (DOMException e) {}
} else if (type instanceof IPointerType) {
result.append(Keywords.cpSTAR); needSpace=true;
if (type instanceof IGPPPointerType) {
if (((IGPPPointerType)type).isRestrict()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.RESTRICT); needSpace=true; }
} else if (type instanceof ICPointerType) {
if (((ICPointerType)type).isRestrict()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.RESTRICT); needSpace=true; }
}
try {
if (((IPointerType)type).isConst()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.CONST); needSpace=true; }
if (((IPointerType)type).isVolatile()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.VOLATILE); needSpace=true; }
} catch (DOMException e) {}
} else if (type instanceof IQualifierType) {
if (type instanceof ICQualifierType) {
if (((ICQualifierType)type).isRestrict()) { result.append(Keywords.RESTRICT); needSpace=true; }
} else if (type instanceof IGPPQualifierType) {
if (((IGPPQualifierType)type).isRestrict()) { result.append(Keywords.RESTRICT); needSpace=true; }
}
try {
if (((IQualifierType)type).isConst()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.CONST); needSpace=true; }
if (((IQualifierType)type).isVolatile()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.VOLATILE); needSpace=true; }
} catch (DOMException e) {}
}
return result.toString();
}
public static String getType(IType type) {
StringBuffer result = new StringBuffer();
IType[] types = new IType[DEAULT_ITYPE_SIZE];
// push all of the types onto the stack
while(type != null && type instanceof ITypeContainer) {
types = (IType[]) ArrayUtil.append( IType.class, types, type );
try {
type = ((ITypeContainer)type).getType();
} catch (DOMException e) {}
}
if (type != null && !(type instanceof ITypeContainer)) {
types = (IType[]) ArrayUtil.append( IType.class, types, type );
}
// pop all of the types off of the stack, and build the string representation while doing so
for(int j=types.length-1; j>=0; j--) {
if (types[j] != null)
result.append(getTypeString(types[j]));
if (types[j] != null && j>0) result.append(SPACE);
}
return result.toString();
}
public static String getDeclaratorType(IASTDeclarator decltor) {
// get the most nested declarator
while(decltor.getNestedDeclarator() != null)
decltor = decltor.getNestedDeclarator();
IBinding binding = decltor.getName().resolveBinding();
IType type = null;
try {
if (binding instanceof CExternalFunction) {
type = ((CExternalFunction)binding).getType();
} else if (binding instanceof CExternalVariable) {
type = ((CExternalVariable)binding).getType();
} else if (binding instanceof IEnumerator) {
type = ((IEnumerator)binding).getType();
} else if (binding instanceof IFunction) {
type = ((IFunction)binding).getType();
} else if (binding instanceof ITypedef) {
type = ((ITypedef)binding).getType();
} else if (binding instanceof IVariable) {
type = ((IVariable)binding).getType();
}
} catch (DOMException e) {
return EMPTY_STRING;
}
if (type != null) {
return getType(type);
}
return EMPTY_STRING;
}
/**
* Return's the String representation of a node's type (if available). This is
* currently only being used for testing.
*
* TODO Remove this function when done testing if it is no longer needed
*
* @param node
* @return
*/
public static String getNodeType(IASTNode node) {
try {
if (node instanceof IASTDeclarator)
return getDeclaratorType((IASTDeclarator)node);
if (node instanceof IASTName && ((IASTName)node).resolveBinding() instanceof IVariable)
return getType(((IVariable)((IASTName)node).resolveBinding()).getType());
if (node instanceof IASTName && ((IASTName)node).resolveBinding() instanceof IFunction)
return getType(((IFunction)((IASTName)node).resolveBinding()).getType());
if (node instanceof IASTName && ((IASTName)node).resolveBinding() instanceof IType)
return getType((IType)((IASTName)node).resolveBinding());
if (node instanceof IASTTypeId)
return getType((IASTTypeId)node);
} catch (DOMException e) { return EMPTY_STRING; }
return EMPTY_STRING;
}
public static String getType(IASTTypeId typeId) {
if (typeId instanceof CASTTypeId)
return createCType(typeId.getAbstractDeclarator());
else if (typeId instanceof CPPASTTypeId)
return createCPPType(typeId.getAbstractDeclarator());
return EMPTY_STRING;
}
private static String createCType(IASTDeclarator declarator) {
IType type = CVisitor.createType(declarator);
return getType(type);
}
private static String createCPPType(IASTDeclarator declarator) {
IType type = CPPVisitor.createType(declarator);
return getType(type);
}
}

View file

@ -53,6 +53,7 @@ public class Keywords {
public static final String INLINE = "inline"; //$NON-NLS-1$
public static final String INT = "int"; //$NON-NLS-1$
public static final String LONG = "long"; //$NON-NLS-1$
public static final String LONG_LONG = "long long"; //$NON-NLS-1$
public static final String MUTABLE = "mutable"; //$NON-NLS-1$
public static final String NAMESPACE = "namespace"; //$NON-NLS-1$
public static final String NEW = "new"; //$NON-NLS-1$

View file

@ -176,7 +176,7 @@ public class CFunction implements IFunction, ICBinding {
while (functionName.getNestedDeclarator() != null)
functionName = functionName.getNestedDeclarator();
IType tempType = CVisitor.createType( functionName.getName() );
IType tempType = CVisitor.createType( functionName );
if (tempType instanceof IFunctionType)
type = (IFunctionType)tempType;
}

View file

@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName;
@ -43,6 +44,7 @@ public class CParameter implements IParameter {
}
private IASTName [] declarations;
private IType type = null;
public CParameter( IASTName parameterName ){
this.declarations = new IASTName [] { parameterName };
@ -53,7 +55,10 @@ public class CParameter implements IParameter {
*/
public IType getType() {
return CVisitor.createType( declarations[0] );
if ( type == null && declarations[0].getParent() instanceof IASTDeclarator)
type = CVisitor.createType( (IASTDeclarator)declarations[0].getParent() );
return type;
}
/* (non-Javadoc)

View file

@ -38,8 +38,8 @@ public class CTypeDef implements ITypedef, ITypeContainer {
* @see org.eclipse.cdt.core.dom.ast.ITypedef#getType()
*/
public IType getType() {
if (type == null)
type = CVisitor.createType(name);
if (type == null && name.getParent() instanceof IASTDeclarator)
type = CVisitor.createType((IASTDeclarator)name.getParent());
return type;
}

View file

@ -58,8 +58,8 @@ public class CVariable implements IVariable, ICBinding {
* @see org.eclipse.cdt.core.dom.ast.IVariable#getType()
*/
public IType getType() {
if (type == null)
type = CVisitor.createType(declarations[0]);
if (type == null && declarations[0].getParent() instanceof IASTDeclarator)
type = CVisitor.createType((IASTDeclarator)declarations[0].getParent());
return type;
}

View file

@ -582,7 +582,7 @@ public class CVisitor {
}
} else if( expression instanceof IASTCastExpression ){
IASTTypeId id = ((IASTCastExpression)expression).getTypeId();
return createType( id.getAbstractDeclarator().getName() );
return createType( id.getAbstractDeclarator() );
} else if( expression instanceof IASTFieldReference ){
IBinding binding = ((IASTFieldReference)expression).getFieldName().resolveBinding();
if( binding instanceof IVariable ){
@ -709,7 +709,7 @@ public class CVisitor {
try{
IFunction function = (IFunction) binding;
IFunctionType ftype = function.getType();
IType type = createType( declarator.getName() );
IType type = createType( declarator );
if( ftype.equals( type ) ){
if( parent instanceof IASTSimpleDeclaration )
((CFunction)function).addDeclarator( (IASTFunctionDeclarator) declarator );
@ -731,7 +731,7 @@ public class CVisitor {
} else {
IType t1 = null, t2 = null;
if( binding != null && binding instanceof IVariable ){
t1 = createType( declarator.getName() );
t1 = createType( declarator );
try {
t2 = ((IVariable)binding).getType();
} catch ( DOMException e1 ) {
@ -1666,16 +1666,13 @@ public class CVisitor {
// }
/**
* Create an IType for an IASTName.
* Create an IType for an IASTDeclarator.
*
* @param name the IASTName whose IType will be created
* @return the IType of the IASTName parameter
* @param declarator the IASTDeclarator whose IType will be created
* @return the IType of the IASTDeclarator parameter
*/
public static IType createType(IASTName name) {
if (!(name.getParent() instanceof IASTDeclarator)) return null;
public static IType createType(IASTDeclarator declarator) {
IASTDeclSpecifier declSpec = null;
IASTDeclarator declarator = (IASTDeclarator) name.getParent();
IASTNode node = declarator.getParent();
while( node instanceof IASTDeclarator ){
@ -1802,7 +1799,7 @@ public class CVisitor {
IType parmTypes[] = new IType[parms.length];
for( int i = 0; i < parms.length; i++ ){
parmTypes[i] = createType( parms[i].getDeclarator().getName() );
parmTypes[i] = createType( parms[i].getDeclarator() );
}
return parmTypes;
} else if ( decltor instanceof ICASTKnRFunctionDeclarator ) {
@ -1811,7 +1808,7 @@ public class CVisitor {
for( int i = 0; i < parms.length; i++ ){
IASTDeclarator dtor = getKnRParameterDeclarator( (ICASTKnRFunctionDeclarator) decltor, parms[i] );
parmTypes[i] = createType( dtor.getName() );
parmTypes[i] = createType( dtor );
}
return parmTypes;
} else {

View file

@ -1707,6 +1707,8 @@ public class CPPVisitor {
declSpec = ((IASTSimpleDeclaration)node).getDeclSpecifier();
else if( node instanceof IASTFunctionDefinition )
declSpec = ((IASTFunctionDefinition)node).getDeclSpecifier();
else if( node instanceof IASTTypeId )
declSpec = ((IASTTypeId)node).getDeclSpecifier();
IType type = createType( declSpec );
type = createType( type, declarator );

View file

@ -13,6 +13,7 @@ package org.eclipse.cdt.ui.tests.DOMAST;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.CDOM;
import org.eclipse.cdt.core.dom.IASTServiceProvider;
import org.eclipse.cdt.core.dom.ast.ASTUtil;
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
@ -104,6 +105,8 @@ import org.eclipse.ui.part.ViewPart;
*/
public class DOMAST extends ViewPart {
private static final String ASTUTIL_MENU_LABEL = "ASTUtil#"; //$NON-NLS-1$
private static final String DISPLAY_TYPE = "getNodeType(IASTNode)"; //$NON-NLS-1$
private static final String NOT_VALID_COMPILATION_UNIT = "The active editor does not contain a valid compilation unit."; //$NON-NLS-1$
private static final String EXTENSION_CXX = "CXX"; //$NON-NLS-1$
private static final String EXTENSION_CPP = "CPP"; //$NON-NLS-1$
@ -125,6 +128,7 @@ public class DOMAST extends ViewPart {
private DrillDownAdapter drillDownAdapter;
private Action openDeclarationsAction;
private Action openReferencesAction;
private Action displayNodeTypeAction;
private Action singleClickAction;
private Action loadActiveEditorAction;
private Action refreshAction;
@ -674,6 +678,11 @@ public class DOMAST extends ViewPart {
manager.add(openDeclarationsAction);
manager.add(openReferencesAction);
manager.add(new Separator());
// ASTUtil#... menu
MenuManager astMenu = new MenuManager(ASTUTIL_MENU_LABEL);
astMenu.add(displayNodeTypeAction);
manager.add(astMenu);
manager.add(new Separator());
drillDownAdapter.addNavigationActions(manager);
// Other plug-ins can contribute there actions here
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
@ -771,6 +780,19 @@ public class DOMAST extends ViewPart {
openReferencesAction.setText(OPEN_REFERENCES);
openReferencesAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages()
.getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
displayNodeTypeAction = new Action() {
public void run() {
ISelection selection = viewer.getSelection();
if (selection instanceof IStructuredSelection &&
((IStructuredSelection)selection).getFirstElement() instanceof TreeObject &&
((TreeObject)((IStructuredSelection)selection).getFirstElement()).getNode() != null) {
showMessage("ASTUtil#getNodeType(IASTNode): \"" + ASTUtil.getNodeType(((TreeObject)((IStructuredSelection)selection).getFirstElement()).getNode()) + "\""); //$NON-NLS-1$ //$NON-NLS-2$
}
} };
displayNodeTypeAction.setText(DISPLAY_TYPE);
displayNodeTypeAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages()
.getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
singleClickAction = new ASTHighlighterAction(part);
}